深度学习——残差网络(ResNet)

这篇具有很好参考价值的文章主要介绍了深度学习——残差网络(ResNet)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

随着卷积神经网络的发展和普及,我们了解到增加神经网络的层数可以提高模型的训练精度和泛化能力,但简单地增加网络的深度,可能会出现“梯度弥散”“梯度爆炸”等问题。传统对应的解决方案则是权重的初始化(normalized initializatiton)和批标准化(batch normlization),这样虽然解决了梯度的问题,但深度加深了,却带来了另外的问题,就是网络性能的退化问题。

一、什么是网络的退化问题?

深度学习——残差网络(ResNet)

由上图可以看出,56-layer(层)的网络比20-layer的网络在训练集和测试集上的表现都要差【注意:这里不是过拟合(过拟合是在训练集上表现得好,而在测试集中表现得很差)】,说明如果只是简单的增加网络深度,可能会使神经网络模型退化,进而丢失网络前面获取的特征。

网络退化:在增加网络层数的过程中,training accuracy (精度)逐渐趋于饱和,继续增加层数,training accuracy 就会出现下降的现象,而这种下降不是由过拟合造成的。实际上较深模型后面添加的不是恒等映射,而是一些非线性层。

退化问题的实质:通过多个非线性层来近似恒等映射可能是困难的(恒等映射亦称恒等函数:是一种重要的映射,对任何元素,象与原象相同的映射)。神经网络在反向传播过程中要不断传播梯度,而当层数加深,梯度在传播过程中逐渐消失【而梯度消失则是导致网络退化的一个重要因素】,导致无法对前面网络的权重进行有效调整(这里大家可以想一下一条很长的绳子从头抖一下,有时候是不能影响末端的。

二、残差网络解决的问题

神经网络越来越深的时候,反传回来的梯度之间的相关性会越来越差,最后接近白噪声。因为我们知道图像是具备局部相关性的,那其实可以认为梯度也应该具备类似的相关性,这样更新的梯度才有意义,如果梯度接近白噪声,那梯度更新可能根本就是在做随机扰动。

何凯明提出残差网络概念的论文地址:https://arxiv.org/abs/1512.03385

基于网络退化问题,论文(https://arxiv.org/pdf/1702.08591.pdf)的作者通过浅层网络等同映射构造深层模型,结果深层模型并没有比浅层网络有等同或更低的错误率,推断退化问题可能是因为深层的网络并不是那么好训练,也就是求解器很难去利用多层网络拟合同等函数

如果深层网络的后面那些层是恒等映射,那么模型就退化为一个浅层网络。那当前要解决的就是学习恒等映射函数了。 但是直接让一些层去拟合一个潜在的恒等映射函数:,比较困难,这可能就是深层网络难以训练的原因。但是,如果把网络设计为:深度学习——残差网络(ResNet)       

1.残差块原理:

一个残差块的数学模型如下图示。残差网络和之前的网络最大的不,同就是多了一条identity的捷径分支。而因为这一条分支的存在,使得网络在反向传播时,损失可以通过这条捷径将梯度直接传向更前的网络,从而减缓了网络退化的问题。在第二节分析网络退化的原因时,我们了解到梯度之间是有相关性的。我们在有了梯度相关性这个指标之后,作者分析了一系列的结构和激活函数,发现resnet在保持梯度相关性方面很优秀,从梯度流来看,有一路梯度是保持原样不动地往回传,这部分的相关性是非常强的。除此之外,残差网络并没有增加新的参数,只是多了一步加法。而在GPU的加速下,这一点额外的计算量几乎可以忽略不计。

不过我们可以看到,因为残差块最后是 F ( x ) + x F(x) + x F(x)+x的操作,那么意味着 F ( x ) F(x) F(x) 与 x x x的shape必须一致。但在实际的网络搭建中,还可以利用1x1的卷积改变通道数目。

如图1。

深度学习——残差网络(ResNet)

我们可以转换为学习一个残差函数:,只要:就构成了一个恒等映射:而且,拟合残差肯定更加容易。

F是求和前网络映射,H是从输入到求和后的网络映射。比如把5映射到5.1,那么引入残差前是:

 ,

引入残差后是:,深度学习——残差网络(ResNet)

这里的和都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如S输出从5.1变到5.2,映射的输出增加了2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。明显后者输出变化对权重的调整作用更大,所以效果更好。残差的思想都是去掉相同的主体部分,从而突出微小的变化。

2、残差块代码示例:

import torch
import torch.nn as nn
#残差块
class Res_Block(nn.Module):
    def __init__(self,c):
        super(Res_Block, self).__init__()
        #残差网络要求整个模型输入和输出的通道一样
        self.layer=nn.Sequential(
            #增加Padding是为了保持通道一样
            nn.Conv2d(in_channels=c, out_channels=c, kernel_size=3, stride=1,padding=1,bias=False),
            nn.BatchNorm2d(c),#批标准化
            nn.ReLU(),
            nn.Conv2d(c, c, 3, 1,1),
            nn.BatchNorm2d(c),
            nn.ReLU(),
        )
    def forward(self,x):
        #残差网络的应用+x
        return self.layer(x)+x
if __name__ == '__main__':
    net=Res_Block(3)
    x=torch.randn(1,3,28,28)
    y=net.forward(x)
    print(y.shape)

三、残差网络讨论

至于为何shortcut(捷径)的输入是X,而不是X/2或是其他形式。作者的另一篇文章中探讨了这个问题,对以下6种结构(图2)的残差结构进行实验比较,shortcut是X/2的就是第二种,结果发现还是第一种效果好。

深度学习——残差网络(ResNet)

这种残差学习结构可以通过前向神经网络+shortcut连接实现,如结构图1所示。而且shortcut连接相当于简单执行了同等映射,不会产生额外的参数,也不会增加计算复杂度。 而且,整个网络可以依旧通过端到端的反向传播训练。 

根据多层的神经网络理论上可以拟合任意函数,那么可以利用一些层来拟合函数。问题是直接拟合 还是残差函数,拟合残差函数更简单。虽然理论上两者都能得到近似拟合,但是后者学习起来显然更容易。作者说,这种残差形式是由退化问题激发的。根据前文,如果增加的层被构建为同等函数,那么理论上,更深的模型的训练误差不应当大于浅层模型,但是出现的退化问题表明,求解器很难去利用多层网络拟合同等函数。但是,残差的表示形式使得多层网络近似起来要容易的多,如果`同等函数可被优化近似,那么多层网络的权重就会简单地逼近0来实现同等映射,即 。

 实际情况中,同等映射函数可能不会那么好优化,但是对于残差学习,求解器根据输入的同等映射,也会更容易发现扰动,总之比直接学习一个同等映射函数要容易的多。根据实验,可以发现学习到的残差函数通常响应值比较小,同等映射(shortcut)提供了合理的前提条件。

通过shortcut同等映射

深度学习——残差网络(ResNet)

F(x)与x相加就是就是逐元素相加,但是如果两者维度不同,需要给x执行一个线性映射来匹配维度:

深度学习——残差网络(ResNet)

用来学习残差的网络层数应当大于1,否则退化为线性。文章实验了layers = 2或3,更多的层也是可行的。

用卷积层进行残差学习:以上的公式表示为了简化,都是基于全连接层的,实际上当然可以用于卷积层。加法随之变为对应channel间的两个feature map逐元素相加。

1.网络结构

作者由VGG19设计出了plain 网络和残差网络,如图3中部和右侧网络。然后利用这两种网络进行实验对比。

设计网络的规则:

1.对于输出feature map大小相同的层,有相同数量的filters,即channel数相同;

2. 当feature map大小减半时(池化),filters数量翻倍。

对于残差网络,维度匹配的shortcut连接为实线,反之为虚线。维度不匹配时,同等映射有两种可选方案:直接通过zero padding 来增加维度(channel)、乘以W矩阵投影到新的空间。实现是用1x1卷积实现的,直接改变1x1卷积的filters数目。这种会增加参数。

图3:

深度学习——残差网络(ResNet)

ResNet推荐参数如上图所示,作者还用全局平均池化替代了全连接层,一方面减少了参数量,另一方面全连接层易于过拟合并且严重依赖于 dropout 正则化,而全局平均池化本身就是起到了正则化作用,其本身防止整体结构的过拟合。此外,全局平均池汇总了空间信息,因此对输入的空间转换更加健壮。

2.残差网络代码实现:

import torch
import torch.nn as nn
DEVICE=torch.device( "cuda"if torch.cuda.is_available()else"cpu")
#残差块
class Res_Block(nn.Module):
    def __init__(self,c):
        super(Res_Block, self).__init__()
        #残差网络要求整个模型输入和输出的通道一样
        self.layer=nn.Sequential(
            nn.Conv2d(c, c, 3, 1,padding=1),#增加Padding是为了保持通道一样
            nn.ReLU(),
            nn.Conv2d(c, c, 3, 1, padding=1),
            nn.ReLU(),
        )
    def forward(self,x):
        #残差网络的应用+x
        return self.layer(x)+x
#封装Net类
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer=nn.Sequential(
            nn.Conv2d(1,64,3,1,padding=1),
            nn.ReLU(),

            Res_Block(64),#实例化对象
            Res_Block(64),
            Res_Block(64),
            Pool(64,128),

            Res_Block(128),
            Res_Block(128),
            Res_Block(128),
            Res_Block(128),
            Pool(128, 256),

            Res_Block(256),
            Res_Block(256),
            Res_Block(256),
            Res_Block(256),
            Res_Block(256),
            Pool(256,512),

            Res_Block(512),
            Res_Block(512),
            # nn.Linear(512*32*32,10)
        )
        self.layer2=nn.Sequential(
            nn.Linear(512*32*32,10)
        )

    def forward(self, x):
        OUT=self.layer(x)
        OUT=OUT.reshape(-1,512*32*32)
        return self.layer2(OUT)
#实现下采样
class Pool(nn.Module):
    def __init__(self,c_in,c_out):
        super(Pool, self).__init__()
        self.layer=nn.Sequential(
            nn.Conv2d(c_in,c_out,3,1,padding=1),
            nn.ReLU(),
            nn.Conv2d(c_out,c_out,3,1,padding=1),
            nn.ReLU()
        )
    def forward(self,x):
        return self.layer(x)
if __name__ == '__main__':
    res=Net()
    x=torch.randn(32,1,32,32)
    y=res.forward(x)
    print(y.shape)
    # print(res)

作者探索的更深的网络。 考虑到时间花费,将原来的building block(残差学习结构)改为瓶颈结构,如图4。首端和末端的1x1卷积用来削减和恢复维度,相比于原本结构,只有中间3x3成为瓶颈部分。这两种结构的时间复杂度相似。此时投影法映射带来的参数成为不可忽略的部分(以为输入维度的增大),所以要使用zero padding的同等映射。替换原本ResNet的残差学习结构,同时也可以增加结构的数量,网络深度得以增加。生成了ResNet-50,ResNet-101,ResNet-152. 随着深度增加,因为解决了退化问题,性能不断提升。

总结:

关于残差网络的我还在不断学习中,以上内容大多数来自网络,我只是把他们整理了一下,并用代码实现了,后面可能会对残差网络再进行一次深入学习,拜拜。文章来源地址https://www.toymoban.com/news/detail-459043.html

到了这里,关于深度学习——残差网络(ResNet)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【深度学习】了解残差网 ResNet 和 ResNeXt 的架构

            了解和实现 ResNet 和 ResNeXt 的架构以实现最先进的图像分类:从Microsoft到 Facebook [第 1 部分], 在这篇由两部分组成的博客文章中,我们将探讨残差网络。更具体地说,我们将讨论Microsoft研究和Facebook AI研究发布的三篇论文,最先进的图像分类网络 - ResNet和ResNeXt架构

    2024年02月17日
    浏览(36)
  • 【AI】《动手学-深度学习-PyTorch版》笔记(十九):卷积神经网络模型(GoogLeNet、ResNet、DenseNet)

    发布时间:2014年 GoogLeNet的贡献是如何选择合适大小的卷积核,并将不同大小的卷积核组合使用。 之前介绍的网络结构都是串行的,GoogLeNet使用并行的网络块,称为“Inception块” “Inception块”前后进化了四次,论文链接: [1]https://arxiv.org/pdf/1409.4842.pdf [2]https://arxiv.org/pdf/150

    2024年02月12日
    浏览(61)
  • 深度学习图像分类实战——pytorch搭建卷积神经网络(AlexNet, LeNet, ResNet50)进行场景图像分类(详细)

    目录 1  一、实验过程 1.1  实验目的 1.2  实验简介 1.3  数据集的介绍 1.4  一、LeNet5网络模型 1.5  二、AlexNet网络模型 1.6  三、ResNet50(残差网络)网络模型  二、实验代码 导入实验所需要的库  参数配置 数据预处理 重新DataSet 加载数据转为DataLoader函数 可视化一批训练

    2024年02月05日
    浏览(63)
  • Python基于深度学习机器学习卷积神经网络实现垃圾分类垃圾识别系统(GoogLeNet,Resnet,DenseNet,MobileNet,EfficientNet,Shufflent)

    文章目录 1 前言+ 2 卷积神经网络(CNN)详解+ 2.1 CNN架构概述+ 2.1.1 卷积层+ 2.1.2 池化层+ 2.1.3 全连接层 2.2 CNN训练过程+ 2.3 CNN在垃圾图片分类中的应用 3 代码详解+ 3.1 导入必要的库+ 3.2 加载数据集+ 3.3 可视化随机样本+ 3.4 数据预处理与生成器+ 3.5 构建、编译和训练CNN模型+ 3.5.

    2024年02月04日
    浏览(47)
  • 经典神经网络论文超详细解读(五)——ResNet(残差网络)学习笔记(翻译+精读+代码复现)

    《Deep Residual Learning for Image Recognition》这篇论文是何恺明等大佬写的,在深度学习领域相当经典,在2016CVPR获得best paper。今天就让我们一起来学习一下吧! 论文原文:https://arxiv.org/abs/1512.03385 前情回顾: 经典神经网络论文超详细解读(一)——AlexNet学习笔记(翻译+精读)

    2024年02月08日
    浏览(44)
  • 残差网络ResNet

    残差网络的提出,是为了解决深度学习中的退化问题。 退化问题指的是随着神经网络层数的增加,网络性能反而逐渐降低的现象。换句话说,当我们不断增加神经网络的层数时,神经网络的训练误差可能会持续下降,但是验证集误差却不断增加,最终网络性能达到瓶颈。 退化

    2024年02月06日
    浏览(43)
  • ResNet-残差网络二

    上一篇讲了 ResNet 论文中的第一篇:Deep Residual Learning for Image Recognition,主要是介绍了残差网络解决了网络随着深度的增加而带来的退化问题;介绍了残差的概念及两种残差结构;最后通过丰富的实验来证明残差结构对增加网络深度,增强表达能力的准确率有足够的优化作用,

    2024年02月14日
    浏览(38)
  • 残差网络 ResNet

    目录 1.1 ResNet 2.代码实现 如上图函数的大小代表函数的复杂程度,星星代表最优解,可见加了更多层之后的预测比小模型的预测离真实最优解更远了, ResNet做的事情就是使得模型加深一定会使效果变好而不是变差。 参考: inplace=True (原地操作)-CSDN博客 Python中initialize的全面讲

    2024年01月22日
    浏览(35)
  • 适合新手搭建ResNet50残差网络的架构图(最全)

    适合新手搭建ResNet50残差网络的架构图+代码(最全) 网上的教程大多复杂难懂,不适合新手,本来神经网络就难,这些教程本身更难,对新手极度不友好,因此自己做的这个架构图和写的代码,面向新手,大神跳过 后续还会上传ResNet30,FCN,UNet等架构图和代码。

    2024年02月14日
    浏览(29)
  • 卷积神经网络学习—Resnet50(论文精读+pytorch代码复现)

    如果说在CNN领域一定要学习一个卷积神经网络,那一定非Resnet莫属了。 接下来我将按照:Resnet论文解读、Pytorch实现ResNet50模型两部分,进行讲解,博主也是初学者,不足之处欢迎大家批评指正。 预备知识 :卷积网络的深度越深,提取的特征越高级,性能越好,但传统的卷积

    2024年01月19日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包