目录
一、前言
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊|接辅导、项目定制
-
● 难度:夯实基础⭐⭐
-
● 语言:Python
3、Pytorch
3
-
● 时间:
2月
10日-
2月
17日
-
🍺要求:
-
-
1.根据本文的Tensorflow代码,编写Pytorch代码
-
2.了解ResnetV
2和Resnet的区别
-
3.改进地方可以迁移到哪里呢
二、论文解读
论文:Identity Mappings in Deep Residual Networks
论文的主要贡献:
分析了残差块的传播公式
提出了一种新的残差单元
从理论上证明为什么残差网络有效(为什么可以让梯度在网络中顺畅传递而不会爆炸和消失)
1、ResNetV2结构与ResNet结构对比
🧲 改进点:
(a)original表示原始的ResNet的残差结构,(b)proposed表示新的ResNet的残差结构。
主要差别就是
(a)结构先卷积后进行BN和激活函数计算,最后执行addition后再进行ReLU计算;(b)结构先进性BN和激活函数计算后卷积,把addition后的ReLU计算放到了残差结构内部。
📌 改进结果:作者使用这两种不同的结构再CIFAR-10数据集上做测试,模型用的是1001层的ResNet模型。从图中的结果我们可以看出,(b)proposed的测试集错误率明显更低一些,达到了4.92%的错误率。(a)original的测试集错误率是7.61%
2、关于残差结构的不同尝试
(b-f)中的快捷连接被不同的组件阻碍。为了简化插图,我们不显示BN层,这里所有的单位均采用权值层之后的BN层。图中(a-f)都是作者对残差结构的shortcut部分进行的不同尝试,作者对不同shortcut结构的尝试结果如下表所示。
作者用不同的shortcut结构的ResNet-110在CIFAR-10数据集上做测试,发现最原始的(a)original结构是最好的,也就是identity mapping恒等映射是最好的。
3、关于激活的尝试
最好的结果是(e)full pre-activation,其次是(a)original。
三、模型复现
1.Residual Block
-
''' 残差块
-
Arguments:
-
x: 输入张量
-
filters: integer, filters, of the bottleneck layer.
-
kernel_size: default 3, kernel size of the bottleneck layer.
-
stride: default 1, stride of the first layer.
-
conv_shortcut: default False, use convolution shortcut if True, otherwise identity shortcut.
-
name: string, block label.
-
Returns:
-
Output tensor for the residual block.
-
'''
-
def
block2(
x, filters, kernel_size=3, stride=1, conv_shortcut=False, name=None):
-
preact = BatchNormalization(name=name+
'_preact_bn')(x)
-
preact = Activation(
'relu', name=name+
'_preact_relu')(preact)
-
-
if conv_shortcut:
-
shortcut = Conv2D(
4*filters,
1, strides=stride, name=name+
'_0_conv')(preact)
-
else:
-
shortcut = MaxPooling2D(
1, strides=stride)(x)
if stride>
1
else x
-
-
x = Conv2D(filters,
1, strides=
1, use_bias=
False, name=name+
'_1_conv')(preact)
-
x = BatchNormalization(name=name+
'_1_bn')(x)
-
x = Activation(
'relu', name=name+
'_1_relu')(x)
-
-
x = ZeroPadding2D(padding=((
1,
1), (
1,
1)), name=name+
'_2_pad')(x)
-
x = Conv2D(filters, kernel_size, strides=stride, use_bias=
False, name=name+
'_2_conv')(x)
-
x = BatchNormalization(name=name+
'_2_bn')(x)
-
x = Activation(
'relu', name=name+
'_2_relu')(x)
-
-
x = Conv2D(
4*filters,
1, name=name+
'_3_conv')(x)
-
x = layers.Add(name=name+
'_out')([shortcut, x])
-
return x
2.堆叠Residual Block
-
def
stack2(
x, filters, blocks, stride1=2, name=None):
-
x = block2(x, filters, conv_shortcut=
True, name=name+
'_block1')
-
for i
in
range(
2, blocks):
-
x = block2(x, filters, name=name+
'_block'+
str(i))
-
x = block2(x, filters, stride=stride1, name=name+
'_block'+
str(blocks))
-
return x
3、ResNet50V2架构复现
-
''' 构建ResNet50V2 '''
-
def
ResNet50V2(
include_top=True, # 是否包含位于网络顶部的全链接层
-
preact=True, # 是否使用预激活
-
use_bias=True, # 是否对卷积层使用偏置
-
weights='imagenet',
-
input_tensor=None, # 可选的keras张量,用作模型的图像输入
-
input_shape=None,
-
pooling=None,
-
classes=1000, # 用于分类图像的可选类数
-
classifer_activation='softmax'):
# 分类层激活函数
-
img_input = Input(shape=input_shape)
-
x = ZeroPadding2D(padding=((
3,
3), (
3,
3)), name=
'conv1_pad')(img_input)
-
x = Conv2D(
64,
7, strides=
2, use_bias=use_bias, name=
'conv1_conv')(x)
-
-
if
not preact:
-
x = BatchNormalization(name=
'conv1_bn')(x)
-
x = Activation(
'relu', name=
'conv1_relu')(x)
-
-
x = ZeroPadding2D(padding=((
1,
1), (
1,
1)), name=
'pool1+pad')(x)
-
x = MaxPooling2D(
3, strides=
2, name=
'pool1_pool')(x)
-
-
x = stack2(x,
64,
3, name=
'conv2')
-
x = stack2(x,
128,
4, name=
'conv3')
-
x = stack2(x,
256,
6, name=
'conv4')
-
x = stack2(x,
512,
3, strides=
1, name=
'conv5')
-
-
if preact:
-
x = BatchNormalization(name=
'post_bn')(x)
-
x = Activation(
'relu', name=
'post_relu')(x)
-
if include_top:
-
x = GlobalAveragePooling2D(name=
'avg_pool')(x)
-
x = Dense(classes, activation=classifer_activation, name=
'predictions')(x)
-
else:
-
if pooling==
'avg':
-
# GlobalAveragePooling2D就是将每张图片的每个通道值各自加起来再求平均,
-
# 最后结果是没有了宽高维度,只剩下个数与平均值两个维度
-
# 可以理解成变成了多张单像素图片
-
x = GlobalAveragePooling2D(name=
'avg_pool')(x)
-
elif pooling==
'max':
-
x = GlobalMaxPooling2D(name=
'max_pool')(x)
-
-
model = Model(img_input, x, name=
'resnet50v2')
-
return model
4.ResNet50V2模型结构大图
转载:https://blog.csdn.net/m0_58585940/article/details/129078152