【李沐】动手学深度学习 学习笔记

目录

  • 【内容介绍】动手学深度学习-基于pytorch版本
  • 【脉络梳理】
    • 预备知识
      • 数据操作
      • 数据预处理
      • 线性代数
      • 矩阵计算
      • 自动求导
    • 线性神经网络
      • 线性回归
      • 深度学习的基础优化算法
      • 线性回归的从零开始实现
      • 线性回归的简洁实现
      • Softmax回归
      • 损失函数
      • 图像分类数据集
      • Softmax回归的从零开始实现
      • Softmax回归的简洁实现
    • 多层感知机
      • 感知机
      • 多层感知机
      • 多层感知机的从零开始实现
      • 多层感知机的简洁实现
      • 模型选择
      • 过拟合和欠拟合
      • 权重衰退
      • 暂退法(Dropout)
      • 数值稳定性
      • 模型初始化和激活函数
    • 深度学习计算
      • 层和块
      • 参数管理
      • 自定义层
      • 读写文件
    • 卷积神经网络
      • 从全连接层到卷积
      • 图像卷积
      • 填充和步幅
      • 多输入多输出通道
      • 池化层(汇聚层)
      • LeNet
    • 现代卷积神经网络
      • 深度卷积神经网络(AlexNet)
      • 使用块的网络(VGG)
      • 网络中的网络(NiN)
      • 含并行连结的网络(GoogLeNet)
      • 批量规范化(归一化)
      • 残差网络(ResNet)
    • 计算性能
      • 深度学习硬件(CPU和GPU)
      • 深度学习硬件(TPU和其他)
      • 单机多卡并行
      • 分布式训练
    • 计算机视觉
      • 图像增广
      • 微调
      • 物体检测和数据集
      • 锚框
      • 物体检测算法:R-CNN,SSD,YOLO
      • 单发多框检测(SSD)
      • YOLO
      • 语义分割
      • 转置卷积
      • 全连接卷积神经网络 FCN
      • 样式迁移
    • 循环神经网络
      • 序列模型
      • 语言模型
      • 循环神经网络
    • 现代循环神经网络
      • 门控循环单元GRU
      • 长短期记忆网络(LSTM)
      • 深度循环神经网络
      • 双向循环神经网络
      • 编码器-解码器
      • 序列到序列学习
      • 束搜索
      • 注意力机制
      • 注意力分数
      • 使用注意力机制的seq2seq
      • 自注意力
      • Transformer
    • 自然语言处理:预训练
      • BERT预训练
    • 自然语言处理:应用
      • BERT微调
    • 优化算法
      • 优化算法

【内容介绍】动手学深度学习-基于pytorch版本

你好! 这是【李沐】动手学深度学习v2-基于pytorch版本的学习笔记
教材
源代码
安装教程(安装pytorch不要用pip,改成conda,pip太慢了,下载不下来)
个人推荐学习学习笔记

【脉络梳理】

预备知识

数据操作

  本节代码文件在源代码文件的chapter_preliminaries/ndarray.ipynb中

  • 创建数组
      创建数组需要:
      ①形状
      ②每个元素的数据类型
      ③每个元素的值
  • 访问元素
      ①一个元素:[1,2]
      ②一行:[1,:]
      ③一列:[:,1]
      ④子区域:[1:3,1:] #第1到2行,第1到最后1列
      ⑤子区域:[::3,::2] #从第0行开始,每3行一跳,从第0列开始,每2列一跳。

数据预处理

  本节代码文件在源代码文件的chapter_preliminaries/pandas.ipynb中

  • reshape函数
      使用reshape函数后不指向同一块内存,但数据改变是同步的
    import torch
    a=torch.arange(12)
    b=a.reshape((3,4))
    b[:]=2 # 改变b,a也会随之改变
    print(a) # tensor([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) 
    a[:]=1 # 改变a,b也会随之改变
    print(b) # tensor([[1, 1, 1, 1],[1, 1, 1, 1],[1, 1, 1, 1]])
    print(id(b)==id(a)) # False 
    # 但a、b内存不同
    print(id(a)) # 2157597781424
    print(id(b)) # 2157597781424
    

线性代数

  本节代码文件在源代码文件的chapter_preliminaries/linear-algebra.ipynb中

  • 张量的按元素操作
      标量、向量、矩阵和任意数量轴的张量(统称为张量)有一些实用的属性。 例如,你可能已经从按元素操作的定义中注意到,任何按元素的一元运算都不会改变其操作数的形状。 同样,给定具有相同形状的任意两个张量,任何按元素二元运算的结果都将是相同形状的张量。
      例如,将两个相同形状的矩阵相加,会在这两个矩阵上执行按元素加法;两个矩阵的按元素乘法称为Hadamard积(Hadamard product)(数学符号 ⨀ \bigodot )。 对于矩阵 A ∈ R m n , B ∈ R m n \bf A\in\mathbb R^{mn},\bf B\in\mathbb R^{mn} ARmn,BRmn, 其中第 i \it i i行和第 j \it j j列的元素是 b i j b_{ij} bij。 矩阵 A \bf A A B \bf B B的Hadamard积为
    【李沐】动手学深度学习 学习笔记_第1张图片
    import torch
    A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
    B = A.clone()  # 通过分配新内存,将A的一个副本分配给B
    print(A)
    #tensor([[ 0.,  1.,  2.,  3.],[ 4.,  5.,  6.,  7.],[ 8.,  9., 10., 11.],[12., 13., 14., 15.],[16., 17., 18., 19.]])
    print(A+B)
    #tensor([[ 0.,  2.,  4.,  6.],[ 8., 10., 12., 14.],[ 16., 18., 20., 22.],[24., 26., 28., 30.],[32., 34., 36., 38.]])
    print(A*B)
    #tensor([[0., 1., 4., 9.],[16., 25., 36., 49.],[64., 81., 100., 121.],[144., 169., 196., 225.],[256., 289., 324., 361.]])
    
  • 降维求和
      ①原始shape:[5,4]
        · axis=0 sum:[ 4 ]
        · axis=1 sum:[ 5 ]
      ②原始shape:[2,5,4]
        · axis=1 sum:[2,4]
        · axis=2 sum:[2,5]
        · axis=[1,2] sum:[ 4 ]
  • 非降维求和
      原始shape:[2,5,4] 参数 keepdims=True
        · axis=1 sum:[2,1,4]
        · axis=1 sum:[2,1,1]

矩阵计算

  本节代码文件在源代码文件的chapter_preliminaries/calculus.ipynb中

  • 将导数拓展到向量
      将导数拓展到向量

  • 标量对列向量求导
         其中, a 不是关于 x 的函数, 0 和 1 是向量 ; 其中,\it a不是关于\bf x的函数,\color{black} 0和\bf 1是向量; 其中,a不是关于x的函数,01是向量;
          【李沐】动手学深度学习 学习笔记_第2张图片

  • 列向量对列向量求导
      结果是矩阵
        【李沐】动手学深度学习 学习笔记_第3张图片
       样例:
          x ∈ R n , y ∈ R m , ∂ y ∂ x ∈ R m n ; a , a 和 A 不是关于 x 的函数, 0 和 I 是矩阵 ; \bf x\in\mathbb R^{n} ,\bf y\in\mathbb R^{m},\frac{\partial\bf y}{\partial\bf x}\in\mathbb R^{mn};\it a,\bf a和\bf A不是关于\bf x的函数,\color{black} 0和\bf I是矩阵; xRn,yRm,xyRmn;a,aA不是关于x的函数,0I是矩阵;
              【李沐】动手学深度学习 学习笔记_第4张图片

  • 将导数拓展到矩阵
        【李沐】动手学深度学习 学习笔记_第5张图片

自动求导

  本节代码文件在源代码文件的chapter_preliminaries/autograd.ipynb中

  • 向量链式法则
      【李沐】动手学深度学习 学习笔记_第6张图片
      样例:
          【李沐】动手学深度学习 学习笔记_第7张图片
  • 自动求导的两种模式
        【李沐】动手学深度学习 学习笔记_第8张图片
  • 反向累积模式
        【李沐】动手学深度学习 学习笔记_第9张图片

    样例:
      【李沐】动手学深度学习 学习笔记_第10张图片

  • 正向累积与反向累积复杂度比较
      正向累积内存复杂度为O(1),反向累积内存复杂度为O(n);但神经网络通常不会用正向累积,因为正向累积每计算一个变量的梯度都需要扫一遍,计算复杂度太高。
      【李沐】动手学深度学习 学习笔记_第11张图片

线性神经网络

线性回归

  本节代码文件在源代码文件的chapter_linear-networks/linear-regression.ipynb中

  • 线性模型
        【李沐】动手学深度学习 学习笔记_第12张图片
      线性模型可以看做是单层神经网络:
          【李沐】动手学深度学习 学习笔记_第13张图片
       衡量预估质量(损失函数):
          【李沐】动手学深度学习 学习笔记_第14张图片
  • 训练数据
        【李沐】动手学深度学习 学习笔记_第15张图片
  • 参数学习
        【李沐】动手学深度学习 学习笔记_第16张图片
      显示解:
          【李沐】动手学深度学习 学习笔记_第17张图片
  • 总结
        【李沐】动手学深度学习 学习笔记_第18张图片

