ResNet-50 结构

ResNet-50 结构,第1张

ResNet有2个基本的block,一个是Identity Block,输入和输出的dimension是一样的,所以可以串联多个;另外一个基本block是Conv Block,输入和输出的dimension是不一样的,所以不能连续串联,它的作用本来就是为了改变特征向量的dimension

因为CNN最后都是要把输入图像一点点的转换成很小但是depth很深的feature map,一般的套路是用统一的比较小的kernel(比如VGG都是用3*3),但是随着网络深度的增加,output的channel也增大备型(学到败滚孝的东西察稿越来越复杂),所以有必要在进入Identity Block之前,用Conv Block转换一下维度,这样后面就可以连续接Identity Block.

Conv Block:

Identity Block:

其实就是在shortcut path的地方加上一个conv2D layer(1*1 filter size),然后在main path改变dimension,并与shortcut path对应起来.

ResNetV1-50流程如下, 不使用bottleneck, 且只有resnetv1在initial_conv后面做BN和Relu:

Keras版结构如下, res2a代表stage2的第1个block, branch1是shortcut path, branch2是main path, branch2a代表是main path的第1个卷积:

在pytorch中的torchvision封装了Resnet的源码,我们通过对源码的分析进一步了解ResNet网络结构,方便对以后对ResNet结构的理解,以及日后搭建自己的网络,或者修改别人的网络。

首先我们需要先了解ResNet系列的网络结构。

从源码中我们可以看到他直接引入了 Bottleneck 后边接了 3,4,6,3 层从上图中可以看到

在ResNet中ResNet50 的结构在 conv2_x 中有三个 卷积层的堆叠

当然同理在 conv3_ 中有4个卷积层的堆叠,在ResNet中将卷积层分为4个大层,也就是[3,4,6,3]分别代表每个大层中卷积的重复次数

总共是 层

不过这里涉及到了一个 Bottleneck 类,可以把一个 Bottleneck 当成一个基础的block就是对应上图中 卷积核大小的组合

在论文中数据首举晌御先进入的是谨歼一个卷积和一个池化层后出来的就是个56* 56 *64的大小的图正岩片了,这样就再进入到一个大层中。

因此在输入到 Bottleneck 之前得到一个56(height)* 56(weight) * 64(channel)大小的 feature map

根据源码中我们可以看到1 *1 的卷积核以及3 * 3 的卷积核都不会改变输入的 feature map 的大小

下面看一下 Bottleneck 的 forward 函数

在downsample,因为 feature map 的大小不会改变,但是经过 Bottleneck 后他的 channel 变成原来的4倍,因此想要和原来的 feature map 相加,需要将原来的 feature map 也变为原来的4倍, downsample 的作用就是为了保持当前的维度是一样的方便进行计算。

Resnet 也是由 __init__ 和 forward 构成

为了方便分析 这里首先分析 init 函数,在 init 中最重要的是 _make_layer 函数

以 layer1 为例

block 为 Bottleneck , planes=64 (即 channel 数目) blocks=3 ([3,4,6,3] 分别代表每一层的 blocks 数目)这里要注意 layer1 的 stride 为 1 其他layer的 stride 为 2

对于 layer1 而言

因此需要经过 downsample 才能够使得残差和经过该层的 feature map 能够相加, downsample 即为右路部分

主体分支

downsample 分支

更新 inplanes=64*4

其余的都是一样的我们可以看到他的结构

forward


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12566445.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存