Paddle.DarkNet53框架详细介绍
2020-08-29 16:11
96 查看
Paddle.DarkNet53框架详细介绍
步骤
(一)上图从下往上看、上图从下往上看、上图从下往上看,
首先输入一张图片(h, w, c),其中h为图片高度(像素),w为图片宽度(像素),c为图片通道数,例如.jpg图片分R、G、B三个通道。
-
(二)经过第一个卷积(即: 卷积 32 3x3 256x256)位置,以(256,256,c)的图片为例
将图片的通道数由原来的 c 变成了 32
输入:图片(256, 256, c)
卷积核(filter):3x3
步长(stride):1
填充(padding):1
通道数:由 c 变成 32
输出,图片由原来的(256, 256, c)变成了(256, 256, 32)
-
(三)经过第二个卷积(即:卷积 64 3x3/2 128x128)
对图片进行下采样处理,
输入:图片(256, 256, 32)
卷积核(filter):3x3
步长(stride):2
填充(padding):1
通道数:x2
输出,图片由原来的(256, 256, 32)变成了(128, 128, 64)
-
(四)经过第一个残差块(1x)表示残差块用1次,残差块有两部分组成,分别是卷积1(即:卷积 32 1x1)、卷积2(即:卷积 64 3x3)
卷积1
输入:图片(128, 128, 64)
卷积核(filter):1x1
步长(stride):1
填充(padding):0
通道数:x0.5
输出,图片由原来的(128, 128, 64)变成了(128, 128, 32)
-
卷积2
输入:图片(128, 128, 32)
卷积核(filter):3x3
步长(stride):1
填充(padding):1
通道数:x2
输出,图片由原来的(256, 256, 32)变成了(128, 128, 64)
-
残差
输入:卷积1输入(128, 128, 64)、卷积2输出(128, 128, 64)
输出:卷积1输入(128, 128, 64) + 卷积2输出(128, 128, 64),对应位置数值相加,输出大小依旧为(128, 128, 64)
-
(五)经过残差块输出的下一个卷积(即:卷积 128 3x3/2 64x64)
对图片进行下采样处理,
输入:图片(128, 128, 64)
卷积核(filter):3x3
步长(stride):2
填充(padding):1
通道数:x2
输出,图片由原来的(128, 128, 64)变成了(64, 64, 128)
-
(六)经过第二个残差块(2x)表示残差块用2次,残差块有两部分组成,分别是卷积1(即:卷积 64 1x1)、卷积2(即:卷积 128 3x3)
卷积1
输入:图片(64, 64, 128)
卷积核(filter):1x1
步长(stride):1
填充(padding):0
通道数:x0.5
输出,图片由原来的(64, 64, 128)变成了(64, 64, 64)
-
卷积2
输入:图片(64, 64, 64)
卷积核(filter):3x3
步长(stride):1
填充(padding):1
通道数:x2
输出,图片由原来的(64, 64, 64)变成了(64, 64, 128)
-
残差
输入:卷积1输入(64, 64, 128)、卷积2输出(64, 64, 128)
输出:卷积1输入(64, 64, 128) + 卷积2输出(64, 64, 128),对应位置数值相加,输出大小依旧为(64, 64, 128)
(七)重复步骤(五)——(六),将对应位数值改改即可。
DarkNet53代码
import paddle.fluid as fluid from paddle.fluid.param_attr import ParamAttr from paddle.fluid.regularizer import L2Decay from paddle.fluid.dygraph.nn import Conv2D, BatchNorm DarkNet_cfg = {53:([1,2,8,8,4])} # 卷积神经网络特征提取 # YOLO-V3 骨干网络结构Darknet53 class ConvBNLayer(fluid.dygraph.Layer): """ 卷积 + 批归一化, BN层之后激活函数默认用leaky_relu """ def __init__(self, ch_in, ch_out, filter_size=3, stride=1, groups=1, padding=0, act='leaky', is_test=True): super(ConvBNLayer,self).__init__() self.conv = Conv2D( num_channels=ch_in, num_filters=ch_out, filter_size=filter_size, stride=stride, padding=padding, groups=groups, param_attr=ParamAttr( initializer=fluid.initializer.Normal(0.,0.02) ), bias_attr=False, act=None ) self.batch_norm = BatchNorm( num_channels=ch_out, is_test=is_test, param_attr=ParamAttr( initializer=fluid.initializer.Normal(0.,0.02), regularizer=L2Decay(0.) ), bias_attr=ParamAttr( initializer=fluid.initializer.Constant(0.0), regularizer=L2Decay(0.) ) ) self.act = act def forward(self, inputs): out = self.conv(inputs) out = self.batch_norm(out) if self.act == 'leaky': out = fluid.layers.leaky_relu(x=out,alpha=0.1) return out class DownSample(fluid.dygraph.Layer): """ 下采样,图片尺寸减半,具体实现stirde=2卷积 """ def __init__(self, ch_in, ch_out, filter_size=3, stride=2, padding=1, is_test=True): super(DownSample,self).__init__() self.conv_bn_layer = ConvBNLayer( ch_in=ch_in, ch_out=ch_out, filter_size=filter_size, stride=stride, padding=padding, is_test=is_test ) self.ch_out = ch_out def forward(self,inputs): out = self.conv_bn_layer(inputs) return out class BasicBlock(fluid.dygraph.Layer): """ 基本残差块的定义,输入x经过两层卷积,第二层的输出和输入x相加 """ def __init__(self, ch_in, ch_out, is_test=True): super(BasicBlock,self).__init__() self.conv1 = ConvBNLayer( ch_in=ch_in, ch_out=ch_out, filter_size=1, stride=1, padding=0, is_test=is_test ) self.conv2 = ConvBNLayer( ch_in=ch_out, ch_out=ch_out*2, filter_size=3, stride=1, padding=1, is_test=is_test ) def forward(self, inputs): conv1 = self.conv1(inputs) conv2 = self.conv2(conv1) out = fluid.layers.elementwise_add(x=inputs,y=conv2,act=None) return out class LayerWarp(fluid.dygraph.Layer): def __init__(self, ch_in, ch_out, count, is_test=True): super(LayerWarp,self).__init__() self.basicblock0 = BasicBlock(ch_in=ch_in, ch_out=ch_out, is_test=is_test) self.res_out_list = [] for i in range(1,count): res_out = self.add_sublayer("basic_block_%d"%(i), BasicBlock(ch_out*2, ch_out, is_test=is_test)) self.res_out_list.append(res_out) def forward(self,inputs): y = self.basicblock0(inputs) for basic_block_i in self.res_out_list: y = basic_block_i(y) return y class DarkNet53_conv_body(fluid.dygraph.Layer): def __init__(self,is_test=True): super(DarkNet53_conv_body, self).__init__() self.stages = DarkNet_cfg[53] self.stages = self.stages[0:5] # 第一层卷积 self.conv0 = ConvBNLayer( ch_in=3, ch_out=32, filter_size=3, stride=1, padding=1, is_test=is_test ) # 下采样,使用stride=2的卷积来实现 self.downsample0 = DownSample( ch_in=32, ch_out=32*2, is_test=is_test ) # 添加各个层级的实现 self.darknet53_conv_block_list = [] self.downsample_list = [] for i, stage in enumerate(self.stages): conv_block = self.add_sublayer( "stage_%d"%(i), LayerWarp(32*(2**(i+1)), 32*(2**i), stage, is_test=is_test) ) self.darknet53_conv_block_list.append(conv_block) # 两个层级之间的使用DownSample将尺寸减半 for i in range(len(self.stages) - 1): downsample = self.add_sublayer( "stage_%d_downsample"%i, DownSample(ch_in=32*(2**(i+1)), ch_out=32*(2**(i+2)), is_test=is_test) ) self.downsample_list.append(downsample) def forward(self,inputs): out = self.conv0(inputs) out = self.downsample0(out) blocks = [] for i,conv_block_i in enumerate(self.darknet53_conv_block_list): out = conv_block_i(out) blocks.append(out) if i < len(self.stages) - 1: out = self.downsample_list[i](out) return blocks[-1:-4:-1]
相关文章推荐
- struts2+spring+mybatis框架整合详细介绍
- Glide图片框架使用详细介绍(四)自定义动画
- Unity shader教程-第二课:Shader的框架和Properties详细介绍
- ThinkPHP框架视图详细介绍 View 视图--模板(九)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- 连接数据库登录 -详细介绍基本的JSP结构- 不使用任何框架
- 深度学习入门(1)之基础知识篇及百度PaddlePaddle深度学习框架介绍
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- linux kernel 时钟框架详细介绍
- 开源Java EE框架 JBoss Seam 详细介绍
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- StrangeIoc框架的详细介绍
- Intellij IDEA基于maven创建springMVC项目以及文件配置,小白搭建springmvc框架(超详细图文介绍)
- vert.x详细介绍,全异步框架
- struts2+spring+mybatis框架整合详细介绍
- Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一)
- Android EventBus框架(一)之使用详细介绍
- 物联网框架ServerSuperIO(SSIO)更新、以及增加宿主程序和配置工具,详细介绍
- Android 常见的图片加载框架详细介绍
- Glide图片框架使用详细介绍(三)自定义glide以及图片处理自定义transform