深度学习|卷积神经网络,深度学习中的卷积神经网络解析

马肤

温馨提示:这篇文章已超过449天没有更新,请注意相关的内容是否还可用!

摘要:本文介绍了深度学习中卷积神经网络的相关知识。卷积神经网络是一种特殊的神经网络结构,广泛应用于图像处理和计算机视觉领域。它通过卷积运算提取图像特征,并通过逐层传递的方式将低层次特征组合成高层次特征,以实现图像的分类和识别。卷积神经网络具有强大的特征学习能力,已成为当前研究的热点之一。

一、卷积神经网络简介

卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习神经网络结构,主要用于图像识别、计算机视觉等领域。该结构在处理图像等高维数据时表现出色,因为它具有共享权重和局部感知的特点,一方面减少了权值的数量使得网络易于优化,另一方面降低了模型的复杂度,也就是减小了过拟合的风险。

卷积神经网络主要由卷积层(Convolutional layer)、池化层(Pooling layer)、全连接层(Fully connected layer)和激活函数(Activation function)等组成。其中,卷积层是CNN的核心部分,它通过卷积操作提取输入图像的特征,并将这些特征作为下一层的输入。池化层则用于降采样,可以减少卷积层输出的特征图的大小,从而减少网络参数和计算量。全连接层则用于将卷积层和池化层的输出连接起来,以便最终进行分类和预测。

卷积神经网络的训练主要是通过反向传播算法(Back-propagation)来更新网络中的权重(类似于BP神经网络),从而使得网络能够逐步学习到输入数据的特征,并在最终的分类或预测任务中得到较好的性能。

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第1张

目前,卷积神经网络已经在图像分类、物体识别、人脸识别、自然语言处理等领域取得了非常出色的成果,是现代深度学习领域的重要组成部分。

二、卷积层

在数学中,两个函数(比如 g)之间的“卷积”被定义为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第2张

也就是说,卷积是把一个函数“翻转”并移位x,测量之间的重叠。当为离散对象时,积分就变成求和。例如,对于索引为Z的、平方可和的、无限维向量集合中抽取的向量,我们可得到如下定义:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第3张

对于二维张量,则为 的索引(a,b)和 的索引(i-a, j-b)上的对应加和:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第4张

这里需要说明的是,在卷积神经网络中,卷积层的实现方式实际上是数学中定义的互相关 (cross-correlation)运算,与数学分析中的卷积定义有所不同,使用互相关运算作为卷积的定义。互相关(Cross-Correlation)是一个衡量两个序列相关性的函数,通常是用滑动窗口的点积计算来实现,而卷积则需要将滤波器经过反转。

2.1 一维卷积

一维卷积经常用在信号处理中,用于计算信号的延迟累积。假设一个信号发生器每个时刻t产生一个信号深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第5张,其信息的衰减率为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第6张,即在k-1个时间步长后,信息为原来的深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第6张倍。而在时刻t收到的信号深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第8张为当前时刻产生的信息和以前时刻延迟信息的叠加,即:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第9张

其中,深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第6张被称为滤波器(filter)或卷积核(convolution kernnel)。

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第11张

2.2 二维卷积 

在图像处理中,图像是以二维矩阵的形式输入到神经网络中,给定一个图像(深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第12张)和一个滤波器(深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第13张),且有深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第14张,则其卷积为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第15张

具体计算过程如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第16张

通常我们将一个输入信息X和滤波器W的二维卷积定义为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第17张。假设卷积核的高和宽分别为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第18张深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第19张,则将称其为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第20张卷积,如深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第21张卷积,就是指卷积核的高为3,宽为5。在卷积神经网络中,一个卷积算子除了上面描述的卷积过程外,还包括加上偏置项的操作。

当卷积核尺寸大于1时,经过一次卷积之后,输出特征图的尺寸会小于输入图片尺寸,输出特征图尺寸计算方法有:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第22张

2.2.1 填充

