文章目录

  • 1. 从全连接层到卷积
    • 1.1 平移不变性
    • 1.2 局部性
  • 2. 图像卷积
    • 2.1 卷积计算图示
    • 2.2 学习卷积核
    • 2.3 小结
  • 3. 填充和步幅
    • 3.1 填充
    • 3.2 填充 - Pytorch
    • 3.3 步幅 stride
  • 4. 多输入和多输出通道
    • 4.1 多通道
    • 4.2 多输入通道 -> 单输出通道
    • 4.3 多个输入通道,单输出通道
    • 4.4 多输入通道,多输出通道
    • 4.5 输出通道的意义
    • 4.6 1 X 1 卷积层
  • 5. 汇聚层
    • 5.1 池化层
    • 5.2 最大汇聚层
    • 5.3 平均汇聚层
  • 6. 卷积神经网络 LeNet
    • 6.1 LeNet 思路简图
    • 6.2 LeNet 卷积网络大小分析
    • 6.3 代码
    • 6.4 小结

1. 从全连接层到卷积

因为我们遵循平移不变形和局部性,所以我们在全连接层的基础上形成了卷积神经网络,故卷积神经网络是一种特殊的全连接层。

1.1 平移不变性

不管检测对象出现在图像的哪个位置,神经网络的前几层应该对相同的图像区域具有相似的反应。
我们定义两个变量:

  • [X]i,j[X]_{i,j}[X]i,j​:表示输入图像的中位置 (i,j) 的像素
  • [H]i,j[H]_{i,j}[H]i,j​:表示隐藏的中位置 (i,j) 的像素
    为了使每个隐藏神经元都能接收到每个输⼊像素的信息,我们将参数从权重矩阵(如同我们先前在多层感知机中所做的那样)替换为四阶权重张量 W。假设 U 包含偏置参数,我们可以将全连接层形式化地表⽰为:
    [H]i,j=[U]i,j+∑k∑l[W]i,j,k,l[X]k,l(1)[H]_{i,j}=[U]_{i,j}+\sum_k\sum_l[W]_{i,j,k,l}[X]_{k,l}\tag1[H]i,j​=[U]i,j​+k∑​l∑​[W]i,j,k,l​[X]k,l​(1)
    [H]i,j=[U]i,j+∑a∑b[V]i,j,a,b[X]i+a,j+b(2)[H]_{i,j}=[U]_{i,j}+\sum_a\sum_b[V]_{i,j,a,b}[X]_{i+a,j+b}\tag2[H]i,j​=[U]i,j​+a∑​b∑​[V]i,j,a,b​[X]i+a,j+b​(2)
    从 W到V之间的转换只是形式的转换,因为在这两个四阶张量的元素之间存在一一对应的关系,我们只需重新索引下标(k,l);k=i+a;l=j+b;因此可得如下:
    [V]i,j,a,b=[W]i,j,i+a,j+b(3)[V]_{i,j,a,b}=[W]_{i,j,i+a,j+b}\tag{3}[V]i,j,a,b​=[W]i,j,i+a,j+b​(3)
    索引 a,b 通过在正偏移和负偏移之间移动覆盖整个图像。对于隐藏表示中任意给定位置 (i,j)处的像素值 [H]i,j[H]_{i,j}[H]i,j​,可以通过在 x 中以 (i,j) 为中心对像素进行加权求和得到,加权使用的权重为[V]i,j,a,b[V]_{i,j,a,b}[V]i,j,a,b​,平移不变性指的是在检测对象在输入 X 中的平移,应该仅仅导致隐藏表示 H中的平移。也就是 U 和 V实际上不依赖 i,j 的值。数学可表达为:
    [V]i,j,a,b=[V]a,b(4)[V]_{i,j,a,b}=[V]_{a,b}\tag{4}[V]i,j,a,b​=[V]a,b​(4)
    其中 U 可以看作是常数 u.则可以表示如下:
    [H]i,j=u+∑a∑b[V]a,b[X]i+a,j+b(5)[H]_{i,j}=u+\sum_a\sum_b[V]_{a,b}[X]_{i+a,j+b}\tag{5}[H]i,j​=u+a∑​b∑​[V]a,b​[X]i+a,j+b​(5)
    上述为卷积,表示的是使用系数[V]a,b[V]_{a,b}[V]a,b​对位置 [i,j] 附近的像素(i+a,j+b)进行加权得到 [H]i,j[H]_{i,j}[H]i,j​。因为卷积考虑到局部性和平移不变性,所以参数表示上小了很多,是巨大的进步,但是其本质上还是来自全连接层。