深度学习的基础优化算法

  • 梯度下降
      通过不断地在损失函数递减的方向上更新参数来降低误差。
        【李沐】动手学深度学习 学习笔记_第19张图片
      学习率不能太大也不能太小:
        【李沐】动手学深度学习 学习笔记_第20张图片
  • 小批量随机梯度下降
        【李沐】动手学深度学习 学习笔记_第21张图片
      批量大小不能太大也不能太小:
          【李沐】动手学深度学习 学习笔记_第22张图片
  • 总结
        【李沐】动手学深度学习 学习笔记_第23张图片

线性回归的从零开始实现

  本节代码文件在源代码文件的chapter_linear-networks/linear-regression-scratch.ipynb中

  • 实现流程
生成数据集
读取数据集
初始化模型参数
定义模型
训练

  其中,定义模型包括定义损失函数和定义优化算法

线性回归的简洁实现

  本节代码文件在源代码文件的chapter_linear-networks/linear-regression-concise.ipynb中
  简洁实现是指通过使用深度学习框架来实现线性回归模型,具体流程与从零开始实现大体相同,不过一些常用函数不需要我们自己写了(直接导库,用别人写好的)

  • 实现流程
生成数据集
读取数据集
定义模型
初始化模型参数
训练

Softmax回归

  本节代码文件在源代码文件的chapter_linear-networks/softmax-regression.ipynb中

  • 回归vs分类(从回归到多类分类)
      回归估计一个连续值;分类预测一个离散类别。
         【李沐】动手学深度学习 学习笔记_第24张图片
  • 从回归到多类分类 — 均方损失
         【李沐】动手学深度学习 学习笔记_第25张图片
  • 从回归到多类分类 — 无校验比例
         【李沐】动手学深度学习 学习笔记_第26张图片
  • 从回归到多类分类 — 校验比例
        【李沐】动手学深度学习 学习笔记_第27张图片
  • Softmax和交叉熵损失
        【李沐】动手学深度学习 学习笔记_第28张图片
  • 总结
        【李沐】动手学深度学习 学习笔记_第29张图片

损失函数

  本节代码文件在源代码文件的chapter_linear-networks/softmax-regression.ipynb中