如果经过多次卷积,输出图片尺寸会不断减小,为避免卷积之后图片尺寸变小,通常会在图片的外围进行填充(padding),如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第23张

若沿着图片高度方向,在第一行之前填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第24张行,在最后一行之后填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第25张行;沿着图片宽度方向,在第一列之前填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第26张列,在最后一列之后填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第27张列,则填充之后的图片经过大小为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第20张的卷积核操作之后,输出图片的尺寸为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第29张

在卷积计算过程中,通常会在高度或宽度的两侧采取等量填充,即要求:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第30张

则变换后的尺寸变为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第31张

卷积核通常用1,3,5,7这样的奇数。如果使用的填充大小为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第32张

则卷积之后图像尺寸不变。例如,当卷积核大小为5,padding大小为2时,卷积之后图像尺寸就不会改变。

为加深理解,假设创建一个高度和宽度为3的二维卷积层,并在所有侧边填充一个像素,给定高度和宽度为8的输入,则输出的高度和宽度也是8:

import torch
from torch import nn
# 为了方便起⻅,我们定义了一个计算卷积层的函数。
# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数 
def comp_conv2d(conv2d, X):
    # 这里的(1,1)表示批量大小和通道数都是1
    X = X.reshape((1, 1) + X.shape)
    Y = conv2d(X)
    # 省略前两个维度:批量大小和通道
    return Y.reshape(Y.shape[2:])
# 请注意,这里每边都填充了1行或1列,因此总共添加了2行或2列 
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)
X = torch.rand(size=(8, 8))
comp_conv2d(conv2d, X).shape
## 结果
torch.Size([8, 8])

当卷积核的高度和宽度不同时,我们可以填充不同的高度和宽度,使输出和输入具有相同的高度和宽度。若使用高度为5,宽度为3的卷积核,高度和宽度两边的填充则分别为2和1:

conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape
## 结果
torch.Size([8, 8]) 

2.2.2 步幅

步幅(stride)也会影响输出图片的尺寸,下图是步幅为2的卷积过程,卷积核在图片上移动时,每次移动大小为2 个像素点:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第33张

 当宽和高方向的步幅分别为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第34张深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第35张时,输出特征图尺寸为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第36张

2.2.3 代码实现

我们可以使用torch库实现以上过程。设定如下输入数据与核函数,输出数据可表示为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第37张

import torch
from torch import nn
def corr2d(X, K): #@save 
    """计算二维互相关运算"""
    h, w = K.shape
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
    return Y

输入上图中的张量x和卷积核张量k,可以得到图上的输出张量:

X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
corr2d(X, K)
## 输出结果
tensor([[19., 25.],
        [37., 43.]])

2.2.4 感受野

在二维卷积中,随着卷积层数的提高,输出特征图上每个点的数值代表的信息会更多。在一层卷积中,输出特征图上每个点的数值是由输入图片上大小为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第20张的区域中元素与卷积核每个元素相乘再相加得到的,所以输入图像上该区域内每个元素数值的改变都会影响输出点的像素值。我们可将这个区域叫做输出特征图上对应点的感受野。以深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第39张卷积为例,对应的感受野为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第39张大小的区域:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第41张

 而卷积层数为2时,感受野的大小会增加到深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第42张,如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第43张

2.2.5 连接

在卷积层中每一个神经元都只和下一层中局部的神经元相连,构成一个局部连接网络。使用卷积层代替全连接层后,可以使得层和层之间的连接数大大减少,如图所示(一维与二维):

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第44张

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第45张

 2.2.6 通道 

我们熟知的图像一般包含了三个通道(三个颜色),称为RGB。实际上,图像并不是二维张量,而是一个由高度、宽度和颜色组成的三位张量,如深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第46张个像素,前两个轴与像素的空间位置有关,而第三个轴可以看作每个像素的多维表示。

(1)多输入通道场景

