动手学深度学习pytorch学习笔记 —— 第六章

目   录

1 从全连接层到卷积

1.1 不变性

1.2 多层感知机的限制

1.2.1 平移不变性

1.2.2 局部性

1.3 扩展

1.4 小结

2 图像卷积

2.1 互相关运算

 2.2 图像边缘检测

2.3 学习卷积核

2.4 扩展

2.4.1 互相关和卷积

2.4.2 特征映射核感受野

2.5 小结

3 填充和步幅

3.1 填充

3.2 步幅

3.3 多输入多输出通道

3.3.1 多输入通道

3.3.2 多输出通道

3.3.3 1×1卷积层

3.4 小结

4 汇聚层

4.1 最大汇聚层和平均汇聚层

4.2 填充和步幅

4.3 多通道

4.4 小结

5 卷积神经网络

5.1 LeNet

5.2 小结

6 结语


第六章 — 卷积神经网络

章节导航:前面学到的图像数据,仅将图像数据展平成一维向量而忽略了每个图像的空间结构信息,再将数据送入一个全连接的多层感知机中。本章所学的卷积神经网络就是一类强大的、为处理图像数据而设计的神经网络。 本章中介绍的构成所有卷积网络主干的基本元素有卷积层本身、填充和步幅、汇聚层、多通道。 以及第一个成功应用的卷积神经网络LeNet模型。

1 从全连接层到卷积

之前所学的多层感知机合处理表格数据,其中行对应样本,列对应特征。对于表格数据,我们寻找的模式可能涉及特征之间的交互,但是我们不能预先假设任何与特征交互相关的先验结构(列与列交互相关)。此时,多层感知机可能是最好的选择,然而对于高维感知数据,这种缺少结构的网络可能会变得不实用。

1.1 不变性

书中假设我们需要从一张图片中找到某个物体。合理的假设是:无论哪种方法找到这个物体,都应该与物体的位置无关。如果在包含名叫沃尔多的图像中找到他,可以做一个检测器,该检测器将图像分割成多个区域,并为每个区域包含沃尔多的可能性打分。 卷积神经网络正是将空间不变性的这一概念系统化,从而基于这个模型使用较少的参数来学习有用的表示。

总结上述想法

  • 平移不变性:不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。

  • 局部性:神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。

1.2 多层感知机的限制

多层感知机的输入是二维图像X,其隐藏表示H在数学上是一个矩阵,在代码中表示为二维张量。其中X和H具有相同的形状。为了方便理解,我们可以认为,无论是输入还是隐藏表示都拥有空间结构

书中使用[X]i,j和[H]i,j分别表示输入图像和隐藏表示中位置(i,j)处的像素。为了使每个隐藏神经元都能接收到每个输入像素的信息,我们将参数从权重矩阵替换为四阶权重张量W。假设U包含偏置参数,可以将全连接层形式化地表示为

其中,从W到V的转换只是形式上的转换,因为这两个四阶张量的元素之间存在一一对应的关系。我们只需重新索引下标(k,l),使k=i+a、l=j+b,由此可得[V]i,j,a,b=[W]i,j,i+a,j+b。索引a和b通过在正偏移和负偏移之间移动覆盖了整个图像。对于隐藏表示中任意给定位置(i,j)处的像素值[H]i,j,可以通过在x中以(i,j)为中心对像素进行加权求和得到,加权使用的权重为[V]i,j,a,b。

因此,我们联想到前面所说的不变性

1.2.1 平移不变性

意味着检测对象在输入X中的平移,应该仅导致隐藏表示H中的平移。也就是说,V和U实际上不依赖于(i,j)的值,即[V]i,j,a,b=[V]a,b。并且U是一个常数,比如u。因此,我们可以简化H定义为:

这就是卷积。使用系数[V]a,b对位置(i,j)附近的像素(i+a,j+b)进行加权得到[H]i,j。[V]a,b的系数比[V]i,j,a,b少很多,因为前者不再依赖于图像中的位置,从四阶张量变成二阶

1.2.2 局部性

为了收集用来训练参数[H]i,j的相关信息,不应偏离到距(i,j)很远的地方。这意味着在|a|>Δ或|b|>Δ的范围之外,可以设置[V]a,b=0。因此,书中以此将[H]i,j重写为