损失函数用来衡量预测值与真实值之间的区别,是机器学习里非常重要的概念。下面介绍三种常用的损失函数。

  • ①L2 Loss
         l ( y , y ′ ) = ∣ y − y ′ ∣ \it l(y,y') = \mid y-y' \mid l(y,y)=∣yy
            【李沐】动手学深度学习 学习笔记_第30张图片
    蓝色曲线:表示当y=0时,变换预测值y’。
    绿色曲线:表示似然函数。
    橙色曲线:表示损失函数的梯度,可以发现,当y与y’相差较大的时候,梯度的绝对值也较大。
  • ②L1 Loss
         l ( y , y ′ ) = 1 2 ( y − y ′ ) 2 \it l(y,y') = \frac{1}{2} ( y-y')^2 l(y,y)=21(yy)2
            【李沐】动手学深度学习 学习笔记_第31张图片
    蓝色曲线:表示当y=0时,变换预测值y’。
    绿色曲线:表示似然函数。
    橙色曲线:表示损失函数的梯度,可以发现,当y’>0时,导数为1,当y’<0时,导数为-1。
  • ③Huber’s Robust Loss(鲁棒损失)
            【李沐】动手学深度学习 学习笔记_第32张图片
    蓝色曲线:表示当y=0时,变换预测值y’。
    绿色曲线:表示似然函数。
    橙色曲线:表示损失函数的梯度。

图像分类数据集

  本节代码文件在源代码文件的chapter_linear-networks/image-classification-dataset.ipynb中

  • MNIST数据集
      是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集。
  • Fashion-MNIST数据集
      Fashion-MNIST由10个类别的图像组成,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。
       每个类别由训练数据集(train dataset)中的6000张图像 和测试数据集(test dataset)中的1000张图像组成。
       每个输入图像的高度和宽度均为28像素。 数据集由灰度图像组成,其通道数为1。

Softmax回归的从零开始实现

  本节代码文件在源代码文件的chapter_linear-networks/softmax-regression-scratch.ipynb中

  • 实现流程
      我们使用Fashion-MNIST数据集, 并设置数据迭代器的批量大小为256。每个样本都将用固定长度的向量表示。 原始数据集中的每个样本都是 28×28 的图像。 在本节中,我们将展平每个图像,把它们看作长度为784的向量。 在后面的章节中,我们将讨论能够利用图像空间结构的特征, 但现在我们暂时只把每个像素位置看作一个特征。
初始化模型参数
定义softmax操作
定义模型
定义损失函数
分类精度
训练
预测

    分类精度即正确预测数量与总预测数量之比

Softmax回归的简洁实现

  本节代码文件在源代码文件的chapter_linear-networks/softmax-regression-concise.ipynb中
  通过深度学习框架的高级API也能更方便地实现softmax回归模型。

  • 实现流程
      本节 继续使用Fashion-MNIST数据集,并保持批量大小为256。
初始化模型参数
定义损失函数
优化算法
训练
预测

多层感知机

感知机

  • 感知机
      【李沐】动手学深度学习 学习笔记_第33张图片
  • 感知机与回归和Softmax回归的区别
      感知机是二分类(1或-1),而回归的输出是实数,Softmax回归的输出是概率。
  • 训练感知机
        【李沐】动手学深度学习 学习笔记_第34张图片
  • 收敛定理
        【李沐】动手学深度学习 学习笔记_第35张图片
  • XOR问题
       【李沐】动手学深度学习 学习笔记_第36张图片
  • 总结
      【李沐】动手学深度学习 学习笔记_第37张图片

多层感知机

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/mlp.ipynb中

  • 学习XOR
        【李沐】动手学深度学习 学习笔记_第38张图片

  • 单隐藏层
      隐藏层大小是超参数(输入和输出大小由数据决定,输出大小人为决定。)
        【李沐】动手学深度学习 学习笔记_第39张图片

  • 单隐藏层 — 单分类
      只有一个输出,即输出是标量。
        【李沐】动手学深度学习 学习笔记_第40张图片
    Q:为什么需要非线性的激活函数?(σ(x)不可以等于x,也不可以等于nx)
    A: 如果激活函数是线性的,那么单隐藏层的多层感知机就变成了最简单的线性模型。
       【李沐】动手学深度学习 学习笔记_第41张图片

  • 激活函数
      ①Sigmoid 激活函数
        【李沐】动手学深度学习 学习笔记_第42张图片
      ②Tanh 激活函数
       【李沐】动手学深度学习 学习笔记_第43张图片
      ③ReLU 激活函数
        【李沐】动手学深度学习 学习笔记_第44张图片

  • 单隐藏层 — 多类分类
        【李沐】动手学深度学习 学习笔记_第45张图片

  • 多隐藏层
        多隐藏层

  • 总结
       在这里插入图片描述

多层感知机的从零开始实现

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/mlp-scratch.ipynb中

  • 实现流程
      我们实现一个具有单隐藏层的多层感知机, 它包含256个隐藏单元。 注意,我们可以将这两个变量都视为超参数。 通常,我们选择2的若干次幂作为层的宽度。 因为内存在硬件中的分配和寻址方式,这么做往往可以在计算上更高效。
初始化模型参数
激活函数
模型
损失函数
训练

多层感知机的简洁实现

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/mlp-concise.ipynb中

  • 与softmax回归的简洁实现相比
      唯一的区别是我们添加了2个全连接层(之前我们只添加了1个全连接层)。第一层是隐藏层,它包含256个隐藏单元,并使用了ReLU激活函数。第二层是输出层。
      训练过程的实现与我们实现softmax回归时完全相同。

模型选择

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/underfit-overfit.ipynb中

  • 训练误差和泛化误差
       训练误差和泛化误差
  • 验证数据集和测试数据集
       【李沐】动手学深度学习 学习笔记_第46张图片
  • K-折交叉验证
       【李沐】动手学深度学习 学习笔记_第47张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第48张图片

过拟合和欠拟合

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/underfit-overfit.ipynb中

  • 过拟合和欠拟合
       【李沐】动手学深度学习 学习笔记_第49张图片
       【李沐】动手学深度学习 学习笔记_第50张图片
  • 数据复杂度
       【李沐】动手学深度学习 学习笔记_第51张图片
  • 模型容量
       【李沐】动手学深度学习 学习笔记_第52张图片
  • 模型容量的影响
       【李沐】动手学深度学习 学习笔记_第53张图片
  • 估计模型容量
       【李沐】动手学深度学习 学习笔记_第54张图片
        其中,d+1中的1是偏移,m是隐藏层大小,k是分类的类别数
  • VC 维

    【李沐】动手学深度学习 学习笔记_第55张图片

  • 线性分类器的 VC 维
       【李沐】动手学深度学习 学习笔记_第56张图片
  • VC 维的用处
       【李沐】动手学深度学习 学习笔记_第57张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第58张图片

权重衰退

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/weight-decay.ipynb中
  权重衰退是一种常见的处理过拟合(模型复杂度过高)的方法

  • 使用均方范数作为硬性限制
       【李沐】动手学深度学习 学习笔记_第59张图片
  • 使用均方范数作为柔性限制
       【李沐】动手学深度学习 学习笔记_第60张图片
  • 演示对最优解的影响
       演示对最优解的影响
  • 参数更新法则
       【李沐】动手学深度学习 学习笔记_第61张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第62张图片

暂退法(Dropout)

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/dropout.ipynb中

  • 暂退法(丢弃法)的动机
       【李沐】动手学深度学习 学习笔记_第63张图片
  • 无偏差的加入噪音
       【李沐】动手学深度学习 学习笔记_第64张图片
  • 使用丢弃法
       【李沐】动手学深度学习 学习笔记_第65张图片
  • 推理中的丢弃法
       【李沐】动手学深度学习 学习笔记_第66张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第67张图片

数值稳定性

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/numerical-stability-and-init.ipynb中

  • 神经网络的梯度
       神经网络的梯度
       其中,矩阵乘法容易带来梯度爆炸和梯度消失的问题
  • 数值稳定性的常见两个问题
       【李沐】动手学深度学习 学习笔记_第68张图片
    例子:MLP
       【李沐】动手学深度学习 学习笔记_第69张图片
       【李沐】动手学深度学习 学习笔记_第70张图片
          ↑ ↑ ↑ 此时,就会造成梯度爆炸
       【李沐】动手学深度学习 学习笔记_第71张图片
       【李沐】动手学深度学习 学习笔记_第72张图片
          ↑ ↑ ↑ 此时,就会造成梯度消失
  • 梯度爆炸的问题
       【李沐】动手学深度学习 学习笔记_第73张图片
  • 梯度消失的问题
       【李沐】动手学深度学习 学习笔记_第74张图片
  • 总结
       总结

模型初始化和激活函数

  本节代码文件在源代码文件的chapter_multilayer-perceptrons/numerical-stability-and-init.ipynb中

  • 让训练更加稳定
       【李沐】动手学深度学习 学习笔记_第75张图片
  • 让每层的方差是个常数
       【李沐】动手学深度学习 学习笔记_第76张图片
  • 权重初始化
       【李沐】动手学深度学习 学习笔记_第77张图片
    例子:MLP
        【李沐】动手学深度学习 学习笔记_第78张图片
      ①假设没有激活函数:
        【李沐】动手学深度学习 学习笔记_第79张图片
       正向方差:
         【李沐】动手学深度学习 学习笔记_第80张图片
       反向均值和方差:
          【李沐】动手学深度学习 学习笔记_第81张图片
      ②假设线性的激活函数:
       正向:
         【李沐】动手学深度学习 学习笔记_第82张图片
       反向:
         【李沐】动手学深度学习 学习笔记_第83张图片
  • Xavier 初始
       Xavier 是一种常见的权重初始化方法
       【李沐】动手学深度学习 学习笔记_第84张图片
  • 检查常用激活函数
       【李沐】动手学深度学习 学习笔记_第85张图片
  • 总结
       总结

深度学习计算

层和块

  本节代码文件在源代码文件的chapter_deep-learning-computation/model-construction.ipynb中

  • 块的组成
      块(block)可以描述单个层、由多个层组成的组件或整个模型本身。 使用块进行抽象的一个好处是可以将一些块组合成更大的组件, 这一过程通常是递归的。
        【李沐】动手学深度学习 学习笔记_第86张图片
      从编程的角度来看,块由类(class)表示。 它的任何子类都必须定义一个将其输入转换为输出的前向传播函数, 并且必须存储任何必需的参数。 注意,有些块不需要任何参数。 最后,为了计算梯度,块必须具有反向传播函数在定义我们自己的块时,由于自动微分提供了一些后端实现,我们只需要考虑前向传播函数和必需的参数。

  • 块需要提供的基本功能
      ①将输入数据作为其前向传播函数的参数。
      ②通过前向传播函数来生成输出。注:输出的形状可能与输入的形状不同。
      ③计算其输出关于输入的梯度,可通过其反向传播函数进行访问。通常这是自动发生的。
      ④存储和访问前向传播计算所需的参数。
      ⑤根据需要初始化模型参数。

  • 自定义块
      在下面的代码片段中,我们从零开始编写一个块。 它包含一个多层感知机,其具有256个隐藏单元的隐藏层和一个10维输出层。 注意,下面的MLP类继承了表示块的类。我们的实现只需要提供我们自己的构造函数(Python中的__init__函数)和前向传播函数。

    class MLP(nn.Module):
        # 用模型参数声明层。这里,我们声明两个全连接的层
        def __init__(self):
            # 调用MLP的父类Module的构造函数来执行必要的初始化。
            # 这样,在类实例化时也可以指定其他函数参数,例如模型参数params(稍后将介绍)
            super().__init__()
            self.hidden = nn.Linear(20, 256)  # 隐藏层
            self.out = nn.Linear(256, 10)  # 输出层
    
        # 定义模型的前向传播,即如何根据输入X返回所需的模型输出
        def forward(self, X):
            # 注意,这里我们使用ReLU的函数版本,其在nn.functional模块中定义。
            return self.out(F.relu(self.hidden(X)))
    

    注意一些关键细节: 首先,我们定制的__init__函数通过super().init() 调用父类的__init__函数, 省去了重复编写模版代码的痛苦。 然后,我们实例化两个全连接层, 分别为self.hidden和self.out。 注意,除非我们实现一个新的运算符, 否则我们不必担心反向传播函数或参数初始化, 系统将自动生成这些。

  • 顺序块
      回想一下Sequential的设计是为了把其他模块串起来。 为了构建我们自己的简化的MySequential, 我们只需要定义两个关键函数:
       ①一种将块逐个追加到列表中的函数。
       ②一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”。
    下面的MySequential类提供了与默认Sequential类相同的功能:

    class MySequential(nn.Module):
        def __init__(self, *args):
            super().__init__()
            for idx, module in enumerate(args):
                # 这里,module是Module子类的一个实例。我们把它保存在'Module'类的成员
                # 变量_modules中。_module的类型是OrderedDict
                self._modules[str(idx)] = module
    
        def forward(self, X):
            # OrderedDict保证了按照成员添加的顺序遍历它们
            for block in self._modules.values():
                X = block(X)
            return X
    

    _modules:__init__函数将每个模块逐个添加到有序字典_modules中,_modules的主要优点是: 在模块的参数初始化过程中, 系统知道在_modules字典中查找需要初始化参数的子块。

参数管理

  本节代码文件在源代码文件的chapter_deep-learning-computation/parameters.ipynb中

  • 参数访问
      为方便解释,先定义如下神经网络:
    import torch
    from torch import nn
    
    net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
    X = torch.rand(size=(2, 4))
    net(X)
    
      我们从已有模型中访问参数。 当通过Sequential类定义模型时, 我们可以通过索引来访问模型的任意层。 这就像模型是一个列表一样,每层的参数都在其属性中。 如下所示,我们可以检查第二个全连接层的参数。
    print(net[2].state_dict())
    #OrderedDict([('weight', tensor([[ 0.0251, -0.2952, -0.1204,  0.3436, -0.3450, -0.0372,  0.0462,  0.2307]])), ('bias', tensor([0.2871]))])
    
  • 提取目标参数
      从第二个全连接层(即第三个神经网络层)提取偏置, 提取后返回的是一个参数类实例,并进一步访问该参数的值:
    print(type(net[2].bias))
    #
    print(net[2].bias)
    #Parameter containing:
    #tensor([0.2871], requires_grad=True)
    print(net[2].bias.data)
    #tensor([0.2871])
    
    参数是复合的对象,包含值、梯度和额外信息。 这就是我们需要显式参数值的原因。 除了值之外,我们还可以访问每个参数的梯度。 在上面这个网络中,由于我们还没有调用反向传播,所以参数的梯度处于初始状态。
    print(net[2].weight.grad == None)
    #True
    
  • 一次性访问所有参数
      当我们需要对所有参数执行操作时,逐个访问它们可能会很麻烦。 当我们处理更复杂的块(例如,嵌套块)时,情况可能会变得特别复杂, 因为我们需要递归整个树来提取每个子块的参数。 下面,我们将通过演示来比较访问第一个全连接层的参数访问所有层:
    print(*[(name, param.shape) for name, param in net[0].named_parameters()])
    #('weight', torch.Size([8, 4])) ('bias', torch.Size([8]))
    print(*[(name, param.shape) for name, param in net.named_parameters()])
    #('0.weight', torch.Size([8, 4])) ('0.bias', torch.Size([8])) ('2.weight', torch.Size([1, 8])) ('2.bias', torch.Size([1]))
    
    这为我们提供了另一种访问网络参数的方式,如下所示:
    net.state_dict()['2.bias'].data
    #tensor([0.2871])
    
  • 从嵌套块收集参数
      我们首先定义一个生成块的函数(可以说是“块工厂”),然后将这些块组合到更大的块中。
    def block1():
        return nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                             nn.Linear(8, 4), nn.ReLU())
    
    def block2():
        net = nn.Sequential()
        for i in range(4):
            # 在这里嵌套
            net.add_module(f'block {i}', block1())
        return net
    
    rgnet = nn.Sequential(block2(), nn.Linear(4, 1))
    rgnet(X)
    #tensor([[0.1713],
    #    [0.1713]], grad_fn=)
    
    设计了网络后,我们看看它是如何工作的:
    print(rgnet)
    '''
    Sequential(
      (0): Sequential(
        (block 0): Sequential(
          (0): Linear(in_features=4, out_features=8, bias=True)
          (1): ReLU()
          (2): Linear(in_features=8, out_features=4, bias=True)
          (3): ReLU()
        )
        (block 1): Sequential(
          (0): Linear(in_features=4, out_features=8, bias=True)
          (1): ReLU()
          (2): Linear(in_features=8, out_features=4, bias=True)
          (3): ReLU()
        )
        (block 2): Sequential(
          (0): Linear(in_features=4, out_features=8, bias=True)
          (1): ReLU()
          (2): Linear(in_features=8, out_features=4, bias=True)
          (3): ReLU()
        )
        (block 3): Sequential(
          (0): Linear(in_features=4, out_features=8, bias=True)
          (1): ReLU()
          (2): Linear(in_features=8, out_features=4, bias=True)
          (3): ReLU()
        )
      )
      (1): Linear(in_features=4, out_features=1, bias=True)
    )
    '''
    
    因为层是分层嵌套的,所以我们也可以像通过嵌套列表索引一样访问它们。 下面,我们访问第一个主要的块中、第二个子块的第一层的偏置项:
    rgnet[0][1][0].bias.data
    #tensor([-0.0444, -0.4451, -0.4149,  0.0549, -0.0969,  0.2053, -0.2514,  0.0220])
    
  • 参数初始化
      深度学习框架提供默认随机初始化, 也允许我们创建自定义初始化方法, 满足我们通过其他规则实现初始化权重。默认情况下,PyTorch会根据一个范围均匀地初始化权重和偏置矩阵, 这个范围是根据输入和输出维度计算出的。 PyTorch的nn.init模块提供了多种预置初始化方法。
    ①内置初始化
      下面的代码将所有权重参数初始化为标准差为0.01的高斯随机变量, 且将偏置参数设置为0。
    def init_normal(m):
        if type(m) == nn.Linear:
            nn.init.normal_(m.weight, mean=0, std=0.01)
            nn.init.zeros_(m.bias)
    net.apply(init_normal)
    net[0].weight.data[0], net[0].bias.data[0]
    #(tensor([-0.0017,  0.0232, -0.0026,  0.0026]), tensor(0.))
    
      我们还可以将所有参数初始化为给定的常数,比如初始化为1:
    def init_constant(m):
        if type(m) == nn.Linear:
            nn.init.constant_(m.weight, 1)
            nn.init.zeros_(m.bias)
    net.apply(init_constant)
    net[0].weight.data[0], net[0].bias.data[0]
    #(tensor([1., 1., 1., 1.]), tensor(0.))
    
      我们还可以对某些块应用不同的初始化方法。 例如,下面我们使用Xavier初始化方法初始化第一个神经网络层, 然后将第三个神经网络层初始化为常量值42:
    def xavier(m):
        if type(m) == nn.Linear:
            nn.init.xavier_uniform_(m.weight)
    def init_42(m):
        if type(m) == nn.Linear:
            nn.init.constant_(m.weight, 42)
    
    net[0].apply(xavier)
    net[2].apply(init_42)
    print(net[0].weight.data[0])
    #tensor([-0.4645,  0.0062, -0.5186,  0.3513])
    print(net[2].weight.data)
    #tensor([[42., 42., 42., 42., 42., 42., 42., 42.]])
    
    ②自定义初始化
      有时,深度学习框架没有提供我们需要的初始化方法。 在下面的例子中,我们使用以下的分布为任意权重参数 定义初始化方法:
    w ∽ { U ( 5 , 10 ) , 可能性1/4 0 , 可能性1/2 U ( − 10 , − 5 ) , 可能性1/4 w \backsim \begin{cases} U(5,10), & \text{可能性1/4} \\ 0, & \text{可能性1/2} \\ U(-10,-5), & \text{可能性1/4} \\ \end{cases} w U(5,10),0,U(10,5),可能性1/4可能性1/2可能性1/4
    def my_init(m):
        if type(m) == nn.Linear:
            print("Init", *[(name, param.shape)
                            for name, param in m.named_parameters()][0])
            nn.init.uniform_(m.weight, -10, 10)
            m.weight.data *= m.weight.data.abs() >= 5
    '''
    Init weight torch.Size([8, 4])
    Init weight torch.Size([1, 8])
    '''
    net.apply(my_init)
    net[0].weight[:2]
    '''
    tensor([[ 8.8025,  6.4078,  0.0000, -8.4598],
            [-0.0000,  9.0582,  8.8258,  7.4997]], grad_fn=)
    '''
    
    注意,我们始终可以直接设置参数:
    net[0].weight.data[:] += 1
    net[0].weight.data[0, 0] = 42
    net[0].weight.data[0]
    #tensor([42.0000,  7.4078,  1.0000, -7.4598])
    
  • 参数绑定
      有时我们希望在多个层间共享参数: 我们可以定义一个稠密层,然后使用它的参数来设置另一个层的参数。
    # 我们需要给共享层一个名称,以便可以引用它的参数
    shared = nn.Linear(8, 8)
    net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                        shared, nn.ReLU(),
                        shared, nn.ReLU(),
                        nn.Linear(8, 1))
    net(X)
    # 检查参数是否相同
    print(net[2].weight.data[0] == net[4].weight.data[0])
    '''
    tensor([True, True, True, True, True, True, True, True])
    '''
    net[2].weight.data[0, 0] = 100
    # 确保它们实际上是同一个对象,而不只是有相同的值
    print(net[2].weight.data[0] == net[4].weight.data[0])
    '''
    tensor([True, True, True, True, True, True, True, True])
    '''
    
      这个例子表明第三个和第五个神经网络层的参数是绑定的。 它们不仅值相等,而且由相同的张量表示。 因此,如果我们改变其中一个参数,另一个参数也会改变。 你可能会思考:当参数绑定时,梯度会发生什么情况? 答案是由于模型参数包含梯度,因此在反向传播期间第二个隐藏层 (即第三个神经网络层)和第三个隐藏层(即第五个神经网络层)的梯度会加在一起。

