一、引言

1.2. 机器学习中的关键组件

1.2.1. 数据

每个数据集由一个个样本(example, sample)组成,大多时候,它们遵循独立同分布(independently and identically distributed, i.i.d.)。
样本有时也叫做数据点(data point)或者数据实例(data instance),通常每个样本由一组称为特征(features,或协变量(covariates))的属性组成。
机器学习模型会根据这些属性进行预测。 在监督学习问题中,要预测的是一个特殊的属性,它被称为标签(label,或目标(target))。 当每个样本的特征类别数量都是相同的时候,其特征向量是固定长度的,这个长度被称为数据的维数(dimensionality)。

1.2.2. 模型

深度学习与经典方法的区别主要在于:前者关注的功能强大的模型,这些模型由神经网络错综复杂的交织在一起,包含层层数据转换,因此被称为深度学习(deep learning)

1.2.3. 目标函数

需要定义模型的优劣程度的度量,这个度量在大多数情况是“可优化”的,这被称之为目标函数(objective function)
我们通常定义一个目标函数,并希望优化它到最低点。 因为越低越好,所以这些函数有时被称为损失函数(loss function,或cost function)。
最常见的损失函数是平方误差(squared error),即预测值与实际值之差的平方。
可用数据集通常可以分成两部分:训练数据集用于拟合模型参数,测试数据集用于评估拟合的模型。
当一个模型在训练集上表现良好,但不能推广到测试集时,这个模型被称为**过拟合(overfitting)**的。

1.2.4. 优化算法

大多流行的优化算法通常基于一种基本方法–梯度下降(gradient descent)

1.3. 各种机器学习问题

1.3.1. 监督学习

监督学习(supervised learning)擅长在“给定输入特征”的情况下预测标签。 每个“特征-标签”对都称为一个样本(example)。 有时,即使标签是未知的,样本也可以指代输入特征。 我们的目标是生成一个模型,能够将任何输入特征映射到标签(即预测)。
监督学习的学习过程一般可以分为三大步骤
  1. 从已知大量数据样本中随机选取一个子集,为每个样本获取真实标签。有时,这些样本已有标签(例如,患者是否在下一年内康复?);有时,这些样本可能需要被人工标记(例如,图像分类)。这些输入和相应的标签一起构成了训练数据集;
  1. 选择有监督的学习算法,它将训练数据集作为输入,并输出一个“已完成学习的模型”;
  1. 将之前没有见过的样本特征放到这个“已完成学习的模型”中,使用模型的输出作为相应标签的预测。
notion image
  • 回归(regression)是最简单的监督学习任务之一。
  • 分类(classification)问题
  • 多标签分类(multi-label classification)
  • 信息检索
  • 推荐系统(recommender system)
  • 序列学习

1.3.2. 无监督学习

数据中不含有“目标”的机器学习问题通常被为无监督学习(unsupervised learning)
  • 聚类(clustering)问题
  • 主成分分析(principal component analysis)问题
  • 因果关系(causality)和概率图模型(probabilistic graphical models)问题
  • 生成对抗性网络(generative adversarial networks)

二、预备知识

非常数学,按需补充
 

三、线性神经网络

3.1 线性回归 linear regression

输入包含𝑑个特征时,我们将预测结果(通常使用“尖角”符号表示𝑦的估计值)表示为:
 

梯度下降 gradient descent

notion image
挑选一个作为初始值,重复迭代t=1,2,3,…
沿着梯度方向增加损失函数值
η学习率:步长的超参数 hyperparameter

小批量随机梯度下降 minibatch stochastic gradient descent

批量大小:超参数 hyperparameter
随机采样b个样本来近似损失:

实现

3.2 Softmax回归

notion image
 
可以视为一个正确的概率分布。
softmax运算不会改变未规范化的预测𝑜之间的大小次序,只会确定分配给每个类别的概率。
因此,在预测过程中,我们仍然可以用下式来选择最有可能的类别。

交叉熵损失

我们可以将视为“对给定任意输入𝑥的每个类的条件概率”
交叉熵用来衡量两个概率的区别
将它作为损失:
它的梯度是真实概率和预测概率的区别:

实现

3.3 损失函数

蓝色线:y=0时,变换预测值y’时的函数 绿色线:似然函数(模型参数的概率) 橙色线:损失函数的梯度(蓝色线的导数)

L2 Loss

notion image

L1 Loss

notion image

Huber‘s Robust Loss

notion image

四、多层感知机

4.1 感知机

notion image
感知机是一个二分类模型:输出-1或1
notion image

训练感知机

等价于使用批量大小为1的梯度下降,并使用如下损失函数:
(预测正确,预测错误就有梯度,因为大于0)

收敛定理

notion image

XOR问题

感知机不能拟合XOR函数(异或运算),他只能产生线性分割面
 

4.2 多层感知机

可以解决XOR问题
我们可以把前𝐿−1层看作表示,把最后一层看作线性预测器。 这种架构通常称为多层感知机(multilayer perceptron),通常缩写为MLP
隐藏层大小是超参数
右图这个多层感知机有4个输入,3个输出,其隐藏层包含5个隐藏单元。 输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算。 因此,这个多层感知机中的层数为2。 注意,这两个层都是全连接的。 每个输入都会影响隐藏层中的每个神经元, 而隐藏层中的每个神经元又会影响输出层中的每个神经元。
右图这个多层感知机有4个输入,3个输出,其隐藏层包含5个隐藏单元。 输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算。 因此,这个多层感知机中的层数为2。 注意,这两个层都是全连接的。 每个输入都会影响隐藏层中的每个神经元, 而隐藏层中的每个神经元又会影响输出层中的每个神经元。
notion image
notion image

实现

4.3 激活函数

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。

sigmoid函数

sigmoid函数将输入变换为区间(0, 1)上的输出
因此,sigmoid通常称为挤压函数(squashing function): 它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值
notion image

tanh函数

notion image
 

ReLU函数

最受欢迎的激活函数是修正线性单元(Rectified linear unit,ReLU), 因为它实现简单,同时在各种预测任务中表现良好。
notion image

4.4 模型选择、欠拟合和过拟合

4.4.1 训练误差和泛化误差

训练误差:模型在训练数据上的误差
泛化误差:模型在新数据上的误差
例子:根据摸考成绩来预测未来考试分数
在过去的考试中表现很好(训练误差)不代表未来考试一定会好(泛化误差)
学生A通过背书在摸考中拿到很好成绩
学生B知道答案后面的原因

4.4.2 模型选择

验证数据集:一个用来评估模型好坏的数据集
例如拿出 50% 的训练数据
不要跟训练数据混在一起(常犯错误)
测试数据集:只用一次的数据集
K-折交叉验证
无法提供足够的数据来构成一个合适的验证集时使用
将训练数据分割成K块,使用第 i 块(i = 1, …, K)作为验证数据集,其余的作为训练数据集,报告K个验证集误差的平均
常用K = 5或K = 10
 

4.4.3. 欠拟合还是过拟合?

notion image
模型容量:拟合各种函数的能力
低容量的模型难以拟合训练数据,高容量的模型可以记住所有的训练数据
模型复杂度对欠拟合和过拟合的影响
模型复杂度对欠拟合和过拟合的影响
VC维:对于一个分类模型,VC等于一个最大的数据集的大小,不管如何给定标号,都存在一个模型对它进行完美分类
notion image
它可以衡量训练误差和泛化误差之间的间隔,但深度学习中很少使用,因为它衡量不准确、且计算深度学习模型的VC维很困难
 

4.5 权重衰退 weight decay

正则化,通过函数与零的距离来衡量函数的复杂度
控制模型容量方法:模型参数少,模型参数值选择范围小

使用均方范数作为硬性限制

权重衰退通过限制参数值的选择范围来控制模型容量
通常不限制偏移b(限不限制都差不多)
小的θ意味着更强的正则项

使用均方范数作为柔性限制

对每个θ,都可以找到λ,使得之前的目标函数等价于下面
超参数λ控制了正则项的重要程度
notion image

参数更新法则

计算梯度
时间t更新参数
通常,在深度学习中通常叫做权重衰退

实现

4.6 Dropout

全连接层使用

无偏差的加入噪音

对x加入噪音得到x’,我们希望E[x’]=x
丢弃法对每个元素进行如下扰动:

dropout的使用

通常作用在隐藏全连接层的输出上
notion image
正则项只在训练中使用:他们影响模型参数的更新
在推理(预测)过程中,丢弃法直接返回输入 h= dropout(h)
这样也能保证确定性的输出
超参数:p(通常写λ) 可以取0.5 0.1 0.9…

实现

4.8 数值稳定性和模型初始化

考虑如下有d层的神经网络
计算损失关于参数的梯度

梯度爆炸

过多的矩阵累乘(d-t太大)
问题:
  • 值超出值域(infinity)
  • 对学习率敏感
    • 如果学习率太大 ->大参数值 ->更大的梯度
    • 如果学习率太小 ->训练无进展
    • 我们可能需要在训练过程不断调整学习率

梯度消失

notion image
当sigmoid函数的输入很大或是很小时,它的梯度都会消失。
问题:
  • 梯度值变为0
  • 无论如何选择学习率,训练没有进展
  • 对于底部层尤为严重,仅仅顶部层训练的较好,无法让神经网络更深

让每层的方差都是一个常数(要求)

让每层的输出和梯度都看作随机变量
让他们的均值和方差都保持一致
notion image
使用以下方法来满足该要求:

权重初始化

在合理值区间里随机初始参数
训练开始的时候更容易有数值不稳定
  • 远离最优解的地方损失函数表面可能很复杂
  • 最优解附近表面会比较平
使用 来初始可能对小网络没问题,但不能保证深度神经网络

Xavier初始

notion image
 
 

五、深度学习计算

5.1 层和块

5.2 参数管理

参数访问

 

5.4 自定义层

不带参数

带参数

 

5.5 读写文件

加载和保存张量

加载和保存模型参数

 

六、卷积神经网络 CNN

6.1 从全连接层到卷积

将输入和输出变形为矩阵(宽度高度)
将权重变形为4-D张量(h, w)到(h’, w’)
V是W的重新索引
对于隐藏表示中任意给定位置(i,j)处的像素值,可以通过在x中以(i,j)为中心对像素进行加权求和得到,加权使用的权重为

两个原则

平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。
x的平移导致h的平移
v不应该依赖于(i,j)
解决方案:
这就是2维卷积(交叉相关)
局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。
当评估时,我们不应该用远离的参数
解决方案:当时,使得

6.2 图像卷积