上式就是一个卷积层,而卷积神经网络是包含卷积层的一类特殊的神经网络。其中,V被称为卷积核或者滤波器,亦或简单地称之为该卷积层的权重,通常该权重是可学习的参数,英文kernel,因此后面使用k表示。

当图像处理的局部区域很小时,卷积神经网络与多层感知机的训练差异可能是巨大的:以前,多层感知机可能需要数十亿个参数来表示网络中的一层,而现在卷积神经网络通常只需要几百个参数,而且不需要改变输入或隐藏表示的维数。 

参数大幅减少的代价特征现在是平移不变的,并且当确定每个隐藏活性值时,每一层只包含局部的信息。 

1.3 扩展

书中扩展卷积的概念。在数学中,两个函数(比如f,g:Rd→R)之间的“卷积”被定义为

卷积是当把一个函数“翻转”并移位x时,测量f和g之间的重叠

当为离散对象时,积分就变成求和。例如,对于由索引为Z的、平方可和的、无限维向量集合中抽取的向量,我们得到以下定义

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

1.4 小结

  • 图像的平移不变性使我们以相同的方式处理局部图像,而不在乎它的位置。

  • 局部性意味着计算相应的隐藏表示只需一小部分局部图像像素。

  • 在图像处理中,卷积层通常比全连接层需要更少的参数,但依旧获得高效用的模型。

  • 卷积神经网络(CNN)是一类特殊的神经网络,它可以包含多个卷积层。

  • 多个输入和输出通道使模型在每个空间位置可以获取图像的多方面特征。

2 图像卷积

2.1 互相关运算

为什么会引入互相关运算呢?严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算,而不是卷积运算。

先了解一下互相关运算怎么进行运算的,运用书中的例子。输入是高度为3、宽度为3的二维张量(即3×3)。卷积核的高度和宽度都是2(即2×2)。

阴影部分就是输入的一部分与卷积核进行互相关运算后得到的结果。类似于之前所学习的对位相乘,互相关运算就是对位相乘之后求和 0×0+1×1+3×2+4×3=19.

这里的输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1, 而卷积核只与图像中每个大小完全适合的位置进行互相关运算。因此,可以得到输出大小等于输入大小nh×nw减去卷积核大小kh×kw:

在如下代码中,函数接受输入张量X和卷积核张量K,并返回输出张量Y。h,w表示核张量K的高和宽,再将X与之对应的核进行运算后求和放到Y作为返回值返回。

import torch
from torch import nn
from d2l import torch as d2l

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

正如前面所述,卷积神经网络是包含卷积核的神经网络。因此,卷积层对输入和卷积核权重进行互相关运算后,还需要添加标量偏置之后产生输出。因此,需要基于上面定义的corr2d函数实现二维卷积层。在__init__构造函数中,将weightbias声明为两个模型参数。前向传播函数调用corr2d函数并添加偏置。

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super().__init__()
        self.weight = nn.Parameter(torch.rand(kernel_size))
        self.bias = nn.Parameter(torch.zeros(1))

    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

 2.2 图像边缘检测

 首先,书中构造的是一个6×8像素的黑白图像。中间四列为黑色用 0 表示,白色用 1 表示。

X = torch.ones((6, 8))
X[:, 2:6] = 0

 得到张量如下:

然后为了能够感知到从1到0,或者从0到1的变化。可以采用(1,-1)的卷积核(结构为1*2),然后对X与核K执行互相关运算并将结果放入Y中

K = torch.tensor([[1.0, -1.0]])
Y = corr2d(X, K)

结果如下:

我们可以发现

  • 结果Y形状变为6*7
  • 1代表从白色到黑色的边缘
  • -1代表从黑色到白色的边缘
  • 其他情况的输出为0

2.3 学习卷积核

当有了更复杂数值的卷积核,或者连续的卷积层时,不可能手动设计卷积核。那么我们是否可以学习由X生成Y的卷积核呢?

先构造一个卷积层,并将其卷积核初始化为随机张量。接下来,在每次迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。书中在此使用内置的二维卷积层,忽略偏置。

# 构造一个二维卷积层,它具有1个输出通道和形状为(1,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)

# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2  # 学习率

