1 深度残差网络

 随着CNN的不断发展,为了获取深层次的特征,卷积的层数也越来越多。一开始的 LeNet 网络只有 5 层,接着 AlexNet 为 8 层,后来 VggNet 网络包含了 19 层,GoogleNet 已经有了 22 层。但仅仅通过增加网络层数的方法,来增强网络的学习能力的方法并不总是可行的,因为网络层数到达一定的深度之后,再增加网络层数,那么网络就会出现随机梯度消失的问题,也会导致网络的准确率下降。以下实验结果也表明确实出现了该现象,论文中称为网络退化现象,注意这和网络过拟合是两种情况。

1.1 什么是梯度爆炸、梯度消失?


上图是一个四层的全连接的网络,包括输入层、隐层(中间除了输入层跟输出层的总和)、输出层,假设每层网络激活后的输出为fi(x),其i表示第i层,x指的是第i层的输入,也就是第i-1层的输出,f是作为激活函数,那么就,反向传播算法是基于梯度下降,以目标负梯度方向对参数进行调整,参数的更新为,如果要更新第二层隐藏层的权值信息,根据链式求导法则:其实类似于就是对激活函数进行求导,如果所求导结果大于1,那么随着层数的增加,求出的梯度的更新将以指数形式相应增加,发生前文所提到的梯度爆炸;如果小于1,求出的梯度的更新将以指数形式相应减少,就会发生梯度消失。

1.2 如何解决这个问题?

 为了解决这一问题,传统的方法是采用数据初始化和正则化的方法,这解决了梯度消失的问题,但是网络准确率的问题并没有改善。而残差网络的出现可以解决梯度问题,而网络层数的增加也使其表达的特征也更好,相应的检测或分类的性能更强,再加上残差中使用了 1×1 的卷积,这样可以减少参数量,也能在一定程度上减少计算量。

 ResNet 网络的关键就在于其结构中的残差单元,如下图所示,在残差网络单元中包含了跨层连接,图中的曲线可以将输入直接跨层传递,进行了同等映射,之后与经过卷积操作的结果相加。假设输入图像为 x,输出为H(x),中间经过卷积之后的输出为F(x)的非线性函数,那最终的输出为H(x) = F(x) + x,这样的输出仍然可以进行非线性变换,残差指的是“差”,也就是F(x),而网络也就转化为求残差函数F(x) = H(x) - x,这样残差函数要比 F(x) = H (x) 更加容易优化。


 Resnet可以理解为三个人之间传话的游戏,第一个人传给第二个人,第二个人传给第三个人,那么第三个人收到的信息可能会由于第二个人理解错误,接收的信息受到影响,增加了传错的概率,所以Resnet的作用可以直跳过第二个人,直接把话给到第三个人。这个就是对于Resnet的简单理解。

1.3 什么是残差?

 ResNet提出了两种mapping:一种是identity mapping,指的就是图中”弯弯的曲线”,另一种residual mapping,指的就是除了”弯弯的曲线“那部分,所以最后的输出是 H(x) = F(x) + x,identity mapping顾名思义,就是指本身,也就是公式中的x,而residual mapping指的是“差”,也就是F(x) = H(x)−x,所以残差指的就是F(x)部分,这里有解释了一遍F(x) = H(x)−x。

2 Resnet50 网络

 Resnet50网络中包含了49 个卷积层,外加一个全连接层(FC)。如下图所示,Resnet50网络结构可以分成七个部分,第一部分不包含残差块,主要对输入进行卷积、正则化、激活函数、最大池化的计算。第二、三、四、五部分结构都包含了残差块,图中的绿色图块不会改变残差块的尺寸,只用于改变残差块的维度。在Resnet50网络结构中,残差块都有三层卷 积,那网络总共就是有1+3 × (3+4+6+3) = 49个卷积层,加上最后的全连接层总共是50层,这也是Resnet50名称的由来。网络的输入为224×224×3,经过前五部分的卷积计算,输出为7×7×2048,池化层会将其转化成一个特征向量,最后分类器会对这个特征向量进行计算并输出类别概率。

下面这张图片是Resnet文章所展示的结构图,文章会对其进行剖析,让人好理解。

Resnet50的另外一种理解。

2.1 ResNet50整体结构

上图可划分为左、中、右3个部分,三者内容分别:Resnet50整体结构;Resnet50各个stage具体结构;Bottleneck具体结构。

整体结构部分分为5个stage,其中stage 0 的结构是比较简单,可以视其为对INPUT图像的预处理,后4个Stage都由Bottleneck组成,结构较为相似。Stage 1包含3个Bottleneck,剩下的3个stage分别包括4、6、3个Bottleneck。