notion image
输入
偏差
输出
是可学习的参数
深度学习中的二维卷积实际上是数学中的二维交叉相关
深度学习中的二维卷积实际上是数学中的二维交叉相关
notion image
 

6.3 填充和步幅

给定 32×32 的输入图像
应用 5×5 大小的卷积核:第1层得到输出大小28×28,…,第7层得到输出大小4×4
更大的卷积核可以更快地减小输出大小

填充

如果不想输出大小太小,可以在输入周围添加额外的行/列
notion image
填充行和列,输出形状为:

步幅

填充减小的输出大小与层数线性相关,步幅用来解决层数过大的问题
 
notion image
给定高度和宽度的步幅,输出形状是:

6.4. 多输入多输出通道

每个通道都有一个卷积核,结果是所有通道卷积结果的和
notion image
输入 输出
notion image
每个输出通道可以识别特定模式,输入通道识别并组合输入中的模式
notion image
notion image
 

6.5 池化层 pooling

卷积对位置敏感,如果需要一定程度的平移不变性,考虑池化层

二维最大池化

返回滑动窗口中的最大值
notion image
notion image
与卷积层类似,都具有填充和步幅
没有可学习的参数
在每个输入通道应用池化层以获得相应的输出通道,输出通道数=输入通道数

平均池化层

最大池化层:每个窗口中最强的模式信号
平均池化层:将最大池化层中的“最大”操作替换为“平均”

实现

 

6.6 LeNet

总体来看,LeNet(LeNet-5)由两个部分组成:
  • 卷积编码器:由两个卷积层组成;
  • 全连接层密集块:由三个全连接层组成。
notion image
notion image
LeNet简化版
LeNet简化版
 

七、现代卷积神经网络

7.1 AlexNet

notion image
notion image
notion image
notion image

7.2 VGG

notion image
VGG使用可重复使用的卷积块来构建深度卷积神经网络
不同的卷积块个数和超参数(n层,m通道)可以得到不同复杂度的变种

7.3. 网络中的网络(NiN)

notion image
卷积层需要较少的参数:输入通道数*输出通道数**
NiN块
一个卷积层后跟两个全连接层
  • 步幅1,无填充,输出形状跟卷积层输出一样
  • 起到全连接层的作用
NiN架构
无全连接层
交替使用NiN块和步幅为2的最大池化层,逐步减小高宽和增大通道数
最后使用全局平均池化层得到输出,其输入通道数是类别数

7.4. 含并行连结的网络(GoogLeNet)

Inception块
notion image
4个路径从不同的层面抽取信息,然后在输出通道维合并
notion image
跟单3×3或5×5卷积层比,inception块有更少的参数个数和计算复杂度
GoogleNet
notion image
5段,9个inception块
notion image
notion image
notion image
notion image
notion image
notion image
notion image
Inception块用4条有不同超参数的卷积层和池化层的路来抽取不同的信息,它的一个主要优点是模型参数小,计算复杂度低
GoogleNet使用了9个Inception块,是第一个达到上百层的网络,后续有一系列改进

7.5 批量归一化 batch normalization

固定小批量里面的均值和方差
然后再做额外的调整(可学习的参数)
notion image
批量归一化层
可学习的参数:γ,β
作用在:
  • 全连接层和卷积层输出上,激活函数前
  • 全连接层和卷积层输入上
对全连接层,作用在特征维
特征维:二维的输入,每一行是一样本,每一列是一个特征,全连接层每一个特征计算一个标量的均值、方差,将特征变为均值为0,方差为1)
对于卷积层,作用在通道维
通道维:每个像素有多通道,n个通道就是长为n的向量,这个向量是这个像素的特征,每个像素都是一个样本,对卷积层来说,若输入是批量大小*高*宽*通道数,那么样本数是批量大小*高*宽(通道层当作是特征层)
 
批量归一化固定小批量中的均值和方差,然后学习出适合的偏移和缩放
可以加速收敛速度,但一般不改变模型精度
我们现在可以[创建一个正确的BatchNorm]。 这个层将保持适当的参数:拉伸gamma和偏移beta,这两个参数将在训练过程中更新。 此外,我们的层将保存均值和方差的移动平均值,以便在模型预测期间随后使用。

7.6 残差网络(ResNet)

添加更多的层不一定总是会改进精度,只有当较复杂的函数类包含较小的函数类时,我们才能确保提高它们的性能。
对于非嵌套函数类,较复杂(由较大区域表示)的函数类不能保证更接近“真”函数 f*。这种现象在嵌套函数类中不会发生。
对于非嵌套函数类,较复杂(由较大区域表示)的函数类不能保证更接近“真”函数 f*。这种现象在嵌套函数类中不会发生。
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。
残差块 residual block
notion image
ResNet架构
notion image

八、循环神经网络

8.1. 序列模型

在时间t观察到,那么得到T个不独立的随机变量
使用条件概率展开
notion image
马尔科夫模型假设当前只跟最近少数数据相关,从而简化模型
 
 
notion image
潜变量模型使用港变量来概括历史信息
 

8.2. 文本预处理

读取数据集
词元化
词表
构建一个字典,通常也叫做词表(vocabulary), 用来将字符串类型的词元映射到从00开始的数字索引中

8.3. 语言模型和数据集

语言模型
给定文本序列,语言模型的目标是估计联合概率
notion image
notion image
在实际中,最流行的词看起来很无聊, 这些词通常被称为停用词(stop words)
读取长序列数据
  • 随机采样
    • 在随机采样中,每个样本都是在原始的长序列上任意捕获的子序列。
      在迭代过程中,来自两个相邻的、随机的、小批量中的子序列不一定在原始序列上相邻。
  • 顺序分区
    • 保证两个相邻的小批量中的子序列在原始序列上也是相邻的
      这种策略在基于小批量的迭代过程中保留了拆分的子序列的顺序,因此称为顺序分区。

8.4. 循环神经网络 RNN

无隐状态的神经网络

只有单隐藏层的多层感知机MLP
notion image

有隐状态的循环神经网络

notion image
 

困惑度(Perplexity)

困惑度的最好的理解是“下一个词元的实际选择数的调和平均数”
  • 在最好的情况下,模型总是完美地估计标签词元的概率为1。 在这种情况下,模型的困惑度为1。
  • 在最坏的情况下,模型总是预测标签词元的概率为0。 在这种情况下,困惑度是正无穷大。
  • 在基线上,该模型的预测是词表的所有可用词元上的均匀分布。 在这种情况下,困惑度等于词表中唯一词元的数量。
 

梯度剪裁

迭代中计算这个时间步上的梯度,在反向传播过程中产生长度为 的矩阵乘法链,导致数值不稳定
梯度裁剪能有效预防梯度爆炸,如果梯度长度超过,那么拖影回长度
 
 

九、现代循环神经网络

9.1. 门控循环单元(GRU)

门控循环单元(gated recurrent unit,GRU)
重置门(reset gate)和更新门(update gate)
能关注的机制:更新门
能遗忘的机制:重置门
在门控循环单元模型中计算重置门和更新门
在门控循环单元模型中计算重置门和更新门
候选隐状态 candidate hidden state
在门控循环单元模型中计算候选隐状态
在门控循环单元模型中计算候选隐状态
符号是Hadamard积(按元素乘积)运算符
可以减少以往状态的影响
使用tanh非线性激活函数来确保候选隐状态中的值保持在区间(−1,1)中
隐状态 hidden state
计算门控循环单元模型中的隐状态
计算门控循环单元模型中的隐状态
每当更新门Zt接近1时,模型就倾向只保留旧状态 当接近0时,就会接近候选隐状态
 

9.2. 长短期记忆网络(LSTM)

输入门、忘记门和输出门
忘记门(forget gate):将值朝0减少
输入门(input gate):决定不是忽略掉输入数据
输出门(output gate):决定是不是使用隐状态
长短期记忆模型中的输入门、遗忘门和输出门
长短期记忆模型中的输入门、遗忘门和输出门
候选记忆元 candidate memory cell
长短期记忆模型中的候选记忆元
长短期记忆模型中的候选记忆元
记忆元 memory cell
在长短期记忆网络模型中计算记忆元
在长短期记忆网络模型中计算记忆元
隐状态
在长短期记忆模型中计算隐状态¶
在长短期记忆模型中计算隐状态
 

9.3. 深度循环神经网络

具有L个隐藏层的深度循环神经网络, 每个隐状态都连续地传递到当前层的下一个时间步和下一层的当前时间步
具有L个隐藏层的深度循环神经网络, 每个隐状态都连续地传递到当前层的下一个时间步和下一层的当前时间步
 

9.4. 双向循环神经网络

双向循环神经网络架构
双向循环神经网络架构
双向循环神经网络通过反向更新的隐藏层来利用方向时间信息
通常用来对序列抽取特征、填空,而不是预测未来
 

9.6. 编码器-解码器架构

编码器-解码器架构
编码器-解码器架构
编码器(encoder)处理输入 解码器(decoder)生成输出
notion image
 
notion image
 

9.7. 序列到序列学习(seq2seq)

Seq2seq从一个句子生成另一个句子
使用循环神经网络编码器和循环神经网络解码器的序列到序列学习
使用循环神经网络编码器和循环神经网络解码器的序列到序列学习
编码器是一个没有输出的RNN,读取输入句子(可以是双向,双向可以做encoder,不可做做decoder)
解码器使用另外一个RNN来输出,最后时间步的隐状态作为解码器的初始隐状态
notion image
 
衡量生成序列的好坏的BLEU(bilingual evaluation understudy)
对于预测序列中的任意n元语法(n-grams), BLEU的评估都是这个n元语法是否出现在标签序列中
例:标签序列A B C D E F 预测序列A B B C D
惩罚过短的预测,长匹配有高权重
 
 
 

9.8. 束搜索

notion image
notion image
notion image
notion image

十、注意力机制

10.1. 注意力机制

卷积、全连接、池化层都只考虑非自主性提示
注意力机制则显示的考虑随意线索
自主性提示被称为查询(query)
给定任何查询,注意力机制通过注意力汇聚(attention pooling) 将选择引导至感官输入(sensory inputs,例如中间特征表示) 在注意力机制中,这些感官输入被称为(value)
每个值都与一个(key)配对, 这可以想象为感官输入的非自主提示
通过注意力池化层(attention pooling)来有偏向性的选择选择某些输入
注意力机制通过注意力汇聚将查询(自主性提示)和键(非自主性提示)结合在一起,实现对值(感官输入)的选择倾向
注意力机制通过注意力汇聚将查询(自主性提示)和(非自主性提示)结合在一起,实现对(感官输入)的选择倾向

非参注意力池化层