for i in range(10):
    Y_hat = conv2d(X)
    l = (Y_hat - Y) ** 2
    conv2d.zero_grad()
    l.sum().backward()
    # 迭代卷积核
    conv2d.weight.data[:] -= lr * conv2d.weight.grad

conv2d.weight.data.reshape((1, 2))

最后得到的输出结果为,与[1, -1]已十分接近。

2.4 扩展

2.4.1 互相关和卷积

正式的卷积运算不是互相关运算。它们差别不大,我们只需水平和垂直翻转二维卷积核张量,然后对输入张量执行互相关运算

由于卷积核是从数据中学习到的,因此无论这些层执行严格的卷积运算还是互相关运算,卷积层的输出都不会受到影响。假设卷积层执行互相关运算并学习中的卷积核,该卷积核在这里由矩阵K表示。假设其他条件不变,当这个层执行严格的卷积时,学习的卷积核K′在水平和垂直翻转之后将与K相同。也就是说,当卷积层执行严格卷积运算时,将得到与互相关运算相同的输出。

书中表明:为了与深度学习文献中的标准术语保持一致,将继续把“互相关运算”称为卷积运算,尽管严格地说略有不同。此外,对于卷积核张量上的权重,我们称其为元素。

2.4.2 特征映射核感受野

卷积层有时被称为特征映射,因为它可以被视为一个输入映射到下一层的空间维度的转换器。 在卷积神经网络中,对于某一层的任意元素x,其感受野是指在前向传播期间可能影响x计算的所有元素(来自所有先前层)。

感受野可能大于输入的实际大小。因此,当一个特征图中的任意元素需要检测更广区域的输入特征时,我们可以构建一个更深的网络。

2.5 小结

  • 二维卷积层的核心计算是二维互相关运算。最简单的形式是,对二维输入数据和卷积核执行互相关操作,然后添加一个偏置。

  • 我们可以设计一个卷积核来检测图像的边缘。

  • 我们可以从数据中学习卷积核的参数。

  • 学习卷积核时,无论用严格卷积运算或互相关运算,卷积层的输出不会受太大影响。

  • 当需要检测输入特征中更广区域时,我们可以构建一个更深的卷积网络。

3 填充和步幅

在前面的例子中,我们得出果结论:卷积的输出形状取决于输入形状和卷积核的形状

本节将介绍填充和步幅这俩个影响因素。英文名为padding和stride,因此后续使用ps表示。有时,在应用了连续的卷积之后,我们最终得到的输出远小于输入的大小。填充是解决丢失边缘像素的方法;有时,我们希望大幅降低图像的宽度和高度,则使用步幅完成

3.1 填充

如下图所示,我们在3*3的张量外填充“一圈 0”,然后再与2*2的卷积核运算后,得到的结果为4*4

因此,如果我们添加ph行填充(大约一半在顶部,一半在底部)和pw列填充(左侧大约一半,右侧一半),则输出形状将为

如果我们需要使输入和输出具有相同的高和度,多数需要设置ph=kh−1和pw=kw−1。卷积神经网络中卷积核的高和宽通常为奇数。 选择奇数的好处是,保持空间维度的同时,我们可以在顶部和底部填充相同数量的行,在左侧和右侧填充相同数量的列

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

上述代码中创建的是一个3*3的二维卷积层,并在所有侧边填充1个像素。给定8*8的输入,则输出也是8*8.

3.2 步幅

在计算互相关时,卷积窗口从输入张量的左上角开始,向下、向右滑动。 在前面的例子中,我们默认每次滑动一个元素。 但是,有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素,我们将每次滑动元素的数量称为步幅

如下图所示,将之前填充的作为输入,与X进行垂直步幅为3,水平步幅为2的二维互相关运算。

与之前还是有所区别的,为了计算输出中第一列的第二个元素和第一行的第二个元素,卷积窗口分别向下滑动三行和向右滑动两列。但是,当卷积窗口继续向右滑动两列时,没有输出,因为输入元素无法填充窗口

因此,我们可以再次总结,再含有垂直步幅为sh、水平步幅为sw时时,输出结果大小

# 下面,我们将高度和宽度的步幅设置为2,从而将输入的高度和宽度减半。
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)

3.3 多输入多输出通道

当我们添加通道时,我们的输入和隐藏的表示都变成了三维张量。例如,每个RGB输入图像具有3×h×w的形状。我们将这个大小为3的轴称为通道维度。

