基于深度学习框架pytorch搭建卷积神经网络ResNet

王尧的技术 2019-01-03

pytorch

在开始深度学习项目之前,选择一个合适的框架是非常重要的,因为选择一个合适的框架能起到事半功倍的作用。深度学习框架PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。它不仅更加灵活,支持动态图,而且提供了强大的Python接口。

基于深度学习框架pytorch搭建卷积神经网络ResNet

pytorch

神经网络难以训练的问题

神经网络之所以难以训练,是因为存在着梯度消失的问题,离 loss 函数越远的层,在反向传播的时候,梯度越小,就越难以更新,随着层数的增加,这个现象越严重。

基于深度学习框架pytorch搭建卷积神经网络ResNet

神经网络

有两种常见的方案来解决这个问题:

  1. 按层训练,先训练比较浅的层,然后在不断增加层数
  2. 使用更宽的层,或者增加输出通道,而不加深网络的层数

这两种方案或多或少的都存在一些问题,ResNet 通过引入了跨层连接(残差块)解决了梯度回传消失的问题。

ResNet

2015 年 ImageNet 比赛上卷积神经网络ResNet大获全胜,它是由微软亚洲研究院提出的,ResNet 有效地解决了深度神经网络难以训练的问题,可以训练高达 1000 层的卷积网络。

基于深度学习框架pytorch搭建卷积神经网络ResNet

普通连接和跨层连接

如图所示,左边的表示普通的卷积神经网络的连接方式,上层的梯度必须要一层一层传回来。而右边的图使用的是跨层连接(残差块),相当于中间有了一条更短的路,梯度能够从这条更短的路传回来,避免了梯度过小的情况,残差网络ResNet的结构其实就是上面这种残差块的堆叠。

使用pytorch搭建ResNet

使用深度学习框架pytorch可以快速方便的帮助我们搭建一个卷积神经网络ResNet,具体代码如下所示:

def conv3x3(in_channel, out_channel, stride=1):
 return nn.Conv2d(in_channel, out_channel, 3, stride=stride, padding=1, bias=False)
class residual_block(nn.Module):
 def __init__(self, in_channel, out_channel, same_shape=True):
 super(residual_block, self).__init__()
 self.same_shape = same_shape
 stride=1 if self.same_shape else 2
 
 self.conv1 = conv3x3(in_channel, out_channel, stride=stride)
 self.bn1 = nn.BatchNorm2d(out_channel)
 
 self.conv2 = conv3x3(out_channel, out_channel)
 self.bn2 = nn.BatchNorm2d(out_channel)
 if not self.same_shape:
 self.conv3 = nn.Conv2d(in_channel, out_channel, 1, stride=stride)
 
 def forward(self, x):
 out = self.conv1(x)
 out = F.relu(self.bn1(out), True)
 out = self.conv2(out)
 out = F.relu(self.bn2(out), True)
 
 if not self.same_shape:
 x = self.conv3(x)
 return F.relu(x+out, True)

这就是基于深度学习框架pytorch搭建卷积神经网络ResNet的原理和过程

相关推荐