stage 0 阶段

  • (3,224,224) 指输入INPUT的通道数(channel)、高(height)和宽(width),即(C,H,W)。现假设输入的高度和宽度相等,所以用(C,W,W)表示。
    该stage中第1层包括3个先后操作:
    1.CONV
    CONV是卷积(Convolution)的缩写,7×7指卷积核大小,64指卷积核的数量(即该卷积层输出的通道数),/2指卷积核的步长为2。
    2.BN
    BN是Batch Normalization的缩写,即常说的BN层。
    3.RELU
    RELU指ReLU激活函数。

  • 该stage中第2层为MAXPOOL,即最大池化层,其卷积核大小为3×3、步长为2。

  • (64,56,56)是该stage输出的通道数(channel)、高(height)和宽(width),其中64等于该stage第1层卷积层中卷积核的数量,56等于224/2/2(步长为2会使输入尺寸减半)。

总体来讲,在Stage 0中,形状为(3,224,224)的输入先后经过卷积层、BN层、ReLU激活函数、MaxPooling层得到了形状为(64,56,56)的输出。

stage 1 阶段

与stage 0类似,stage1输入的形状为(64,56,56),输出的形状为(64,56,56)

Bottleneck具体结构

现在要介绍2种Bottleneck的结构。“BTNK”指的是BottleNeck的缩写。

2种Bottleneck分别对应了2种情况:输入与输出通道数相同(BTNK2)、输入与输出通道数不同(BTNK1),这一点可以结合ResNet原文。

BTNK2

BTNK2有2个可变的参数C和W,即输入的形状(C,W,W)中的c和W。

令形状为(C,W,W)的输入为x,令BTNK2左侧的3个卷积块(以及相关BN和RELU)为函数F(x),两者相加(F(x)+x)后再经过1个ReLU激活函数,就得到了BTNK2的输出,该输出的形状仍为(C,W,W),即上文所说的BTNK2对应输入x与输出F(x)通道数相同的情况。

BTNK1

BTNK1有4个可变的参数C、W、C1和S。

与BTNK2相比,BTNK1多了1个右侧的卷积层,令其为函数G(x)。BTNK1对应了输入x与输出F(x)通道数不同的情况,也正是这个添加的卷积层将x变为G(x),起到匹配输入与输出维度差异的作用(G(x)和F(x)通道数相同),进而可以进行求和F(x)+G(x)。

总结

ResNet后4个stage中都有BTNK1和BTNK2。

  • 4个stage中BTNK2参数规律相同,4个stage中BTNK2的参数全都是1个模式和规律,只是输入的形状(C,W,W)不同。
  • stage 1中BTNK1参数的规律与后3个stage不同,然而,4个stage中BTNK1的参数的模式并非全都一样。具体来讲,后3个stage中BTNK1的参数模式一致,stage 1中BTNK1的模式与后3个stage的不一样,这表现在以下2个方面:
    1.参数S:BTNK1左右两个1×1卷积层是否下采样:
     stage 1中的BTNK1:步长S为1,没有进行下采样,输入尺寸和输出尺寸相等。
     后3个stage的BTNK1:步长S为2,进行了下采样,输入尺寸是输出尺寸的2倍。
    2.参数C和C1:BTNK1左侧第一个1×1卷积层是否减少通道数
     stage 1中的BTNK1:输入通道数C和左侧1×1卷积层通道数C1相等(C=C1=64),即左侧1×1卷积层没有减少通道数。
     后3个stage的BTNK1:输入通道数C和左侧1×1卷积层通道数C1不相等(C=2*C1),左侧1×1卷积层有减少通道数。

代码实现

class Bottleneck(nn.Module):expansion = 4  # 卷积核是前一个卷积核的四倍def __init__(self, in_channel, out_channel, stride=1, downsample=None):super(Bottleneck, self).__init__()self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,kernel_size=1, stride=1, bias=False)  # squeeze channelsself.bn1 = nn.BatchNormalization(out_channel)# -----------------------------------------self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel, kernel_size=3, bias=False,stride=stride, padding=1)self.bn2 = nn.BatchNormalization(out_channel)# -----------------------------------------self.conv3 = nn.Conv2d(out_channels=out_channel * self.expansion, kernel_size=1, stride=1,bias=False)self.bn3 = nn.BatchNormalization(out_channel * self.expansion)# -----------------------------------------self.relu = nn.ReLU(inplace=True)self.downsample = downsampledef forward(self, x):identity = xif self.downsample is not None:  # 为None的话对应实线的残差结构,如果不为None则是虚线的identity = self.downsample(x)out = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out = self.relu(out)out = self.conv3(out)out = self.bn3(out)out = self.add([out, identity])out = self.relu(out)return out

引入Resnet50网络之后的效果