Nadaraya-Watson核回归
根据输入的位置对输出进行加权
其中(kernel)
高斯核(Gaussian kernel)
代入得
 

带参数注意力汇聚

非参数的Nadaraya-Watson核回归具有一致性(consistency)的优点: 如果有足够的数据,此模型会收敛到最优结果。 尽管如此,我们还是可以轻松地将可学习的参数集成到注意力汇聚中。
是可学习参数,是query,是key
 

10.3. 注意力评分函数

notion image
计算注意力汇聚的输出为值的加权和
计算注意力汇聚的输出为值的加权和
α(x,xi):注意力权重(权重一般是一组大于等于零,相加和为 1 的数)
注意力分数:高斯核的指数部分(相当于是注意力权重归一化之前的版本)
上图所展示的是:假设已知一些 key-value 对和一个 query,首先将 query 和每一个 key 通过注意力分数函数 a 和 softmax 运算得到注意力权重(与 key 对应的值的概率分布),将这些注意力权重再与已知的 value 进行加权求和,最终就得到了输出
 
拓展到更高的维度
notion image
假设 query 是一个长为 q 的向量,ki 是长为 k 的向量,vi 是长为 v 的向量(这里 key 和 value 的长度可以不同)
其中 query 和 ki 的注意力权重(标量)是通过注意力评分函数 a 将两个向量映射成标量,再经过 softmax 运算得到的
 
掩蔽 softmax 操作(masked softmax operation)
softmax 操作用于输出一个概率分布作为注意力权重,但是在某些情况下,并非所有的值都应该被纳入到注意力汇聚中
在处理文本数据集的时候,为了提高计算效率,可能会采用填充的方式使每个文本序列具有相同的长度,便于以相同形状的小批量进行加载,因此可能会存在一些文本序列被填充了没有意义的特殊词源(比如“<pad>”词元)
因此,为了仅仅将有意义的词元作为值来获取注意力汇聚,可以指定一个有效序列长度(即词元的个数),任何超出有效长度的位置都被掩蔽并置于 0,便于在计算 softmax 的时候过滤掉超出指定范围的位置,这也就是掩蔽 softmax 操作

注意力分数函数 α 的设计

加性注意力(Additive attention)
 
notion image
等价于将 query 和 key 合并起来变成一个长度为 k+q 的向量,然后将其输入到一个隐藏层大小为 h ( h 是一个超参数),输出大小为 1 的但隐藏层的 MLP(没有偏置项),最终得到输出
优点是 key、value 向量可以是任意的长度,可以不同
缩放点积注意力(Scaled Dot-Product Attention)
notion image
假设 query 和 key 的所有元素都是独立的随机变量,并且都满足零均值和单位方差,那么两个向量的点积的均值为 0 ,方差为 d
这里不需要学习任何东西,直接利用 <q,ki> 将 q 和 ki 做内积然后除以根号 d (除以根号 d 的目的是为了降低对 ki 的长度的敏感度,使得无论向量的长度如何,点积的方差在不考虑向量长度的情况下仍然是 1 )
 

10.4. Bahdanau 注意力

动机
notion image
在机器翻译的时候,每个生成的词可能相关于源句子中不同的词
在语言翻译的时候,中文和英文之间的翻译可能会存在倒装,但是可能在西方语言之间,相同意思的句子中的词的位置可能近似地是对应的,所以在翻译句子的某个部位的时候,只需要去看源句子中对应的位置就可以了
然而,Seq2Seq 模型中不能对此直接建模。Seq2Seq 模型中编码器向解码器中传递的信息是编码器最后时刻的隐藏状态(例如图片中的.,但实际bonjour应该根据hello),解码器只用到了编码器最后时刻的隐藏状态作为初始化,从而进行预测,所以解码器看不到编码器最后时刻的隐藏状态之前的其他隐藏状态
源句子中的所有信息虽然都包含在这个隐藏状态中,但是要想在翻译某个词的时候,每个解码步骤使用编码相同的上下文变量,但是并非所有输入(源)词元都对解码某个词元有用。将注意力关注在源句子中的对应位置,这也是将注意力机制应用在Seq2Seq 模型中的动机
加入注意力
一个带有Bahdanau注意力的循环神经网络编码器-解码器模型
一个带有Bahdanau注意力的循环神经网络编码器-解码器模型
编码器对每次词的输出(隐藏状态)作为 key 和 value,序列中有多少个词元,就有多少个 key-value 对,它们是等价的,都是第 i 个词元的 RNN 的输出
解码器 RNN 对上一个词的预测输出(隐藏状态)是 query(假设 RNN 的输出都是在同一个语义空间中,所以在解码器中对某个词元进行解码的时候,需要用到的是 RNN 的输出,而不能使用词嵌入之后的输入,因为 key 和 value 也是 RNN 的输出,所以 key 和 query 做匹配的时候,最好都使用 RNN 的输出,这样能够保证它们差不多在同一个语义空间)
注意力的输出和下一个词的词嵌入合并进入 RNN 解码器
对 Seq2Seq 的改进之处在于:之前 Seq2Seq 的 RNN 解码器的输入是 RNN 编码器最后时刻的隐藏状态,加入注意力机制之后的模型相当于是对所有的词进行了加权平均,根据翻译的词的不同使用不同时刻的 RNN 编码器输出的隐藏状态
 
总结
Seq2Seq 中通过编码器最后时刻的隐藏状态在编码器和解码器中传递信息
注意力机制可以根据解码器 RNN 的输出来匹配到合适的编码器 RNN 的输出来更有效地传递信息
在预测词元时,如果不是所有输入词元都是相关的,加入注意力机制能够使 RNN 编码器-解码器有选择地统计输入序列的不同部分(通过将上下文变量视为加性注意力池化的输出来实现)
 

10.6. 自注意力和位置编码

自注意力

  • 在深度学习中,经常使用卷积神经网络或者循环神经网络对序列进行编码
  • 对于 key 、value 和 query ,自注意力有自己的一套选法,因为 key 、value 和 query 的值来自同一组输入,因此被称为自注意力(self-attention)或者内部注意力(intra-attention)
notion image
给定序列是一个长为 n 的序列,每个 xi 是一个长为 d 的向量
自注意力将 xi 同时作为 key 、value 和 query ,以此来对序列抽取特征
基本上可以认为给定一个序列,会对序列中的每一个元素进行输出,也就是说,每个查询都会关注所有的键-值对并生成一个注意力输出
自注意力之所以叫做自注意力,是因为 key,value,query 都是来自于自身,xi 既作为 key ,又作为 value ,同时还作为 query (self-attention 中的 self 所强调的是 key,value,query 的取法)
 
和 CNN,RNN 对比
notion image
CNN、RNN、自注意力都可以用来处理序列
CNN 如何处理序列:给定一个序列,将其看作是一个一维的输入(之前在处理图片时,图片具有高和宽,而且每个像素都具有 chanel 数,也就是特征数),如果用 CNN 做序列的话,经过一个 1d 的卷积(只有宽没有高)之后,将每个元素的特征看作是 channel 数,这样就可以用来处理文本序列了
k:窗口大小,每次看到的长度为 k n:长度 d:dimension,每个 x 的维度(长度)
并行度:每个输出( yi )可以自己并行做运算,因为 GPU 有大量的并行单元,所以并行度越高,计算的速度就越快
最长路径:对于最长的那个序列,前面时刻的信息通过神经元传递到后面时刻,对应于计算机视觉中的感受野的概念(每一个神经元的输出对应的图片中的视野)
 
自注意力机制比较适合处理长文本,但与之对应的计算量也非常的大
 

位置编码(position encoding)

