ResNet--从理论到实践

1、理论

理论部分参考:https://blog.csdn.net/weixin_43624538/article/details/85049699 (我下边这篇写得有点简略,完整公式还是直接点击原博链接吧,我不想复制了,因为会导致格式乱八七糟的。强烈恳求CSDN能出一个一键转载的功能!!!)

ResNet论文地址: https://arxiv.org/pdf/1512.03385.pdf 

添加了自己的理解,如果有理解不对的地方,还请指出!

 

ResNet主要思想恒等映射(identity mapping) 。当我们直接对网络进行简单的堆叠到特别长,网络内部的特征在其中某一层已经达到了最佳的情况,这时候剩下层应该不对该特征做任何改变,自动形成恒等映射的形式,至少让深度网络实现和浅层网络一样的性能,即让深度网络后面的层至少实现恒等映射的作用。

前向传播:

å¨è¿éæå¥å¾çæè¿°

根据上图,copy一个浅层网络的输出加给深层的输出,这样当网络特征达到optimal的时候更深层恒等映射的任务就从原来堆叠的层中释放到新建的这个恒等映射关系中,而原来层中的任务就从恒等映射转为全0。
F(x)=H(x)−x,x为浅层的输出,H(x)为深层的输出,F(x) 为夹在二者中间的的两层代表的变换,当浅层的x代表的特征已经足够成熟,如果任何对于特征x 的改变都会让loss变大的话,F(x) 会自动趋向于学习成为0,x 则从恒等映射的路径继续传递。这样就在不增加计算成本的情况下实现了一开始的目的:在前向过程中,当浅层的输出已经足够成熟(optimal),让深层网络后面的层能够实现恒等映射的作用。
 

反向传播

residual模块将输出分成F(x)+x 两部分,其中F依然是x的函数,也就是说F实际上是对于x 的补充,是对于x 的fun-tuning,这样就把任务从根据x 映射成一个新的y 转为了根据x 求x 和y 之间的差距,这明显是一个相对更加简单的任务,论文是这么写的,到底怎么简单的,我们来分析一下。

举个例子,假设不加residual模块的输出为h(x) 。x=10,h(x)=11 ,h 简化为线性运算Wh ,Wh 明显为1.1,加了redidual模块后,F(x)=1 ,H(x)=F(x)+x=11 ,F也简化为线性运算,对应的WF为0.1。当标签中的真实值为12,反向传播的损失为1,而对于F中的参数和h中参数回传的损失实际上是一样大的而且梯度都是x的值,但是对于F的参数就从0.1到0.2,而h的参数是从1.1到1.2,因此redidual模块会明显减小模块中参数的值从而让网络中的参数对反向传导的损失值有更敏感的响应能力,虽然根本上没有解决回传的损失小得问题,但是却让参数减小,相对而言增加了回传损失的效果,也产生了一定的正则化作用。

其次,因为前向过程中有恒等映射的支路存在,因此在反向传播过程中梯度的传导也多了更简便的路径,仅仅经过一个relu就可以把梯度传达给上一个模块。

所谓反向传播就是网络输出一个值,然后与真实值做比较的到一个误差损失,同时将这个损失做差改变参数,返回的损失大小取决于原来的损失和梯度,既然目的是为了改变参数,而问题是改变参数的力度过小,则可以减小参数的值,使损失对参数改变的力度相对更大。

因此残差模块最重要的作用就是改变了前向和后向信息传递的方式从而很大程度上促进了网络的优化。
 

图左:basic block ,用于18/34层。    图右:bottleneck,用于50/101/152层。

左侧的通道数是64,右侧的通道数是256,bottleneck残差模块将两个3*3的卷积核换成了1*1+3*3+1*1的形式,第一个1*1用来降维,3*3用来在降维后的特征上卷积,后一个1*1用来升维(下边会介绍)。这样操作,会使参数大大减少,

basic block参数个数

3*3*256*64+3*3*256*64=294912

bottleneck参数个数

1*1*256*64+3*3*64*64+1*1*64*256=69632

å¨è¿éæå¥å¾çæè¿°

需要注意的一点是对于block和block之间的特征大小不同,即网络深度不同时(如下图34-layer residual的虚线),因为是在F内部发生变化,x也需要随之变化才能对应相加,论文中采用的调整方法是采用0填充来拟补深度,但是如何缩小特征尺寸没有说,而且官网的复现方式都是直接用一个1*1的卷积核来操作这一步(即:升维),理论上讲会破坏恒等映射。

 

2、代码

除了原博中提到的基于pytorch的实现代码: https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py 

还有基于tensorflow实现的代码: https://github.com/tensorpack/tensorpack/tree/master/examples/ResNet 

博客 https://blog.csdn.net/superman_xxx/article/details/65452735 中也有50/101/152源码。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值