【人工智能学习之卷积神经网络篇(二)】

本文详细介绍了残差网络(ResNet)的设计理念,包括残差块的引入以解决深度学习中的梯度消失问题,以及ResNet在解决深度网络性能退化上的卓越表现。此外,文章还探讨了1x1卷积在ResNet中的作用,如降维、增加非线性以及跨通道信息交融,以及如何通过批量归一化(Batch Normalization)缓解梯度消失和梯度爆炸问题,加速网络训练并提高模型的泛化能力。
摘要由CSDN通过智能技术生成

1 残差网络

1.1 背景介绍

随着深度学习的不断发展,模型的层数越来越多,网络结构也越来越复杂。但是增加网络的层数之后,训练误差往往不降反
升。由此,Kaiming He等人提出了残差网络ResNet来解决上述问题。ResNet是2015年ImageNet比赛的冠军,将识别错误率降
低到了3.6%,这个结果甚至超出了正常人眼识别的精度。在ResNet中,提出了一个非常经典的结构—残差块(Residual
block)。
自从2015年ResNet进入人们的视线,并引发人们思考之后,许多研究界人员已经开始研究其成功的秘诀,并在架构中纳入了许多新的改进。ResNet可以实现高达数百,甚至数千个层的训练,且仍能获得超赞的性能。
自从AlexNet投入使用以来,最先进的卷积神经网络(CNN)架构越来越深。虽然AlexNet只有5层卷积层,但VGG网络和GoogleNet(代号也为Inception_v1)分别有19层和22层。
但是,如果只是通过简单地将层叠加在一起,增加网络深度并不会起到什么作用。随着网络层数的增加,就会出现梯度消失问题,这就会造成网络是难以进行训练,因为梯度反向传播到前层,重复乘法可能使梯度无穷小,这造成的结果就是,随着网络
加深,其性能趋于饱和,或者甚至开始迅速退化。

其实早在ResNet之前,已经有过方法来处理梯度消失问题,但遗憾的是,似乎没有一个方法可以真正解决这个问题。
ResNet的核心思想是引入所谓的“恒等映射(identity shortcutconnection)”,可以跳过一层或多层,如下图所示:
在这里插入图片描述

1.2 梯度消失问题分析

BP算法:链式求导(复合函数求导,导数连乘),连乘过程中(0.99^365)只要有一个值接近于0,整个乘法运算就接近于0,梯度则消失,模型失去了训练的意义。loss:对loss进行链式求导,该导数根据梯度下降法进行更新权重。

1.3 传统的连接方式

在这里插入图片描述

1.4 残差块的连接方式

在这里插入图片描述
在残差块中有一点变化,将a[l]直接向后拷贝神经网络的深层。
意味着最后的等式a[l+2] = g(z[l+2]) 变成了 a[l+2] = g(z[l+2] +a[l]), 也就是加上的这个a[l]产生了一个残差块。
当前a[l] 就是残差块, 也有另一个术语叫做 跳跃连接, 指的就是a[l] 跳过一层或者几层,从而将信息传递到神经网络的更深层。
将a[l+2]展开,那么a[l+2] = g(W[l+2]a[l+1] + b[l+2] + a[l]), 假如当前W[l+2] = 0, 同时b[l+2]=0,那么残差的表达式就变为:a[l+2] = g(a[l]) =a[l], 也就是当出现参数为0的极端情况下,残差块也可以很容易得出a[l+2]=a[l], 意味着,即使神经网络增加了这两层,它的效果也不会差。因为恒等函数很简单。当然这是在极端的情况下,参数都为0,如果这些隐藏层学到一些有用的信息,那么它可能会比学习恒等函数表现都更好。
而那些不含有残差块的的普通网络情况就不一样,当网络不断加深,学习起来就会很困难。

1.5 残差网络结构

在这里插入图片描述
残差块:

import torch
from torch import nn
import torch.nn.functional as F
class ResBlock(nn.Module):
	def __init__(self, channel):
		super().__init__()
		self.conv1 = nn.Conv2d(channel, channel, kernel_size=3, padding=1)
		self.conv2 = nn.Conv2d(channel, channel, kernel_size=3, padding=1)
	def forward(self, x):
		residual = x
		ou1 = F.relu(self.conv1(x))
		ou2 = self.conv2(ou1)
		return F.relu(residual + ou2)
if __name__ == '__main__':
	x = torch.randn(1, 64, 32, 32)
	resblock = ResBlock(64)
	print(resblock(x).shape)

残差网络:

import torch
import torch.nn.functional as F
from torch import nn
class Res_Block(nn.Module):
	def __init__(self, c):
		super().__init__()
		self.conv1 = torch.nn.Conv2d(c, c, 3, padding=1)
		self.conv2 = torch.nn.Conv2d(c, c, 3, padding=1)
	def forward(self, x):
		y = F.relu(self.conv1(x))
		y = self.conv2(y)
		return F.relu(y + x)
class Net(torch.nn.Module):
	def __init__(self):
		super(Net, self).__init__()
		self.conv1 = torch.nn.Conv2d(1, 16, 3, 1)
		self.rblock1 = Res_Block(16)
		self.conv2 = torch.nn.Conv2d(16, 32, 1, 1)
	def forward(self, x):
		out = self.conv1(x)
		x = self.rblock1(out)
		y = self.conv2(x)
		return y
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值