若要计算卷积的输出结果,卷积核的形式也会发生变化,假设输入图片的通道数为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第47张,输入数据的形状为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第48张,计算过程如下:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第49张

  1. 对每个通道分别涉及一个2维数组作为卷积核,卷积核数组的形状是深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第50张
  2. 对任一通道深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第51张,分别用大小为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第20张的卷积核在大小为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第53张二维数组上做卷积;
  3. 将这深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第47张个通道的计算结果相加,得到的是一个形状为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第55张的二维数组。

通过torch库实现以下两个输入通道之间的运算:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第56张

import torch
from d2l import torch as d2l
def corr2d_multi_in(X, K):
    # 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起 
    return sum(d2l.corr2d(x, k) for x, k in zip(X, K))

将上图中的值对应的张量x和核张量k输入该函数:

X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])
K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])
corr2d_multi_in(X, K)
## 输出结果
tensor([[ 56.,  72.],
        [104., 120.]])

 (2)多输出通道场景

卷积操作的输出特征图也会具有多个通道深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第57张,这时要设计深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第57张个维度为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第50张的卷积核,卷积核数组的维度是深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第60张,如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第61张

卷积核的输出通道数也称为卷积核的个数,图中包含了两个卷积核,红绿蓝代表第一个卷积核的三个输入通道,颜色稍浅的代表第二个卷积核的三个输入通道。

在一个卷积层中,一个卷积核可以学习并提取图像中的一种特征,但往往图片中包含多种不同的特征信息,因此我们需要多个不同的卷积核提取不同的特征。 

同样我们实现一个计算多个通道的输出函数:

def corr2d_multi_in_out(X, K):
# 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。 # 最后将所有结果都叠加在一起
return torch.stack([corr2d_multi_in(X, k) for k in K], 0)

将核张量k与k+1(k中每个元素加1)和k+2连接起来,构造一个具有3个输出通道的卷积核:

K = torch.stack((K, K + 1, K + 2), 0)
K.shape
## 结果
torch.Size([3, 2, 2, 2])

我们对输入张量与卷积核张量k执行运算,现在输出包含3个通道,第一个通道结果与先前输入张量x和多输入单输出通道的结果一致:

corr2d_multi_in_out(X, K)
## 输出结果
tensor([[[ 56.,  72.],
         [104., 120.]],
        [[ 76., 100.],
         [148., 172.]],
        [[ 96., 128.],
         [192., 224.]]])

(3)批量操作

在卷积神经网络计算过程中,通常将多个样本放在一起形成一个mini-batch进行批量操作,即输入数据的维度是深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第62张。由于会对每张图片使用同样的卷积核进行卷积操作,卷积核的维度与上面多输出通道的情况一样,仍然是深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第60张,输出特征图的维度是深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第64张,如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第65张

三、池化层与全连接层

3.1 池化

3.1.1 池化操作

池化(pooling layer)也称汇聚层或子采样层,自主要作用是进行特征选择、降低特征数量从而减少参数数量。池化相当于在空间范围内做了维度删减,分别作用于每个输入的特征并减小其大小。

池化层包含预设定的池化函数,其功能是将特征图中单个点的结果替换为其相邻区域的特征图统计量。使用某一位置的相邻输出的总体统计特征代替网络在该位置的输出,其好处是当输入数据做出少量平移时,经过池化函数后的大多数输出还能保持不变。

池化通常有两种,分别为平均池化和最大池化,如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第66张

与卷积核类似,池化窗口(用深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第20张表示池化窗口)在图片上滑动时,每次移动的步长称为步幅,当宽和高方向的移动大小不一样时,分别用深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第35张深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第34张表示。当然也可对需要进行池化的图片进行填充,填充方式与卷积类似,假设在第一行之前填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第24张行,在最后一行后面填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第25张行,在第一列之前填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第26张列,在最后一列之后填充深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第27张列,则池化层的输出特征图大小为:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第74张

通常使用深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第75张大小的池化窗口,步幅也使用2,填充为0;通过这种方式的池化,输出特征图的高和宽都减半,但通道数不会改变。