自定义层

  本节代码文件在源代码文件的chapter_deep-learning-computation/custom-layer.ipynb中

  • 不带参数的层
      下面的CenteredLayer类要从其输入中减去均值。 要构建它,我们只需继承基础层类并实现前向传播功能。

    import torch
    import torch.nn.functional as F
    from torch import nn
    
    
    class CenteredLayer(nn.Module):
        def __init__(self):
            super().__init__()
    
        def forward(self, X):
            return X - X.mean()
    

    让我们向该层提供一些数据,验证它是否能按预期工作。

    layer = CenteredLayer()
    layer(torch.FloatTensor([1, 2, 3, 4, 5]))
    #tensor([-2., -1.,  0.,  1.,  2.])
    

    我们可以将层作为组件合并到更复杂的模型中,比如:

    net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
    
  • 带参数的层
      下面我们定义具有参数的层, 这些参数可以通过训练进行调整。 我们可以使用内置函数来创建参数,这些函数提供一些基本的管理功能。 比如管理访问、初始化、共享、保存和加载模型参数。 这样做的好处之一是:我们不需要为每个自定义层编写自定义的序列化程序。
      现在,让我们实现自定义版本的全连接层。该层需要两个参数,一个用于表示权重,另一个用于表示偏置项。 在此实现中,我们使用修正线性单元作为激活函数。该层需要输入参数:in_units和units,分别表示输入数(输入维度)和输出数(输出维度)。

    class MyLinear(nn.Module):
        def __init__(self, in_units, units):
            super().__init__()
            self.weight = nn.Parameter(torch.randn(in_units, units))
            self.bias = nn.Parameter(torch.randn(units,))
        def forward(self, X):
            linear = torch.matmul(X, self.weight.data) + self.bias.data
            return F.relu(linear)
    linear = MyLinear(5, 3)
    linear.weight
    '''
    Parameter containing:
    tensor([[ 1.9054, -3.4102, -0.9792],
            [ 1.5522,  0.8707,  0.6481],
            [ 1.0974,  0.2568,  0.4034],
            [ 0.1416, -1.1389,  0.5875],
            [-0.7209,  0.4432,  0.1222]], requires_grad=True)
    '''
    

    我们可以使用自定义层直接执行前向传播计算:

    linear(torch.rand(2, 5))
    '''
    tensor([[2.4784, 0.0000, 0.8991],
            [3.6132, 0.0000, 1.1160]])
    '''
    

    我们还可以使用自定义层构建模型,就像使用内置的全连接层一样使用自定义层:

    net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))
    net(torch.rand(2, 64))
    '''
    tensor([[0.],
            [0.]])
    '''
    

