ResNet中残差块的理解(附代码)

更新时间:2023-07-16 17:09:01 阅读: 评论:0

ResNet中残差块的理解(附代码)
原论⽂下载地址:
原代码下载地址:
⽐较完整的论⽂理解:
这⾥我只讲他的核⼼理念,残差块,也是我理解了很久的地⽅,请原谅我描述的如此⼝语化,希望能帮助⼤家理解,如果有理解的不对的地⽅,欢迎指正
生完孩子多久来月经算正常
ImageNet的⼀个更深层次的残差函数F。左图:⼀个积⽊块(56×56个特征图),如图3所⽰,⽤于ResNet-34。右图:ResNet-
50/101/152的“瓶颈”构建块。
左边的就叫做BasicBlock,右边就叫bottleneck
我们可以看到⽅框(就是⼀个卷积层layer)中的数字33,64,表⽰什么意思呢?就是卷积的⼤⼩是33的,然后维度是64,就是特征层有64个(⼤⼩是33),叠加在⼀起就是⼀个⽅块的样⼦,那在BasicBlock中,两个层的⼤⼩是相等,所以加在⼀起是长⽅体。
世界奢侈品牌这样的话,是否就能够理解,bottleneck这个残差块的名字的由来了呢?
没错,上⾯是11,64⼤⼩的块,中间是33,64⼤⼩的块,下⾯是11,256⼤⼩的块,叠加在⼀起,是不是⼀个瓶⼦的形状,上⾯细,中间粗,下⾯细。
然后我们来看⼀下代码:
ResNet类(仅展⽰代码核⼼部分)
⼏个关键点:
1.在残差结构之前,先对原始224 x 224的图⽚处理,在经过7 x 7的⼤卷积核、BN、ReLU、最⼤池化之后得到56 x 56 x 64的feature map
2.从layer1、layer2、layer3、layer4的定义可以看出,第⼀个stage不会减⼩feature map,其余都会在stage的第⼀层⽤步长2的3 x 3卷积进⾏feature map长和宽减半
3._make_layer函数中downsample对残差结构的输⼊进⾏升维,直接1 x 1卷积再加上BN即可,后⾯BasicBlock类和Bottleneck类⽤得到
4.最后的池化层使⽤的是⾃适应平均池化,⽽⾮论⽂中的全局平均池化
def __init__(lf, block, layers, num_class=1000, zero_init_residual=Fal):
super(ResNet, lf).__init__()
lf.inplanes = 64
bias=Fal)
lf.bn1 = nn.BatchNorm2d(64)
lf.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
lf.layer1 = lf._make_layer(block, 64, layers[0])
lf.layer2 = lf._make_layer(block, 128, layers[1], stride=2)
lf.layer3 = lf._make_layer(block, 256, layers[2], stride=2)
lf.layer4 = lf._make_layer(block, 512, layers[3], stride=2)
lf.avgpool = nn.AdaptiveAvgPool2d((1, 1))
lf.fc = nn.Linear(512 * pansion, num_class)
def _make_layer(lf, block, planes, blocks, stride=1):
downsample = None
if stride != 1 or lf.inplanes != planes * pansion:
downsample = nn.Sequential(
conv1x1(lf.inplanes, planes * pansion, stride),
长叶竹柏nn.BatchNorm2d(planes * pansion),
)
layers = []
layers.append(block(lf.inplanes, planes, stride, downsample))
lf.inplanes = planes * pansion
for _ in range(1, blocks):
layers.append(block(lf.inplanes, planes))
return nn.Sequential(*layers)
def forward(lf, x):
x = lf.conv1(x)
x = lf.bn1(x)
x = lf.relu(x)
x = lf.maxpool(x)
x = lf.layer1(x)
x = lf.layer2(x)
x = lf.layer3(x)
x = lf.layer4(x)
x = lf.avgpool(x)
x = x.view(x.size(0), -1)
x = lf.fc(x)
return x
BasicBlock
expansion是残差结构中输出维度是输⼊维度的多少倍,BasicBlock没有升维,所以expansion = 1残差结构是在求和之后才经过ReLU层
lf.bn1 = nn.BatchNorm2d(planes)
lf.bn2 = nn.BatchNorm2d(planes)
lf.downsample = downsample
lf.stride = stride
def forward(lf, x):
identity = x
out = lf.conv1(x)
out = lf.bn1(out)
out = lf.relu(out)
out = lf.conv2(out)
out = lf.bn2(out)
思美人歌曲
if lf.downsample is not None:
identity = lf.downsample(x)
out += identity
小人国观后感
out = lf.relu(out)
return out
bottleneck
注意Res18、Res34⽤的是BasicBlock,其余⽤的是Bottleneck
expansion = 4,因为Bottleneck中每个残差结构输出维度都是输⼊维度的4倍
lf.bn1 = nn.BatchNorm2d(planes)
lf.bn2 = nn.BatchNorm2d(planes)
做纸花lf.bn3 = nn.BatchNorm2d(planes * lf.expansion)
lf.downsample = downsample
lf.stride = stride
def forward(lf, x):
identity = x
out = lf.conv1(x)粉玫瑰代表什么意思
out = lf.bn1(out)
out = lf.relu(out)
out = lf.conv2(out)
out = lf.bn2(out)
out = lf.relu(out)
out = lf.conv3(out)
out = lf.bn3(out)
if lf.downsample is not None:
identity = lf.downsample(x)
out += identity
out = lf.relu(out)
115网盘怎么用
return out
注意Res18、Res34⽤的是BasicBlock,其余⽤的是Bottleneck 这⾥有⼀个对block代码的详解(超级好懂):

本文发布于:2023-07-16 17:09:01,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1099969.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:残差   理解   结构   池化   意思   维度   地址   下载
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图