为实现池化层的前向传播,我们仍可以使用corr2d函数,只是此处没有卷积核,输出为输入中每个区域的最大值或平均值:

import torch
from torch import nn
from d2l import torch as d2l
def pool2d(X, pool_size, mode='max'):
    p_h, p_w = pool_size
    Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            if mode == 'max':
                Y[i, j] = X[i: i + p_h, j: j + p_w].max()
            elif mode == 'avg':
                Y[i, j] = X[i: i + p_h, j: j + p_w].mean()
return Y

构建输入张量x,验证二维最大池化层的输出:

## 最大池化
X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool2d(X, (2, 2))
## 结果
tensor([[4., 5.],
        [7., 8.]])
# 平均池化
pool2d(X, (2, 2), 'avg')
# 结果
tensor([[2., 3.],
        [5., 6.]])

3.1.2 池化作用

池化层不但可以有效地减少神经元的数量,还可以使得网络对一些小的局部形态改变保持不变性,并拥有更大的感受野,如下图所示:

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第76张

 3.2 全连接层

深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第77张

全连接层(fully-connected layer)中每一个节点都与上一层所有节点相连,把前向层提取到的特征综合起来。由于其全相连的特征,一般全连接层的参数也是最多的。

在 CNN 结构中,经多个卷积层和池化层后,连接着1个或1个以上的全连接层,与 MLP 类似,全连接层中的每个神经元与其前一层的所有神经元进行全连接。为提升 CNN 网络性能,全连接层每个神经元的激励函数一般采用 ReLU 函数,最后一层全连接层的输出值被传递给一个输出,可以采用softmax逻辑回归进行分类。

四、LeNet网络

LeNet是最早发布的卷积神经网络之一,因其在计算机视觉任务中的高效性能而受到广泛关注。这个模型是由AT&T⻉尔实验室的研究员Yann LeCun在1989年提出。当时,LeNet取得了与支持向量机(support vector machines)性能相媲美的成果,成为监督学习的主流方法。LeNet被广泛用于自动取款机(ATM)机中,帮助识别处理支票的数字,到如今还有相当范围的使用。

4.1 LeNet结构