读写文件

  本节代码文件在源代码文件的chapter_deep-learning-computation/read-write.ipynb中

  有时我们希望保存训练的模型, 以备将来在各种环境中使用(比如在部署中进行预测)。 此外,当运行一个耗时较长的训练过程时, 最佳的做法是定期保存中间结果, 以确保在服务器电源被不小心断掉时,我们不会损失几天的计算结果。

  • 加载和保存张量
      对于单个张量,我们可以直接调用load和save函数分别读写它们。 这两个函数都要求我们提供一个名称,save要求将要保存的变量作为输入。

    import torch
    from torch import nn
    from torch.nn import functional as F
    
    x = torch.arange(4)
    torch.save(x, 'x-file')
    

    我们现在可以将存储在文件中的数据读回内存。

    x2 = torch.load('x-file')
    x2
    #tensor([0, 1, 2, 3])
    

      我们可以存储一个张量列表,然后把它们读回内存。

    y = torch.zeros(4)
    torch.save([x, y],'x-files')
    x2, y2 = torch.load('x-files')
    (x2, y2)
    #(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))
    

      我们甚至可以写入或读取从字符串映射到张量的字典。 当我们要读取或写入模型中的所有权重时,这很方便。

    mydict = {'x': x, 'y': y}
    torch.save(mydict, 'mydict')
    mydict2 = torch.load('mydict')
    mydict2
    #{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}
    
  • 加载和保存模型参数
      保存单个权重向量(或其他张量)确实有用, 但是如果我们想保存整个模型,并在以后加载它们, 单独保存每个向量则会变得很麻烦。 毕竟,我们可能有数百个参数散布在各处。 因此,深度学习框架提供了内置函数来保存和加载整个网络。 需要注意的一个重要细节是,这将保存模型的参数而不是保存整个模型。 例如,如果我们有一个3层多层感知机,我们需要单独指定架构。 因为模型本身可以包含任意代码,所以模型本身难以序列化。 因此,为了恢复模型,我们需要用代码生成架构, 然后从磁盘加载参数。 让我们从熟悉的多层感知机开始尝试一下。

    class MLP(nn.Module):
        def __init__(self):
            super().__init__()
            self.hidden = nn.Linear(20, 256)
            self.output = nn.Linear(256, 10)
    
        def forward(self, x):
            return self.output(F.relu(self.hidden(x)))
    
    net = MLP()
    X = torch.randn(size=(2, 20))
    Y = net(X)
    

    接下来,我们将模型的参数存储在一个叫做“mlp.params”的文件中。

    torch.save(net.state_dict(), 'mlp.params')
    

    为了恢复模型,我们实例化了原始多层感知机模型的一个备份。 这里我们不需要随机初始化模型参数,而是直接读取文件中存储的参数。

    clone = MLP()
    clone.load_state_dict(torch.load('mlp.params'))
    clone.eval()
    '''
    MLP(
      (hidden): Linear(in_features=20, out_features=256, bias=True)
      (output): Linear(in_features=256, out_features=10, bias=True)
    )
    '''
    

    由于两个实例具有相同的模型参数,在输入相同的X时, 两个实例的计算结果应该相同。 让我们来验证一下。

    Y_clone = clone(X)
    Y_clone == Y
    '''
    tensor([[True, True, True, True, True, True, True, True, True, True],
            [True, True, True, True, True, True, True, True, True, True]])
    '''
    

卷积神经网络

从全连接层到卷积

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/why-conv.ipynb中

  • 重新考察全连接层
       【李沐】动手学深度学习 学习笔记_第87张图片
  • 平移不变性
      不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。
       【李沐】动手学深度学习 学习笔记_第88张图片
  • 局部性
       【李沐】动手学深度学习 学习笔记_第89张图片
  • 全连接层与卷积层的关系
       【李沐】动手学深度学习 学习笔记_第90张图片

图像卷积

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/conv-layer.ipynb中

  • 互相关运算
      在卷积层中,输入张量和核张量通过互相关运算产生输出张量。
         【李沐】动手学深度学习 学习笔记_第91张图片
         【李沐】动手学深度学习 学习笔记_第92张图片
      不同的卷积核可以带来不同的效果:
         不同的卷积核的举例
  • 交叉相关vs卷积
       【李沐】动手学深度学习 学习笔记_第93张图片
  • 一维和三维交叉相关
       【李沐】动手学深度学习 学习笔记_第94张图片
  • 一维和三维交叉相关
       【李沐】动手学深度学习 学习笔记_第95张图片

填充和步幅

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/padding-and-strides.ipynb中

  填充和步幅是卷积层的两个控制输出大小的超参数

  • 填充
       【李沐】动手学深度学习 学习笔记_第96张图片
      由于卷积核的宽度和高度通常大于1,在应用多层卷积时,我们常常丢失边缘像素。 由于我们通常使用小卷积核,因此对于任何单个卷积,我们可能只会丢失几个像素。 但随着我们应用许多连续卷积层,累积丢失的像素数就多了。 解决这个问题的简单方法即为填充:
       【李沐】动手学深度学习 学习笔记_第97张图片
      填充原则:
         【李沐】动手学深度学习 学习笔记_第98张图片
  • 步幅
       【李沐】动手学深度学习 学习笔记_第99张图片
      有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素。
       【李沐】动手学深度学习 学习笔记_第100张图片
      步幅原则:
         【李沐】动手学深度学习 学习笔记_第101张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第102张图片

多输入多输出通道

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/channels.ipynb中

  • 多个输入通道
       【李沐】动手学深度学习 学习笔记_第103张图片
      当输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数的卷积核,以便与输入数据进行互相关运算。
       【李沐】动手学深度学习 学习笔记_第104张图片
       【李沐】动手学深度学习 学习笔记_第105张图片
  • 多个输出通道
       【李沐】动手学深度学习 学习笔记_第106张图片
  • 多个输入和输出通道
       【李沐】动手学深度学习 学习笔记_第107张图片
  • 1x1卷积层
       【李沐】动手学深度学习 学习笔记_第108张图片
  • 二维卷积层
       【李沐】动手学深度学习 学习笔记_第109张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第110张图片

池化层(汇聚层)

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/pooling.ipynb中

  • 卷积层的缺点
       卷积层的缺点
  • 二维最大池化层
       【李沐】动手学深度学习 学习笔记_第111张图片
       【李沐】动手学深度学习 学习笔记_第112张图片
  • 池化层vs卷积层
      池化层没有可学习的参数,也不会融合多输入通道。
       【李沐】动手学深度学习 学习笔记_第113张图片
  • 平均池化层
       【李沐】动手学深度学习 学习笔记_第114张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第115张图片

LeNet

  本节代码文件在源代码文件的chapter_convolutional-neural-networks/lenet.ipynb中

  • 手写数字识别
       【李沐】动手学深度学习 学习笔记_第116张图片
  • MNIST数据集
       【李沐】动手学深度学习 学习笔记_第117张图片
  • LeNet
      LeNet是最早发布的卷积神经网络之一,因其在计算机视觉任务中的高效性能而受到广泛关注。 这个模型是由AT&T贝尔实验室的研究员Yann LeCun在1989年提出的(并以其命名),目的是识别图像中的手写数字。 当时,LeNet取得了与支持向量机性能相媲美的成果,成为监督学习的主流方法。 LeNet被广泛用于自动取款机(ATM)机中,帮助识别处理支票的数字。 时至今日,一些自动取款机仍在运行Yann LeCun和他的同事Leon Bottou在上世纪90年代写的代码呢!
      总体来看,LeNet(LeNet-5)由两个部分组成:
        ①卷积编码器:由两个卷积层组成。
        ②全连接层密集块:由三个全连接层组成。
       【李沐】动手学深度学习 学习笔记_第118张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第119张图片

现代卷积神经网络

深度卷积神经网络(AlexNet)

  本节代码文件在源代码文件的chapter_convolutional-modern/alexnet.ipynb中

  • 机器学习VS神经网路
      在上世纪90年代初到2012年之间的大部分时间里,神经网络往往被其他机器学习方法超越,如支持向量机(support vector machines)。
       【李沐】动手学深度学习 学习笔记_第120张图片

  • 计算机视觉与几何学
      卷积神经网络通常用在计算机视觉,在2000年时,计算机视觉的知识主要来源于几何学。
        【李沐】动手学深度学习 学习笔记_第121张图片

  • 计算机视觉与特征工程
      15年前,计算机视觉中,最重要的是特征工程。
        【李沐】动手学深度学习 学习笔记_第122张图片

  • 深度学习的崛起原因
      尽管一直有一群执着的研究者不断钻研,试图学习视觉数据的逐级表征,然而很长一段时间里这些尝试都未有突破。深度卷积神经网络的突破出现在2012年。突破可归因于两个关键因素。
    ①硬件
      2012年,当Alex Krizhevsky和Ilya Sutskever实现了可以在GPU硬件上运行的深度卷积神经网络时,一个重大突破出现了。他们意识到卷积神经网络中的计算瓶颈:卷积和矩阵乘法,都是可以在硬件上并行化的操作。 于是,他们使用两个显存为3GB的NVIDIA GTX580 GPU实现了快速卷积运算。他们的创新cuda-convnet几年来它一直是行业标准,并推动了深度学习热潮。
       【李沐】动手学深度学习 学习笔记_第123张图片

    ②数据
      2009年,ImageNet数据集发布,并发起ImageNet挑战赛:要求研究人员从100万个样本中训练模型,以区分1000个不同类别的对象。ImageNet数据集由斯坦福教授李飞飞小组的研究人员开发,利用谷歌图像搜索(Google Image Search)对每一类图像进行预筛选,并利用亚马逊众包(Amazon Mechanical Turk)来标注每张图片的相关类别。这种规模是前所未有的。这项被称为ImageNet的挑战赛推动了计算机视觉和机器学习研究的发展,挑战研究人员确定哪些模型能够在更大的数据规模下表现最好。
       【李沐】动手学深度学习 学习笔记_第124张图片

  • AlexNet vs LeNet
       【李沐】动手学深度学习 学习笔记_第125张图片
       【李沐】动手学深度学习 学习笔记_第126张图片

  • AlexNet
       【李沐】动手学深度学习 学习笔记_第127张图片
       【李沐】动手学深度学习 学习笔记_第128张图片

  • 总结
       【李沐】动手学深度学习 学习笔记_第129张图片

