需要的第三方库:
pytorch、matplotlib、json、os、tqdm
一、model.py的编写
参照ResNet网络结构进行构建(如下图),其中18层和34层每层主分支采用的卷积核个数与本层最后采用的卷积核个数相等,可共用同一个类进行编写;50、101、152层最后采用的卷积核个数为每层主分支采用的卷积核个数的4倍,共用另一个类进行编写
(1)18层/34层残差结构的编写
先定义一个expansion=1,对应上面说到的主干channel与输出channel相等,再定义初始化函数,设置以下几个参数:in_channel对应输入特征矩阵的深度,out_channel对应输出特征矩阵的深度,步长默认为1,下采样参数默认为None,对应虚线的残差结构(即conv3至conv5层开始时起降维作用残差结构)
再按照上图中网络结构图定义卷积层、激活函数、Batch Normalization层,注意其中卷积层的偏置需设定为False
接下来定义正向传播过程,首先将特征矩阵传入,并赋给identity,对应捷径的输出值,再判断是否使用下采样函数,再按照结构图,让x依次经过之前定义的各种层,得到主干的输出,最后与捷径输出相加,再经过激活,得到最后输出
(2)50层/101层/152层残差结构的编写
首先定义expansion=4,对应上述主干卷积核个数的4倍关系,再定义初始化函数,其内容与18层/34层基本一致,其中width实为out_channel,inplace=True的作用是对传递来的tensor进行覆盖式的修改,其余定义与18层/34层相同,不多赘述
接着是正向传播过程,基本与18层/34层一致
(3)ResNet类的定义
初始化函数的编写
参数设置有:
block——对应上面写好的残差结构;blocks_num——一个列表,用于存放每层有多少个残差结构;
关键字参数设有:num_classes=1000,groups=1,width_per_group=64
然后开始定义一个完整的resnet网络的层结构,从一开始的conv1、maxpool,到中间的conv2到conv5,再到最后的平均池化和全连接;然后对卷积层进行初始化(_make_layer函数定义详情在下面)
残差结构生成函数(_make_layer函数)的编写
参数设置:
block——对应上面写好的残差结构;channel——对应第一层残差结构卷积核个数;block_num——该层残差结构个数
然后对下采样函数进行定义,判断条件只有conv3到conv5可以通过,即下采样函数不对conv2生效,然后定义一个layers用于存放一个conv下的残差结构,在利用循环,将对应个数的残差结构放入其中,最后返回打包的结构
正向传播过程
将初始化函数中定义好的各结构按resnet结构图的顺序依次写即可,注意进行全连接之前要先进行展平
(4)各种ResNet的定义
列表即各种resnet的conv2到conv5对应的残差结构个数
二、train.py的编写
大部分代码与vgg网络相同,下面只讲述不同的方面
(1)数据预处理
标准化处理时使用的参数来自于官网,与vgg不同;对验证集的处理也不同,是先通过resize将最小边缩放到256(原图片的长宽比不动),再通过中心裁剪裁剪出224*224的图片
(2)模型实例化及损失函数和优化器
其余部分与vgg网络一致
三、predict.py的编写
数据预处理部分需要与train.py一致(如下图),其余部分与vgg网络一致
效果展示