1.2 局部性

局部性指的是我们卷积只对局部部分进行加权计算,而不考虑局部以外的值。假设局部区间为△,我们希望:∣a∣>△|a|>△∣a∣>△或者∣b∣>△|b|>△∣b∣>△时,其训练参数 [V]a,b=0[V]_{a,b}=0[V]a,b​=0,故卷积层表示如下:
[H]i,j=u+∑a=−△△∑b=−△△[V]a,b[X]i+a,j+b(6)[H]_{i,j}=u+\sum_{a=-△}^{△}\sum_{b=-△}^{△}[V]_{a,b}[X]_{i+a,j+b}\tag{6}[H]i,j​=u+a=−△∑△​b=−△∑△​[V]a,b​[X]i+a,j+b​(6)

2. 图像卷积

2.1 卷积计算图示


2.2 学习卷积核

关于卷积核的学习,详见下述链接。
深度学习到底是学习了什么?卷积核学习思考

2.3 小结

  • 二维卷积层的核心计算为二维互相关计算,跟数学上的卷积计算有所差别
  • 我们可以通过卷积核计算来对图像进行不同的处理,如锐化,高斯处理等
  • 我们可以通过输入数据X和最终数据Y,通过深度学习来学习到卷积核的值
  • 当需要检测输入特征中更广阔的区域,我们需要设计更深的网络。

3. 填充和步幅

3.1 填充

填充的意义在于,当我们的卷积核的大小大于1的时候,我们总会丢失部分的边缘像素,当神经网络比较浅的时候,我们可能看不出来。但当我们的网络非常深的时候,那么最终我们就会丢失掉很多信息,所以我们需要填充输入的矩阵。

  • 填充方式,对称填充

如果我们添加 php_hph​行来填充(一半在顶部,一半在底部),添加pwp_wpw​列(一半在最左列,一半在最右列),输出形状为:
(nh−kh+ph+1)×(nw−kw+pw+1)(7)(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1)\tag{7}(nh​−kh​+ph​+1)×(nw​−kw​+pw​+1)(7)

  • 注:
    nh:输入矩阵行数;kh:卷积核行数;ph:填充的行数n_h:输入矩阵行数;k_h:卷积核行数;p_h:填充的行数nh​:输入矩阵行数;kh​:卷积核行数;ph​:填充的行数
    nw:输出矩阵列数;kw:卷积核列数;pw:填充的列数n_w:输出矩阵列数;k_w:卷积核列数;p_w:填充的列数nw​:输出矩阵列数;kw​:卷积核列数;pw​:填充的列数

我们知道输入矩阵 X 的大小为(nh,nw)(n_h,n_w)(nh​,nw​),输出矩阵 Y 的大小为(nh−kh+ph+1)×(nw−kw+pw+1)(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1)(nh​−kh​+ph​+1)×(nw​−kw​+pw​+1);为了保证输出大小和输入大小不变,我们通常假设填充如下:
−kh+ph+1=0;−kw+pw+1=0(8)-k_h+p_h+1=0;-k_w+p_w+1=0\tag{8}−kh​+ph​+1=0;−kw​+pw​+1=0(8)

  • 整理可得如下:
    ph=kh−1;pw=kw−1(9)p_h=k_h-1;p_w=k_w-1\tag{9}ph​=kh​−1;pw​=kw​−1(9)

3.2 填充 - Pytorch

  • pytorch
    在 Pytorch 二维卷积 nn.Conv2d中的参数 padding 值是单边填充量,比如
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)

那么输入矩阵 X 的填充是 顶部 1,底部 1,所以输出矩阵大小应该为
(nh−kh+2∗ph+1)×(nw−kw+2∗pw+1)(10)(n_h-k_h+2*p_h+1)\times(n_w-k_w+2*p_w+1)\tag{10}(nh​−kh​+2∗ph​+1)×(nw​−kw​+2∗pw​+1)(10)
代入可得:
(nh−3+2∗1+1)×(nw−3+2∗1+1)(11)(n_h-3+2*1+1)\times(n_w-3+2*1+1)\tag{11}(nh​−3+2∗1+1)×(nw​−3+2∗1+1)(11)
输出矩阵Y的形状如下,这样输入矩阵X和输出矩阵Y的大小不变
nh×nw(12)n_h\times n_w\tag{12}nh​×nw​(12)

  • 代码
# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: padding
# @Create time: 2021/12/4 15:56# 1. 导入相关数据库
import torch
from torch import nn
from d2l import torch as d2l# 2.矩阵大小计算
# 输入 conv2d: 卷积核,x :输入矩阵
# 返回 y:输出矩阵,y.shape :输出矩阵的形状
def comp_conv2d(conv2d, x):# 将矩阵 x 加入批量大小和通道数:(批量大小,通道数,输入矩阵)x = x.reshape((1, 1) + x.shape)# 卷积计算y = conv2d(x)# 去掉矩阵中的 (批量大小,通道数)y = y.reshape(y.shape[2:])return y, y.shape# 3. 定义二维卷积运算
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)# 4. 获取卷积矩阵的填充值(padding) ,卷积核大小(kernel_size)
padding = conv2d.padding
kernel_size = conv2d.kernel_size# 5. 初始化 x ,
x = torch.randn(8, 8)
x_shape = x.shape# 6. 获取相关参数
n_h, n_w = x_shape[0], x_shape[1]
k_h, k_w = kernel_size[0], kernel_size[1]
p_h, p_w = padding[0], padding[1]
y_h, y_w = x_shape[0], x_shape[1]# 7. 卷积计算,得到输出矩阵及形状
y, y_shape = comp_conv2d(conv2d, x)# 8. 打印相关数据
print(f'x_shape={x_shape},kernel_size={kernel_size},padding={padding},y_shape={y_shape}')
print(f'{y_h}:(y_h)={n_h}:(n_h)-{k_h}:(k_h)+{2*p_h}:(2*p_h)+1')
print(f'{y_w}:(y_w)={n_w}:(n_w)-{k_w}:(k_w)+{2*p_w}:(2*p_w)+1')
  • 结果
x_shape=torch.Size([8, 8]),kernel_size=(3, 3),padding=(1, 1),y_shape=torch.Size([8, 8])
8:(y_h)=8:(n_h)-3:(k_h)+2:(2*p_h)+1
8:(y_w)=8:(n_w)-3:(k_w)+2:(2*p_w)+1

3.3 步幅 stride