3.3.1 多输入通道

输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数的卷积核,以便与输入数据进行互相关运算。假设输入通道数为ci,那么卷积核输入通道数也需要为ci。如果卷积核的窗口形状是kh×kw,那么当ci=1时,我们可以把卷积核看作形状为kh×kw的二维张量。

然而,当ci>1时,我们卷积核的每个输入通道将包含形状为kh×kw的张量。将这些张量ci连结在一起可以得到形状为ci×kh×kw的卷积核。由于输入和卷积核都有ci个通道,我们可以对每个通道输入的二维张量和卷积核的二维张量进行互相关运算,再对通道求和(将ci的结果相加)得到二维张量。下图即为2个输入通道的3*3输入与2个通道的2*2卷积核的互相关运算:

其中56 = (1×1+2×2+4×3+5×4)+(0×0+1×1+3×2+4×3)。

# 实现多输入通道互相关运算
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 = 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)

结果为:

3.3.2 多输出通道

每一层有多个输出通道是至关重要的。在最流行的神经网络架构中,随着神经网络层数的加深,我们常会增加输出通道的维数,通过减少空间分辨率以获得更大的通道深度。直观地说,我们可以将每个通道看作对不同特征的响应。而现实可能更为复杂一些,因为每个通道不是独立学习的,而是为了共同使用而优化的。因此,多输出通道并不仅是学习多个单通道的检测器。

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

这里可以回忆一下torch.cat,作用为连接俩个张量并返回给引用者,而stack则是新开辟一个空间返回,0则是代表进行互相关运算后按照第0个维度进行连接。

K = torch.stack((K, K + 1, K + 2), 0)

将核张量KK+1K中每个元素加1)和K+2连接起来,构造了一个具有3个输出通道的卷积核。得到的结果K的形状为[3, 2, 2, 2]

3.3.3 1×1卷积层

1×1卷积层看起来似乎没有多大意义失去了卷积层的特有能力——在高度和宽度维度上,识别相邻元素间相互作用的能力。其实1×1卷积的唯一计算发生在通道上。如下图中的互相关计算使用了具有3个输入通道和2个输出通道的 1×1 卷积核。其中,输入和输出具有相同的高度和宽度。

def corr2d_multi_in_out_1x1(X, K):
    c_i, h, w = X.shape
    c_o = K.shape[0]
    X = X.reshape((c_i, h * w))
    K = K.reshape((c_o, c_i))
    # 全连接层中的矩阵乘法
    Y = torch.matmul(K, X)
    return Y.reshape((c_o, h, w))

验证 

X = torch.normal(0, 1, (3, 3, 3))
K = torch.normal(0, 1, (2, 3, 1, 1))

Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6

3.4 小结

  • 填充可以增加输出的高度和宽度。这常用来使输出与输入具有相同的高和宽。

  • 步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n。

  • 填充和步幅可用于有效地调整数据的维度。

  • 多输入多输出通道可以用来扩展卷积层的模型。

  • 当以每像素为基础应用时,1×1卷积层相当于全连接层。

  • 1×1卷积层通常用于调整网络层的通道数量和控制模型复杂性。

4 汇聚层

当处理图像时,我们希望逐渐降低隐藏表示的空间分辨率、聚集信息,这样随着我们在神经网络中层叠的上升,每个神经元对其敏感的感受野(输入)就越大。

而我们的机器学习任务通常会跟全局图像的问题有关(例如,“图像是否包含一只猫”),所以我们最后一层的神经元应该对整个输入的全局敏感通过逐渐聚合信息,生成越来越粗糙的映射,最终实现学习全局表示的目标同时将卷积图层的所有优势保留在中间层

本节将介绍汇聚层,英文表示为pooling,具有双重目的

  • 降低卷积层对位置的敏感性
  • 降低对空间降采样表示的敏感性

4.1 最大汇聚层和平均汇聚层

与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口遍历的每个位置计算一个输出。然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为最大汇聚层和平均汇聚层

如下图所示汇聚窗口形状为 2×2 的最大汇聚层。阴影计算这个输出的输入元素: max(0,1,3,4)=4。

汇聚窗口形状为p×q的汇聚层称为p×q汇聚层,汇聚操作称为p×q汇聚。