LeNet网络由两个部分组成,分别为:

  • 卷积编码器:由两个卷积层组成
  • 全连接层密集块:由三个全连接层组成。

    其网络架构如下图所示:

    深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第78张

     每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均池化层。每个卷积层使用5深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第42张卷积核和一个sigmoid激活函数。这 些层将输入映射到多个二维特征输出,通常同时增加通道的数量。第一卷积层有6个输出通道,而第二个卷积层有16个输出通道,卷积的输出形状由批量大 小、通道数、高度、宽度决定。

    深度学习框架实现此类模型并不难,只需实例化一个Sequential模块并将需要的层连接在一起:

    import torch
    from torch import nn
    from d2l import torch as d2l
    net = nn.Sequential(
        nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Flatten(),
        nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
        nn.Linear(120, 84), nn.Sigmoid(),
        nn.Linear(84, 10))

    对原始模型做一点小改动,去掉最后一层的高斯激活,其余与最初的网络一致。将一个大小为深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第80张的单通道(黑白)图像通过LeNet,通过在每一层打印输出的形状,我们可以检查模型,以确保其操作与我们期望的一致,如下图:

    深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第81张

    X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
    for layer in net:
        X = layer(X)
        print(layer.__class__.__name__,'output shape: \t',X.shape)
    ## 输出结果
    Conv2d output shape:            torch.Size([1, 6, 28, 28])
    Sigmoid output shape:           torch.Size([1, 6, 28, 28])
    AvgPool2d output shape:         torch.Size([1, 6, 14, 14])
    Conv2d output shape:            torch.Size([1, 16, 10, 10])
    Sigmoid output shape:           torch.Size([1, 16, 10, 10])
    AvgPool2d output shape:         torch.Size([1, 16, 5, 5])
    Flatten output shape:           torch.Size([1, 400])
    Linear output shape:            torch.Size([1, 120])
    Sigmoid output shape:           torch.Size([1, 120])
    Linear output shape:            torch.Size([1, 84])
    Sigmoid output shape:           torch.Size([1, 84])
    Linear output shape:            torch.Size([1, 10])

    在整个卷积块中,与上一层相比,每一层的特征高度和宽度都减小了。第一个卷积层使用2个像素的 填充,来补偿深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第42张卷积核导致的特征减少。相反,第二个卷积层没有填充,因此高度和宽度都减少了4个像素。随着层叠的上升,通道的数量从输入时的1个,增加到第一个卷积层之后的6个,再到第二个卷积层之后的16个。同时,每个汇聚层的高度和宽度都减半。最后,每个全连接层减少维数,最终输出一个维数与结果分类数相匹配的输出。

    4.2 LeNet模型训练

    在实现LeNet的基础上,用其实现Fashion-MNIST数据集上的表现。

    batch_size = 256
    train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)

    虽然卷积神经网络的参数较少,但与深度的多层感知机相比,它们的计算成本仍然很高,因为每个参数都参与更多的乘法。通过使用GPU,可以用它加快训练。

    def evaluate_accuracy_gpu(net, data_iter, device=None): #@save 
        """使用GPU计算模型在数据集上的精度"""
        if isinstance(net, nn.Module):
            net.eval() # 设置为评估模式
            if not device:
                device = next(iter(net.parameters())).device 
        # 正确预测的数量,总预测的数量
        metric = d2l.Accumulator(2)
        with torch.no_grad():
            for X, y in data_iter:
                if isinstance(X, list):
                    X = [x.to(device) for x in X]
                else:
                    X = X.to(device)
                y = y.to(device)
                metric.add(d2l.accuracy(net(X), y), y.numel())
        return metric[0] / metric[1]

    与全连接层一样,我们使用交叉熵损失函数和小批量随机梯度下降:

    #@save
    def train_ch6(net, train_iter, test_iter, num_epochs, lr, device): 
        def init_weights(m):
            if type(m) == nn.Linear or type(m) == nn.Conv2d:
                nn.init.xavier_uniform_(m.weight)
        net.apply(init_weights)
        print('training on', device)
        net.to(device)
        optimizer = torch.optim.SGD(net.parameters(), lr=lr)
        loss = nn.CrossEntropyLoss()
        animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                                legend=['train loss', 'train acc', 'test cc'])
        timer, num_batches = d2l.Timer(), len(train_iter)
        for epoch in range(num_epochs):
            # 训练损失之和,训练准确率之和,样本数 
            metric = d2l.Accumulator(3)
            net.train()
            for i, (X, y) in enumerate(train_iter):
                timer.start()
                optimizer.zero_grad()
                X, y = X.to(device), y.to(device)
                y_hat = net(X)
                l = loss(y_hat, y)
                l.backward()
                optimizer.step()
                with torch.no_grad():
                    metric.add(l * X.shape[0],
                               d2l.accuracy(y_hat,y), X.shape[0])
                timer.stop()
                train_l = metric[0] / metric[2]
                train_acc = metric[1] / metric[2]
                if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                    animator.add(epoch + (i + 1) / num_batches,
                                 (train_l, train_acc, None))
            test_acc = evaluate_accuracy_gpu(net, test_iter)
            animator.add(epoch + 1, (None, None, test_acc))
        print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, '
              f'test acc {test_acc:.3f}')
        print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec '
              f'on {str(device)}')

    之后,我们可以训练和评估LeNet模型:

    lr, num_epochs = 0.9, 10
    train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
    ## 输出结果
    loss 0.467, train acc 0.825, test acc 0.821
    88556.9 examples/sec on cuda:0

    深度学习|卷积神经网络,深度学习中的卷积神经网络解析 第83张


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码