Tensorflow2.0之深度残差网络resnet18实现

Tensorflow2.0之深度残差网络resnet18实战

深度残差网络

AlexNet、VGG、GoogLeNet 等网络模型的出现将神经网络的发展带入了几十层的阶段,研究人员发现网络的层数越深,越有可能获得更好的泛化能力。但是当模型加深以后,网络变得越来越难训练,这主要是由于梯度弥散和梯度爆炸现象造成的。在较深层数的神经网络中,梯度信息由网络的末层逐层传向网络的首层时,传递的过程中会出现梯度接近于0 或梯度值非常大的现象。网络层数越深,这种现象可能会越严重。

那么怎么解决深层神经网络的梯度弥散和梯度爆炸现象呢?一个很自然的想法是,既然浅层神经网络不容易出现这些梯度现象,那么可以尝试给深层神经网络添加一种回退到浅层神经网络的机制。当深层神经网络可以轻松地回退到浅层神经网络时,深层神经网络可以获得与浅层神经网络相当的模型性能,而不至于更糟糕。

通过在输入和输出之间添加一条直接连接的Skip Connection 可以让神经网络具有回退的能力。以VGG13 深度神经网络为例,假设观察到VGG13 模型出现梯度弥散现象,而10 层的网络模型并没有观测到梯度弥散现象,那么可以考虑在最后的两个卷积层添加SkipConnection,通过这种方式,网络模型可以自动选择是否经由这两个卷积层完成特征变换,还是直接跳过这两个卷积层而选择Skip Connection,亦或结合两个卷积层和Skip Connection 的输出

ResNet原理

ResNet 通过在卷积层的输入和输出之间添加Skip Connection 实现层数回退机制,如下图所示,输入𝒙通过两个卷积层,得到特征变换后的输出ℱ(𝒙),与输入𝒙进行对应元素的相加运算,得到最终输出ℋ(𝒙):ℋ(𝒙) = 𝒙 + ℱ(𝒙)
在这里插入图片描述

ResBlock 实现

深度残差网络并没有增加新的网络层类型,只是通过在输入和输出之间添加一条SkipConnection,因此并没有针对ResNet 的底层实现。在TensorFlow 中通过调用普通卷积层即可实现残差模块。
首先创建一个新类,在初始化阶段创建残差块中需要的卷积层、激活函数层等,首先新建ℱ(𝑥)卷积层,代码如下:

