ResNet:Deep Residual Learning for Image Recognition

ResNet通过引入残差学习解决了深度神经网络中训练误差增大的问题。其核心思想是学习残差函数F(x),使得H(x) = F(x) + x,当F(x)=0时形成恒等映射。恒等变换的使用有助于优化过程,避免梯度消失。实验表明,ResNet在保持较低训练和测试误差的同时,优化效果优于传统深层网络。

背景

There exists a solution by construction to the deeper model: the added layers are constructed as identity mappings, and the other layers are copied from the learned shallower model. The existence of this constructed solution indicates that a deeper model should produce no higher training error than its shallower counterpart.

CNN可以提取到不同层级的特征(low/mid/high level),且网络层数越高,提取到的特征语义信息越丰富。然而研究者发现,当网络不断加深时,网络的training error与test error均增大。这并不是因为过拟合,因为过拟合的话应该是training error减小,test error增大,而且这种现象还会随着深度加深而变差。这并不符合逻辑,因为可以把深层网络看做一个浅层网络+由增加的层组成的恒等变换,深层网络的训练误差至少也能达到与浅层网络一样的训练误差才对。而深层网络显然没有把这种恒等变换学习到。因此出现了ResNet,它的存在本质上就是学习到这个恒等变换。

ResNet

当一个深层网络后面的那些层是恒等变换,那么深层网络就退化为了一个浅层网络。现在要解决的就是学习恒等变换函数了。多层的神经网络理论上可以拟合任意函数,若直接让一些层去拟合一个潜在的恒等变换函数H(x) = x比较困难,这可能就是深层网络难以训练的原因。但是,如果把网络设计为H(x) = F(x) + x,如下图。我们可以转换为学习一个残差函数F(x) = H(x) - x. 只要F(x)=0,就构成了一个恒

Deep Residual Learning for Image Recognition》由何恺明、张祥雨、任少卿、孙剑所著,是2016年CVPR最佳论文。该论文提出的ResNet深度残差网络)通过残差模块解决深层网络的退化问题,大大提升了神经网络深度,使各类计算机视觉任务能从深度模型提取出的特征中获益。ResNet还获得了2015年ImageNet图像分类、定位、目标检测竞赛冠军,MS COCO目标检测、图像分割冠军,并在ImageNet图像分类性能上超过人类水平[^1]。 残差学习框架是ResNet的核心思想,它能有效缓解深度网络的退化问题,使得网络层数可以进一步增加,而不会导致梯度消失或模型性能下降[^2]。与早期训练多层感知机添加线性层、部分中间层连接辅助分类器解决梯度消失和爆炸问题不同,也和“highway networks”使用含参数的shortcut搭配门函数不同,ResNet的残差连接不含参数,且identity shortcut并非封闭,所有信息可直接传入以学习额外的残差函数,同时随着网络深度增加精确度也会增加[^4]。 在ImageNet上的实现遵循了AlexNet和VGGNet中的一些操作。图像的短边会随机resize到[256,480]的范围(长边等比例缩放),接着从resize后的图像或其水平翻转图像中随机裁剪出224×224大小的图像,并将每个像素减去该坐标上所有像素值的平均。每次卷积之后、激活函数之前应用BN。按照特定论文初始化权重,plain和residual网络的训练都是train from scratch。使用MBGD,mini - batch size为256,初始学习率设为0.1,当loss不再明显下降时,学习率除以10。模型共训练60×10⁴次迭代,weight decay设为0.0001,momentum参数设为0.9,且不使用dropout[^3]。 以下是一个简单的使用PyTorch实现ResNet残差块的代码示例: ```python import torch import torch.nn as nn class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_channels, out_channels, stride=1): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(out_channels) self.shortcut = nn.Sequential() if stride != 1 or in_channels != self.expansion * out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, self.expansion * out_channels, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(self.expansion * out_channels) ) def forward(self, x): out = self.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x) out = self.relu(out) return out ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值