使用块的网络(VGG)

  本节代码文件在源代码文件的chapter_convolutional-modern/vgg.ipynb中

  • VGG 出现的背景
       【李沐】动手学深度学习 学习笔记_第130张图片
  • VGG 块
       【李沐】动手学深度学习 学习笔记_第131张图片
  • VGG 架构
       【李沐】动手学深度学习 学习笔记_第132张图片
  • 进度(发展)
       【李沐】动手学深度学习 学习笔记_第133张图片
      下图横坐标代表速率,纵坐标代表准确率,圆的大小代表内存占用的大小:
       【李沐】动手学深度学习 学习笔记_第134张图片
  • 总结
       总结

网络中的网络(NiN)

  本节代码文件在源代码文件的chapter_convolutional-modern/nin.ipynb中

  • 全连接层的问题
       【李沐】动手学深度学习 学习笔记_第135张图片
  • NiN 块
       【李沐】动手学深度学习 学习笔记_第136张图片
  • NiN 架构
       【李沐】动手学深度学习 学习笔记_第137张图片
  • NiN 网络
       【李沐】动手学深度学习 学习笔记_第138张图片
       【李沐】动手学深度学习 学习笔记_第139张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第140张图片

含并行连结的网络(GoogLeNet)

  本节代码文件在源代码文件的chapter_convolutional-modern/googlenet.ipynb中

  • GoogLeNet 出现的背景
      我们往往不确定到底选取什么样的层效果更好,到底是3X3卷积层还是5X5的卷积层,诸如此类的问题是GooLeNet选择了另一种思路“小学生才做选择,我全都要”,这也使得GooLeNet成为了第一个模型中超过1000个层的模型。
       【李沐】动手学深度学习 学习笔记_第141张图片
       【李沐】动手学深度学习 学习笔记_第142张图片
  • Inception 块
      Inception块由四条并行路径组成。 前三条路径使用窗口大小为1x1、3x3和5x5的卷积层,从不同空间大小中提取信息。 中间的两条路径在输入上执行1x1卷积,以减少通道数,从而降低模型的复杂性。 第四条路径使用3x3最大汇聚层,然后使用1x1卷积层来改变通道数。 这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并构成Inception块的输出。在Inception块中,通常调整的超参数是每层输出通道数。
       【李沐】动手学深度学习 学习笔记_第143张图片
       【李沐】动手学深度学习 学习笔记_第144张图片
  • GoogLeNet
      GoogLeNet一共使用9个Inception块和全局平均汇聚层(Global AvgPool)的堆叠来生成其估计值。Inception块之间的最大汇聚层可降低维度。 第一个模块类似于AlexNet和LeNet,Inception块的组合从VGG继承,全局平均汇聚层避免了在最后使用全连接层(FC)。
       【李沐】动手学深度学习 学习笔记_第145张图片
       【李沐】动手学深度学习 学习笔记_第146张图片
       【李沐】动手学深度学习 学习笔记_第147张图片
       【李沐】动手学深度学习 学习笔记_第148张图片
  • Inception 有各种后续变种
      v3是在v2基础上变化的:
       【李沐】动手学深度学习 学习笔记_第149张图片
       【李沐】动手学深度学习 学习笔记_第150张图片
       【李沐】动手学深度学习 学习笔记_第151张图片
       【李沐】动手学深度学习 学习笔记_第152张图片
  • Inception与其他网络的比较
      下图横坐标代表速率,纵坐标代表准确率,圆的大小代表内存占用的大小。由图可见,Inception V3速率较低,占用内存较大,但准确率很高。
       【李沐】动手学深度学习 学习笔记_第153张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第154张图片

批量规范化(归一化)

  本节代码文件在源代码文件的chapter_convolutional-modern/batch-norm.ipynb中

  • 背景
       【李沐】动手学深度学习 学习笔记_第155张图片
  • 批量归一化
       【李沐】动手学深度学习 学习笔记_第156张图片
  • 批量归一化层
       【李沐】动手学深度学习 学习笔记_第157张图片
  • 批量归一化在做什么?
       【李沐】动手学深度学习 学习笔记_第158张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第159张图片

残差网络(ResNet)

  本节代码文件在源代码文件的chapter_convolutional-modern/resnet.ipynb中

  • 加更多的层总是改进精度吗?
       【李沐】动手学深度学习 学习笔记_第160张图片
  • 残差块
       【李沐】动手学深度学习 学习笔记_第161张图片
  • ResNet 块细节
       【李沐】动手学深度学习 学习笔记_第162张图片
  • 不同的残差块
       【李沐】动手学深度学习 学习笔记_第163张图片
  • ResNet 块
       【李沐】动手学深度学习 学习笔记_第164张图片
  • ResNet 架构
       【李沐】动手学深度学习 学习笔记_第165张图片
  • ResNet与其他网络的比较
      下图横坐标代表速率,纵坐标代表准确率,圆的大小代表内存占用的大小。由图可见,ResNet 152 速率较低,但占用内存较小,且准确率很高。
       【李沐】动手学深度学习 学习笔记_第166张图片
  • 总结
       总结

计算性能

深度学习硬件(CPU和GPU)

  • 电脑CPU、GPU、内存之间的关系
       【李沐】动手学深度学习 学习笔记_第167张图片
  • CPU芯片图
       【李沐】动手学深度学习 学习笔记_第168张图片
  • 提升CPU利用率
       【李沐】动手学深度学习 学习笔记_第169张图片
       【李沐】动手学深度学习 学习笔记_第170张图片
       【李沐】动手学深度学习 学习笔记_第171张图片
       【李沐】动手学深度学习 学习笔记_第172张图片
  • GPU芯片图
       【李沐】动手学深度学习 学习笔记_第173张图片
  • GPU vs CPU
       【李沐】动手学深度学习 学习笔记_第174张图片
  • 提升GPU利用率
       【李沐】动手学深度学习 学习笔记_第175张图片
  • CPU/GPU 带宽
       【李沐】动手学深度学习 学习笔记_第176张图片
  • 更多的 CPUs 和 GPUs
       【李沐】动手学深度学习 学习笔记_第177张图片
  • CPU/GPU 高性能计算编程
       【李沐】动手学深度学习 学习笔记_第178张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第179张图片

深度学习硬件(TPU和其他)

  • 手机内部的芯片
       【李沐】动手学深度学习 学习笔记_第180张图片
  • DSP:数字信号处理
       【李沐】动手学深度学习 学习笔记_第181张图片
  • 可编程阵列(FPGA)
       【李沐】动手学深度学习 学习笔记_第182张图片
  • AI ASIC
       【李沐】动手学深度学习 学习笔记_第183张图片
  • Systolic Array
       【李沐】动手学深度学习 学习笔记_第184张图片
    【李沐】动手学深度学习 学习笔记_第185张图片
    【李沐】动手学深度学习 学习笔记_第186张图片
    【李沐】动手学深度学习 学习笔记_第187张图片
    【李沐】动手学深度学习 学习笔记_第188张图片
    【李沐】动手学深度学习 学习笔记_第189张图片
    【李沐】动手学深度学习 学习笔记_第190张图片
    【李沐】动手学深度学习 学习笔记_第191张图片
    【李沐】动手学深度学习 学习笔记_第192张图片
       【李沐】动手学深度学习 学习笔记_第193张图片
  • 总结
      · 灵活性、易用性:Intel(CPU) > GPU > DSP > FPGA > ASIC
      · 性能功耗:Intel(CPU) < GPU < DSP < FPGA < ASIC
       【李沐】动手学深度学习 学习笔记_第194张图片

单机多卡并行

  • 多GPU并行
       【李沐】动手学深度学习 学习笔记_第195张图片
  • 单机多卡并行
       【李沐】动手学深度学习 学习笔记_第196张图片
  • 数据并行 vs 模型并行
       【李沐】动手学深度学习 学习笔记_第197张图片
  • 数据并行
       【李沐】动手学深度学习 学习笔记_第198张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第199张图片

