Python深度学习神经网络残差块

目录
  • ResNet模型
  • 训练模型

ResNet沿用VGG完整的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层设计。残差块里首先有2个相同输出通道数的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层。每个卷积层后接一个批量归一化层和ReLU激活函数。然后我们通过跨层数据通路,跳过这2个卷积运算,将输入直接加在最后的ReLU激活函数前。这样的设计要求2个卷积层的输出与输入形状一样,从而可以相加。如果想改变通道数,就需要引入一个额外的 1 × 1 1\times1 1×1卷积层来讲输入变换成需要的形状后再做相加运算。

残差块的实现如下:

import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l

class Residual(nn.Module):
	def __init__(self, input_channels, num_channels, use_1x1conv=False, strides=1):
	super().__init__()
	self.conv1 = nn.Conv2d(input_channels, num_channels, kernel_size=3, padding=1, stride=strides)
	self.conv2 = nn.Conv2d(num_channels, num_channels, kernel_size=3, padding=1)

	if use_1x1conv:
		self.conv3 = nn.Conv2d(input_channels, num_channels, kernel_size=1, stride=strides)
	else:
		self.conv3 = None
	self.bn1 = nn.BatchNorm2d(num_channels)
	self.bn2 = nn.BatchNorm2d(num_channels)
	self.relu = nn.ReLU(inplace=True)

def forward(self, X):
	Y = F.relu(self.bn1(self.conv1(X)))
	Y = self.bn2(self.conv2(Y))
	if self.conv3:
		X = self.conv3(X)
	Y += X
	return F.relu(Y)

如下图所示,此外码生成两种类型的网络:一种是在use_1x1conv=False、应用ReLU非线性函数之前,将输入添加到输出。另一种是在use_1x1conv=True时,添加通过 1 × 1 卷积调整通道和分辨率。

下面我们来查看输入和输出形状一致的情况。

blk = Residual(3, 3)
X = torch.rand(4, 3, 6, 6)
Y = blk(X)
Y.shape
torch.Size([4, 3, 6, 6])

我们也可以在增加输出通道数的同时,减半输出的高和宽。

blk = Residual(3, 6, use_1x1conv=True, strides=2)
blk(X).shape
torch.Size([4, 6, 3, 3])

ResNet模型

ResNet的前两层为:在输出通道数为64、步幅为2的 7 × 7 卷积层后,接步幅为2的 3 × 3 的最大汇聚层。不同之处在于ResNet的每个卷积层后增加了批量归一化层。

b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
				   nn.BatchNorm2d(64), nn.ReLU(),
				   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

ResNet使用4个由残差块组成的模块,每个模块使用若干个同样输出通道数的残差块。第一个模块的通道数同输入通道数一致。由于之前已经使用了步幅为2的最大汇聚层,所以无须减小高和宽。之后的每个模块在第一个残差块里将上一个模块的通道数翻倍,并将高和宽减半。

下面我们来实现这个模块。注意,我们对第一个模块做了特别处理。

def resnet_block(input_channels, num_channels, num_residuals, first_block=False):
	blk = []
	for i in range(num_residuals):
		if i == 0 and not first_block:
			blk.append(Residual(input_channels, num_channels, use_1x1conv=True, strides=2))
		else:
			blk.append(Residual(num_channels, num_channels))
	return blk

接着在ResNet加入所有残差块,这里每个模块使用2个残差块。

b2 = nn.Sequential(*resnet_block(64, 64, 2, first_block=True))
b3 = nn.Sequential(*resnet_block(64, 128, 2))
b4 = nn.Sequential(*resnet_block(128, 256, 2))
b5 = nn.Sequential(*resnet_block(256, 512, 2))

最后,在ResNet中加入全局平均汇聚层,以及全连接层输出。

net = nn.Sequential(b1, b2, b3, b4, b5,
					nn.AdaptiveAvgPool2d((1, 1)),
					nn.Flatten(), nn.Linear(512, 10))

每个模块有4个卷积层(不包括恒等映射的 1 × 1 1\times1 1×1卷积层)。加上第一个 7 × 7 7\times7 7×7卷积层和最后一个全连接层,共有18层。因此,这种模型通常被称为ResNet-18。通过配置不同的通道数和模块里的残差块数可以得到不同的ResNet模型,例如更深的152层的ResNet-152。ResNet的结构更简单,修改也更方便。这些因素都导致了ResNet迅速被广泛使用。下图描述了完整的ResNet-18。

在训练ResNet之前,让我们观察一下ResNet中的不同模块的输入形状是如何变化的。在之前的所有架构中,分辨率降低,通道数量增加,直到全局平均汇聚层聚集所有特征。

X = torch.rand(size=(1, 1, 224, 224))
for layer in net:
	X = layer(X)
	print(layer.__class__.__name__,'output shape:\t', X.shape)
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 128, 28, 28])
Sequential output shape: torch.Size([1, 256, 14, 14])
Sequential output shape: torch.Size([1, 512, 7, 7])
AdaptiveAvgPool2d output shape: torch.Size([1, 512, 1, 1])
Flatten output shape: torch.Size([1, 512])
Linear output shape: torch.Size([1, 10])