# 实现汇聚层的前向传播
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 = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool2d(X, (2, 2))

 

验证平均汇聚

pool2d(X, (2, 2), 'avg')

4.2 填充和步幅

与卷积层一样,汇聚层也可以改变输出形状。和以前一样,我们可以通过填充和步幅以获得所需的输出形状。 下面,我们用深度学习框架中内置的二维最大汇聚层,来演示汇聚层中填充和步幅的使用。 我们首先构造了一个输入张量X,它有四个维度,其中样本数和通道数都是1。

X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))

默认情况下,深度学习框架中的步幅与汇聚窗口的大小相同。 因此,如果我们使用形状为(3, 3)的汇聚窗口,那么默认情况下,我们得到的步幅形状为(3, 3)

pool2d = nn.MaxPool2d(3)

结果:

设定一个任意大小的矩形汇聚窗口,并分别设定填充和步幅的高度和宽度。

pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))

结果:

4.3 多通道

在处理多通道输入数据时,汇聚层在每个输入通道上单独运算,而不是像卷积层一样在通道上对输入进行汇总。意味着汇聚层的输出通道数与输入通道数相同

# 在通道维度上连结张量X和X + 1,以构建具有2个通道的输入
X = torch.cat((X, X + 1), 1)
# 汇聚后输出通道的数量仍然是2
pool2d = nn.MaxPool2d(3, padding=1, stride=2)

结果:

4.4 小结

  • 对于给定输入元素,最大汇聚层会输出该窗口内的最大值,平均汇聚层会输出该窗口内的平均值。

  • 汇聚层的主要优点之一是减轻卷积层对位置的过度敏感。

  • 我们可以指定汇聚层的填充和步幅。

  • 使用最大汇聚层以及大于1的步幅,可减少空间维度(如高度和宽度)。

  • 汇聚层的输出通道数与输入通道数相同。

5 卷积神经网络

为了能够应用softmax回归和多层感知机,我们首先将每个大小为28×28的图像展平为一个784维的固定长度的一维向量,然后用全连接层对其进行处理。而现在,我们已经掌握了卷积层的处理方法,我们可以在图像中保留空间结构。同时,用卷积层代替全连接层的另一个好处是:模型更简洁、所需的参数更少

5.1 LeNet

LeNet由两个部分组成:

  • 卷积编码器:由两个卷积层组成;

  • 全连接层密集块:由三个全连接层组成。

每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均汇聚层。为了将卷积块的输出传递给稠密块,我们必须在小批量中展平每个样本。换言之,我们将这个四维输入转换成全连接层所期望的二维输入。这里的二维表示的第一个维度索引小批量中的样本,第二个维度给出每个样本的平面向量表示。LeNet的稠密块有三个全连接层,分别有120、84和10个输出。因为我们在执行分类任务,所以输出层的10维对应于最后输出结果的数量。

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))

将一个大小为28×28的单通道(黑白)图像通过LeNet。通过在每一层打印输出的形状

# 检查模型
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)

从上往下:我们输入的28*28,填充、激活后仍为28*28;平均汇聚步幅为2输出为14*14;然后不填充,经过5*5的卷积层后得到的大小为10*10;再次经过平均汇聚步幅为2输出为1*16*5*5;平展为1*400后进行后续计算。

5.2 小结

  • 卷积神经网络(CNN)是一类使用卷积层的网络。

  • 在卷积神经网络中,我们组合使用卷积层、非线性激活函数和汇聚层。

  • 为了构造高性能的卷积神经网络,我们通常对卷积层进行排列,逐渐降低其表示的空间分辨率,同时增加通道数。

  • 在传统的卷积神经网络中,卷积块编码得到的表征在输出之前需由一个或多个全连接层进行处理。

  • LeNet是最早发布的卷积神经网络之一。

6 结语

本章链接:6. 卷积神经网络 — 动手学深度学习 2.0.0 documentation

学习链接:【视频+教材】原著大佬李沐带你读《动手学习深度学习》真的通俗易懂!深度学习入门必看!(人工智能、机器学习、神经网络、计算机视觉、图像处理、AI)_哔哩哔哩_bilibili

如果你有任何建议或疑问,欢迎留言讨论,最近每天基本上都会看留言,看到会及时回复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值