分布式训练

  • 分布式计算
      本质上来说和之前讲的单机多卡并行没有区别。二者之间的区别是分布式计算是通过网络把数据从一台机器搬到另一台机器。
       【李沐】动手学深度学习 学习笔记_第200张图片【李沐】动手学深度学习 学习笔记_第201张图片
  • GPU机器架构
      总的来说,gpu到gpu的通讯是很快的,gpu到cpu慢一点。机器到机器更慢。因而总体性能的关键就是尽量在本地做通讯而少在机器之间做通讯。
       【李沐】动手学深度学习 学习笔记_第202张图片
    举例:计算一个小批量:
       【李沐】动手学深度学习 学习笔记_第203张图片【李沐】动手学深度学习 学习笔记_第204张图片
       【李沐】动手学深度学习 学习笔记_第205张图片【李沐】动手学深度学习 学习笔记_第206张图片
       【李沐】动手学深度学习 学习笔记_第207张图片【李沐】动手学深度学习 学习笔记_第208张图片
       【李沐】动手学深度学习 学习笔记_第209张图片【李沐】动手学深度学习 学习笔记_第210张图片
  • 同步 SGD
       【李沐】动手学深度学习 学习笔记_第211张图片
  • 性能
       【李沐】动手学深度学习 学习笔记_第212张图片
  • 性能的权衡
       【李沐】动手学深度学习 学习笔记_第213张图片
  • 实践时的建议
       【李沐】动手学深度学习 学习笔记_第214张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第215张图片

计算机视觉

图像增广

  本节代码文件在源代码文件的chapter_computer-vision/image-augmentation.ipynb中

  • 数据增广
       【李沐】动手学深度学习 学习笔记_第216张图片【李沐】动手学深度学习 学习笔记_第217张图片

  • 数据增强
       【李沐】动手学深度学习 学习笔记_第218张图片

  • 使用增强数据训练
       【李沐】动手学深度学习 学习笔记_第219张图片

  • 翻转
       【李沐】动手学深度学习 学习笔记_第220张图片

  • 切割
       【李沐】动手学深度学习 学习笔记_第221张图片

  • 颜色
       【李沐】动手学深度学习 学习笔记_第222张图片

  • 几十种其他办法
       【李沐】动手学深度学习 学习笔记_第223张图片

  • 总结
       【李沐】动手学深度学习 学习笔记_第224张图片

微调

  本节代码文件在源代码文件的chapter_computer-vision/fine-tuning.ipynb中

  • 微调的原因
       【李沐】动手学深度学习 学习笔记_第225张图片
  • 神经网络的网络架构
       【李沐】动手学深度学习 学习笔记_第226张图片
        【李沐】动手学深度学习 学习笔记_第227张图片
  • 微调中的权重初始化
       【李沐】动手学深度学习 学习笔记_第228张图片
  • 训练时的微调
       【李沐】动手学深度学习 学习笔记_第229张图片
  • 重用分类器权重
       重用分类器权重
  • 固定一些层
       【李沐】动手学深度学习 学习笔记_第230张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第231张图片

物体检测和数据集

  本节代码文件在源代码文件的chapter_computer-vision/bounding-box.ipynb中

  • 图片分类与目标检测的区别
      目标检测更加复杂,需要进行多个物体的识别,还要找出每个物体的位置。目标检测的应用场景也更多。
       【李沐】动手学深度学习 学习笔记_第232张图片

  • 边缘框
       【李沐】动手学深度学习 学习笔记_第233张图片

  • 目标检测数据集
       【李沐】动手学深度学习 学习笔记_第234张图片

  • 总结
       总结

锚框

  本节代码文件在源代码文件的chapter_computer-vision/anchor.ipynb中

  • 锚框
       【李沐】动手学深度学习 学习笔记_第235张图片
  • IoU - 交并比
       IoU - 交并比
  • 赋予锚框标号
       【李沐】动手学深度学习 学习笔记_第236张图片
       【李沐】动手学深度学习 学习笔记_第237张图片
  • 使用非极大值抑制(NMS)输出
       【李沐】动手学深度学习 学习笔记_第238张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第239张图片

物体检测算法:R-CNN,SSD,YOLO

  本节代码文件在源代码文件的chapter_computer-vision/rcnn.ipynb中

  • R-CNN
       
    【李沐】动手学深度学习 学习笔记_第240张图片
  • 兴趣区域(RoI)池化层
      目的:每个锚框都可以变成想要的形状
       兴趣区域(RoI)池化层
  • Fast RCNN
      RCNN需要对每个锚框进行CNN运算,这些特征抽取计算有重复,并且锚框数量大,特征抽取的计算量也大。Fast RCNN改进了这种计算量大的问题,使用CNN对整张图片抽取特征(快的关键),再使用Rol池化层对每个锚框(将在原图片中搜索到的锚框,映射到CNN得到的结果上),生成固定长度的特征。
       【李沐】动手学深度学习 学习笔记_第241张图片
  • Faster RCNN
      将CNN结果输入到卷积层,然后用锚框去圈区域,这些锚框很多有好有坏,然后进行预测,binary 预测是预测这个锚框的好坏,即有没有有效的圈住物体,bounding box prediction预测是对锚框进行一些改进,最后用NMS(非极大值抑制)对锚框进行合并。
       【李沐】动手学深度学习 学习笔记_第242张图片
  • Mask RCNN
       【李沐】动手学深度学习 学习笔记_第243张图片
      如图,Faster RCNN精度高但是速度慢(贵):
       【李沐】动手学深度学习 学习笔记_第244张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第245张图片

单发多框检测(SSD)

  本节代码文件在源代码文件的chapter_computer-vision/ssd.ipynb中

  • 生成锚框
       【李沐】动手学深度学习 学习笔记_第246张图片
  • SSD模型
       【李沐】动手学深度学习 学习笔记_第247张图片
      如图,SSD速度快但精度不高:
       【李沐】动手学深度学习 学习笔记_第248张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第249张图片

YOLO

  • YOLO(你只看一次)
       【李沐】动手学深度学习 学习笔记_第250张图片
      如图,相同精度下YoLo比SSD速度快:
       【李沐】动手学深度学习 学习笔记_第251张图片

语义分割

  本节代码文件在源代码文件的chapter_computer-vision/semantic-segmentation-and-dataset.ipynb中

  • 语义分割
       【李沐】动手学深度学习 学习笔记_第252张图片
  • 应用:背景虚化
       【李沐】动手学深度学习 学习笔记_第253张图片
  • 应用:路面分割
       【李沐】动手学深度学习 学习笔记_第254张图片
  • 应用:实例分割
       应用

转置卷积

  本节代码文件在源代码文件的chapter_computer-vision/transposed-conv.ipynb中

  • 转置卷积
       【李沐】动手学深度学习 学习笔记_第255张图片
  • 为什么称之为“转置”
       【李沐】动手学深度学习 学习笔记_第256张图片
  • 转置卷积是一种卷积
       【李沐】动手学深度学习 学习笔记_第257张图片
  • 重新排列输入和核
       【李沐】动手学深度学习 学习笔记_第258张图片
       【李沐】动手学深度学习 学习笔记_第259张图片
       【李沐】动手学深度学习 学习笔记_第260张图片
  • 形状换算
       形状换算
  • 同反卷积的关系
       【李沐】动手学深度学习 学习笔记_第261张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第262张图片

全连接卷积神经网络 FCN

  本节代码文件在源代码文件的chapter_computer-vision/fcn.ipynb中

  • 全连接卷积神经网络(FCN)
       全连接卷积神经网络(FCN)
       【李沐】动手学深度学习 学习笔记_第263张图片

样式迁移

  本节代码文件在源代码文件的chapter_computer-vision/neural-style.ipynb中

  • 样式迁移
       【李沐】动手学深度学习 学习笔记_第264张图片
       【李沐】动手学深度学习 学习笔记_第265张图片
  • 基于CNN的样式迁移
       【李沐】动手学深度学习 学习笔记_第266张图片

循环神经网络

序列模型

  本节代码文件在源代码文件的chapter_recurrent-neural-networks/sequence.ipynb中

  • 序列数据
       【李沐】动手学深度学习 学习笔记_第267张图片
  • 序列数据 - 更多例子
       【李沐】动手学深度学习 学习笔记_第268张图片
  • 统计工具
       【李沐】动手学深度学习 学习笔记_第269张图片
       【李沐】动手学深度学习 学习笔记_第270张图片
  • 序列模型
       【李沐】动手学深度学习 学习笔记_第271张图片
       【李沐】动手学深度学习 学习笔记_第272张图片
       【李沐】动手学深度学习 学习笔记_第273张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第274张图片

语言模型

  本节代码文件在源代码文件的chapter_recurrent-neural-networks/language-models-and-dataset.ipynb中

  • 语言模型
       【李沐】动手学深度学习 学习笔记_第275张图片
       【李沐】动手学深度学习 学习笔记_第276张图片
  • 使用计数来建模
       【李沐】动手学深度学习 学习笔记_第277张图片
  • N元语法
       【李沐】动手学深度学习 学习笔记_第278张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第279张图片

循环神经网络

  本节代码文件在源代码文件的chapter_recurrent-neural-networks/rnn.ipynb中

  • 潜变量自回归模型
       【李沐】动手学深度学习 学习笔记_第280张图片
  • 循环神经网络
       循环神经网络
  • 使用循环神经网络的语言模型
       【李沐】动手学深度学习 学习笔记_第281张图片
  • 困惑度(perplexity)
       【李沐】动手学深度学习 学习笔记_第282张图片
  • 梯度裁剪
       【李沐】动手学深度学习 学习笔记_第283张图片
  • 更多的应用RNNs
       【李沐】动手学深度学习 学习笔记_第284张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第285张图片