训练模型

同之前一样,我们在Fashion-MNIST数据集上训练ResNet。

lr, num_epochs, batch_size = 0.05, 10, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
loss 0.014, train acc 0.996, test acc 0.895
4680.2 examples/sec on cuda:0

以上就是Python深度学习神经网络残差块的详细内容,更多关于Python神经网络的资料请关注我们其它相关文章!

(0)

相关推荐

  • python机器学习之神经网络(一)

    python有专门的神经网络库,但为了加深印象,我自己在numpy库的基础上,自己编写了一个简单的神经网络程序,是基于Rosenblatt感知器的,这个感知器建立在一个线性神经元之上,神经元模型的求和节点计算作用于突触输入的线性组合,同时结合外部作用的偏置,对若干个突触的输入求和后进行调节.为了便于观察,这里的数据采用二维数据. 目标函数是训练结果的误差的平方和,由于目标函数是一个二次函数,只存在一个全局极小值,所以采用梯度下降法的策略寻找目标函数的最小值. 代码如下: import numpy

  • Python利用神经网络解决非线性回归问题实例详解

    本文实例讲述了Python利用神经网络解决非线性回归问题.分享给大家供大家参考,具体如下: 问题描述 现在我们通常使用神经网络进行分类,但是有时我们也会进行回归分析. 如本文的问题: 我们知道一个生物体内的原始有毒物质的量,然后对这个生物体进行治疗,向其体内注射一个物质,过一段时间后重新测量这个生物体内有毒物质量的多少. 因此,问题中有两个输入,都是标量数据,分别为有毒物质的量和注射物质的量,一个输出,也就是注射治疗物质后一段时间生物体的有毒物质的量. 数据如下图: 其中Dose of Myco

  • 用Python实现BP神经网络(附代码)

    用Python实现出来的机器学习算法都是什么样子呢? 前两期线性回归及逻辑回归项目已发布(见文末链接),今天来讲讲BP神经网络. BP神经网络 全部代码 https://github.com/lawlite19/MachineLearning_Python/blob/master/NeuralNetwok/NeuralNetwork.py 神经网络model 先介绍个三层的神经网络,如下图所示 输入层(input layer)有三个units( 为补上的bias,通常设为1) 表示第j层的第i个

  • python机器学习之神经网络实现

    神经网络在机器学习中有很大的应用,甚至涉及到方方面面.本文主要是简单介绍一下神经网络的基本理论概念和推算.同时也会介绍一下神经网络在数据分类方面的应用. 首先,当我们建立一个回归和分类模型的时候,无论是用最小二乘法(OLS)还是最大似然值(MLE)都用来使得残差达到最小.因此我们在建立模型的时候,都会有一个loss function. 而在神经网络里也不例外,也有个类似的loss function. 对回归而言: 对分类而言: 然后同样方法,对于W开始求导,求导为零就可以求出极值来. 关于式子中

  • python实现简单神经网络算法

    python实现简单神经网络算法,供大家参考,具体内容如下 python实现二层神经网络 包括输入层和输出层 import numpy as np #sigmoid function def nonlin(x, deriv = False): if(deriv == True): return x*(1-x) return 1/(1+np.exp(-x)) #input dataset x = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]]) #out

  • python实现BP神经网络回归预测模型

    神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回归模型,用来做室内定位.模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数Sigmoid换成f(x)=x函数.这样做的主要原因是Sigmoid函数的输出范围太小,在0-1之间,而回归模型的输出范围较大.模型修改如下: 代码如下: #coding: utf8 '''' author: Huangyuliang ''' import json import random impo

  • Python深度学习神经网络残差块

    目录 ResNet模型 训练模型 ResNet沿用VGG完整的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层设计.残差块里首先有2个相同输出通道数的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层.每个卷积层后接一个批量归一化层和ReLU激活函数.然后我们通过跨

  • Python深度学习神经网络基本原理

    目录 神经网络 梯度下降法 神经网络 梯度下降法 在详细了解梯度下降的算法之前,我们先看看相关的一些概念. 1. 步长(Learning rate):步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度.用上面下山的例子,步长就是在当前这一步所在位置沿着最陡峭最易下山的位置走的那一步的长度. 2.特征(feature):指的是样本中输入部分,比如2个单特征的样本(x(0),y(0)),(x(1),y(1))(x(0),y(0)),(x(1),y(1)),则第一个样本特征为x(0)x(0

  • Python深度学习之实现卷积神经网络

    一.卷积神经网络 Yann LeCun 和Yoshua Bengio在1995年引入了卷积神经网络,也称为卷积网络或CNN.CNN是一种特殊的多层神经网络,用于处理具有明显网格状拓扑的数据.其网络的基础基于称为卷积的数学运算. 卷积神经网络(CNN)的类型 以下是一些不同类型的CNN: 1D CNN:1D CNN 的输入和输出数据是二维的.一维CNN大多用于时间序列. 2D CNNN:2D CNN的输入和输出数据是三维的.我们通常将其用于图像数据问题. 3D CNNN:3D CNN的输入和输出数

  • Python深度学习pytorch卷积神经网络LeNet

    目录 LeNet 模型训练 在本节中,我们将介绍LeNet,它是最早发布的卷积神经网络之一.这个模型是由AT&T贝尔实验室的研究院Yann LeCun在1989年提出的(并以其命名),目的是识别手写数字.当时,LeNet取得了与支持向量机性能相媲美的成果,成为监督学习的主流方法.LeNet被广泛用于自动取款机中,帮助识别处理支票的数字. LeNet 总体来看,LeNet(LeNet-5)由两个部分组成: 卷积编码器: 由两个卷积层组成 全连接层密集快: 由三个全连接层组成 每个卷积块中的基本单元

  • Python深度学习理解pytorch神经网络批量归一化

    目录 训练深层网络 为什么要批量归一化层呢? 批量归一化层 全连接层 卷积层 预测过程中的批量归一化 使用批量归一化层的LeNet 简明实现 争议 训练深层神经网络是十分困难的,特别是在较短的实践内使他们收敛更加棘手.在本节中,我们将介绍批量归一化(batch normalization),这是一种流行且有效的技术,可持续加速深层网络的收敛速度.在结合之后将介绍的残差快,批量归一化使得研究人员能够训练100层以上的网络. 训练深层网络 为什么要批量归一化层呢? 让我们回顾一下训练神经网络时出现的

  • Python深度学习pytorch神经网络Dropout应用详解解

    目录 扰动的鲁棒性 实践中的dropout 简洁实现 扰动的鲁棒性 在之前我们讨论权重衰减(L2​正则化)时看到的那样,参数的范数也代表了一种有用的简单性度量.简单性的另一个有用角度是平滑性,即函数不应该对其输入的微笑变化敏感.例如,当我们对图像进行分类时,我们预计向像素添加一些随机噪声应该是基本无影响的. dropout在正向传播过程中,计算每一内部层同时注入噪声,这已经成为训练神经网络的标准技术.这种方法之所以被称为dropout,因为我们从表面上看是在训练过程中丢弃(drop out)一些

  • Python深度学习pytorch神经网络图像卷积运算详解

    目录 互相关运算 卷积层 特征映射 由于卷积神经网络的设计是用于探索图像数据,本节我们将以图像为例. 互相关运算 严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算(cross-correlation),而不是卷积运算.在卷积层中,输入张量和核张量通过互相关运算产生输出张量. 首先,我们暂时忽略通道(第三维)这一情况,看看如何处理二维图像数据和隐藏表示.下图中,输入是高度为3.宽度为3的二维张量(即形状为 3 × 3 3\times3 3×3).卷积核的高度和宽度都是2. 注意,

  • Python深度学习pytorch神经网络填充和步幅的理解

    目录 填充 步幅 上图中,输入的高度和宽度都为3,卷积核的高度和宽度都为2,生成的输出表征的维度为 2 × 2 2\times2 2×2.从上图可看出卷积的输出形状取决于输入形状和卷积核的形状. 填充 以上面的图为例,在应用多层卷积时,我们常常丢失边缘像素. 解决这个问题的简单方法即为填充(padding):在输入图像的边界填充元素(通常填充元素是0). 例如,在上图中我们将 3 × 3 3\times3 3×3输入填充到 5 × 5 5\times5 5×5,那么它的输出就增加为 4 × 4

  • Python深度学习pytorch神经网络多输入多输出通道

    目录 多输入通道 多输出通道 1 × 1 1\times1 1×1卷积层 虽然每个图像具有多个通道和多层卷积层.例如彩色图像具有标准的RGB通道来指示红.绿和蓝.但是到目前为止,我们仅展示了单个输入和单个输出通道的简化例子.这使得我们可以将输入.卷积核和输出看作二维张量. 当我们添加通道时,我们的输入和隐藏的表示都变成了三维张量.例如,每个RGB输入图像具有 3 × h × w 3\times{h}\times{w} 3×h×w的形状.我们将这个大小为3的轴称为通道(channel)维度.在本节

  • Python深度学习pytorch神经网络汇聚层理解

    目录 最大汇聚层和平均汇聚层 填充和步幅 多个通道 我们的机器学习任务通常会跟全局图像的问题有关(例如,"图像是否包含一只猫呢?"),所以我们最后一层的神经元应该对整个输入的全局敏感.通过逐渐聚合信息,生成越来越粗糙的映射,最终实现学习全局表示的目标,同时将卷积图层的所有有时保留在中间层. 此外,当检测较底层的特征时(例如之前讨论的边缘),我们通常希望这些特征保持某种程度上的平移不变性.例如,如果我们拍摄黑白之间轮廓清晰的图像X,并将整个图像向右移动一个像素,即Z[i, j] = X[

随机推荐