参考:

  1. https://zhuanlan.zhihu.com/p/353235794
  2. 哔哩哔哩—霹雳吧啦
  3. https://arxiv.org/abs/1512.03385

什么是Resnet50模型?相关推荐

  1. 寺冈labelnet使用说明_基于imagenet数据集的ResNet50模型训练示例

    基于imagenet数据集的ResNet50模型训练示例 训练前准备 数据集获取 本训练示例以imagenet数据集为例,从imagenet官方网站http://www.image-net.org/获 ...

  2. 基于ResNet50模型的行车环境下天气时间分类

    AI达人特训营 2022/6/14 雾切凉宫 一.项目简介 ​ 现在自动驾驶场景中,天气和时间(黎明.早上.下午.黄昏.夜晚)会对传感器的精度造成影响,比如雨天和夜晚会对视觉传感器的精度造成很大的影响 ...

  3. 基于ResNET50模型进行迁移学习构建中药饮片分类Web App

    本文主要介绍如何利用深度学习迁移方法进行中药分类的设计的过程 1.数据采集 大量有效的中药图片是宝贵的资源,采用自己拍照的方式收集非常耗时,可以从借助搜索引擎从网络抓取中药材图片,方法如下 (1)安装 ...

  4. 深度学习100例 | 第29天-ResNet50模型:船型识别

    作者:K同学啊 数据:公众号(K同学啊)内回复 DL+29可以获取数据 代码:全部代码已放入文中,也可以去我的 GitHub 上下载 数据中一共包含1462张数据图片,分为浮标.游轮.渡船.货船.贡多 ...

  5. pytorch实现ResNet50模型(小白学习,详细讲解)

    参考资料 作为新手学习难免会有很多不懂的地方,以下是我参考的一些资料: ResNet源码:https://github.com/pytorch/vision/blob/master/torchvisi ...

  6. 10亿级数据规模的半监督图像分类模型,Imagenet测试精度高达81.2% | 技术头条...

    译者 | linstancy 作者| I. Zeki Yanlniz, Herve Jegou, Kan Chen, Manohar Paluri, Dhruv Mahajan 编辑 | 蓝色琥珀鱼, ...

  7. ICCV2021 | SMCA:即插即用的共同注意力模型,可使DETR收敛加速10倍

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 计算机视觉领域顶级会议 ICCV(国际计算机视觉大会)于10月11日 ...

  8. TensorRT和PyTorch模型的故事

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨伯恩legacy 来源丨https://zhuanlan.zh ...

  9. 手动搭建的VGG16网络结构训练数据和使用ResNet50微调(迁移学习)训练数据对比(图像预测+前端页面显示)

    文章目录 1.VGG16训练结果: 2.微调ResNet50之后的训练结果: 3.结果分析: 4.实验效果: (1)VGG16模型预测的结果: (2)在ResNet50微调之后预测的效果: 5.相关代 ...

最新文章

  1. 基于SSM实现个人博客系统
  2. UNIX网络编程 第3章 套接字编程简介
  3. Microsoft.Net框架程序设计学习笔记(11):类型构造器
  4. 复习(三)—— 进程管理详解
  5. 面向对象——多态,抽象类,接口(二)
  6. “程序员千万不要选全栈开发”
  7. Appium+PythonUI自动化测试之uiautomatorviewer和Inspector元素定位
  8. 【Java数据结构与算法】第三章 双向链表和约瑟夫问题
  9. 题目36:二叉搜索树
  10. 关于Excel中,下拉菜单的制作。
  11. 关于scala中lazy val的几个注意事项
  12. 数值分析(1)-绪论:误差
  13. Springmvc返回中文字符乱码问题
  14. TFTP服务器的使用
  15. 软件开发流程都是什么样的呢?
  16. 恶意程序新趋势-钻粪坑+数签
  17. 用postman测试post接口的设置步骤,参数为json
  18. Linux 常用的软件包管理器/软件包管理工具详解
  19. 测试cpu是否有问题的软件,cpu测试软件|CPU检测软件有哪些 5款CPU检测工具介绍
  20. 计算机主机的输出设备,计算机的输出设备有哪些呢?

热门文章

  1. 怎么将项目上传到git仓库(gitee)
  2. 简易计算器(C语言实现)
  3. 数据、数据元素和数据项
  4. (转)Python--matplotlib绘图可视化知识点整理
  5. htons() ntohl() ntohs() htons()的区别及详解
  6. GeoHash算法获取附近店铺和距离
  7. 【UCOSIII操作系统】任务篇(1)创建任务
  8. 一、Oracle数据库的安装和配置
  9. 使用哈希函数:H(k)=3k MOD 11,并采用链地址法处理冲突。试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,求等概率情况下查找成功的查找长度,并设计构造哈希表
  10. Android Studio 中 为模拟器添加图片和图片路径(图文级教程)