现代循环神经网络

门控循环单元GRU

  本节代码文件在源代码文件的chapter_recurrent-modern/gru.ipynb中

  • 门控循环单元GRU
       【李沐】动手学深度学习 学习笔记_第286张图片
  • 关注一个序列
       【李沐】动手学深度学习 学习笔记_第287张图片

  •    【李沐】动手学深度学习 学习笔记_第288张图片
  • 候选隐状态
       【李沐】动手学深度学习 学习笔记_第289张图片
  • 隐状态
       【李沐】动手学深度学习 学习笔记_第290张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第291张图片

长短期记忆网络(LSTM)

  本节代码文件在源代码文件的chapter_recurrent-modern/lstm.ipynb中

  • 长短期记忆网络
       【李沐】动手学深度学习 学习笔记_第292张图片

  •    【李沐】动手学深度学习 学习笔记_第293张图片
  • 候选记忆单元
       【李沐】动手学深度学习 学习笔记_第294张图片
  • 记忆单元
       【李沐】动手学深度学习 学习笔记_第295张图片
  • 隐状态
       【李沐】动手学深度学习 学习笔记_第296张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第297张图片

深度循环神经网络

  本节代码文件在源代码文件的chapter_recurrent-modern/deep-rnn.ipynb中

  • 回顾:循环神经网络
       【李沐】动手学深度学习 学习笔记_第298张图片
  • Plan A - Nonlinearity in the units
       【李沐】动手学深度学习 学习笔记_第299张图片
  • 更深
       【李沐】动手学深度学习 学习笔记_第300张图片
       【李沐】动手学深度学习 学习笔记_第301张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第302张图片

双向循环神经网络

  本节代码文件在源代码文件的chapter_recurrent-modern/bi-rnn.ipynb中

  • 未来很重要
       未来很重要
       【李沐】动手学深度学习 学习笔记_第303张图片
  • 双向RNN
       【李沐】动手学深度学习 学习笔记_第304张图片
       【李沐】动手学深度学习 学习笔记_第305张图片
  • 推理
       【李沐】动手学深度学习 学习笔记_第306张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第307张图片

编码器-解码器

  本节代码文件在源代码文件的chapter_recurrent-modern/encoder-decoder.ipynb中

  • 重新考察CNN
       【李沐】动手学深度学习 学习笔记_第308张图片
  • 重新考察RNN
       【李沐】动手学深度学习 学习笔记_第309张图片
  • 编码器-解码器架构
       【李沐】动手学深度学习 学习笔记_第310张图片
  • 总结
       总结

序列到序列学习

  本节代码文件在源代码文件的chapter_recurrent-modern/seq2seq.ipynb中

  • 序列到序列学习(seq2seq)
       【李沐】动手学深度学习 学习笔记_第311张图片
  • 机器翻译
       【李沐】动手学深度学习 学习笔记_第312张图片
  • Seq2seq
       【李沐】动手学深度学习 学习笔记_第313张图片
  • 编码器-解码器细节
       【李沐】动手学深度学习 学习笔记_第314张图片
  • 训练
       【李沐】动手学深度学习 学习笔记_第315张图片
  • 衡量生成序列的好坏的BLEU
       【李沐】动手学深度学习 学习笔记_第316张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第317张图片

束搜索

  本节代码文件在源代码文件的chapter_recurrent-modern/beam-search.ipynb中

  • 贪心搜索
       【李沐】动手学深度学习 学习笔记_第318张图片
  • 穷举搜索
       【李沐】动手学深度学习 学习笔记_第319张图片
  • 束搜索
       【李沐】动手学深度学习 学习笔记_第320张图片
       【李沐】动手学深度学习 学习笔记_第321张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第322张图片

注意力机制

  本节代码文件在源代码文件的chapter_attention-mechanisms/attention-cues.ipynb中

  • 心理学
       【李沐】动手学深度学习 学习笔记_第323张图片
  • 注意力机制
       【李沐】动手学深度学习 学习笔记_第324张图片
  • 非参注意力池化层
       【李沐】动手学深度学习 学习笔记_第325张图片
  • Nadaraya-Watson核回归
       【李沐】动手学深度学习 学习笔记_第326张图片
  • 参数化的注意力机制
       【李沐】动手学深度学习 学习笔记_第327张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第328张图片

注意力分数

  本节代码文件在源代码文件的chapter_attention-mechanisms/attention-scoring-functions.ipynb中

  • 注意力分数
       【李沐】动手学深度学习 学习笔记_第329张图片
  • 拓展到高维度
       【李沐】动手学深度学习 学习笔记_第330张图片
  • Additive Attention
       【李沐】动手学深度学习 学习笔记_第331张图片
  • Scaled Dot-Product Attention
       【李沐】动手学深度学习 学习笔记_第332张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第333张图片

使用注意力机制的seq2seq

  本节代码文件在源代码文件的chapter_attention-mechanisms/bahdanau-attention.ipynb中

  • 动机
       【李沐】动手学深度学习 学习笔记_第334张图片
  • 加入注意力
       【李沐】动手学深度学习 学习笔记_第335张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第336张图片

自注意力

  本节代码文件在源代码文件的chapter_attention-mechanisms/self-attention-and-positional-encoding.ipynb中

  • 自注意力
       【李沐】动手学深度学习 学习笔记_第337张图片
  • 跟CNN,RNN对比
       【李沐】动手学深度学习 学习笔记_第338张图片
  • 位置编码
       【李沐】动手学深度学习 学习笔记_第339张图片
  • 位置编码矩阵
       【李沐】动手学深度学习 学习笔记_第340张图片
  • 绝对位置信息
       【李沐】动手学深度学习 学习笔记_第341张图片
       【李沐】动手学深度学习 学习笔记_第342张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第343张图片

Transformer

  本节代码文件在源代码文件的chapter_attention-mechanisms/transformer.ipynb中

  • Transformer架构
       【李沐】动手学深度学习 学习笔记_第344张图片
  • 多头注意力
       【李沐】动手学深度学习 学习笔记_第345张图片
       【李沐】动手学深度学习 学习笔记_第346张图片
  • 有掩码的多头注意力
       【李沐】动手学深度学习 学习笔记_第347张图片
  • 基于位置的前馈网络
       【李沐】动手学深度学习 学习笔记_第348张图片
  • 层归一化
       【李沐】动手学深度学习 学习笔记_第349张图片
  • 信息传递
       【李沐】动手学深度学习 学习笔记_第350张图片
  • 预测
       【李沐】动手学深度学习 学习笔记_第351张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第352张图片

自然语言处理:预训练

BERT预训练

  本节代码文件在源代码文件的chapter_natural-language-processing-pretraining/bert-pretraining.ipynb中

  • NLP里的迁移学习
       【李沐】动手学深度学习 学习笔记_第353张图片
  • BERT的动机
       【李沐】动手学深度学习 学习笔记_第354张图片
  • BERT架构
       【李沐】动手学深度学习 学习笔记_第355张图片
  • 对输入的修改
       【李沐】动手学深度学习 学习笔记_第356张图片
  • 预训练任务1:带掩码的语言模型
       【李沐】动手学深度学习 学习笔记_第357张图片
  • 预训练任务2:下一句子预测
       【李沐】动手学深度学习 学习笔记_第358张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第359张图片

自然语言处理:应用

BERT微调

  本节代码文件在源代码文件的chapter_natural-language-processing-applications/finetuning-bert.ipynb中

  • 微调 Bert
       【李沐】动手学深度学习 学习笔记_第360张图片
  • 句子分类
       【李沐】动手学深度学习 学习笔记_第361张图片
  • 命名实体识别
       【李沐】动手学深度学习 学习笔记_第362张图片
  • 问题回答
       【李沐】动手学深度学习 学习笔记_第363张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第364张图片

优化算法

优化算法

  本节代码文件在源代码文件的chapter_optimization/optimization-intro.ipynb中

  • 优化问题
       【李沐】动手学深度学习 学习笔记_第365张图片
  • 局部最小 vs 全局最小
       【李沐】动手学深度学习 学习笔记_第366张图片
  • 凸集
       【李沐】动手学深度学习 学习笔记_第367张图片
  • 凸函数
       凸函数
  • 凸函数优化
       【李沐】动手学深度学习 学习笔记_第368张图片
  • 凸和非凸例子
       【李沐】动手学深度学习 学习笔记_第369张图片
  • 梯度下降
       【李沐】动手学深度学习 学习笔记_第370张图片
  • 随机梯度下降
       【李沐】动手学深度学习 学习笔记_第371张图片
  • 小批量随机梯度下降
       【李沐】动手学深度学习 学习笔记_第372张图片
  • 冲量法
       【李沐】动手学深度学习 学习笔记_第373张图片
  • Adam
       【李沐】动手学深度学习 学习笔记_第374张图片
       【李沐】动手学深度学习 学习笔记_第375张图片
  • 总结
       【李沐】动手学深度学习 学习笔记_第376张图片

你可能感兴趣的:(深度学习,学习,python)