class BasicBlock(layers.Layer):
	# 残差模块类
	def __init__(self, filter_num, stride=1):
	super(BasicBlock, self).__init__()
	# f(x)包含了2 个普通卷积层,创建卷积层1
	self.conv1 = layers.Conv2D(filter_num, (3, 3), strides=stride, paddi
	ng='same')
	self.bn1 = layers.BatchNormalization()
	self.relu = layers.Activation('relu')
	# 创建卷积层2
	self.conv2 = layers.Conv2D(filter_num, (3, 3), strides=1, padding='s
	ame')
	self.bn2 = layers.BatchNormalization()

当ℱ(𝒙)的形状与𝒙不同时,无法直接相加,我们需要新建identity(𝒙)卷积层,来完成𝒙的形状转换。紧跟上面代码,实现如下:

	if stride != 1: # 插入identity 层
	self.downsample = Sequential()
	self.downsample.add(layers.Conv2D(filter_num, (1, 1), strides=st
	ride))
	else: # 否则,直接连接
	self.downsample = lambda x:x

在前向传播时,只需要将ℱ(𝒙)与identity(𝒙)相加,并添加ReLU 激活函数即可。前向计算函数代码如下:

	def call(self, inputs, training=None):
		# 前向传播函数
		out = self.conv1(inputs) # 通过第一个卷积层
		out = self.bn1(out)
		out = self.relu(out)
		out = self.conv2(out) # 通过第二个卷积层
		out = self.bn2(out)
		# 输入通过identity()转换
		identity = self.downsample(inputs)
		# f(x)+x 运算
		output = layers.add([out, identity])
		# 再通过激活函数并返回
		output = tf.nn.relu(output)
		return output

DenseNet

Skip Connection 的思想在ResNet 上面获得了巨大的成功,研究人员开始尝试不同的Skip Connection 方案,其中比较流行的就是DenseNet [11]。DenseNet 将前面所有层的特征图信息通过Skip Connection 与当前层输出进行聚合,与ResNet 的对应位置相加方式不同,DenseNet 采用在通道轴𝑐维度进行拼接操作,聚合特征信息
如下图 所示,输入𝑿 通过H1卷积层得到输出𝑿1,𝑿1与𝑿 在通道轴上进行拼接,得到聚合后的特征张量,送入H2卷积层,得到输出𝑿2,同样的方法,𝑿2与前面所有层的特征信息 𝑿1与𝑿 进行聚合,再送入下一层。如此循环,直至最后一层的输出𝑿4和前面所有层的特征信息:{𝑿𝑖}𝑖= 1 2 3进行聚合得到模块的最终输出。这样一种基于SkipConnection稠密连接的模块叫做Dense Block。

在这里插入图片描述
DenseNet 通过堆叠多个Dense Block 构成复杂的深层神经网络
在这里插入图片描述
比较了不同版本的DenseNet 的性能、DenseNet 与ResNet 的性能比较,以及DenseNet 与ResNet的训练曲线
在这里插入图片描述

ResNet18实战

网络的搭建

我们将实现18 层的深度残差网络ResNet18,并在CIFAR10 图片数据集上训练与测试。并将与13 层的普通神经网络VGG13 进行简单的性能比较。
标准的 ResNet18 接受输

### ResNet18 深度学习模型架构与实现 ResNet18 是一种基于残差网络ResNet)的深度学习模型,它通过引入跳跃连接解决了深度神经网络训练中的梯度消失问题。这种设计使得训练非常深的网络成为可能,并显著提升了模型性能[^2]。 #### 1. ResNet18 的整体架构 ResNet18 的架构由一系列卷积层、批归一化层(Batch Normalization)、ReLU 激活函数以及全连接层组成。它的主要特点是使用了残差块(Residual Block),每个残差块包含两个 3x3 卷积层和一个跨层的恒等映射(Identity Mapping)。当输入和输出维度不匹配时,会通过线性投影进行调整以匹配维度[^2]。 以下是 ResNet18 的主要组成部分: - **输入层**:接收大小为 224x224 的图像。 - **卷积层**:第一层卷积核大小为 7x7,步长为 2,通道数为 64。 - **最大池化层**:步长为 2,池化窗口大小为 3x3。 - **残差块**:共包含 4 个阶段,每个阶段包含多个残差块,具体如下: - 第一阶段:2 个残差块,通道数为 64。 - 第二阶段:2 个残差块,通道数为 128。 - 第三阶段:2 个残差块,通道数为 256。 - 第四阶段:2 个残差块,通道数为 512。 - **全局平均池化层**:将特征图降维为固定大小。 - **全连接层**:用于分类任务,输出类别数根据具体任务而定。 #### 2. ResNet18实现代码 以下是一个基于 PyTorch 的 ResNet18 实现示例: ```python import torch import torch.nn as nn import torchvision.models as models # 加载预训练的 ResNet18 模型 model = models.resnet18(pretrained=True) # 将模型指定到 GPU 上运行(如果可用) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = model.to(device) # 示例:定义输入数据并将其移动到 GPU input_tensor = torch.randn(1, 3, 224, 224).to(device) # 假设输入为单张 RGB 图像 output = model(input_tensor) print(output) ``` 上述代码展示了如何加载预训练的 ResNet18 模型,并将其指定到 GPU 上运行[^4]。 #### 3. 预训练模型下载 ResNet18 的预训练模型可以从官方或第三方资源中获取。例如,在 PyTorch 中可以直接通过 `torchvision.models` 加载预训练权重。此外,也可以从其他开源项目中下载特定变体的预训练模型。例如,ResNet50 IBN-A 的预训练模型可以参考以下链接进行下载[^3]: ```plaintext https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet50_ibn_a-d9d0bb7b.pth ``` 需要注意的是,不同版本的 ResNet 可能具有不同的预训练权重,因此在选择时应确保其与目标任务相匹配。 ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值