和 CNN / RNN 不同,自注意力并没有记录位置信息:
CNN 中其实是有记录位置信息的,从输出可以反推出输入所在的窗口的位置,窗口大小可以看成是位置信息
RNN 本身就是序列相关的,它是通过逐个的重复地处理词元
对于自注意力来说,如果将输入进行随机打乱,对应输出的位置可能会发生变化,但是每个输出的内容不会发生变化
所以如果是想纯用自注意力机制来做序列模型的话,没有位置信息的话可能会出现问题,所以可以通过加入位置编码来加入位置信息(不是加到模型里,
位置编码不是将位置信息加入到模型中,一旦位置信息加入到模型中,会出现各种问题(比如在 CNN 中就需要看一个比较长的序列,RNN 中会降低模型的并行度) 位置编码将位置信息注入到输入里
notion image
P 中的每个元素根据对应的 X 中元素位置的不同而不同
P 的元素具体计算如下:
对于 P 中的每一列,奇数列是一个 cos 函数,偶数列是一个 sin 函数,不同的列之间的周期是不一样的
 
位置编码矩阵
notion image
X 轴横坐标表示 P 矩阵中的行数
图中不同颜色的曲线表示 P 矩阵中不同的列
这里可以理解为 X 轴上任意一点对应的 j 列的曲线上在 Y 轴的值,就表示 P 矩阵第 X 行第 j 列的元素的值
图中的四条曲线分别代表了第 6 、7 、8 、9 列,从图中可以看出,第 6 列是一个 sin 函数,第 7 列在第 6 列的基础上发生了位移,变成了 cos 函数,第 8 列在第 6 列的基础上周期变长了一倍,仍然是 sin 函数,第 9 列在第 8 列的基础上发生了唯一,变成了 cos 函数
从图中可以看出,对于 P 矩阵中同一行,不同的列的元素的数值是不同的,也就是说,对于输入序列(X + P 作为自编码输入)来讲,每个 dimension 所加的值是不同的;同样的,对于同一个输入序列,不同的样本所加的值也是不同的(对于同一条曲线,X 不同的情况下,即不同的行,元素的值也是不同的,这里 sin 函数和 cos 函数都是周期函数,应该讲的是在同一个周期内的样本)
 
P 实际上是对每一个样本(row)、每一个维度(dimension)添加一点不一样的值,使得模型能够分辨这种细微的差别,作为位置信息
这种方式跟之前的方式的不同之处在于,之前是将位置信息放进模型中或者将位置信息与数据分开然后进行拼接(concat),位置编码是直接将位置信息加入到了数据中,这样做的好处是不改变模型和数据的大小,缺点是需要模型对于 P 中元素的细微信息进行辨认,取决于模型是否能够有效地使用 P 中的位置信息
 
绝对位置信息
计算机使用的是二进制编码
notion image
 
notion image
可以认为,假设计算机要表示八个数字的话,可以用一个长为 3 的特征来表示,可以认为是一个三维的特征,每一个维度都在 0 和 1 之间进行变化,而且变化的频率不同,最后一维变化的频率最快,最前面一维变化的频率最慢
位置矩阵编码可以认为和计算机的二进制编码类似
首先,位置编码是实数(因为对应的输入也是实数),是在 1 和 -1 之间进行实数的变化,所以能编码的范围更广,可以在任意多的维度上进行编码
其次,因为位置编码中所使用的 sin 函数和 cos 函数都是周期函数,所以位置编码也是存在周期性
上图是一个热度图,和上一个图是一样的,只不过将 X 轴和 Y 轴进行了翻转(X 轴表示特征,Y 轴表示样本)
可以认为是对每一行的位置信息进行了编码,将第 i 个样本用一个长为 d 的向量进行编码
这里和计算机的二进制编码有一点不同,最前面的维度变化频率比较高,越到后面变化频率越来越慢
 
核心思想是对序列中的第 i 个样本,给定长为 d 的独一无二的位置信息,然后加入到数据中作为自编码输入,使得模型能够看到数据的位置信息
 
相对位置信息
为什么要使用 sin 函数和 cos 函数?
notion image
编码的是一个相对位置信息,位置位于 i + σ 处的位置编码可以线性投影位置 i 处的位置编码来表示,也就是说位置信息和绝对位置 i 无关,只是和相对位置 σ 有关
投影矩阵和序列中的位置 i 是无关的,但是和 j 是相关的(和 dimension 的信息是相关的),意味着在一个序列中,假设一个词出现在另外一个词两个或者三个位置的时候,不管这对词出现在序列中的什么位置,对于位置信息来讲,都是可以通过一个同样的线性变换查找出来的
相对来讲,这样编码的好处在于模型能够更加关注相对的位置信息,而不是关注一个词出现在一个句子中的绝对位置
 
 
总结
自注意力池化层将 xi 当作 key ,value query 来对序列抽取特征
完全并行最长序列为 1 、但对长序列计算复杂度高
  • 可以完全并行,和 CNN 是一样的,所以计算效率比较高
  • 最长序列为 1 ,对于任何一个输出都能够看到整个序列信息,所以这也是为什么当处理的文本比较大、序列比较长的时候,通常会用注意力和自注意力
  • 但是问题是对长序列的计算复杂度比较高,这也是一大痛点
位置编码在输入中加入位置信息,使得自注意力能够记忆位置信息
  • 类似于计算机的数字编码,对每个样本,给定一个长为 d 的编码
  • 编码使用的是 sin 函数或者是 cos 函数,使得它对于序列中两个固定距离的位置编码,不管它们处于序列中的哪个位置,他们的编码信息都能够通过一个线性变换进行转换
 
 

10.7. Transformer

transformer架构
transformer架构
Transformer 模型是完全基于注意力机制,没有任何卷积层或循环神经网络
Transformer 最初应用在文本数据上的序列到序列学习,现在已经推广到各种现代的深度学习中,如语言视觉语音强化学习领域

Transformer 架构

notion image
基于编码器-解码器的架构来处理序列对,Transformer 的编码器和解码器是基于自注意力的模块叠加而成的
源(source,输入)序列和目标(target,输出)序列的嵌入(embedding)表示通过加上位置编码(positional encoding)加入位置信息,再分别输入到编码器和解码器中
Transformer 的编码器是由多个相同的层叠加而成的,每个层都有两个子层(每个子层都采用了残差连接,并且在残差连接的加法计算之后,都使用了层归一化,因此 Transformer 编码器都将输出一个 d 维表示向量)
第一个子层是多头自注意力汇聚
  • Transformer 块中的多头注意力实际上就是自注意力(自注意力同时具有并行计算和最短的最大路径长度这两个优势)
  • 在计算编码器的自注意力时,key 、value 和 query 的值都来自前一个编码器层的输出
第二个子层是基于位置的前馈网络
  • Positionwise FFN 实际上是全连接
  • 本质上和编码器-解码器的架构没有本质上的区别,将 Transformer 编码器最后一层的输出作为解码器的输入来完成信息的传递
Transformer 解码器也是由多个相同的层叠加而成的,每层都有三个子层,并且在每个子层中也使用了残差连接层归一化
第一个子层是解码器自注意力(带掩码的多头自注意力)
  • 在解码器自注意力中,key 、value 和 query 都来自上一个解码器层的输出
  • 解码器中的每个位置只能考虑该位置之前的所有位置
  • 带掩码的自注意力保留了自回归的属性,确保预测仅仅依赖于已生成的输出词元(为了在解码器中保留自回归的属性,带掩码的自注意力设定了有效长度(dec_valid_lens)作为参数,以便任何查询都只会与解码器中所有已经生成的词元的位置(即直到该查询为止)进行注意力计算,而不会对当前位置之后的 key-value 对进行注意力计算)
第二个子层是编码器-解码器注意力
  • 除了编码器中所描述的两个子层之外,解码器还在这两个子层之间插入了编码器-解码器注意力层,作为第三个子层,它的 query 来自上一个解码器层的输出,key 和 value 来自整个编码器的输出
第三个子层是基于位置的前馈网络
 
对比 seq2seq
和使用注意力的 seq2seq 的不同之处在于:Transformer 是纯基于注意力(具体来讲,它是一个纯基于自注意力的架构,里面没有 RNN)
Transformer 将使用注意力的 seq2seq 中的 RNN 全部换成了 Transformer 块
 

多头注意力(Multi-head attention)

同一个 key 、value 、query 抽取不同的信息(例如短距离关系和长距离关系)
多头注意力使用 h 个独立的注意力池化,合并各个头(head)输出得到最终输出
多头注意力:多个头连结然后线性变换
多头注意力:多个头连结然后线性变换
key 、value 、query 都是长为 1 的向量,通过全连接层映射到一个低一点的维度,然后进入到注意力模块中
notion image
f可以是加性注意力和缩放点积注意力
 

带掩码的多头注意力(Masked Multi-head attention)

解码器对序列中一个元素输出时,不应该考虑该元素之后的元素
注意力中是没有时间信息的,在输出中间第 i 个信息的时候,也能够看到后面的所有信息,这在编码的时候是可以的,但是在解码的时候是不行的,在解码的时候不应该考虑该元素本身或者该元素之后的元素
可以通过掩码来实现,也就是计算 xi 输出时,假装当前序列长度为 i
 

基于位置的前馈网络(Positionwise FFN)

  • 基于位置的前馈网络对序列中的所有位置的表示进行变换时使用的是同一个多层感知机(MLP),这就是称前馈网络是基于位置的原因
其实就是全连接层,将输入形状由(b,n,d)变成(bn,d),然后作用两个全连接层,最后输出形状由(bn,d)变回(b,n,d),等价于两层核窗口为 1 的一维卷积层
  • b:batchsize
  • n:序列长度
  • d:dimension
  • 在做卷积的时候是将 n 和 d 合成一维,变成 nd ;但是现在 n 是序列的长度,会变化,要使模型能够处理任意的特征,所以不能将 n 作为一个特征,因此对每个序列中的每个元素作用一个全连接(将每个序列中的 xi 当作是一个样本)
 

残差连接和层归一化(Add & norm)

notion image
Add 就是一个 Residual_block(上图左一)
加入归一化能够更好地训练比较深的网络,但是这里不能使用批量归一化,批量归一化对每个特征/通道里元素进行归一化
  • 这里的特征指的是每个序列中 D 中的一维,所以在做归一化的时候就是将其方差变 1 ,均值变 0
  • 在做 NLP 的时候,如果选择将 d 作为特征的话,那么批量归一化的输入是 n*b ,b 是批量大小,n 是序列长度,序列的长度是会变的,所以每次做批量归一化的输入大小都不同,所以会导致不稳定,训练和预测的长度本来就不一样,预测的长度会慢慢变长,所以批量归一化不适合长度会变的 NLP 应用
层归一化对每个样本里的元素进行归一化
  • b 代表 batchsize
  • d 代表特征维度
  • len 表示序列长度
  • 层归一化和批量归一化的目标相同,但是层归一化是基于特征维度进行归一化的
  • 层归一化和批量归一化的区别在于:批量归一化在 d 的维度上找出一个矩阵,将其均值变成 0 ,方差变成 1,层归一化每次选的是一个元素,也就是每个 batch 里面的一个样本进行归一化
  • 尽管批量归一化在计算机视觉中被广泛应用,但是在自然语言处理任务中,批量归一化通常不如层归一化的效果好,因为在自然语言处理任务中,输入序列的长度通常是变化的
  • 虽然在做层归一化的时候,长度也是变化的,但是至少来说还是在一个单样本中,不管批量多少,都给定一个特征,这样对于变化的长度来讲,稍微稳定一点,不会因为长度变化,导致稳定性发生很大的变化
 

信息传递

假设编码器中的输出是 y1,... ,yn ,将其作为解码中第 i 个 Transformer 块中多头注意力的 key 和 value
  • 一共有三个多头注意力(包括一个带掩码的多头注意力),位于带掩码的多头注意力与其它两个不同,其他两个都是自注意力(key 、value 和 query 都相同),而它是普通的注意力(它的 key 和 value 来自编码器的输出, query 来自目标序列)
这就意味着编码器和解码器中块的个数和输出维度都是一样的
位于解码器中间的multi-head attention的key和value来自编码器的输出(即其他两个都是自注意力,而它是普通的注意力)
 
 

预测

notion image
预测第 t+1 个输出时,解码器中输入前 t 个预测值
  • 在自注意力中,前 t 个预测值作为 key 和 value ,第 t 个预测值还作为 query
关于序列到序列模型,在训练阶段,输出序列的所有位置(时间步)的词元都是已知的;但是在预测阶段,输出序列的次元是逐个生成的
  • 在任何解码器时间步中,只有生成的词元才能用于解码器的自注意力计算中
 
总结
和 seq2seq 有点类似,不同之处在于 Transformer 是一个纯使用注意力的编码-解码器
编码器和解码器都有 n 个 Transformer 块
每个块里使用多头(自)注意力(multi-head attention)基于位置的前馈网络(Positionwise FFN)残差连接层归一化
  • 编码器和解码器中各有一个自注意力,但是在编码器和解码器中传递信息的是一个正常的注意力
  • 基于位置的前馈网络使用同一个多层感知机,作用是对所有序列位置的表示进行转换,实际上就是一个全连接,等价于 1*1 的卷积
  • Add & norm:Add 实际上就是 Residual block 可以帮助将网络做的更深,norm 使用的是 Layer Norm 使得训练起来更加容易;Transformer 中的残差连接和层规范化是训练非常深度模型的重要工具
在 Transformer 中,多头注意力用于表示输入序列和输出序列,但是解码器必须通过掩码机制来保留自回归属性
  • 梯度下降会从圆圈外一直到圆圈中心值最小的地方
2、学习率(learning rate)
学习率决定目标函数能否收敛到局部最小值,以及何时收敛到最小值,通常用 η 表示
  • 如果使用的学习率太小,将导致 x 的更新非常缓慢,需要更多的迭代
  • 如果学习率过高可能会导致 x 振荡甚至可能逐渐发散
小结
1、学习率的大小很重要:学习率太大会使模型发散,学习率太小会没有进展
3、在高维模型中,调整学习率是比较复杂的

十一、优化算法

对于深度学习问题,通常会先定义损失函数,在有了损失函数之后,就可以使用优化算法来尝试最小化损失
在优化中,损失函数通常被称为优化问题的目标函数
大多数优化算法都关注的是最小化,如果需要最大化目标,只需要在目标函数前加负号就可以了

11.1. 优化和深度学习

1、尽管优化提供了一种最大限度减少深度学习损失函数的方法,但本质上优化和深度学习的目标是根本不同的
  • 优化主要关注的是最小化目标
  • 深度学习关注的是在给定有限数据量的情况下寻找合适的模型
2、具体的区别例如训练误差泛化误差
  • 优化算法的目标函数通常是基于训练数据集的损失函数,因此优化的目标是减少训练误差
  • 深度学习的目标是减少泛化误差,为了达到减小泛化误差的目的,除了使用优化算法来减少训练误差外,还需要注意过拟合
3、经验风险和风险
  • 经验风险:训练数据集的平均损失
  • 风险:整个数据群的预期损失
  • 训练数据集的最低经验风险可能和最低风险(泛化误差)不同
4、优化问题的一般形式:
notion image
  • 在深度学习中,f(x) 是损失函数(给定一个输入,预测和真实标号之间的差距);x 是所有的超参数,不管矩阵还是张量 ,最终都会转换成一个向量
  • 限制集合 C 在优化中比较常见,在具体的优化中有很多的假设,但是在深度学习中,尽量使得 C 不受限制,不受限制的话相对来讲优化起来会快一点
深度学习中的挑战
  • 在深度学习中,大多数目标函数都很复杂,没有解析解
局部最小 vs 全局最小
1、全局最小
notion image
  • x* 对应的目标函数的值不大于求解区间中所有的 x 对应的目标函数值
  • 如果 f(x) 在 x 处的值是整个域中目标函数的最小值,那么 f(x) 是全局最小值
2、局部最小
notion image
  • 存在一个 ε ,使得任何 x 和解 x* 的距离小于半径 ε 的时候,在这个范围内的 x 对应的目标函数值都不小于 f(x*)
  • 对于任何目标函数 f(x),如果在 x* 处对应的目标函数的值小于在 x* 附近任意其他点的 f(x) 的值,那么 f(x) 可能是局部最小值
3、例
在 xcos(𝝅x) 中
  • local minimum 表示局部最小值:在该点附近的局部区域内,其他 x 对应的目标函数值都不小于 f(x*)
  • global minimum 表示全局最小值:在整个函数中,定义域内的其他 x 对应的目标函数的值都不小于 f(x*)
notion image
4、求解
一般使用迭代算法来求解,
  • 机器学习也好,深度学习也好,目标问题都不能求出显式解,所以使用迭代算法
  • 一般来说,迭代算法只能保证找到局部最小值
局部最小值处的梯度是零
  • 因为使用的是梯度下降,到了局部最小的地方,梯度就变成零了,此时不管学习率取多大都不会再动了,所以说只能保证找到局部最小值
5、深度学习模型的目标函数通常有许多局部最优解
  • 当优化问题的数值解接近局部最优值时,随着目标函数解的梯度接近或变为零,通过最终迭代获得的数值解可能仅使目标函数局部最优,而不是全局最优
  • 只有一定程度的噪声可能会使参数跳出局部最小值(小批量随机梯度下降的有利特性之一,小批量上梯度的自然变化能够将参数从局部极小值中跳出)
鞍点(saddle point)
  • 除局部最小值之外,鞍点是梯度消失的另外一个原因
1、定义:鞍点指的是函数的所有梯度都消失但既不是全局最小值也不是局部最小值的任何位置
notion image
 
2、假设函数的输入是 k 维向量,它的输出是标量,因此其 **Hessian 矩阵(也称黑塞矩阵)**将有 k 个特征值
函数的解可能是局部最小值、局部最大值或函数梯度为零位置处的鞍点:
  • 当函数在零梯度位置处的 Hessian 矩阵的特征值全部为正值时,该函数存在局部最小值
  • 当函数在零梯度位置处的 Hessian 矩阵的特征值全部为负值时,该函数存在局部最大值
  • 当函数在零梯度位置处的 Hessian 矩阵的特征值为正值和负值时,该函数存在鞍点(对于高维度问题,至少部分特征值为负的可能性相当高,因此鞍点比局部最小值更有可能出现)
3、凸函数是 Hessian 函数的特征值永远不为负值的函数
  • 大多数深度学习问题并不属于这一类,但是它仍是研究优化算法的一个很好的工具
梯度消失
1、在某一个时刻开始,函数 f(x) 的梯度接近零,这会导致优化会停止很长一段时间
  • 比如 f(x) = tanh(x) 从 x = 4 开始,f(x) 的梯度接近 0
notion image
2、引入 ReLU 激活函数能够很好地缓解这个问题
3、对于深度学习,其实没有必要找到最优解,局部最优解或者其近似解仍然非常有用
小结
1、最小化训练误差并不能保证能够找到最佳的参数集来最小化泛化误差
2、优化问题可能有许多局部最小值
3、实际问题中可能会出现多个鞍点,因为问题通常不是凸的
4、梯度消失可能会导致优化停滞,重参数化通常会有所帮助,对参数进行良好的初始化也可能是有益的

11.2. 凸性(convexity)

1、凸性在优化算法的设计中起到至关重要的作用,主要是由于在这种情况下对算法进行分析和测试要容易
  • 如果算法在凸性条件设定下的效果很差,则通常很难在其他条件下看到好的结果
2、即使深度学习中的优化问题通常是非凸的,它们经常也在局部极小值附近表现出一些凸性
凸集
  • 凸集是凸性的基础
1、如果对于任何 a , b ∈ X ,连接 a 和 b 的线段也位于 X 中,则向量空间中的一个集合 X 是(convex)的
  • 在一个区域中找任意两个点连成一条线,这条线上所有的点都在这个区域当中
notion image
左边一列表示的是凸集,右边一列不是凸集
2、假设 X 和 Y 是凸集,那么 X ∩ Y 也是凸集
notion image
  • 相反,凸集的并集并不一定是凸的,也可能是非凸 (nonconvex) 的
notion image
3、定义:
  • 深度学习中的问题通常是在凸集上定义的
notion image
凸函数(convex function)
1、定义
对于某函数上的任意两点所连成的线,这两点之间所有的 x 对应的函数 y 的曲线都在这条线的下方
notion image
  • 除去两点连线的两个端点,函数的曲线都在连线的下方(没有交点)
2、性质
  • 凸函数的局部极小值也是全局极小值(并不意味着不能有多个全局最小值(f(x) = max(|x-1|,0) 在 [-1,1] 区间上都是最小值),或者可能不存在一个全局最小值(f(x) = exp(x) 在 R 上没有最小值,无限趋近于 0 但不等于 0))
凸函数优化
  • 如果代价函数 f 是凸的,且限制集合 C 是凸的,那么就是凸优化问题,那么局部最小一定是全局最小(也就是说优化算法找到的局部最小点一定是全局最优解)
  • 严格凸优化问题有唯一的全局最小
notion image
  • 上图左侧的函数不是严格的凸函数,不满足严格凸函数的定义,函数上存在两点的连线(除端点外)与函数存在交点
  • 上图右侧的函数是一个严格的凸函数,所以它只有唯一的最小值
凸和非凸例子
1、机器学习绝大部分都不是凸优化
2、目前为止只有两个是凸的:
  • 线性回归:
notion image
 
  • softmax 回归:softmax 也是线性的
3、剩下的都是非凸的
  • MLP:有一个隐藏层的 MLP,因为激活函数不是线性的,导致它是非线性的(非线性的是非凸的)
  • CNN:卷积本身是线性的,但是卷积加了激活函数之后就不是线性的了
  • RNN
  • attetion
  • ...
4、所有的模型都是非凸的
  • 凸函数的表达能力是非常有限的
  • 对于深度学习来讲,实用性是排在第一位的,理论是靠后的,如果是研究理论的话,需要从统计的角度来看待问题,从统计的角度来讲会考虑很多的凸优化问题
  • 从深度学习来讲,是从计算机的角度考虑效果,而不是过于考虑理论,所导致基本上做的都是非凸的
  • 优化的很多理论基本上是凸优化,最近也有研究非凸的,但是整体来讲大块是针对凸函数的优化,对于非凸的模型很难说有特别大的指导意义
小结
1、凸集的交点是凸的,并集不是
2、一个二次可微函数是凸函数,当且仅当其 Hessian (二阶导数据矩阵)是半正定

11.3. 梯度下降(gradient descent)

  • 梯度下降很少直接用于深度学习
  • 由于学习率过大,优化问题可能会发散,这种现象早已在梯度下降中出现
1、梯度下降算法是最简单的迭代求解算法
notion image
  • 选取开始点 x0
  • 对 t = 1,2,...,T
notion image
  • η 叫做学习率
  • 上图中蓝色的曲线是目标函数的等高线
  • 圆圈中心表示最小值,离圆心越远的地方值越大
  • 梯度下降会从圆圈外一直到圆圈中心值最小的地方
2、学习率(learning rate)
学习率决定目标函数能否收敛到局部最小值,以及何时收敛到最小值,通常用 η 表示
  • 如果使用的学习率太小,将导致 x 的更新非常缓慢,需要更多的迭代
  • 如果学习率过高可能会导致 x 振荡甚至可能逐渐发散
小结
1、学习率的大小很重要:学习率太大会使模型发散,学习率太小会没有进展
2、梯度下降可能陷入局部极小值,而得不到全局最小值
3、在高维模型中,调整学习率是比较复杂的

11.4. 随机梯度下降(stochastic gradient descent)

  • 在深度学习中,目标函数通常是训练数据集中每个样本的损失函数的平均值
1、通常使用的都是随机梯度下降而不用梯度下降,因为当有 n 个样本的时候,f(x) 表示所有样本上损失的平均值,当样本特别多、计算一个样本比较贵的时候,求 f(x) 的导数是比较贵的
notion image
  • 梯度下降是在整个完整的样本上求导,比较贵,所以通常使用的都是随机梯度下降
2、随机梯度下降在时间 t 随机选择一个样本 ti 上的梯度来近似 f(x) 的梯度
  • 这么做是因为求导是线性可加的
notion image
notion image
  • 因为样本 ti 是随机选择的,所以导数的期望就是所有样本的梯度的均值,而所有样本的梯度的均值和 f(x) 梯度的期望是差不多的,虽然有噪音,但是均值是近似相等的,也就是说大的方向是一致的
  • 这样做的好处是每次只用算一个样本的梯度就可以了,而不用计算全部样本的梯度(可能会导致重复性的计算)
3、对比梯度下降(上)和随机梯度下降(下)
notion image
  • 随机梯度下降整个过程不像梯度下降那么平滑,特别是在最后阶段比较曲折,但是整个大的方向和梯度下降是一致的(均值没有发生变化)
  • 因为每一次计算只需要计算一个样本的梯度,所以虽然可能会走一点弯路,但是整体来看还是比较划算的
4、随机梯度下降在机器学习中的应用是在 2003 的时候提出来的,之前都是使用的梯度下降
  • 随机梯度下降成为了整个深度学习的基础
  • 其他的机器学习模型不一定会使用随机梯度下降
小结
1、对于凸问题,对于广泛的学习率选择,随机梯度下降将收敛到最优解。但是对于深度学习而言,情况通常并非如此。但是对凸问题的分析能够深入了解如何进行优化,即逐步降低学习率,尽管不是太快
2、如果学习率太小或太大都会出现问题,实际上,通常只有经过多次实验之后才能找到合适的学习率
3、当训练数据集中有更多样本时,计算梯度下降的每次迭代的代价更高,因此在这些情况下,首选随机梯度下降
4、随机梯度下降的最优性保证在非凸情况下一般不可用,因为需要检查的局部最小值的数量可能是指数级的

11.5. 小批量随机梯度下降(minibatch gradient descent)

  • 梯度下降使用完整的数据集来计算梯度并更新参数随机梯度下降中一次处理一个训练样本来取得进展
  • 每当数据非常相似时,梯度下降并不是非常**“数据高效”**
  • 由于 CPU 和 GPU 无法充分利用向量化,随机梯度下降并不是特别**“计算高效”**
  • 使用小批量的决策的核心是计算效率
1、在实际应用中,真正使用的是小批量随机梯度下降
  • 之所以用小批量随机梯度下降,不是统计的原因,而是计算的原因,因为随机梯度下降对单样本计算梯度,这样的话很难完全利用硬件资源(CPU 和 GPU 都是多线程的,假设只是对单样本进行梯度计算的话,计算量可能不足以能够占满整个硬件资源)
  • 所以假设可以用多个样本计算的话,每个样本的计算是可以并行的,能够提高计算的并行度,所以在实际使用中通常使用的是小批量随机梯度下降
2、定义:
notion image
  • It:随机采样一个样本的子集
  • b:批量大小
  • 在计算梯度的时候,对 It 中采样的 b 个样本都求梯度,然后除以 b 求平均值,以此来近似整个目标函数的梯度
3、同理,因为是随机采样,最后又除以了随机采样的样本数量,所以它的期望是没变的,是一个无偏的近似,和随机梯度一样,大的方向是一致的,但是它的好处在于这样计算降低了方差(因为是 b 个样本的平均,所以整体在方向上的抖动相对来讲会小一些,噪音会少一点,更加平滑)
4、下图中,y 轴表示损失,x 轴表示时间(已经做了对数处理)
notion image
  • gd:梯度下降,梯度下降在一开始的时候就能达到很好的效果
  • sgd:随机梯度下降,随机梯度下降比梯度下降要慢,因为每次只计算一个样本的梯度,所以无法完全利用硬件资源进行并行计算,所以如果单纯从物理时间来看的话,这样做是不划算的
  • 所以需要在随机梯度下降中加入比较大的批量
  • 一般来说,批量小的时候收敛比较快,但是计算比较慢;批量很大的时候,每次计算的代价比较大,所以批量大小在一个比较合适的数量是比较好的,不能太小也不能太大
小结
  • 随机梯度下降的“统计效率”与大批量一次处理数据的“计算效率”之间存在权衡,小批量随机梯度下降提供了两全其美的答案:计算和统计效率
  • 在小批量随机梯度下降中,处理通过训练数据的随机排列获得的批量数据(每个观测值只处理一次,但按随机顺序)
  • 在训练期间降低学习率有助于训练
  • 一般来说,小批量随机梯度下降比随机梯度下降和梯度下降的速度快,收敛风险较小

11.6. 冲量法(momentum)

  • 对于嘈杂的梯度,在选择学习率需要格外谨慎,如果衰减速度太快,收敛就会停滞;相反,如果太宽松,就肯恶搞无法收敛到最优解
1、冲量法也是在实际应用中使用比较多的算法
2、冲量法使用平滑过的梯度对权重更新
notion image
  • 在小批量随机梯度下降的时候,梯度还是会有比较大的抖动,特别是当整个目标函数比较复杂的时候
  • 真实数据的损失函数是不平滑的,在一个不那么平滑的平面上做优化的时候,梯度的变化趋势就有点类似于随机运动,噪音可能会带来一些不必要的抖动
  • 冲量法中,它维护了一个惯性,使得梯度变化的方向不要变化太快,方向还是要改变的,这是变化起来比较平滑
  • vt 实际上是等于当前时刻的梯度+ β上一个时刻的梯度 + ββ*上上个时刻的梯度...
  • β 是一个小于 1 的值,所以 vt 中历史时刻的梯度项随着时间的下降存在指数级的减少,时间越早的梯度项,最后的值就越小
  • 通过这样的设计使得对整个权重更新的方向并不是完全取决于 gt ,还要参考过去时间的梯度,如果当前时刻的 gt 和上一时刻的 g(t-1) 完全不同的话,使得 g(t-1) 能够通过 β 对 gt 变化的方向进行一定程度的抵消,使得更新不那么剧烈
3、β 常见的取值:0.5、0.9、0.95、0.99
  • 假设 β 取 0.5 的话,vt 中历史时刻的梯度项会衰减得特别快(大概是计算过去两三个时刻的梯度取平均)
  • 假设 β 取 0.99 的话,vt 中历史时刻的梯度项会衰减得比较慢,可以认为 gt 的变化会参考过去几十个时刻梯度的方向(大概是计算过去五十个时刻的梯度取平均,超过 50 个以外的那些梯度项就变得很小了,几乎可以忽略不计)
  • 如果说样本数量比较大,β 取 0.99 也很正常
4、对比随机梯度下降(上)和冲量法(下)
notion image
  • 随机梯度下降上下振动的幅度比较大
  • 冲量法是几个相互冲突的方向在慢慢相互抵消,使得梯度的变化尽量朝着正确的方向
5、通过框架中的 moment 这个超参数来设定冲量法
  • 最简单的 sgd 都有 moment 的选项,只需要将 moment 设置成自己想要的值就可以了
小结
1、冲量法用过去梯度的平均值来替换梯度,大大加快了收敛速度
2、对于无噪声梯度下降和嘈杂随机梯度下降,冲量法都是可取的
3、冲量法可以防止在随机梯度下降的优化过程停滞的问题
4、由于对过去的数据进行了指数降权,有效梯度为 1/(1-β)

11.10. Adam

Adam 对梯度做平滑,且对梯度各个维度值做重新调整 通过实践发现,Adam 不一定比冲量法准确率高或者是收敛快,但是整体来讲 Adam 是比较稳定的,Adam 对学习率不那么敏感,使得调参相对来讲会更加容易一点 对于新的模型,如果没有很好的调参,可以直接使用 Adam
  • 随机梯度下降在解决优化问题时比梯度下降更有效
  • 在一个小批量中使用更大的观测值集,可以通过向量化提供额外效率,这也是高效的多机、多 GPU 和整体并行处理的关键
1、Adam 是在实际应用中使用得最多的
2、之所以用 Adam 并不是因为它比 sgd ,Adam 最大的优点在于它对学习率不是很敏感,在里面做了非常多的平滑,可以认为是一个非常平滑的 sgd
  • sgd+moment 实际上效果已经非常好了,实际上可以不用 Adam 也可以,Adam 优化的效果不一定优于 sgd+moment
  • 平滑的好处在于对学习率不敏感,如果说没有太多的时间去调参的话,Adam 是一个不错的选择;如果会调参的话,使用 sgd+moment 或者是别的一些优化算法,可能效果会比 Adam 还要好一点
  • 因为 Adam 比较简单,所以使用的还是比较多的
3、定义:
notion image
  • 和冲量法的不同之处在于 β1 是不需要调的,通常取 0.9
  • 因为 v0 = 0 ,所以在一开始的时候会偏小,所以当 t 比较小的时候这里做了一个修正(修正偏向 0 的趋势)
  • 对于 t 比较大的时候,由于 β1 是一个小于 1 的数,1 - β1^t 会趋近于零,因此不会对 vt 产生影响,因此这里所做的修正主要是针对 t 比较小的时候
notion image
  • st 和 vt 有点类似,唯一的区别是 st 中的 gt 多了一个平方(gt 是一个向量,gt 的平方计算是对 gt 中的每个元素进行平方),也就是说这里对向量 gt 中的每个元素的平方做了平滑处理
  • 0.999 是一个比较大的窗口的平滑
notion image
  • vt hat 可以认为是整个梯度的平滑版本,过去的所有时间的梯度的加权和‘
  • 这里的除法也是按照元素进行计算
  • 有时候每一个维度的值可能是不一样的,有些值可能比较大,有些值可能比较小(NLP 中出现的比较多,有些词出现的比较频繁,有些词出现的比较少,所以那些频繁出现的词的梯度就会比较大,而出现比较少的词的梯度就会比较小),在做特征提取的时候,如果没有做好归一化,有些特征的值会比较大,有些特征的值会比较小就会出现特征值比较大的梯度就比较大,特征值比较小的梯度就会比较小,所以就会导致在取学习率的时候会比较麻烦:如果学习率取得比较大的话,在乘上比较大的梯度的时候,就会导致更新比较大,从而导致梯度爆炸:如果想要将学习率取得比较小来避免梯度爆炸,但是对于那些值比较小的梯度乘上学习率之后更新的不够,就会导致收敛比较慢
  • 所以这里对于梯度的调整就有点类似于对梯度做归一化,将值比较大或者比较小的梯度拉到一个合适的范围之中(进行维度上的调整)
  • 分母中的 ε 的作用是保证分母不等于零
notion image
  • 因为在 Adam 中做了很多的平滑,所以最终得出的 gt 的值都是比较均匀的
 

十三、计算机视觉

13.1 图像增广

图像增广基于现有的训练数据生成随机图像,来提高模型的泛化能力。

13.2. 微调

迁移学习(transfer learning)将从源数据集学到的知识迁移到目标数据集。
微调通过使用在大数据上得到的预训练好的模型来初始化模型权重来完成提升精度
预训练模型质量很重要
微调通常速度更快、精度更高
网络架构
一个神经网络一般可以分成两块
  • 特征抽取将原始像素变成容易线性分割的特征
  • 线性分类器来做分类
 
在一个源数据集上训练的模型,做特征提取的部分可以拿来使用
notion image
 
  1. 在源数据集(例如ImageNet数据集)上预训练神经网络模型,即源模型
  1. 创建一个新的神经网络模型,即目标模型。这将复制源模型上的所有模型设计及其参数(输出层除外)。我们假定这些模型参数包含从源数据集中学到的知识,这些知识也将适用于目标数据集。我们还假设源模型的输出层与源数据集的标签密切相关;因此不在目标模型中使用该层。
  1. 向目标模型添加输出层,其输出数是目标数据集中的类别数。然后随机初始化该层的模型参数。
  1. 在目标数据集(如椅子数据集)上训练目标模型。输出层将从头开始进行训练,而所有其他层的参数将根据源模型的参数进行微调。
训练
是一个目标数据集上的正常训练任务,但使用更强的正则化,使用更小的学习率,使用更少的数据迭代
源数据集原复杂于目标数据,通常微调效果更好
重用分类器权重
源数据集可能也有目标数据中的部分标号
可以使用预训练好模型分类器中对应标号对应的向量来做初始化
固定一些层
神经网络通常学习有层次的特征表示,低层次的特征更加通用,高层次的特征则更跟数据集相关
可以固定底部一些层的参数,不参与更新
 

13.3. 目标检测和边界框

边界框 bounding box
一个边界框通过四个数字定义
边界框是矩形的,由矩形左上角的以及右下角的x和y坐标决定。
 
notion image

13.4. 锚框

一类目标检测算法是基于锚框来预测
提出多个被称为锚框的区域(边缘框),并赋予编号,每个锚框作为一个样本进行训练
预测时,使用NMS来去掉冗余的预测
生成多个锚框
输入图像的高h,宽w,宽高比h/w=r
缩放比s,即锚框的高为,宽为
要生成多个不同形状的锚框,让我们设置许多缩放比(scale)取值s1,…,sn和许多宽高比(aspect ratio)取值r1,…,rm
即,以同一元素为中心的锚框的数量是n+m-1;对于整个图形,共生成wh(n+m-1)个锚框
loU-交并比
loU 用来计算两个框之间的相似度
0表示无重叠,1表示重合
这是 Jacquard 指数的一个特殊情况
给定两个集合 A和 B
在训练数据中标注锚框
在训练集中,我们将每个锚框视为一个训练样本。 为了训练目标检测模型,我们需要每个锚框的类别(class)和偏移量(offset)标签,其中前者是与锚框相关的对象的类别,后者是真实边界框相对于锚框的偏移量。 在预测时,我们为每个图像生成多个锚框,预测所有锚框的类别和偏移量,根据预测的偏移量调整它们的位置以获得预测的边界框,最后只输出符合特定条件的预测边界框。
目标检测训练集带有真实边界框的位置及其包围物体类别的标签。 要标记任何生成的锚框,我们可以参考分配到的最接近此锚框的真实边界框的位置和类别标签。
notion image
如果一个锚框没有被分配真实边界框,我们只需将锚框的类别标记为背景(background)。 背景类别的锚框通常被称为负类锚框,其余的被称为正类锚框。
 
使用非极大值抑制(NMS)输出
每个锚框预测一个边缘框
NMS可以合并相似的预测
选中是非背景类的最大预测值
去掉所有其它和它IoU值大于θ的预测
重复上述过程直到所有预测要么被选中,要么被去掉
 
notion image

13.5. 多尺度目标检测

以输入图像的每个像素为中心,生成了多个锚框,会得到太多需要计算的锚框,需要减少图像上的锚框数量。
当使用较小的锚框检测较小的物体时,我们可以采样更多的区域,而对于较大的物体,我们可以采样较少的区域。
 
 

13.7. 单发多框检测(SSD)

SSD模型
notion image
通过多尺度特征块,单发多框检测生成不同大小的锚框,并通过预测边界框的类别和偏移量来检测大小不同的目标,因此这是一个多尺度目标检测模型。
  • 一个基础网络来抽取特征,然后多个卷积层块来减半高宽,在每段都生成锚框
  • 底部段来拟合小物体,顶部段来拟合大物体
  • 对每个锚框预测类别和边缘框
 
SSD通过单神经网络来检测模型
以每个像素为中心的产生多个锚框
在多个段的输出上进行多尺度的检测

YOLO模型

SSD中锚框大量重叠,因此浪费了很多计算
YOLO 将图片均匀分成 个锚框
每个锚框预测个边缘框
后续版本(V2,V3,V4...)有持续改进
 

13.8. 区域卷积神经网络(R-CNN)系列

基于锚框的算法

13.8.1. R-CNN

notion image
  1. 对输入图像使用选择性搜索 来选取多个高质量的提议区域(使用启发式搜索算法来选择锚框)。这些提议区域通常是在多个尺度下选取的,并具有不同的形状和大小。每个提议区域都将被标注类别和真实边界框;
  1. 选择一个预训练的卷积神经网络,并将其在输出层之前截断。将每个提议区域变形为网络需要的输入尺寸,并通过前向传播输出抽取提议区域特征
  1. 将每个提议区域的特征连同其标注的类别作为一个样本。训练多个支持向量机对目标分类,其中每个支持向量机用来判断样本是否属于某一个类别;
  1. 将每个提议区域的特征连同其标注的边界框作为一个样本,训练线性回归模型来预测真实边界框
R-CNN的主要性能瓶颈在于,对每个提议区域,卷积神经网络的前向传播是独立的,而没有共享计算。 由于这些区域通常有重叠,独立的特征抽取会导致重复的计算。

13.8.2. Fast R-CNN

使用CNN对图片抽取特征,而不是对每个锚框进行抽取
使用Rol池化层对每个锚框生成固定长度的特征
notion image
  1. 与R-CNN相比,Fast R-CNN用来提取特征的卷积神经网络的输入是整个图像,而不是各个提议区域。此外,这个网络通常会参与训练。设输入为一张图像,将卷积神经网络的输出的形状记为1×c×h1×w1;
  1. 假设选择性搜索生成了n个提议区域。这些形状各异的提议区域在卷积神经网络的输出上分别标出了形状各异的兴趣区域。然后,这些感兴趣的区域需要进一步抽取出形状相同的特征(比如指定高度h2和宽度w2),以便于连结后输出。为了实现这一目标,Fast R-CNN引入了兴趣区域汇聚层(RoI pooling):将卷积神经网络的输出和提议区域作为输入,输出连结后的各个提议区域抽取的特征,形状为n×c×h2×w2;
  1. 通过全连接层将输出形状变换为n×d,其中超参数d取决于模型设计;
  1. 预测n个提议区域中每个区域的类别和边界框。更具体地说,在预测类别和边界框时,将全连接层的输出分别转换为形状为n×q(q是类别的数量)的输出和形状为n×4的输出。其中预测类别时使用softmax回归。
Rol池化层 range of interesting
给定一个锚框,均匀分割成n×m块,输出每块里的最大值
不管锚框多大,总是输出nm个值
使每个锚框变为想要的形状

13.8.3. Faster R-CNN

为了较精确地检测目标结果,Fast R-CNN模型通常需要在选择性搜索中生成大量的提议区域。 Faster R-CNN 提出将选择性搜索替换为区域提议网络(region proposal network),从而减少提议区域的生成数量,并保证目标检测的精度。
notion image
区域提议网络的计算步骤如下:
  1. 使用填充为1的3×3的卷积层变换卷积神经网络的输出,并将输出通道数记为c。这样,卷积神经网络为图像抽取的特征图中的每个单元均得到一个长度为c的新特征。
  1. 以特征图的每个像素为中心,生成多个不同大小和宽高比的锚框并标注它们。
  1. 使用锚框中心单元长度为c的特征,分别预测该锚框的二元类别(含目标还是背景)和边界框。
  1. 使用非极大值抑制,从预测类别为目标的预测边界框中移除相似的结果。最终输出的预测边界框即是兴趣区域汇聚层所需的提议区域。

13.8.4. Mask R-CNN

如果在训练集中还标注了每个目标在图像上的像素级位置,Mask R-CNN能够有效地利用这些详尽的标注信息进一步提升目标检测的精度。
notion image
将兴趣区域汇聚层替换为了 兴趣区域对齐层,使用双线性插值(bilinear interpolation)来保留特征图上的空间信息,从而更适于像素级预测。 兴趣区域对齐层的输出包含了所有与兴趣区域的形状相同的特征图。
 

13.9. 语义分割和数据集

语义分割
语义分割将图片中的每个像素分类到对应的类别
notion image
notion image

13.10. 转置卷积

卷积不会增大输入的高宽,通常要么不变、要么减半
转置卷积则可以用来增大输入高宽
转置卷积是一种卷积,它将输入和核进行了重新排列 同卷积一般是做下采样不同,它通常用作上采样 如果卷积将输入从(h,w)变成了(h,w',同样超参数下它将 (h',w)变成 (h, w)
notion image
填充、步幅和多通道
当将高和宽两侧的填充数指定为1时,转置卷积的输出中将删除第一和最后的行与列。
notion image
重新排列输入和核
notion image
notion image
notion image

13.11. 全连接卷积神经网络 FCN

FCN采用卷积神经网络实现了从图像像素到像素类别的变换
它用转置卷积层来替换CNN最后的全连接层,从而可以实现每个像素的预测
notion image
对每个像素的类别的预测存在通道里面,所以转置卷积层得到的输出通道数为类别数,高宽与输入相同

13.12. 样式迁移

notion image
 

十四、十五、自然语言处理 NLP

BERT

NLP 里的迁移学习

在计算机视觉中比较流行,将 ImageNet 或者更大的数据集上预训练好的模型应用到其他任务中,比如小数据的预测图片分类或者是目标检测
1、使用预训练好的模型(例如 word2vec 或语言模型)来抽取词、句子的特征
2、做迁移学习的时候,一般不更新预训练好的模型
3、在更换任务之后,还是需要构建新的网络来抓取新任务需要的信息
  • 使用预训练好的模型来抽取特征的时候,一般得到的是一些比较底层的特征,很多时候只是当成一个 embedding 层来使用,还是需要设计一个比较复杂的模型
  • word2vec 忽略了时序信息
  • 语言模型只看一个方向,而且训练的模型不是很大(RNN 处理不了很长的序列,因为它只能看到很短的一部分)
 

BERT

BERT 结合了 ELMo 对上下文进行双向编码以及 GPT 任务无关这两方面的优点,对上下文进行双向编码,并且对于大多数的自然语言处理任务只需要最少的架构改变
  • 通过将整个序列作为输入,ELMo 是为输入序列中的每一个单词分配一个表示的函数(ELMo 将来自预训练的双向长短期记忆网络的所有中间层表示组合为输出表示,ELMo 的表示将作为附加特征添加到下游任务的现有监督模型中)
  • 在加入 ELMo 表示之后,冻结了预训练的双向 LSTM 模型中的所有权重;现有的监督模型是专门为给定的任务定制的(为每一个自然语言处理任务设计一个特定的架构实际上并不是一件容易的事情),利用不同任务的不同最佳模型,添加 ELMo 改进了六种自然语言处理任务的技术水平:情感分析自然语言推断语义角色标注共指消解命名实体识别回答
  • GPT (Generative Pre Training ,生成式预训练)模型为上下文的敏感表示设计了通用的任务无关模型,它在 Transformer 解码器的基础上,预训练了一个用于表示文本序列的语言模型,当将 GPT 应用于下游任务时,语言模型的输出被送到一个附加的线性输出层,以预测任务的标签
  • 与 ELMo 冻结预训练模型的参数不同,GPT 在下游任务的监督学习过程中对预训练 Transformer 解码器中的所有参数进行微调,GPT 在自然语言推断问答句子相似性分类等12项任务上进行了评估,并在对模型架构进行最小更改的情况下改善了其中9项任务的最新水平
  • ELMo 对上下文进行双向编码,但使用特定于任务的架构;GPT 是任务无关的,但是从左到右编码上下文(由于语言模型的自回归特性,GPT 只能向前看(从左到右))
  • 在下游任务的监督学习过程中,BERT 在两方面与GPT相似:BERT 表示将被输入到一个添加的输出层中,根据任务的性质对模型架构进行最小的更改(例如预测每个词元与预测整个序列);BERT 对预训练 Transformer 编码器的所有参数进行微调,而额外的输出层将从头开始训练
  • BERT 进一步改进了 11 种自然语言处理任务的技术水平,这些任务分为以下几个大类:单一文本分类(如情感分析)、文本对分类(如自然语言推断)、问答文本标记(如命名实体识别)
notion image
3、原始的 BERT 有两个版本,其中基本模型有 1.1 亿个参数,大模型有 3.4 亿个参数
4、最初的 BERT 模型是在两个庞大的图书馆语料库英语维基百科的合集上预训练的
5、现成的预训练 BERT 模型可能不适合医学等特定领域的应用
6、在预训练 BERT 之后,可以用它来表示单个文本文本对其中的任何词元
7、BERT 表示是上下文敏感的,同一个词元在不同的上下文中具有不同的 BERT 表示
  • 上下文敏感:同一个词可以根据上下文被赋予不同的表示(词的表征取决于它们的上下文)
 

BERT 的动机

1、基于微调的 NLP 模型
2、预训练的模型抽取了足够多的信息
3、新的任务只需要增加一个简单的输出层
notion image
做微调的时候,特征抽取的层是可以复用的(也可以应用到别的任务上面去),只需要修改分类器就可以了
预训练的模型抽取了足够多的信息,使得 feature 已经足够好能够抓住很多的信息,所以在做新的任务的时候,只需要增加一个输出层就可以了

BERT 架构

只有编码器的 Transformer
BERT 在原始的论文中提供了两个原始的版本(原始 BERT 模型中,输入序列最大长度是 512):
  • Base:#blocks=12,hidden size=768,#heads=12,#parameters=110M
  • Large:#blocks=24,hidden size=1024,#heads=16,#parameters=340M
在大规模数据上训练 > 3B 词
 
对输入的修改
notion image
1、每个样本是一个句子对
  • 从源句子到目标句子
  • 翻译的时候,源句子进的是编码器,目标句子进的是解码器,而现在只有一个编码器。因为 NLP 中很多情况下都是两个句子,比如说 Q&A 都是两个句子,一个句子进去,一个句子出来。在 BERT 中,将两个句子拼接起来,然后放进编码器,因此每个样本就是一个句子对
2、加入额外的片段嵌入
上图中的“this movie is great”和“i like it”两个句子是如何放进去的
  • 首先在句首加了一个特殊的分类标签<cls>(class),作为句子对的开头( BERT 输入序列明确地表示单个文本和文本对)
  • 然后在两个句子至今之间使用了一个特殊的分隔符<sep>(separate),将两个句子分开(第二个句子末尾也使用了一个分隔符)
  • 也可以做得更长,将更多的句子连接起来,但是一般没有这种情况的使用场景,所以一般使用两个句子就够了
因为有两个句子,而且仅仅使用标签的话,对于 transformer 来讲并不是很好区分两个句子的先后顺序,所以额外地添加了一个 Segment Embedding 来进行区分
  • 对于第一个句子中的所有词元添加 Segment Embedding 为 0 (包括句首的分类标签以及两个句子之间的分隔符)
  • 对于第尔个句子中的所有词元添加 Segment Embedding 为 1(包括句末的分隔符)
3、位置编码可学习
  • 在 Transformer 编码器中常见的是,位置嵌入被加入到输入序列的每个位置,而 BERT 中使用的是可学习的位置嵌入( BERT 输入序列的嵌入是词元嵌入、片段嵌入和位置嵌入的和)
  • 不再使用 sin 和 cos 函数
 
预训练任务
BERT 是做一个通用的任务,因为他是一个预训练模型,做很常见的通用的任务,使得用这个任务训练出来的数据足够好,以至于做别的任务的时候都能做
在文本中,最通用的任务就是语言模型了,给定一个词,然后预测下一个词
  • 但是 BERT 不能直接这么做,因为他里面的编码器是可以看到后面的东西的
  • Transformer 中的编码器是双向的,既看前面又看后面,解码器才是单向的
  • BERT 中的 B 是 bi-directional ,是双向的意思,所以它是看双向的信息,然后抽取比较好的特征,但是如果用来训练语言模型的话就会有问题
因此在 BERT 中做了一个修改,叫做带掩码的语言模型
  • 给定一个句子,把中间的一些词遮起来,然后预测这些词,有点类似于完型填空
预训练任务 1:掩蔽语言模型(Masked Language Modeling)
1、Transformer 的编码器是双向的,标准语言模型要求单向
  • 语言模型使用左侧的上下文预测词元
  • 为了双向编码上下文以表示每个词元,BERT 随机掩蔽词元并使用来自双向上下文的词元以自监督的方式预测掩蔽词元
2、带掩码的语言模型每次随机(15%概率)将一些词元(作为预测的掩蔽词元)替换成 <mask>
  • 任务就变成了预测被遮起来的那些词,模型就不是预测未来,而是变成了完型填空,因此看双向的信息是没有任何问题的
  • 在每个预测位置,输入可以由特殊的“掩码”词元或随机词元替代,或者保持不变
3、虽然 BERT 在训练的时候加了很多的 <mask> ,但是在微调任务中不出现 <mask> 这种人造特殊词元,为了避免预训练和微调之间的这种不匹配,解决的办法是模型不要总是对 <mask> 遮掉的部分进行预测输出
  • 80% 概率下,将选中的词元变成 <mask>
  • 10% 概率下换成一个随机词元(这种偶然的噪声鼓励 BERT 在其双向上下文编码中不那么偏向于掩蔽词元,尤其是当标签词元保持不变时)
  • 10% 概率下保持原有的词元
4、带掩码的语言虽然能够编码双向上下文来表示单词,但是它并不能显式地建模文本对之间的逻辑关系
预训练任务 2:下一句子预测(Next Sentence Prediction)
1、给定一个句子对,预测这个句子对中两个句子在原始的句子中是不是相邻,从而帮助理解两个文本序列之间的关系
2、在构造样本的时候,训练样本中:
  • 50% 概率选择相邻句子对(在采样一个句子的时候,将该句子后面的一个句子也采样进去):<cls> this movie is great <sep> i like it <sep>
  • 50% 概率选择随机句子对(在采样一个句子的时候,在其他地方再随机挑选一个句子采样进去):<cls> this movie is great <sep> hello world <sep>
3、将 <cls> 对应的输出放到一个全连接层来预测,判断两个句子是不是相邻的
 
总结
1、BERT 是针对 NLP 的微调设计,在大的文本上训练一个比较大的模型,在做别的任务的时候将输出层进行修改,最后的效果会比直接训练好一点( BERT 让微调在 NLP 中变成了主流)
2、BERT 其实就是一个基于 Transformer 的编码器,但是做了一点修改
  • 模型更大,训练数据更多(一般是至少十亿个词,文本不像图片,文本不需要进行标记,所以文本可以无限大)
  • 输入句子对,片段嵌入,可学习的位置编码
  • 训练时使用两个任务:带掩码的语言模型下一个句子预测
3、word2vec 和 GloVe 等词嵌入模型与上下文无关,它们将相同的预训练向量赋给同一个词,而不考虑词的上下文(如果有的话),因此很难处理好自然语言中的一词多义或复杂语义
4、对于上下文敏感的词表示,如 ELMo 和 GPT ,词的表示依赖于它们的上下文
  • ELMo 对上下文进行双向编码,但使用特定于任务的架构(为每个自然语言处理任务设计一个特定的体系架构实际上并不容易)
  • GPT 是任务无关的,但是从左到右编码上下文
5、BERT 结合了这两个方面的优点:对上下文进行双向编码,并且需要对大量自然语言处理任务进行最小的架构更改
6、BERT输入序列的嵌入是词元嵌入、片段嵌入和位置嵌入的和
7、BERT 预训练包括两个任务:掩蔽语言模型和下一句预测
  • 掩蔽语言模型能够编码双向上下文来表示单词
  • 下一句预测能够显式地建模文本对之间的逻辑关系
 
notion image
notion image
notion image
notion image
 

其他

在Colab中永久安装使用d2l

colab使用限制有些迷惑,遂转嫖kaggle

在kaggle中使用d2l

notion image

train_epoch_ch3

 
Loading...