步幅指的是卷积核每次滑动元素的数量。步幅的作用是为了采样的压缩,以前是一步一步的移动卷积核,如果像素之间相似东西太多,我们其实没必要进行一步一步的移动采集,我们完全可以跳着采集嘛,所以一般步幅的作用为了压缩数据,步幅一般是2,比如,输入矩阵是(8,8),当我们的步幅stride = 2的时候,我们得到的矩阵大小一般是(4,4),具体公式如下:

  • 输出矩阵:
    ⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋(13)\lfloor (n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor (n_w-k_w+p_w+s_w)/s_w\rfloor\tag{13}⌊(nh​−kh​+ph​+sh​)/sh​⌋×⌊(nw​−kw​+pw​+sw​)/sw​⌋(13)
  • 设置卷积核大小
    ph=kh−1;pw=kw−1(14)p_h=k_h-1;p_w=k_w-1\tag{14}ph​=kh​−1;pw​=kw​−1(14)
  • 输出矩阵更新为:
    ⌊(nh+sh−1)/sh⌋×⌊(nw+sw−1)/sw⌋(15)\lfloor (n_h+s_h-1)/s_h\rfloor \times \lfloor (n_w+s_w-1)/s_w\rfloor\tag{15}⌊(nh​+sh​−1)/sh​⌋×⌊(nw​+sw​−1)/sw​⌋(15)
  • 一般能被整除,最后简化为:
    (nh/sh)×(nw/sw)(16)(n_h/s_h) \times (n_w/s_w)\tag{16}(nh​/sh​)×(nw​/sw​)(16)

4. 多输入和多输出通道

4.1 多通道

以前我们常常进行的是矩阵运算,其有长宽两个参数,一般为二维通道,当我们的图片是彩色的.而颜色是由RGB三种颜色组成的.所以每个RGB输入图像具有 3×h×w3 \times h \times w3×h×w,那么这个3就是通道的意思。

4.2 多输入通道 -> 单输出通道

假设我们输入为 ci×nh×nwc_i\times n_h \times n_wci​×nh​×nw​;卷积核为ci×kh×kwc_i \times k_h \times k_wci​×kh​×kw​,输出为oh×owo_h \times o_woh​×ow​;为了保证单通道输出,我们可以将每个通道卷积计算出来的结果求和。具体如下

解析:

  • input 输入大小为:2 x 3 x 3
  • kernel 核大小为: 2 x 2 x 2
  • padding 为:0;
  • output 输出大小为: 1 x 2 x 2注: 3-2+1=2; 1 表示的是求和;

代码如下:

# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: channel
# @Create time: 2021/12/4 21:28import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2ldef corr2d_multi_in(x, k):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]]])y = corr2d_multi_in(x, k)print(f'y={y}')
  • 结果
y=tensor([[ 56.,  72.],[104., 120.]])

4.3 多个输入通道,单输出通道

输入 X: ci×nh×nwc_i \times n_h \times n_wci​×nh​×nw​;
核 w: ci×kh×kwc_i \times k_h \times k_wci​×kh​×kw​
输出 Y: mh×mwm_h \times m_wmh​×mw​
Y=∑i=0ciXi,:,:∗Wi,:,:(17)Y=\sum_{i=0}^{c_i}X_{i,:,:} * W_{i,:,:}\tag{17}Y=i=0∑ci​​Xi,:,:​∗Wi,:,:​(17)

4.4 多输入通道,多输出通道

输入 X: ci×nh×nwc_i \times n_h \times n_wci​×nh​×nw​;
核 w: co×ci×kh×kwc_o \times c_i \times k_h \times k_wco​×ci​×kh​×kw​
输出 Y: co×mh×mwc_o \times m_h \times m_wco​×mh​×mw​
Y=Xi,:,:∗Wi,:,:,:;fori=1,2,...,co(18)Y=X_{i,:,:} * W_{i,:,:,:} \quad ;for \quad i = 1,2,...,c_o\tag{18}Y=Xi,:,:​∗Wi,:,:,:​;fori=1,2,...,co​(18)

4.5 输出通道的意义

  • 每个输出通道可以识别特定模式;
    比如说,我们输入有三个通道,可能 A 通道是识别猫的脚, B 通道是识别猫的颜色,C 通道是识别猫的尾巴,最后通过融合我们就知道了图片是一个猫。
  • 输入通道核识别并组合输入中的模式

4.6 1 X 1 卷积层

当卷积核的大小由原来的kh×kwk_h \times k_wkh​×kw​变成 1 X 1 的时候,那么卷积核就失去了原来的作用,以前我们通过卷积核来抽取卷积核范围内的信息,现在变成了 1 X 1 ,所以在使用 1 X 1 卷积时候,我们只作用到了通道里面。

注:当以每像素为基础应⽤时,1 X 1 卷积层相当于全连接层

5. 汇聚层

5.1 池化层

池化层(pooling)有两重作用:

  • 降低卷积层对位置的敏感性
  • 降低对空间降采样表示的敏感性
    注:汇聚层是没有可以学习的参数的层

5.2 最大汇聚层

  • 定义:计算池化窗口中所有元素的最大值

    max(0,1,3,4)=4(19)max(0,1,3,4)=4\tag{19}max(0,1,3,4)=4(19)
    max(1,2,4,5)=5max(1,2,4,5)=5max(1,2,4,5)=5
    max(3,4,6,7)=7max(3,4,6,7)=7max(3,4,6,7)=7
    max(4,5,7,8)=8max(4,5,7,8)=8max(4,5,7,8)=8
  • 代码
# 1. 导入数据库
import torch
from torch import nn
from d2l import torch as d2l# 2. 定义池化层 ,mode = 'max': 最大池化层,mode ='avg':平均池化层
def pool2d(x, pool_size, mode='max'):p_h, p_w = pool_sizey = 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# 3. 定义初始化参数
x = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool_size = (2, 2)# 4. 初始化最大池化层后的矩阵,平均池化层后的矩阵
y_max_pooling = pool2d(x, pool_size, 'max')
y_avg_pooling = pool2d(x, pool_size, 'avg')# 5. 输出相关结果
print(f'y_max_pooling={y_max_pooling}')
print(f'y_avg_pooling={y_avg_pooling}')
  • 结果
y_max_pooling=tensor([[4., 5.],[7., 8.]])
y_avg_pooling=tensor([[2., 3.],[5., 6.]])
  • 分析:代码结果跟我们手算的结果一致。
  • 代码 : 引用 nn.MaxPool2d
# 1. 导入数据库
import torch
from torch import nn# 2. 定义初始化参数
x = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])# 3. 形状变化为 4 维
x = x.reshape(1, 1, 3, 3)# 4. 实例化最大池化层
pool2d = nn.MaxPool2d(2,padding=0,stride=1)# 5. 对张量 X 进行最大池化层计算
y = pool2d(x)# 6. 将 Y 的形状改变
y = y.reshape(2,2)# 7. 输出相关参数
print(f'x={x}')
print(f'x_shape={x.shape}')
print(f'y={y}')
print(f'y_shape={y.shape}')
  • 结果:
x=tensor([[[[0., 1., 2.],[3., 4., 5.],[6., 7., 8.]]]])
x_shape=torch.Size([1, 1, 3, 3])
y=tensor([[4., 5.],[7., 8.]])
y_shape=torch.Size([2, 2])

5.3 平均汇聚层

  • 定义:计算池化窗口中所有元素的平均值

6. 卷积神经网络 LeNet

注:本文代码来自 李沐的书籍,这里只做学习笔记。

  • 运行环境:
  • Pytorch GPU-1.9.1 ;Pycharm

6.1 LeNet 思路简图

6.2 LeNet 卷积网络大小分析

Tensor [output_shape]: torch.Size([1, 1, 28, 28])
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])

6.3 代码

# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: Lenet
# @Create time: 2021/12/6 6:39# 1. 导入相关数据库
import torch
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as plt# 2. 定义整形类,主要是把原始图片变成(28,28)的大小
class Reshape(nn.Module):def forward(self, x):return x.view(-1, 1, 28, 28)# 3. 定义网络 LeNet
net = nn.Sequential(Reshape(),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))# 4. 加载数据
batch_size = 256  # 批量大小
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)  # 训练集和测试集# 5. 使用GPU计算模型在数据集上的精度
# net.eval() 推断模式的情况下,不启用 BatchNormalization 和 Dropout
def evaluate_accuracy_gpu(net, data_iter, device=None):  # @save"""使用GPU计算模型在数据集上的精度。"""if isinstance(net, nn.Module):net.eval()  # 设置为评估模式if not device:  # 如果没有 GPU ,就查看下网路参数在哪里,将 Device设置为 'CPU'device = next(iter(net.parameters())).device# 正确预测的数量,总预测的数量metric = d2l.Accumulator(2)with torch.no_grad():  # 被with torch.no_grad()包住的代码,不用跟踪反向梯度计算for X, y in data_iter:  # 从 data_iter 中拿出数据if isinstance(X, list):# BERT微调所需的(之后将介绍)X = [x.to(device) for x in X]  # 将数据 x 转到 GPU 中else:X = X.to(device)y = y.to(device)  # 将数据 y 转到 GPU 中metric.add(d2l.accuracy(net(X), y), y.numel())return metric[0] / metric[1]# 6.定义训练模型函数
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU训练模型(在第六章定义)。"""# 初始化权重参数def init_weights(m):if type(m) == nn.Linear or type(m) == nn.Conv2d:nn.init.xavier_uniform_(m.weight)  # 如果是卷积或者是全连接层,那么就用 xavier 进行初始化权重net.apply(init_weights)  # 网络参数初始化print('training on', device)net.to(device)  # 将网络转移到 GPU 上optimizer = torch.optim.SGD(net.parameters(), lr=lr)  # 设置神经网络优化器 SGD 随机梯度下降loss = nn.CrossEntropyLoss()  # 设置交叉熵损失来判断 y 和 y_hat 的差距animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],legend=['train loss', 'train acc', 'test acc'])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):  # 开始抽取相关数据 (x,y)timer.start()  # 开始计时optimizer.zero_grad()  # 优化器清零X, y = X.to(device), y.to(device)  # 将数据放在 GPU 上训练y_hat = net(X)# 这里有三个值,X,y 都是样本给的,X表示输入,# 我们希望通过网络得到 y_hat ,最后比较 y 和 y_hatl = loss(y_hat, y)  # 比较 y_hat 和 y 的差异l.backward()  # 损失回传optimizer.step()  # 优化器通过梯度来更新参数with torch.no_grad():  # 被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)}')# 7. 定义超参数
lr, num_epochs = 0.1, 50# 8. 开始训练模型
train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())# 9. 显示结果
plt.show()
  • 结果
loss 0.494, train acc 0.819, test acc 0.807
54179.3 examples/sec on cuda:0

6.4 小结

  • 在训练模式的情况时我们需要用 net.train();在预测模式的情况下我们需要用 net.eval()
net.train()      # 训练模式
net.eval()      # 预测模式
  • 需要将数据 X,Y, net 放到 GPU 上
X, y = X.to(device), y.to(device)  # 将数据放在 GPU 上训练
net.to(device)  # 将神经网络转移到 GPU 上

读书笔记-卷积神经网络相关推荐

  1. [Mitchell 机器学习读书笔记]——人工神经网络

    1.简介 神经网络学习方法对于逼近实数值.离散值或向量值的目标函数提供了一种健壮性很强的方法.在现实中,学习解释复杂的现实世界中的传感器数据,人工神经网络(Artificial Neural Netw ...

  2. 吴恩达深度学习笔记——卷积神经网络(Convolutional Neural Networks)

    深度学习笔记导航 前言 传送门 卷积神经网络(Convolutional Neural Networks) 卷积神经网络基础(Foundations of Convolutional Neural N ...

  3. 神经网络与机器学习 笔记—卷积神经网络(CNN)

    卷积神经网络 之前的一些都是考虑多层感知器算法设计相关的问题,这次是说一个多层感知器结构布局相关的问题.来总结卷积神经网络.对于模式分类非常合适.网络的提出所隐含的思想收到了神经生物学的启发. 第一个 ...

  4. Ng深度学习笔记-卷积神经网络-目标检测

    目标定位 符号表示: 图片左上角的坐标为(0,0)(0,0)(0,0),右下角标记为(1,1)(1,1)(1,1). 红色方框的中心点(bxb_{x}bx​,byb_{y}by​),边界框的高度为bh ...

  5. 李宏毅2021年机器学习笔记———卷积神经网络

    卷积神经网络 Observation1:感受野 Observation2:权值共享 Observation3:Max Pooling The whole CNN   我们开始探讨Network的架构设 ...

  6. 吴恩达深度学习笔记——卷积神经网络(CNN)

    目录 一.计算机视觉(Computer vision) 二.边缘检测示例(Edge detection example) 三.更多的边缘检测内容(More edge detection) 四.Padd ...

  7. [DeeplearningAI笔记]卷积神经网络2.9-2.10迁移学习与数据增强

    4.2深度卷积网络 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.9迁移学习 迁移学习的基础知识已经介绍过,本篇博文将介绍提高的部分. 提高迁移学习的速度 可以将迁移学习模型冻结的部分看 ...

  8. Keras读书笔记----卷积层、池化层

    1. 卷积层 1.1. Convolution1D层 一维卷积层,用以在一维输入信号上进行邻域滤波.当使用该层作为首层时,需要提供关键字参数 input_dim 或 input_shape . ker ...

  9. 深度学习笔记-卷积神经网络CNN与循环神经网络RNN有什么区别?

    转载 https://blog.csdn.net/weixin_35227692/article/details/79223536 转载于:https://www.cnblogs.com/USTBlx ...

最新文章

  1. 认知与设计:理解UI设计准则——序
  2. mysql-proxy 0.8.5_主从读写分离----mysql-proxy0.8.5安装与配置
  3. Codeforces 1205C Palindromic Paths (交互题、DP)
  4. 论文推荐 | 2018中国卫星导航年会论文集
  5. pojo java_什么是POJO,JavaBean?
  6. word2vec相关资料
  7. WorldWind Java 版学习:1、启动过程
  8. 使用C#操作Oracle Spatial的SDO_GEOMETRY对像(读取和写入)
  9. 微型计算机技术试题,《微型计算机技术》试题库
  10. 安卓手机屏幕投射电脑能同步声音
  11. 2021最新(ISC)2 CISSP 考试费用列表
  12. 用html计算长方形的面积公式,长方形面积公式是什么
  13. Android基础| 1G-4G的介绍
  14. SQL Server 端口映射访问方法
  15. GBase 8c 全文检索-表检索
  16. Python实现抓取微信公众号文章
  17. 工具软件推荐——GifCam
  18. R语言结构方程模型(SEM)在生态学领域中的应用
  19. 【第1131期】对于网络爬虫技术的攻与防
  20. DLT645协议解析(二)---07协议数据帧结构解析

热门文章

  1. 信用卡商户mcc代码
  2. ICNet图像实时语义分割
  3. 性能测试之负载测试、压力测试、可靠性测试和容量测试的区别
  4. mysql 廖雪峰_廖雪峰大佬SQL教程学习笔记
  5. 我如何在短短的一年内晋升为P6的
  6. 30岁,银行工作,未婚女,考博OR考公务员?
  7. Apple 计划在 2022 年推出五款新 Mac,包括入门级 MacBook Pro Refresh
  8. 关于蓝桥杯的考生须知和要求
  9. dedecms 5.7 密码修改
  10. 几何图形识别 python_OpenCV中几何形状识别与测量