25李宏毅机器学习
1.机器学习基础
1.1 机器学习基本概念
1.1.1 机器学习任务
首先介绍三个机器学习任务:- regression:回归分析,输出预测值
- classification:分类任务,输出0或者1
- Structured Learning:结构化学习,输出结构化的信息
1.1.2 机器学习步骤:
Setp 1:Model
Function with Unknow Parameters,未知参数方程
首先要猜测一个位置参数方程,其猜测方向是要根据专业知识来猜测,其输入值是一个线性表达式,输出值是特征值,最终得到一个方程式,即Model。
Setp 2:Loss
Define Loss from Training Data,定义损失函数
其计算方法如下,通过统计所有的真实数据与预测数据的差值的绝对值,最后取平均。需要注意的是我们需要Loss的值越小越好。

Setp 3:Optimization
Optimization,优化,找到最小的$ w^*和b^* $
通过Gradient Descent(梯度下降),不断调整参数w,并通过引入学习率来计算新的w参数,最终需要找到Loss最小的值。
那么什么时候会终止梯度下降呢?
(1)迭代到一定次数,通常是开始模型训练之前确定的
(2)梯度为0,即偏导数值为0(会陷入local minma)
当多参数进行梯度下降优化如下图:

最后总结机器学习的过程:

1.2 从机器学习到深度学习
1.2.1 优化机器学习
1.更复杂的Model
为了下图更复杂的图像,通过多个sigmoid图形进行叠加来得到想要的图形。其中$ Sigmoid(x) = \frac{1}{1 + e^{-x}} $
当输入参数变多,$ w_1x_1 $ 就会变成$ {\sum_{j}w_jx_j} $,此时要计算对于的y值,就如下图所示。


为了简化参数,将参数矩阵转化成如下列向量

当然为了得到Model也可以是ReLu来进行模拟,其中ReLu的代码为
def relu(x):
return x * (x > 0)

其中,对于Sigmoid和ReLU都被称为激活函数。
2.更改Loss
此时损失函数和前面的计算方法仍然相同,$ e_n $仍是真实值与预测值差的绝对值。
此时梯度下降的步骤仍然和之前相同,通过计算新的参数向量,不断向下更新。

这里介绍一种方法,样本数据分成不同批次(batch),将上一批计算的参数向量作为下一批计算时的输入。
一个Epoch就是将所有训练样本训练一次的过程。将整个训练样本分成若干个Batch(批 / 一批样本)。Batch_Size为每批样本的大小。训练一个Batch就是一次Iteration(一次迭代)。每个batch更新一次参数。

3.增加Layer
以100层ReLU作为一层,当层数越大时,实际样本集合训练集的Loss函数都有一定下降。
1.2.2 深度学习
通过多层hidden layer组成的训练网络,每层包含一些神经元,最终组成深度学习网络。
2.机器学习训练攻略
2.1.机器学习任务攻略
在实际训练过程中,针对训练集数据的损失函数值过大,即误差过大,有下图的几种情况。
2.1.1 Model bias
模型误差,代表模型函数表达式不能覆盖实际情况,解决方法:(1)重新设置Model,增加更多特征输入
(2)采用深度学习

2.1.2 Optimzation Issue
优化问题,无法采用梯度下降算法得到理想的损失函数。
2.1.3 Model bias与OPtimzation Issue判断
针对两者之间的判断,若在深度学习中使用更少的层可以达到更小的训练损失函数值,那么其一定是优化问题。
2.1.4 Overfitting
过拟合,表示模型在训练集上表示的损失值小,而在测试集中损失值大。其根本原因是训练数据无法良好的限制构造的模型,从而训练出奇怪的模型。:::color5
其具体体现就是,训练集效果比较好,但是测试集效果比较差。
:::
例如:

可以通过增加训练数据来限制生成的模型,从而增加模型的准确度。
除此之外,还可以进行下面的操作来解决过拟合问题:
- 更少的参数,共享参数
- 更少的特征
- 更早停止模型训练(Early stopping)
- 正则化
- Dropout法处理
其中正则化和Dropout适合在比较复杂的神经网络中使用。

而当模型的限制更多时,可能会又导致Model bias。

2.1.5 选择理想模型
1. Corss Validation
交叉验证,通过将数据集中部分数据作为训练集,部分作为验证集,通过验证集得分来选择模型。
2 N-fold Corss Validation
N-fold交叉验证,通过将数据集分为训练集和验证集,其中训练集和验证集分组不定,通过不断不同的分组来对模型进行验证,通过最终平均得分来选择模型。
2.1.6 Dismatch
数据不匹配是指训练集和测试集数据在分布、特征或属性上存在显著差异,从而导致最总训练出的模型性能不佳。
2.2.类神经网络训练
2.2.1 局部极小值与鞍点
1. 临界点及其种类
有时候在训练深层网络模型的时候,会出现一种情况,当损失关于参数的微分为零的时候,梯度下降不能再更新新参数了,此时训练停了下来,损失值也不能再下降。如图所示:
当梯度为0时,最有可能的情况是局部极小值(local minimum),但是还有一种情况梯度值为0但是却不是局部最小值,其梯度为0的点叫做鞍点(saddle point),如图所示,且把梯度为0的点统称为临界点(critical point)。

2. 判断临界值种类的方法
对于判断一个临界值是局部最小值还是鞍点显然需要知道损失函数的形状,但是如何知道呢?我们就损失函数的表达式,对于其表达式可以使用泰勒展开式来进行表示。$ L(\boldsymbol{\theta}) \approx L\left(\boldsymbol{\theta}‘\right) + \left(\boldsymbol{\theta} - \boldsymbol{\theta}’\right)^\text{T} \boldsymbol{g} + \frac{1}{2} \left(\boldsymbol{\theta} - \boldsymbol{\theta}‘\right)^\text{T} \boldsymbol{H} \left(\boldsymbol{\theta} - \boldsymbol{\theta}’\right). $
- $ L\left(\boldsymbol{\theta}‘\right) :表示对:表示对:表示对 {\theta}’ $点出损失函数的值。
- $ \left(\boldsymbol{\theta} - \boldsymbol{\theta}‘\right)^\text{T} \boldsymbol{g} ::: {g} 表示梯度,其是一个向量,有时候会将表示梯度,其是一个向量,有时候会将表示梯度,其是一个向量,有时候会将 {g} 写成写成写成 \nabla L(\boldsymbol{\theta}’) 。。。 {g_i} 表示向量表示向量表示向量 {g} 的第i个元素,其就是L关于的第i个元素,其就是L关于的第i个元素,其就是L关于 {\theta} $的第i个元素的偏导数,即 $ g_i = \frac{\partial L\left(\boldsymbol{\theta}'\right)}{\partial \theta_i} $。
- $ \frac{1}{2} \left(\boldsymbol{\theta} - \boldsymbol{\theta}‘\right)^\text{T} \boldsymbol{H} \left(\boldsymbol{\theta} - \boldsymbol{\theta}’\right) :这一项中跟∗∗海森矩阵(Hessianmatrix)H∗∗有关。其中H存放的是L的二次微分,其第i行第j类的值:这一项中跟**海森矩阵(Hessian matrix)H**有关。其中H存放的是L的二次微分,其第i行第j类的值:这一项中跟∗∗海森矩阵(Hessianmatrix)H∗∗有关。其中H存放的是L的二次微分,其第i行第j类的值 H_{ij} 就是就是就是 {\theta} 对第i个元素对对第i个元素对对第i个元素对 L\left(\boldsymbol{\theta}‘\right) 作微分,再把作微分,再把作微分,再把 {\theta} 的第j个元素对的第j个元素对的第j个元素对 \frac{\partial L(\boldsymbol{\theta}’)}{\partial \theta_i} 做微分得到,做微分得到,做微分得到, H_{ij} = \frac{\partial^2}{\partial \theta_i \partial \theta_j} L\left(\boldsymbol{\theta}'\right) $。
那么该如何判断再某点是局部值还是鞍点呢?
首先使用向量$ v 表示表示表示 \left(\boldsymbol{\theta} - \boldsymbol{\theta}'\right) $,然后又以下三种情况
(1)$ \boldsymbol{v}, \ \boldsymbol{v}^\text{T} \boldsymbol{H} \boldsymbol{v} > 0 ,表示,表示,表示 L\left(\boldsymbol{\theta}\right) > L\left(\boldsymbol{\theta}'\right) $,此时就表示这是一个最低点,也就是局部最小值。
(2)$ \boldsymbol{v}, \ \boldsymbol{v}^\text{T} \boldsymbol{H} \boldsymbol{v} < 0 ,表示,表示,表示 L\left(\boldsymbol{\theta}\right) < L\left(\boldsymbol{\theta}'\right) $,此时就表示这是一个最高点,也就是局部最大值。
(3)$ \boldsymbol{v}, \ \boldsymbol{v}^\text{T} \boldsymbol{H} \boldsymbol{v} $时而大于0时而小于0,此时表示这不是一个最值点,也就是鞍点。
设计一个简单的神经网络来说明这个方法,如下图:
我们设计的模型表达式为$ y= w_1w_2x $,并且希望输入与输出经量相同。

并且可以直接画出神经网络的误差表面,如下图:

此时通过计算$ L\left(\boldsymbol{\theta}\right) 的泰勒展开式中参数,并要通过海森矩阵来判断原点是局部极小值还是鞍点,要看它的特征值,的泰勒展开式中参数,并要通过海森矩阵来判断原点是局部极小值还是鞍点,要看它的特征值,的泰勒展开式中参数,并要通过海森矩阵来判断原点是局部极小值还是鞍点,要看它的特征值, \boldsymbol{H} = \begin{bmatrix}
0 & -2 \
-2 & 0
\end{bmatrix} $ 这个矩阵有两个特征值: 2 和−2,特征值有正有负,因此原点是鞍点。 对于这个鞍点如何通过海森矩阵来更新参数呢?

由上述表达式可知,主要矩阵H的特征值有负数时,就可以朝着特征向量$ u $的方向进行更新,此时损失就会减小。
而在实际情况中,我们训练达到的临界点中,大多数其实都是鞍点,当通过增加维度就可以再次对模型进行优化从而减小损失值。如下图:

其中最小值比例其实就是 正特征值数量 / 总特征值数量,而当有负特征值,我们就可以再次降低模型损失值。正如上图所示,当达到一个临界点时,最小值比例并不为1,此时就有负特征值,就可以再次降低模型损失值。
2.2.2 批量和动量
在计算梯度的过程中,并不是直接对所有数据的损失L计算梯度,而是将所有数据分成一个个的批量(batch),如下图所示。且把遍历所有批量计算梯度新参数的过程叫做回合(epoch)。
1. 批量大小对梯度下降的影响
假设有20笔数据,采用两种方法进行梯度下降。- 在图(a)中,将所有数据视为批量大小,这种方法叫做批量梯度下降法(Batch Gradient Descent,BGD),也就是说只有把20笔数据都看完,才可以进行计算损失和梯度,参数才能更新一次。
- 在图(b)中,将批量大小设置为1,意味着每取出一笔数据既可以计算损失和梯度、更新参数,这种方法叫做随机梯度下降法(Stochastic Gradient Descent,SGD),也叫增量梯度下降法。但是这种方法会产生更多的噪音,因此更新方向是曲曲折折的。

在实际情况中,每次更新消耗时间随着批量大小增大而增大;每个回合消耗时间随着批量大小增大而减小。但是这是不考虑并行计算的情况下,若考虑并行计算,大的批量反而更有效率,消耗时间反而更少。

但是在 MNIST 数据集和CIFAR-10 数据集实验结果上,批量越大,验证集的准确率越差。 但是这不是过拟合,因为批量大小越大,训练准确率也是越低。因为用的是一个模型,这也不是模型偏见的问题。但大的批量大小往往在训练时,结果比较差,因此这是一个优化的问题。大的批量大小优化可能有问题,而小的批量大小优化的结果反而更好。

一个猜想是,对于批量梯度下降算法在更新参数时,可能会开在某个鞍点或者局部最值,但是对于小批量梯度下降时,由于会不断的更新参数,选用第一个批量,用$ L_1 计算梯度卡住了,选用第二个批量时,用计算梯度卡住了,选用第二个批量时,用计算梯度卡住了,选用第二个批量时,用 L_2 $计算梯度不一定会卡住,因此采用小批量梯度下降会让损失值降低到更小,对模型训练更有帮助。

因此,对于大批量梯度下降和小批量梯度下降都有其优点,其两者对比如下表:

2. 动量
动量法(momentum method)是另一个可以对抗靶点或者局部最小值的方法,其借用与物理中的惯性原理,使模型在进行梯度下降的过程中也保持一定的“惯性”,从而减少模型在梯度下降中的卡住的情况。如下图就是物理中的惯性。
在一般的梯度下降中,都是直接对参数进行梯度下降,然后更新参数,如下图:

而在动量梯度下降算法中,添加了移动量的新参数,通过这个参数保存上一次参数移动的趋势,从而在本次参数更新中发挥作用,如下图:

而在实际情况中产生的作用,就如下图所示,小球在到达不是最低点时,前一步的移动量可能推动着小球继续引动,从而可能走向更好的局部最小值点,这就是动量带来的好处。

2.2.3 自适应学习率
临界点(critical point)其实并不一定是训练模型过程中遇到的最大的阻碍。在实际训练过程中,随着参数爹迭代次数增多,损失下降会越来越慢,最终卡住,如下图:
当走到临界点的时候,意味着梯度非常小,但是损失不再下降,不代表梯度真的变得很小,如下图,横轴代表迭代次数,竖轴代表梯度的范数,即梯度这个向量的长度。随着迭代次数增多,虽然损失不在下降,但是梯度的范数并没有变得很小,如下图:

其真实情况可能如下图所示,当达到临界点时,梯度并没有变得很小,而是在山谷的两个谷壁之间来回的震荡。所以有时候训练过程中损失不再下降时,可能不是卡到局部最小值或者鞍点,只是单纯的损失无法在下降。

举个例子,对于下面的误差表面进行梯度下降,当学习率为$ \eta=10^{-2} 时,梯度过大,参数在山壁的两端进行震荡,将学习率调小之后为时,梯度过大,参数在山壁的两端进行震荡,将学习率调小之后为时,梯度过大,参数在山壁的两端进行震荡,将学习率调小之后为 \eta=10^{-7} $时,参数会滑倒山谷底后左转,但是从B点已经永远达不到终点了,因为此时的学习率已经太小了,这样小的学习率已经无法再让训练前进。

由此可得,使用原始的梯度下降已经无法处理这种问题,因此需要引入自适应学习率(adaptive learning rate)的方法,给每个参数不同的学习速率。即如上图,如果在某个方向上,梯度的值很小,非常平坦,就会希望学习率调大一点;如果在某个方向上非常陡峭,坡度很大,就希望将学习率调小一点。
1. AdaGrad
AdaGrad(Adaptive Gradien)是典型的自适应学习率方法,可以根据梯度大小自动调整学习率。当梯度较大的时候,学习率就减小,梯度较小的时候,学习就放大。首先回顾梯度下降算法的参数迭代过程,梯度下降更新某个参数$ {\theta}{t}^{i} 的过程为的过程为的过程为 \boldsymbol{\theta}{t+1}{i}\leftarrow\boldsymbol{\theta}_{t}{i}-\eta\boldsymbol{g}{t}^{i} ,,, {\theta}{t}^{i} $在第t个迭代的值剪掉在第t个迭代参数i计算出来的梯度为 $ \boldsymbol{g}t^i=\left.\frac{\partial L}{\partial\boldsymbol{\theta}^i}\right|{\boldsymbol{\theta}=\boldsymbol{\theta}_t} $。
而对于AdaGard进行梯度下降进行参数更新的过程如下图所示:

对于下图中, $ {\theta_1} 坡度小,计算出来的坡度小,计算出来的坡度小,计算出来的 \sigma_t^i 就小,学习率就大;而对于就小,学习率就大;而对于就小,学习率就大;而对于 {\theta_2} 坡度较大,计算出来的坡度较大,计算出来的坡度较大,计算出来的 \sigma_t^i $就比较大,因此学习率就比较小。

2. RMSProp
当需要进行同一个参数同一个方向学习率的调整时,AdaGrad就不能满足需求了,此时就RMSProp(Root Mean Squared propagation)。其具体步骤如下,其实就是在每次更新参数时,设置参数$ \alpha $来决定当前计算梯度更重要还是之前计算的梯度更重要。
例如下图示例中,当需要较小的步伐时,将$ \alpha 设小一点,从而使设小一点,从而使设小一点,从而使 \sigma_t^i 变大,就会让学习率变小,因此步伐就会比较小;同样的当需要较大的步伐时,将变大,就会让学习率变小,因此步伐就会比较小;同样的当需要较大的步伐时,将变大,就会让学习率变小,因此步伐就会比较小;同样的当需要较大的步伐时,将 \alpha 设大一点,从而使设大一点,从而使设大一点,从而使 \sigma_t^i $变小,就会让学习率变大,因此步伐就会比较大。

3. Adam
最常用的优化的策略或者**优化器(optimizer)**是**Adam(Adaptive moment estiation)**。可以看作RMSprop加上动量,使用动量作为参数更新方向,并可以自适应调整学习率。其中PyTorch中就有Adam优化器。2.2.4 学习率调度
当使用AdaGrad方法进行优化之后,可以得到下图情况,其是为什么呢?在红圈中,快到终点时突然“爆炸”。其原因是$ \sigma_t^i $是把过去所有的梯度拿作平均,当积累当一定程度之后,步伐就变得很大,但是有办法修正。因为其步伐很大,就会走到梯度较大的地方,此时$ \sigma_t^i $就会慢慢变大,更新的步伐就会慢慢变小,从而回到原来的路线。
通过学习率调度(learning rate scheduling)就可以解决这个问题,其常用的策略就是学习率衰减(learning rate decay),也叫学习率退火(learning rate annealing),其可行思路就是让随着参数$ \mathrm{n} 更新越来越小,如下图所示。其更新公式为更新越来越小,如下图所示。其更新公式为更新越来越小,如下图所示。其更新公式为 \boldsymbol{\theta}_{t+1}i\leftarrow\boldsymbol{\theta}_ti-\frac{\eta_t}{\sigma_ti}\boldsymbol{g}_ti $。

从而达到最终结果,如下图。

:::color5
除了对学习率进行衰减,还有一种调度策略就是对学习率进行预热(Warm Up),其思路为:开始时,统计结果$ \sigma 不准确,先让学习率较小用于探索收集一些有关误差表面的信息,等不准确,先让学习率较小用于探索收集一些有关误差表面的信息,等不准确,先让学习率较小用于探索收集一些有关误差表面的信息,等 \sigma $统计比较精准之后,再让学习慢慢增大。
:::

2.2.5 优化总结
通过不同方面的优化,将最初的梯度下降版本 $ \boldsymbol{\theta}_{t+1}^{i}\leftarrow\boldsymbol{\theta}_{t}^{i}-\eta\boldsymbol{g}_{t}^{i} $进化到$ \boldsymbol{\theta}_{t+1}^i\leftarrow\boldsymbol{\theta}_t^i-\frac{\eta_t}{\sigma_t^i}\boldsymbol{m}_t^i $,其中动量$ {m}_t^i 考虑了过去所有的梯度,均方根考虑了过去所有的梯度,均方根考虑了过去所有的梯度,均方根 {\sigma_t^i} 考虑了过去所有的梯度,考虑了过去所有的梯度,考虑了过去所有的梯度, {\eta_t} $考虑了学习率随时间的变化。
2.2.6 分类
1 分类与回归的关系
回归的输入是一个向量$ x $,输出$ y $,并希望$ y $和$ \hat{y} $越接近越好,$ \hat{y} $是要学习的目标。而分类问题也可以当作回归问题来看,输入$ x $之后,输出仍然是一个标量$ y $,要让它和正确答案的类越接近越好。在通常情况下,在分类中需要引入one-hot(独热编码)来表示类。
如果有三个类,$ \hat{y} 就是一个三维的向量,比如类1就是就是一个三维的向量,比如类1就是就是一个三维的向量,比如类1就是 [1,0,0]^\mathrm{T} ,类2就是,类2就是,类2就是 [0,1,0]^\mathrm{T} ,类3就是,类3就是,类3就是 [0,0,1]^\mathrm{T} $。用独热向量来计算,类两两之间的距离都是一样的。
而对于网络中$ \hat{y} 向量的计算就是把向量的计算就是把向量的计算就是把 a_1 、、、 a_2 、、、 a_3 乘上另外三个权值,进行三次就可以得到乘上另外三个权值,进行三次就可以得到乘上另外三个权值,进行三次就可以得到 \hat{y}_1 、、、 \hat{y}_2 、、、 \hat{y}_3 ,最终得到,最终得到,最终得到 \hat{y} $向量。

2 带有 softmax 的分类
分类实际的过程是:输入x,乘上W,加上b,通过激活函数$ {\sigma} $,乘上$ W^{'} $,再加上$ b^{'} $得到向量y但是实际情况中通常会通过softmax函数得到$ y^{\prime} $,才去计算$ y^{'} $和$ \hat{y} $之间的距离。
为什么使用softmax函数呢?因为最终标签$ \hat{y} 向量中数值都是介于0到1之间的,需要通过softmax函数来进行归一化操作。softmax函数具体表达式为:向量中数值都是介于0到1之间的,需要通过softmax函数来进行归一化操作。softmax函数具体表达式为:向量中数值都是介于0到1之间的,需要通过softmax函数来进行归一化操作。softmax函数具体表达式为: y_i^{\prime}=\frac{\exp(y_i)}{\sum_j\exp(y_j)} ,其中,,其中,,其中, 1>y_i^{\prime}>0 ,,, \sum_iy_i^{\prime}=1 。例如下进行的softmax计算得到最终的。例如下进行的softmax计算得到最终的。例如下进行的softmax计算得到最终的 \hat{y} $向量。

上图中考虑三个类的情况,两个类也可以使用softmax函数,但是两个类一般使用sigmoid函数,其表达式为:$ Sigmoid(x) = \frac{1}{1 + e^{-x}} $。
3 分类损失
当通过模型计算出$ y^{\prime} $最终值,计算损失函数的方法有两种,分别是**均方误差(Mean Square Error,MSE)**和**交叉熵(Cross-entropy)**。
在实际情况中,对于分类问题都是使用交叉熵来作为损失函数。也可知,改变损失函数可以改变优化的难度。
3.卷积神经网络
本小节介绍较少,详细可看[https://www.yuque.com/yiqi2/rnq707/olphqc8awiepnzs6?singleDoc#](https://www.yuque.com/yiqi2/rnq707/olphqc8awiepnzs6?singleDoc#) 《机器学习之路》当需要进行对图片进行处理时,就需要使用卷积神经网络了,首先由于图片是由RGB三部分组成,需要对图片进行三个通道的差分,如下图:

中间通过模型进行计算,得到输出one-hot编码,再与model标签进行比较,经过激活函数softmax最终得到结果。如下图:

3.1 卷积运算
进行图像识别时,大多数只需要对图片中某些部分的特性进行识别,如下图:
因此可以通过设计卷积运算的矩阵大小,也就是感受野(receptive field),也叫卷积核,使得神经元只关注一部分的图像特征。例如下图:

其卷积运算核心步骤就是使用卷积核和对应输入举证的位置进行运算从而得到特征图,如下图:

在进行卷积运算时,可能会出现卷积核进行卷积运算时,输入矩阵中没有足够的位来满足卷积核的运算,此时就要使用Padding,对空余位置进行补0或者其他数值。
3.2 共享参数
由于类似的图片特征可能出现在不同区域里,如下图:
因此,卷积运算中的参数可以进行共享,在同一卷积层中可以使用相同的卷积运算参数,如下图:

3.3 池化
当使用滤波器(卷积核)运算之后得到特征图,由于某些图片放大缩小不影响图片特征的表示,因此可以使用**池化(pooling)**来简化提取特征,从而减少运算,最常见的由**最大池化(max pooling)**和**平均池化(mean pooling)**,如下图表示:

当然也不是所有情况下都可以进行池化,只有图片特性不会被池化影响时可以进行。例如 AlphaGo 中卷积神经网络就没有池化操作。
3.4 总结
最终可以得到一个经典的图像识别的网络结构,不断对图像特征进行卷积、提取,最终进行扁平化后输入到全连接层中,最终softmax激活函数后于标签向量比较得到最终分类结果。
4.自注意力机制
4.1 输入是向量序列
在之前的神经网络中,输入都是一个向量,而有时候输入并不只是一个向量,如下图,可能是向量序列,对应的输出可能是标量或者类别。
例如,当输入为一个句子 I eat a apple,此时输入就会转变成独热编码的向量组进行输入。例如下列的词汇生成的独热编码,当然不仅仅只有one-Hot编码可以表示词汇,通过**词嵌入(word embedding)**也可以表示词汇,而且同时可以表示词汇之间的关系,这是独热编码不能表示的。如下图。


对于输入为向量序列,根据输出可以分为三类:输入与输出向量数相同、输入是一个序列且输出是一个标签、序列到序列。
1.输入输出相同
对于输入和输出向量相同,如下图所示。输入序列可以是文字、语音或者图片。
举个例子,在文字处理上,假设要做词性标注(Part-Of-Speech tagging, POS tagging),有一个句子 I saw a saw,其意思是我看到一个锯子,可以知道第一个saw是动词,而第二个saw是名词,然后可以进行词性划分,如下图。

2.输出为标签
第二种情况,整个模型的输出就是一个标签,如下图。
举一些简答的例子,例如给机器看一段话,让其判断这段是积极的(positive)还是消极的(negative)。如果输入是语音,让机器判断这段话是谁讲的。如果是图片,给一个分子,让机器预测该分子的亲水性。如下图。

3.序列到序列
最后一种情况,输出也是一个序列,其原因是我们并不知道输出该需要多少个标签,让机器自己决定来输出多少个标签。例如,聊天机器人就是这种情况。
4.2 自注意力的运作原理
1.引入使用
这里根据第一种情况,输入和输出向量数量一样多的情况,以序列标注(sequence labeling)为例。序列标注需要给序列中每一个向量一个标签。要如何解决序列标注问题呢?直觉的想法就是使用全连接网络,如下图。
但是对一个句子进行序列标注,很明显上面的直接进行没有考虑上下文信息这一点,此时可以将不同向量连接起来,并使用一定大小的窗口来考虑上下文信息,但是当句子足够大时,窗口也会变大,此时全连接层也会需要非常多的参数,这样并不能满足需求。

此时就需要使用自注意力模型来使得生成的每个向量考虑所有的输入向量,通过加入自注意力模型来实现上考虑上下文信息的需求。

其自注意力机制的运作方式如下图。通过考虑每个输入向量来生成每个输出的向量。

2.具体原理
在实际计算中,需要得到当前输入向量与序列中其他某个输入向量的关联度$ \alpha $,也被称为注意力的分数。
计算相关程度方法主要由两种,分别是点积(Dot-produce)和Addtive,这里采用点积进行计算,同时这也是Transformer中采用的方法。

首先通过$ a^1 与与与 w^q 相乘得到相乘得到相乘得到 q ,其被称为查询。在由其他的,其被称为查询。在由其他的,其被称为查询。在由其他的 a^i 与与与 w^k 相乘得到相乘得到相乘得到 k^i ,然后将当前的q分别和其他向量的k进行相乘得到,然后将当前的q分别和其他向量的k进行相乘得到,然后将当前的q分别和其他向量的k进行相乘得到 \alpha_{1,i} ,即得到注意力的分数,在通过softmax激活函数进行激活得到,即得到注意力的分数,在通过softmax激活函数进行激活得到,即得到注意力的分数,在通过softmax激活函数进行激活得到 \alpha_{1,i}^{\prime} $。

最后通过$ a^i 与与与 w^v 相乘得到相乘得到相乘得到 v_i ,并将,并将,并将 \alpha_{1,i} 与对应的与对应的与对应的 v^i 相乘相加得到最终相乘相加得到最终相乘相加得到最终 a^1 的输出向量的输出向量的输出向量 b^1 。可以得到输出向量的公式。可以得到输出向量的公式。可以得到输出向量的公式 \boldsymbol{b}1=\sum_i\alpha_{1,i}{\prime}\boldsymbol{v}^i ,对于非,对于非,对于非 a^1 的其他输入向量也是可以通过这样的方法得到对应的输出向量的其他输入向量也是可以通过这样的方法得到对应的输出向量的其他输入向量也是可以通过这样的方法得到对应的输出向量 b^i $。

3.矩阵演示
在上面的计算中,可以得出要得到$ b^i $,需要计算$ q^i、k^i、v^i $,可以将其所有的$ a ^i $向量组成矩阵$ I $,然后乘上对应的$ W $矩阵得到$ Q、K、V $矩阵,其中存储就是对应的$ q^i、k^i、v^i $。
接下来就需要计算$ \alpha_{i,j} 注意力分数,通过将注意力分数,通过将注意力分数,通过将 K^T 与与与 Q 相乘得到矩阵相乘得到矩阵相乘得到矩阵 A ,在经过softmax激活函数得到最终的注意力分数矩阵,在经过softmax激活函数得到最终的注意力分数矩阵,在经过softmax激活函数得到最终的注意力分数矩阵 A^{\prime} $。

最后需要计算每个输入向量的对应输出向量,通过将注意力分数矩阵$ A^{\prime} 与矩阵与矩阵与矩阵 V 相乘得到最终的输出矩阵相乘得到最终的输出矩阵相乘得到最终的输出矩阵 O $。

将上面的计算步骤进行总结可以得到如下图的矩阵计算,由此可得自注意力其实就是一系列的矩阵计算。且在整个网络的计算过程中只有$ wq、wk、w^v $这三个参数需要进行调整。

4.3 多头自注意力
自注意力的进阶版本——**多头自注意力(multi-head self-attention)**。其应用在一些如翻译、语音识别的任务中,其允许模型同时关注不同的方面。例如下图,使用二头自注意力进行计算。其中需要多少头要根据具体任务来实际分析,但是无论多少头,最终每个头的计算过程和上面的自注意力计算过程相同。
其最终计算的输出矩阵如下图所示。

4.4 位置编码
在自注意力计算中可以观察到,我们的输入序列中每个向量只包含自己内部的信息,有些信息实际上被忽略了。例如在词性标注中,开头的单词实际上更容易是名词,更不容易是动词,因此可以得出,自注意力系统中并没有考虑位置信息。由此就要使用到**位置编码(positional enconding)**。如下图所示,在输入向量中额外加入一个包含位置信息的向量$ e^i $。
4.5 截断自注意力
** 截断自注意力(truncated self-attention)**可以处理向量序列长度过大的问题。 。在做自注意力的时候,也许没有必要让自注意力考虑一整个句子,只需要考虑一个小范围就好,这样就可以加快运算的速度。这就是截断自注意力。
4.6 自注意力与卷积神经网络对比
在处理图像时,也可以换一个角度来看,图像其实也是一个向量序列,既然是一个向量序列就可以使用自注意力来进行处理,如下图的思考角度,将图片的三个Channel来组成一个向量,最终整个图片来组成一个序列。
那么CNN和自注意力都可以处理图片,它们是什么关系呢? 在论文“Onthe Relationship between Self-attention and Convolutional Layers”,使用严谨的数学方法证明得出,**卷积神经网络就是自注意力的特例。 自注意力只要设定合适的参数,就可以做到跟卷积神经网络一模一样的事情。**如下图。

由此可以得出自注意力是更加灵活的卷积神经网络,而卷积神经网络是受限制的自注意力。因此在数据集较小的时候卷积神经网络效果更好,而当数据较多时自注意力的效果更好。

4.7 自注意力和循环神经网络对比
通过对比自注意力和RNN可以得出,其两者的功能应该是十分相似的。因为其输入和输出都是一个序列。但是相比于自注意力,循环神经网络中不能够进行并行运算,而且在考虑最远的两个向量之间的影响时,自注意力很容易就可以进行考虑,而循环神经网络就比较难。由此可以得出结论,自注意力明显优于循环神经网络,实际情况也是如此, 很多的应用已经把循环神经网络的架构逐渐改成自注意力的架构了。
5.Transformer
5.1 Transformer结构
一般的seq2seq模型都会分为编码器和解码器。编码器负责处理出入的序列,再把处理好的结果传给解码器,由解码器决定要输出的序列。而Transformer使用就是seq2seq模型。
对编码器和解码器进行功能差分就可以得到下图,其具体说明了Transformer的结构。

5.2 Transformer编码器
Transformer的编码器使用的自注意力,输入一组向量,同样输出一组同样个数的向量组。 如下图中,编码器中会分成许多的块,每个块都是输入一排相连,输出一排向量。通过块的叠加计算最终输出向量序列。
下面对编码器的核心部分进行解释,首先要介绍的就是残差连接(residual connection)的设计,在经过块中的自注意力之后需要将输出的向量$ a 加上原来的输入向量加上原来的输入向量加上原来的输入向量 b $,得到的向量再进行归一化,这就是residual。然后再进入全连接层,经过全连接层处理之后再进行残差连接和层归一化。以上就是编码器一个块的实现。

5.3 Transformer解码器
5.3.1 自回归解码器
1.词元和softmax
解码器中较为常用的就是自回归解码器 (autoregressive)。在进行解码器的运作中,例如在语音识别中,首先需要对常见的词汇进行softmax的one-hot编码的设置。然后再解码器中第一个输入要为一个特殊的**词元(token)**,其代表着解码器开始工作,且再识别任务解释时也需要一个特殊符号。
解码器最终工作实例如下图。除了第一个特殊的输入之外,其他后面的输出都是前一个的输出。

2.出错情况
由于后一个输入是前一个输出,这就有可能出现一种情况,就是前面的输出出错,将错误的向量给到下一个输入,这有可能导致一系列错误。具体情况如下图。解决方法会在后面的技巧部分进行提出。
3.掩码自注意力
初次之外,解码器还采用掩码自注意力(maskedself-attention ),其与原本的自注意力不同的是,掩码自注意力的输出不是考虑所有的输入向量,只考虑每个输入向量左边的向量作为当前的输出向量的考虑因素,如下图。
掩码自注意力具体的计算过程如下图。

5.3.2 非自回归解码器
非自回归解码器和回归解码器最大的区别就是解码器的输入情况,回归解码器的当前输出向量会作为下一个输入向量,而非自回归解码器是直接一次性得到输出,而不是像回归解码器逐步得到输出。
决定非自回归解码器的输出长度有两种方法:
- 使用另一个预测网络来预测输出长度
- 生成一个非常长的句子,然后通过找这个结束标识,自回归解码器也是使用这种方法来识别任务结束。
5.4 Transformer训练过程
对下面编码器-解码器结构可以得出,编码器的输出会作为解码器的输入。
其具体训练过程如下,当解码器通过掩码自注意力后,会生成$ \mathrm{q’} $,然后与编码器的输出进行自注意力的计算得到最终的输出,然后传给全连接层进行下一步计算。除此之外,可以发现若没有出现错误,解码器的输入其实就是最终的标注答案(Groud Truth)。

5.5 seq2seq训练技巧
1.复制技巧
在某些任务中,解码器没有必要识别所有的输入。例如,用户对机器说:“你好,我 是库洛洛”。机器应该回答:“库洛洛你好,很高兴认识你”。机器其实没有必要识别库洛洛这个词汇,而是只需要简单将其复制下来进行使用即可。 所以对摘要任务而言,从文章里面直接复制一些信息出来是一个很关 键的能力,最早有从输入复制东西的能力的模型叫做指针网络(pointernetwork),后来还有 一个变形叫做复制网络(copynetwork)。2. 引导注意力
seq2seq的模型中训练有时候会出现奇怪的结果。以语音合成为例,机器念4次的“发财”没问题,但是只念一次时就把“发”省略掉了。因此在训练的过程中可以加上一些限制,然后训练从左到右顺序执行,防止在学习过程中注意力颠三倒四的,因此需要使用**引导注意力**,例如下图中第一行使用引导注意力,而第二行中注意力颠三倒四无法生成正确结果。
3.束搜索
假设解码器只能生成两个字A和B,通过每次进行分数最高的输出作为选择叫做**贪心搜索(greedy search),**也叫**贪心解码(greedy decoding)**。但是这样选择有时候无法得到最优结果,此时可以选择**束搜索(beam search)**,其就是在某些情况下,选择分数低一点反而又肯获得更好的结果。束搜索的适用情况:当任务的答案十分明确时,束搜索会比较有帮助;但是需要机器发挥创造力时,束搜索的效果就很一般。

4.加入噪音
在做语音合成时,解码器加噪音,这种完全违背正常的机器学习的做法,在实际结果中返回会使结果更好,因此在语音合成和句子完成任务,解码器找出的结果不一定是最好,反而加入一些随机的结果会获得更好的结果。5. 计划采样
在测试的时候,解码器看到的是自己的输出,有时候会看到一些错误的东西,但是在训练的时候,解码器看到的是完全正确的,这种现象叫做**曝光偏差(exposure bias)**。有一种思考方向可以缓解这种问题,那就是在训练的时候给编码器一些错误的东西,不给其正确的答案,这反而会使他学习的更好,这一技巧叫做**计划采样(scheduled sampling)。**
6.生成式对抗网络
6.1 基本概念介绍
6.1.1 引入GAN
当需要生成的结果并不是一个固定值时,此时就要x和一个简单的分布输入值,通过生成器(Generator)来得到一个复杂的分布。此时的输出都是对的,这种神经网络就是对抗式神经网络GAN(Adversarial Neural Networks)。
这里举一个例子来简单说明GAN中的生成器(Generator)和判定器(****Discriminator)之间的工作原理。这里首先去掉输入x,并做一个输入向量来生成二次元头像的样例,如下图。

其中生成器用于使用输入值,来生产输出值即输出一个图片。而判定器用于判断由生成器生成的图片是否符合二次元头像这个设定,并进行判断,如下图。即通过进行图片评分来进行判定图片是否符合二次元头像要求。

6.1.2 对抗过程
那么整个对抗式神经网络如何来提升模型的准确度呢?这就要使用到对抗这个关键词,其实就是使用生成器和判定器来进行对抗。其实就是首先生成器进行图片生成,然后判定器对生成的图片和真实的图片进行判断,节后生成器更加前面的结果进行调整,然后判定器再进行调整,生成器和判定器之间不断进行调整、对抗、进化。
例如,第一步,先固定生成器并且更新判定器,使得判定器学会如何去判断那个是更好的二次元头像图片。

其第二步,就是固定判定器,更新生成器,使生成器学会如何使自己生成的图片再判定器中获得更好的评分,例如将两者合并起来作为一个大的神经网络,进行梯度下降,并且每次只更新生成器的部分,以此来使生成器进化,想办法“欺骗”生成器。

通过不断执行上面两个步骤来进行不断的“进化”,可以使得生成器和判定器都可以做的越来越好,这就是对抗式神经网络的思想。
6.2 GAN理论介绍
生成器的输入是一系列的从分布中采样出的向量,生成器就会产生一个比较复杂的分布。其产生称为$ P_{G} $,而使用原始数据产生的另一个分布$ P_{data} $,我们需要的就是这两个分布尽可能的相似。由此可以基于神经网络的训练过程得到一个最小化损失函数,对于一般的神经网络其损失函数可以计算,而对于生成器的差异,其为离散的数据,对于连续的差异例如KL散度和JS散度是很复杂的,在实际离散的数据中,我们或许无法计算其对应的积分 。

那么如何实现上面的目标呢?这是就要用到判定器,此时需要训练一个判定器,其目标就是看到真实数据给它较高的分数,看到生成的数据就给他较低的分数。其可以被看作是一个二分类的分类器,我们希望目标函数V的值越大越好, 其中y如果是从$ P_{data} $ 中采样得到的真实数据;如果是从$ P_{G} $采样得到的生成数据,它就要越小越好。
这个目标函数V其实就是交叉熵乘上一个负号。训练一个分类器的操作的就是要最小化交叉熵,所以当最大化目标函数V时就是在最小化交叉熵,也就是在训练一个分类器。

再来看下计算生成器+判别器的过程,目标是要找一个生成器去最小化两个分布$ P_{G} $ 和$ P_{data} $的差异。这个差异就是使用训练好的判别器来最大化它的目标函数值来实现。最小和最大的MinMax过程就像是生成器和判别器进行互动,互相“欺骗”的过程 。

6.3 WGAN
6.3.1 引入Wasserstein
需要进行MinMax操作,因此GAN是不好训练的。下面介绍**Wasserstein GAN(Wasserstein Generative Adversarial Network) **这个训练技巧。首先先分析下JS散度有什么问题。在某些情况下$ P_{G} $ 和$ P_{data} $的选点如果不够多,在分类器中进行分类会导致JS散度总是一个值,因此就会导致无法知道在训练过程中生成器和判断器是否在变好。
此时就用到Wasserstein,假设有两个分布P和Q,当需要得到两个分布之间的距离,就可以想象成推土机将土从P推到Q的平均距离。这个平均走的距离就是Wasserstein 距离。Wasserstein 距离可以想象为有一个 推土机在推土,所以Wasserstein 距离也称为推土机距离(Earth Mover’s Distance,EMD)。

而对于P、Q分布比较复杂时,就使用穷举法找到所有距离中平均距离最小的那个方法的距离来作为Wasserstein 距离。

6.3.2 Wasserstein优点
此时与前面的JS距离相比,使用Wasserstein来计算距离就可以清楚的知道当前情况下,更好的的得知两个分布之间的差异情况。从左到右,生成器的分布和实际数据的分布之间的距离越来越小,生成器也在慢慢变好。这也是使用Wasserstein距离的原因。
6.3.3 Wasserstein计算
在使用Wasserstein距离替换JS距离之后,其分类器的目标函数也变化$ \max_{D\in1-Lipschitz}\{E_{\chi\thicksim P_{data}}[D(x)]-E_{\chi\thicksim P_G}[D(x)]\} $,同样的对于生成器的产生期望希望越小越好,对于实际数据,判定器的输出值越大越好。除此之外,最重要的一点就是函数D必须要是一个1-Lipschitz的函数,其目的就是为了限制目标函数的值,为了不让其变大无限大或者无限小而从导致训练无法收敛。
对于1-Lipschitz的函数,有以下几种类型可以使用。其中Original WGAN只是让判定器的输出变得平滑,并没有实现1-Lipschitz限制。其他方法具体参考对于论文。

6.4 训练GAN的难点和技巧
在生成式对抗网络中,判定器的作用是为了区分真的图片和产生出来的图片的差异,生成器是为骗过判定器,从而生成类似真的图片。实际情况下,这两个部分是相互砥砺才能相互成长的,若一方出现问题就无法正常运行。这也是为什么GAN为什么这么难训练。
训练GAN最难的一个方向就是使用GAN来生成文字。其用Transform中解码器作为生成器。其难点在于,在调整解码器的参数时,只有一点变换不会导致生成器(解码器)输出有变化,此时判定器的输出分数就不会改变,从而导致最终根本无法进行微分,也就无法进行梯度下降。
在ScratchGAN这篇文章中,通过调节超参数,并加上一些训练技巧,就可以从零开始训练生成器。其技巧包括要用SeqGAN-Step的技 术、并且将训练批大小设置的很大(上千)、然后要用强化学习的方法并改一下强化学习的参数,同时加一些正则化等技巧。

6.5 GAN 的性能评估方法
6.5.1 质量与多样性
如何得到GAN生成的图片,例如动漫头像、猫、狗这些图片的效果好不好,其实可以通过一个分类器,其输入是图像,输出是一个概率分布。如果某个类别的比例比较高,那么就代表产生出来的图片质量好;如果概率分布比较平均就说明产生出来的图片质量不好。
在某些情况下,对产生的图片还需要对所有的产生的图片进行多样性的判断。当最终输出的概率分布越平均代表GAN的多样性越好。

6.5.2 两种情况
1.modecollapse
**模型崩塌(modecollapse)**,是指在训练过程中生成式的模型它输出来的图片来来去去就是那几张,可能单一张拿出来你觉得好像还做得不错,但让它多产生几张就露出马脚, 产生出来就只有那几张图片而已,这就是模式崩塌的问题。
2.modedropping
**模式丢失(modeldropping)**,在训练过程中生成式只生成少量简单、高频模式的图片,无法全面覆盖真实数据的多样特征。
上面个两种情况都可以可以通过判断生成图片多样性来进行判断。
6.5.3 Inception和FID
在过去常常使用Inception网络来进行评估,用Inception 网络度量质量和多样性。如果质量高并且多样性又大,那Inception 分数就会比较大。现在经常使用 叫FréchetInceptiondistance (FID) ,这里需要的是通过 InceptionNet之后的高维向量, 假设真实的图片和生成的图片都服从高斯分布,然后去计算这两个分布之间的Fréchet的距离。两个分布间的距离越小 越好,距离越小越代表这两组图片越接近,也就是产生出来的品质越高 。
当然服从高斯分布需要大量数据采样才能满足,且FID的计算也需要一定的计算量。

6.6 条件型生成
在之前介绍都是取出掉输入x的GAN,这里进行带有输入x的GAN,也就是条件型GAN。那么如何实现条件型GAN,这里需要满足几个条件。1. 首先需要给判定器也添加输入变量,以便于验证满足生成图片输入条件
2. 再者,需要给一定的真实数据参照,这里不仅要满足条件的正确图片,还要给不满足条件的正确图片以及满足条件的错误图片。

6.7 Cycle GAN
在之前使用几乎都是监督学习,即训练一个网络,输入是x,输出为y,都需要成对的数据才有办法训练网络,但是有时候并没有成对数据来提供给我们进行网络的训练。例如把真实的照转化为动漫头像。这是可以使用循环生成对抗网络(Cycle GAN),通过增加一个生成器来作为校验,来判断将真人图片转化成动漫头像之后,再转化回去时,是否与最初的输入一致。以此作为生成器额外需要考虑的条件,从而优化生成器完成对于人物。
对于Cycle GAN,重要的是知道通过增加生成器来进行输入一致性验证的思想即可。

7.自监督式学习
自监督学习(Self-Supervised Learning,SSL)是一种无标注的学习方式。- 自监督学习:在模型巡训练期间没有使用标注的数据。
- 监督学习;在模型训练期间使用标注的数据。

7.1 BERT
BERT 模型是自监督学习的经典模型,BERT是一个Transformer 的编码器,BERT的架构与Transformer 的编码器完全相同,里面有很多自注意力和残差连接、归 一化等等. BERT可以输入一行向量,输出另一行向量.输出的长度与输入的长度相同。
7.2 BERT最初使用
1.掩码输入
通过给自己的输入进行掩码,进而训练模型的“填空能力”,即让BERT做填空题。具体实现掩码的方式有两种- 添加一个名为“MASK”的特殊词元
- 用另一个词替换某个词

2. 下一句预测
通过设置特殊词元[CLS]开头、[SEP]间隔,通过训练BERT来实现下一句预测。 所以BERT可以做这件事. 我们只取与[CLS]对应的输出,忽略其他输出,并将[CLS] 的输出乘以线性变换. 现在它做一个二元分类问题,它有两个可能的输出:是或否. 这种方法 是下一句预测,即需要预测第二句是否是第一句的后一句(这两个句子是不是相接的)。但在研究发现中,下一句预测实际对任务没有真正的帮助。句序预测(SentenceOrderPrediction,SOP),其在文献上似乎更有用. 这种方法的主要思想是最初选择的两个句子本来就是连接在一起,可能有两种可能:要么句子1连接在句子2后面,要么句子2连接在句子1后面,有两种可能性,BERT 要回答是哪一种可能性.

7.3 BERT的应用
给BERT一些有标注的数据,其就可以实现各种任务,将BERT分化并用于的各种任务称为**微调(fine-tuning)**。在微调之前BERT的过程叫预训练。因此产生BERET的过程就是自监督学习,也成称预训练。对BERT进行微调之后就可以解决更多的问题。
下面举几个BERT应用例子
1. 情感分析
其实就是对输入句子进行悲观和乐观类型的判断,其BERT内部参数还是用的之前填空时的参数,只是在线性变换使用随机参数。其输入是序列,输出为一个类别。

2. 词性标注
其应用就是给一个句子,通过BERT来判断每个词元的词性。其内容和上面情感分析类似,唯一不同的是BERT 部分,网络的编码器部分,其参数不是随机初始化的,它已经在预训练过程中找到了一组比较好的初始化的参数。
其输入是一个序列,输出也为一个序列。

3. 自然语言推理
其应用就是给定两个句子,判断两个句子之间的关系。其输入是两个序列,输出也为一个类别。

通过将两个句子使用[SEP]特殊词元进行分割输入,[CLS]特殊词元作为起始输入。最终通过[CLS]词元进行线性变换得到最终结果。该应用需要一些标注的数据来训练这个模型,BERT 的这部分不再是随机初始化的,需要使用预训练 的权重进行初始化

4. 基于提取的问答
其应用就是给机器一篇文章,问它一个问题(答案在文章中),然后它回答这个问题的答案。这是**基于提取的问答(extraction-based question answering)**。其输入的问题和文章都是一个序列,$ D={d_1,d_2,\cdots,d_N} \
Q={q_1,q_2,\cdots,q_M} $。
其具体工作原理就是通过初始两个向量(一个起始位置,一个结束位置),通过两次经过BERT计算,在通过softmax转化找到最高概率的位置从而得到最终的初始和结束位置,最终给出问题的答案。
其中起始和结束向量是随机初始化的,而BERT是由其预训练的权重初始化的。

7.4 BERT有用的原因
最常见的解释,当输入一串文字时,每个文字都有一个对应的向量,这个向量称为嵌入。
而对于意思相近的字,他们之间的向量就越接近。例如下面的果和草、鱼和鸟。

对于某些字会有歧义,此时可以计算余弦相似度,从而得到不同语境下不同句子中相同字意思相近的句子。

经过余弦相似度计算之后可以得到不同语境下句子的中相同字的意思相似程度。

7.5 BERT的变种
BERT 还有很多其他的变种,比如**多语言BERT(multi-lingual BERT)**。在谷歌发布的多语言BERT使用104种不同的语言进行训练,所以它可以做104种语言的填空题。
多语言BERT有一个非常神奇的功能,如果用英文问答数据训练它,它会自动学习如何做中文问答。

8.自编码器
8.1 自编码器概念
**自编码器(auto-encoder)**的原理,以图象为例。在自编码器中有两个网络,分别是编码器和解码器。编码器输入一个图像输出一个向量,并将这个向量给到解码器,最后解码器输出一个图片。这里的解码器网络和GAN的生成器类似。最终的训练目的就是让解码器的输出和编码器的输入越接近越好。这个过程也叫重构(reconstruction)。可以得到这里的自编码器的工作和之前的cycle GAN十分相似。
对于编码器输出的向量,可以叫做嵌入(embedding)、表征(representation)或者编码(code)。
那么如果将自编码器运用到下游的任务中呢?通常就是将图片换成一个更长的向量作为输入,但是向量太过于长也不合适,于是就需要编码器将向量的维度降低,然后再拿着这个低纬度的向量来完成后面的任务。可以得到编码器的任务就是进行输入向量的降维,生成低纬度的向量。

8.2 为什么需要自编码器?
为什么需要自编码器?当使用将一张高维的图片转化成一个低维的向量,再使用这个向量还原出原来的高维图片,到底了带来什么样的帮助?设想一下,自编码器这件事情它要做的,是把一张图片压缩又还原回来,但是还原这件事情为什么能成功呢?其本质原因就是图片的变化是有限,并不是每个随机的噪音采样出来的举证都是不同的,例如下面3x3的矩阵
实际情况下最多有四种情况,此时就可以将3x3的矩阵转化成二维的向量,从而实现降维。
由此可以的得出,编码器的工作就是化繁为简进行数据降维,总结出输入数据中的有限变化。因此在下游的任务就可以使用较少的数据,让机器进行学习。

8.3 去噪自编码器
自编码器最常见的一个变体就是**去噪自编码器(denoising auto-encoder)**,其实就是将原来的输入改成增加噪音之后再进行输入。可以直到这样就增加了一个新的任务,就是自编码器需要学会去除噪音干扰。
这里操作其实和BERT中的掩码输入目的一样,都是为了让机器学会去除噪音干扰。

8.4 特征解耦(应用)
自编码器可以应用再**特征解耦(feature disentanglement)**。解耦就是指将原本纠缠在一起的东西分开。为什么需要特征解耦呢?再编码器总结输出的向量中包含输入的所有特征信息。例如图像输入的对象和纹理、音频输入的内容和讲述着、文本输入的语法和语义。
一个重要的应用就是如果可以将这个向量中的不同特征信息分开处理,就可以重构出来我们想要的信息。例如进行语音转换。例如将音频输入经过编码器之后得到的向量中可以划分出内容和讲述者这两个特征信息。此时就可以通过更换某个向量的讲述者信息来达到“换声器”的功能。

8.5 离散隐表征 (应用)
在前面都假设编码器生成的都是向量,是一串实数。其实还可以是其他的,例如是二进制,这样就可以表示某个特征的有无,例如是否为女性、是否戴眼镜。或者向量使用独热编码进行分类的任务,例如进行手写数字识别任务。
在离散的表征技术中,最知名就是向量量化变分自编码器 (vectorquantized variational autoencoder)。其工作原理就是输入一张图片,然后编码器输出一个向量,接着有一个码本,输出的向量会与码本中每个向量计算相似度,接着选中相似度最高的一个作为解码器的输入。其中码本中的向量也是通过逐渐学习出来得到的。这样做的好处就是可以使得解码器的输入是有限的,其必定是码本的某一个向量。
** **
若是最初的输入是语音的话,通过学习之后,码本肯能可以学习到某些发音的音标。
进一步设想,其实表征的表示形式可以可以不是向量,例如是一段文字。现在假如要做文字的自编码器,其中输入是一段文档,编码器的输出是一段文字序列,其解码器的输入和输出都是文字序列,此时编码器和解码器的seq2seq的模型,例如Transform。 这时候表征就是一段文字序列而不是向量,并且这个文字序列代表文档的关键内容,也就是摘要。

如果我们需要的到这个摘要,但是之后获取上面生成文字序列可能会有问题,因为编码器和解码器之后可能会生成一些密文只有它们可以看懂,此时添加一个判定器,判定器是通过人类写出的摘要训练出来的,并用判定器来判定这个生成的文字序列,此时就可以使这段“摘要”可读。
其实这一段的设计就是和Cycle GAN的思路一致的。

8.6 其他应用
上面说明的都是编码器的应用,这里简要介绍一些解码器的应用。对于解码器,例如前面图片的例子,在自编码器中的解码器其实可以直接当作图片生成器来使用。
初次之外,解码器还可以进行压缩。在自编码器中,原图片经过编码器之后会得到一个低纬度的向量,这个向量相对于原图片要小得多,这个过程相当于压缩,而通过解码器还原原图片时,就可以视为解压缩的过程。需要注意的是在还原图片时无法完全还原出原图片,即该压缩过程是失真的。

9.机器学习的可解释性
9.1 可解释性人工智能的重要性
对于**可解释人工智能(explainable Aritificial Intelligence, XAI)**,举个例子来说明,比如一个图像识别模型,给模型一张照片它会给你对于的类别。对于XAI,不仅需要这个图片的类别,还要模型给出答案的原因。为了了解人工智能的可解释性其实就是为了期待在未来可以直到深度学习模型犯错时,可以有更好的方法来改进模型、提升模型。
9.2 可解释机器学习的目的
多数人认为一个好的可解释性就是告诉人们模型在做什么事情,但是实际情况却不是这样。在解释性机器学习中,好的解释就是人们接受的解释,人就是需要一个理由让我们决定高兴。9.3 局部解释性
可解释性机器学习分为两大类,局部的解释和全局的解释。如下例,对于一张猫的图片,局部的可解释性是是要说明为什么机器决定这是一只猫,要提取出图片中猫的特征;而对于全局的可解释性来说,要给出猫长什么样子,在没有前提数据的情况下,直接问分类器什么样的图片叫做猫。
9.3.1 重要部分判断
首先,对于局部解释性。需要直到模型为什么决定这是一只猫,哪些重要的部分让模型做出这个判断的。一个方法就是**计算梯度**,在计算梯度的时候每个地方加上一个$ \Delta x $,梯度变化越大的像素点就代表这个点越重要。实际上这个重要的值计算是通过计算损失关于$ x_N $的偏导,也就是$ \frac{\partial e}{\partial x} $,然后得到一个显著图,其中越白亮的点就代表这个点越重要。
当然直接通过计算梯度也可能会出现问题,在下面的例子中,模型没有真正的判断马的特征,而是投机取巧直接使用图片中的英文介绍。

为了使显著图画的更好,可以使用SmoothGrad的方法。在下面直接生成的显著图看着不太合适,此时可以使用SommthGrad,其实就是在图片上面加上各种不同的噪音,然后得到不同的显著图,最终将所有显著图加起来平局就可以得到SmoothGrad的结果。例如,给一张图片加100中噪音,得到100张显著图,然后平均起来就可以得到SmoothGrad显著图。

当然梯度也不是万能的,在鼻子长度相关是否大象的判断中,当鼻子长度达到一定长度时,是否是大象的相关性就只有很小的变化,此时梯度为0就无法使用梯度来判断鼻子长度的重要性了。

9.3.2 处理过程
判断完输入部分的重要部分后,还要对一个问题进行讨论。就是给网络一个输入之后,它到底是如何处理这个输入,并得到最终的答案的。其中最简单的一个方法就是使用人眼观察,看这个网络到底怎么处理这个输入的。例如在一个语音例子中,可以通过PCA或者t-SNE方法将100维降为2维,然后通过画图进行可视化。
还有方法就是探针(probing),其实简单来理解就是用探针插入到网络中,看看会发生什么事情。可以使用BERT的词嵌入输入来训练一个POS分类器(词性标注分类器),根据这些嵌入,分类器可以决定现在BERT的嵌入是属于那个一词性的词汇。如果POS分类器的正确率高,就代表这个嵌入中有很多词性的信息;如果正确率第,就代表这个嵌入中没有词性的信息。通过对这个词性信息的推断就可以直到BERT在这一层干了什么。

当然需要注意的一点是,在得到POS正确率时,不能直接下结论,有一种情况也可能是POS分类器train的不好,需要对这一点有考虑。
9.4 全局解释性
全局解释性并不是针对一张照片来分析,而是把训练好的模型拿出来,根据这个模型里面的参数检查它的特性,通过这些特型解释模型的行为。假设有一张X输入到卷积神经网络中,会看到滤波器1的特征图中,很多位置都有较大的值,这意味着图像X中有很多滤波器1复杂检查的那些特征。现在要做全局解释,也就是要看滤波器1的模式、特征到底长什么样子。具体做法就是创造一张照片,对于滤波器1中每个值$ a_{ij} 因该越大越好。因此需要找一个因该越大越好。因此需要找一个因该越大越好。因此需要找一个 X^* ,使用梯度上升法求最大的,使用梯度上升法求最大的,使用梯度上升法求最大的 X^* ,当找到这个,当找到这个,当找到这个 X^* $后,观察其有什么样的特征,其在提取什么样的模式。

举个例子,在MNIST手写数字识别的例子中,在滤波器2想要挖掘的模式,左图中画了12个滤波器。但是着12张图片人都无法分辨出来,只有训练模型可以识别出对于的信息。

若是想要得到想要对应图片看起来相关数字,则需要改变$ X^* 的式子,让其加上的式子,让其加上的式子,让其加上 R(x) $,则可以得到右图,可以看到其有利数字的形状。

若希望使用全局解释性看到非常清楚的图片的话,一个方法就是训练图像生成器,将图像生成器和图像分类器连接在一起,现在并不是希望找到一个$ X^* ,使得对应到,使得对应到,使得对应到 y 中某个类别其分数越大越好,现在是希望找到一个中某个类别其分数越大越好,现在是希望找到一个中某个类别其分数越大越好,现在是希望找到一个 z^* ,使得对应到,使得对应到,使得对应到 y 中某个类别其分数越大越好。再将这个中某个类别其分数越大越好。再将这个中某个类别其分数越大越好。再将这个 z^* $放入图像生成器中,看看产生出来的图片是怎么样的。

9.5 拓展与小结
可解释性机器学习还可以有其他应用,比如说可以用一些可解释性的模型来替代黑盒模型,比如说我们可以用线性模型来替代神经网络模型。
局部解释主要是通过对一个特定的样本,去找到一个和这个样本最相关的特征,把这些特征拿出来,去解释这个样本的分类结果。全局解释主要是通过对于一个模型,去找到一些和这个模型最相关的特征,把这些特征拿出来,去解释这个模型的行为。
10.对抗攻击
10.1 对抗攻击简介
在网络模型工作的过程中,不仅要提高模型的正确率,还需要检测一些恶意的行为。可以看下面这个恶意的例子,通过对原图片加入部分噪音来达到使模型分类失败的结果,这就是恶意攻击行为。
10.2 如何进行攻击
对于攻击的种类可以分为无目的攻击和有目的攻击,无目的攻击就是让最终结果输出不是期望的结果即可,有目的攻击就是让最终输出的结果是另外一种指定的结果。例如在图片识别的网络中,需要输入一张图片,使得这张图片输出的种类和人眼实际观察的种类不相同。设计攻击模型之前,先假设原工作的网络模型参数固定,此时攻击的模型需要生成一个尽量和实际正确结果越远越好的图片,因此其损失函数为$ L \left( x \right)=-e \left( y, \widehat y \right) ,当然若攻击为有目的的攻击则还要加上,当然若攻击为有目的的攻击则还要加上,当然若攻击为有目的的攻击则还要加上 e \left( y,y^{target} \right) 好让生成的结果和期望的目标结果越相近越好,最后一点的限制就是让攻击的图片要和原图片相似,且两者的差异不能够被人眼识别出来,若识别出来就达不到攻击的目的,其要求就是好让生成的结果和期望的目标结果越相近越好,最后一点的限制就是让攻击的图片要和原图片相似,且两者的差异不能够被人眼识别出来,若识别出来就达不到攻击的目的,其要求就是好让生成的结果和期望的目标结果越相近越好,最后一点的限制就是让攻击的图片要和原图片相似,且两者的差异不能够被人眼识别出来,若识别出来就达不到攻击的目的,其要求就是 d \left( x^{0},x \right) \leq \epsilon ,让生成出来的攻击图片,让生成出来的攻击图片,让生成出来的攻击图片 x 和工作模型生成出来的图片和工作模型生成出来的图片和工作模型生成出来的图片 x_0 $差异足够小。

对于这个$ d \left( x^{0},x \right) $的计算有两种方法,分别是L2范式和L-无穷范式。在下面四个像素中的例子中,分别给出两个方案,每个像素改变一点(上面的)和很大程度改变一个像素(下面的)。这两个方案的L2范式距离相同,但是下面的L-无穷范式距离更大也更明显被看出来,明显使用L-无穷范式的距离更好,需要让这个距离越小越好。

需要注意的是使用L-无穷计算损失函数大小进行梯度下降时,$ x^0 (真实值)与(真实值)与(真实值)与 x^t (生成值)之间的距离必须要小于(生成值)之间的距离必须要小于(生成值)之间的距离必须要小于 \epsilon ,因此在每次进行梯度下降更新完参数后,如果,因此在每次进行梯度下降更新完参数后,如果,因此在每次进行梯度下降更新完参数后,如果 x^t $超出范围需要将其fix回到距离固定值范围最近的点。

10.3 快速梯度符号法
下面介绍一种简单的攻击方法,**快速梯度符号法(Fast Gradient Sign Method,FGSM)**。在平常更新梯度时需要跟新多次,但是FGSM法只更新一次梯度即可。其设计思路是,对梯度g的每个取值做符号函数,使得最终梯度向量每个取值要不是1要不是-1。因此更新一次的$ x^t $一定会移动到$ x^0 $对于范围的四个角落。
10.4 白盒攻击与黑盒攻击
上面介绍的都是白盒攻击,即已知模型参数、模型输入输出、模型损失函数、模型梯度等,根据模型参数训练攻击模型来生成攻击数据,且白盒攻击的效果一般都是比较明显的。而根据一些方法退出来模型参数,然后进行攻击的方法叫做黑盒攻击。下面例子说明在没有模型数据情况下如何进行攻击,首先使用一些输入给到要攻击的模型中得到输出,根据这些输入输出对来训练出一个代理网络模型,最后train一个网络来攻击这个代理模型,使用这个网络就是我们需要用来攻击原模型的。

且黑盒攻击相对来说也是比较容易的,下面五个模型ResNet-152、ResNet-101、ResNet-50、VGG-16 和 GoogLeNet,通过训练对一个模型的攻击网络来测试,可以得到对其他模型的攻击效果也是不错,其正确率都低于40%。

想要黑盒模型的攻击效果更好,可以使用集成学习的方法,也就是对多个网络进行攻击,可以得到其攻击效果比上面的效果要更好。

为什么黑盒模型的攻击效果比较好,可以从下面的实验中得出。在识别小丑鱼的几个模型中,图片中蓝色的部分代表可以被识别成小丑鱼,而其他部分都是攻击成功的。因此可以的都对于每个网络,攻击的方向对于每一个网络的影响都是类似的,因此黑盒模型的攻击效果比较好。

10.5 被动防御
在上面介绍的都是对网络模型的攻击,而针对这些攻击也有一定的应对策略,即防御。防御分为被动防御和主动防御。被动防御就是放着训练好的模型不同,但是在给网络真正输入是加一层“盾牌”,例如将原始图片放入滤波器中进行平滑处理。这样攻击网络在进行攻击的时候,就可能无法正确的攻击到我们的网络。

但是这样的防御也有弊端,若是网络中被动防御策略被攻击者直到,这样的防御也就没用了。其次,对原模型加上滤波器进行平滑处理后,可能会降低原来模型正确预测的“信心”。

当然也有其他被动防御策略使用,例如可以将图片先进行压缩处理后在输入给原网络或者使用生成器生成一个和原输入相似的图片再输入给到原网络中进行处理。

最后一种方法被称为随机化防御。可以随机的将原图片输入进行放大、缩小,或者将其放到一张灰色背景的随机位置上,将随机得到的图片再输入到原网络当中即可。

10.6 主动防御
主动防御的思路就是在一开始就训练一个不会被攻破的鲁棒性强的模型。这种训练方式叫做对抗训练,其具体思路就是在开始训练模型的时候不仅使用原始数据还加入一些对抗数据来加强模型。这样就可以降低模型被攻破的几率。但是这样的方法也有一个致命的弱点,就是如果有新的攻击方法,其就可能很快就败下阵来。

11.迁移学习
实际情况中,将一个任务A学习到的某些泛化只是迁移到B任务,其中A、B任务相关,且任务A有很多巡礼那数据,这时候可以使用**迁移学习(transfer learning)**。这里主要介绍**领域自适应(domain adaptation)**和**领域泛化(domain generalization)**。11.1 领域偏移
在进行MNIST数字识别模型训练后,将模型迁移到MNIST-M数据集(彩色数字)中,测试数据的准确率就会比较低。在训练数据上训练的模型,用到测试数据上展示的效果不好,这种情况就叫做领域偏移(domain shift)。当然领域偏移并不只是测试时,使用的数据输入分布变换,还有可能是输入和输出的分布是相同的,但是输入输出之间的关系变了,例如在训练数据中标签为‘0’,但是在测试数据中标签为‘1’。

其中,把训练数据叫做源领域(source domain),测试数据叫做目标领域(target domain)。

11.2 领域自适应
接着以上面的数字识别模型作为例子,在实际情况中通常是测试数据有一定的数据但是没有对于的标签,这时候使用领域自适应来处理。
初步设想是通过一个特征提取器来提取源领域数据和目标领域数据中相同的特征分布,从而过滤掉颜色特征指标数字特征。

对于一个分类器,将其分为特征提取器和标签预测器,分类器的前几层是特征提取器,后几层是标签预测器这也是个超参数。其中特征提取器的输出是一个向量,包含着数据的数字特征。对于特征提取的目的就是为了让源领域和目标领域的数字特征尽量的相似。

但是目标领域中数据没有标签,如何让特征提取器尽量让两个领域的数据尽可能的相似,这里使用一个领域分类器,用来判断数据是属于源领域还是目标领域,而特征提取器要‘骗’过这个领域分类器。从这里可以看出,这样的思路和GAN十分相似,其中特征提取器是生成器,而领域分类器是判定器。
可以得到特征提取器有两个任务要实现,一是要尽量使得两个领域的数据尽可能的相似;二是尽量‘骗’过领域分类器。

尽量使得两个领域的数据尽可能的相似,可以用蓝色的圆圈和三角形表示源领域上的两个类别,用正方形来表示目标领域上无类别标签的数据。可以找一个边界去把源领域上的两个类别分开。训练的目标是要让正方形的分布跟圆圈、三角形合起来的分布越接近越好。

让正方形远离边界(boundary)的最简单的方法就是把很多无标注的图片先丢到特征提取器,在经过标签预测器。如果输出的结果集中打某个类别上,就是离边界远;如果输出的记过每个类别十分接近,就是离边界近。初次之外,还可以使用DIRT-T、最大分类器差异等方法。

11.3 领域泛化
最后一种情况就是对目标领域一无所知,此时要将源领域适应到一个特定领域的问题叫做领域泛化。
领域泛化也分为两种情况,一种情况就是训练数据非常丰富,包含不同领域,测试数据只有一种领域;另一种情况就是训练数据只有一个领域,但是测试数据有多种不同领域,对于这种情况可以数据增强的方法产生多个领域的数据。

12.强化学习
**强化学习(Reinforcement Learning,RL)** 是一个可以实现通用人工智能的方法,在之前的监督学习中,都有对于的标签,即在输出有对照。例如在下面的分类器中可以的最终的输出与人类标签猫相对应。
机器跟环境(environment)互动得到奖励(reward),所以其会知道其输出的好坏,其中智能体(agent)会跟环境互动。环境会给智能体一个观测(observation),智能体看到这个观测后,它会采取一个动作。该动作会影响环境并同时给出奖励,环境会给出新的观测,智能体会给出新的动作。

12.1 强化学习例子
强化学习可以用来玩游戏,强化学习最早的几篇论文都是让机器玩《太空侵略者》。智能体会去操控摇杆,控制母舰来和 外星人对抗。 其中动作是左移、右移或者开火,奖励是消灭外星人的分数,环境就是每个动作结束后当前的游戏画面。
例如,智能体观察环境,然后做出右移动作,最后得到奖励0分。

又比如智能体观察环境,然后做出开火动作,最后得到奖励5分。

12.2 强化学习框架
强化学习与机器学习的框架相似,机器学习又定义函数、定义损失函数、优化,这三个步骤,强化学习也是类似的三个步骤。12.2.1 未知函数
第一步是找到未知函数。在强化学习中,有未知数的函数是智能体,智能体是一个网络,通常称为策略网络(policy network)。是一个很复杂的函数,输入是游戏画面上的像素,输出是一个可以采取动作的分数。字在下面这个网络中,网络输出的是每动作的分数,如左移是0.7分、右移是0.2分、开火是0.1分,在这个
似于分类网络中,最后的输出将会通过softmax,使得分数总数为1。通常情况下,把这个分数当作每个动作执行
概率,然后随机执行,那为什么不直接采用分数最大的动作执行呢?其原因是游戏的随机性也是非常重要的一个部分。

12.2.2 定义损失
第二步就是定义损失,从最初的观察开始,智能体得到环境输入并做出动作得到奖励,然后得到环境观察$ S_{2} $作为下轮的输入,以此类推直到游戏结束(消灭完所有怪物或者自己被消灭)。 从游戏开始到 结束的整个过程称为一个**回合(episode)**,所有奖励的总和被称为**回报(return)**。其中我们希望得到的回报值越大越好,此时,就可以采用回报的负值作为损失值。
12.2.3 优化
下图给出了环境和智能体互动的过程, 其中把状态和动作全部组合起来得到的一个序列称为轨迹(trajectory) τ 。
对于得到所有奖励的回报,其输入是s和a的修炼,输出是对应的r,即奖励的总和是回报$ R(\tau)=\sum_{t=1}^Tr_t $。我们需要回最大化,因此优化问题就变成:学习网络的参数让回报越大越好。但是有两个问题:一是智能体的输出是与随机性的;而是环境和奖励也是有随机性的。
如何找到一组网络参数来最大化回报,其方法和GAN类似,将环境和奖励作为判定器,智能体作为生成器,其中生成器要’骗过’判定器,让其输出越大越好。与传统GAN不同的一点,这里的判定器是环境和奖励,其并不是一个网络。生成器我们是一个网络,我们可以使用梯度下降来进行训练。

下面是让智能体看到一个场景做出对应的动作,可以将其看作是一个分类问题。计算智能体的输出跟标准答案之间的交叉熵e,学习θ 让损失(交叉熵)最小,让智能体的输出跟标准答案越接近越好。
当看到场景想要采用某个动作,其损失为e;当不想采用某个动作,其损失为−e。 最终得到损失值为 $ L=+e_{1}-e_{2}+e_{3}\cdots-e_{\mathrm{N}} ,需要优化的参数值为,需要优化的参数值为,需要优化的参数值为 \boldsymbol{\theta}^=\underset{\theta}{\operatorname{\operatorname*{arg\min}}}L $。

考虑到每个动作的差异,每个环境-动作对对应一个分数,当环境对应的东西希望做其对应分数$ A_i 就比较大,反之就比较小。由此可以重新定义损失函数,即就比较大,反之就比较小。由此可以重新定义损失函数,即就比较大,反之就比较小。由此可以重新定义损失函数,即 L=\sum\mathrm{A}_ne_n $。

12.3 评价动作的标准
下面介绍对A的定义,即对动作的评判标准。1.即时奖励
第一种方法也是最容易想到的方法,就是使用即时奖励作为对应分数A。当智能体收到环境$ s_1 $数据,执行$ a_1 $动作后,得到奖励$ r_1 $就被当作$ A_1 $的值了。这种方法往往比较短视,不是一个好的方法。
2.累计奖励
第二种方法是使用未来所有的奖励加起来即可得到累积奖励G,用其来评估一个动作的好坏,表达式为$ G_{t}=\sum_{i=t}^{N}r_{i} $,其中$ G_{t} $是从时间t开始,$ r_{t} $一直加到$ r_{N} $。$ \begin{split} G_{1}&=r_{1}+r_{2}+r_{3}+\ldots \ldots+r_{N}\\ G_{2}&=r_{2}+r_{3}+\ldots\ldots+r_{N}\\ G_{3}&=r_{3}+\ldots\ldots+r_{N}\end{split} $。
3.折扣累计奖励
使用第二种方法没有考虑到一点就是,当不断向后执行动作,后面的奖励对前面的奖励的影响将会逐渐减弱。因此,可以在$ G_{t}^{'} $前面乘上一个折扣因子$ \gamma $,其值通常会设置小于1。得到表达式为$ G_{t}^{\prime}=\sum_{i=t}^{N}\gamma^{i-t}r_{i} $。举个例子,$ G_{1}^{\prime}=r_{1}+\gamma r_{2}+\gamma^{2}r_{3}+\ldots\ldots $。
4.折扣累计奖励减去基线
最后,我们需要做一下标准化,最简单的方法就是$ G^{'} $后面减去一个基线(baseline),可以让$ G^{'} $有正有负。
5.策略梯度
以下为执行Actor连过程种的梯度下降算法,即策略梯度。
需要注意的是,这里强化学习每次更新完一次参数后,都需要重新收集数据,然后才能更新参数。这里介绍 同策略学习(on-policy learning)和异策略学习(off-policy learning),对应同策略学习指训练的智能体和环境的智能体是同一个智能体。而在异策略学习中训练的智能体和环境的智能体是并不是同一个智能体。
这里使用异策略学习可以解决不断要重新收集数据的问题。
**探索(exploration)**是强化学习训练的过程中一个非常重要的技巧。这里主要指智能体的随机性,这非常重要,如果没有随机性的化智能体可能无法训练出来。在实际训练中,为了让智能体的随机性大一些,甚至在训练时会刻意加大它的随机性。
12.4 评价Actor
12.4.1 Actor-Critic
与环境互动的网络称为智能体(Actor),而评价一个智能体好坏的网络称为价值网络(Critic)。Critic 也被称为价值函数(value funciton),可以用 $ V_{\pi_\theta}(s) $ 来表示。对于如何训练一个评价网络有两种方法: 用蒙特卡洛(MonteCarlo,MC) 和 时序差分(TemporalDifferent,TD)。对于蒙特拉洛法类似于监督学习,输入$ s_a 给价值函数给价值函数给价值函数 V^{\theta}(s) ,其输出的,其输出的,其输出的 V^{\theta}(s_a) 要和要和要和 G_{a}^{\prime} 越接近越好;输入越接近越好;输入越接近越好;输入 s_b 给价值函数给价值函数给价值函数 V^{\theta}(s) ,其输出的,其输出的,其输出的 V^{\theta}(s_b) 要和要和要和 G_{b}^{\prime} $越接近越好。需要注意的是,这种方法需要玩完一整局游戏。

但是实际情况中可能有些游戏根本没有结局,或者我们想要不玩完一局游戏就训练出Critic。可以使用时序差分法。两队输入输出计算出对于的$ V^{\theta}(s_i) ,使用完累计折扣后,将两者相减,使用完累计折扣后,将两者相减,使用完累计折扣后,将两者相减 V^\theta(s_{t})-\gamma V^{\theta}(s_{t+1}) ,使其和实际值,使其和实际值,使其和实际值 r_t $越接近越好。

下面对比两种方法,在相同的数据下,使用MC和TD得到的$ V^{\theta}(s) 是不相同的。对蒙特卡洛,它就是直接看我们观察到的数据,是不相同的。 对蒙特卡洛,它就是直接看我们观察到的数据,是不相同的。对蒙特卡洛,它就是直接看我们观察到的数据, s_a 之后接之后接之后接 s_b 得到的,累积奖励就是0。而对于时序差分,得到的,累积奖励就是0。而对于时序差分,得到的,累积奖励就是0。而对于时序差分, s_b 会得到多少奖励跟会得到多少奖励跟会得到多少奖励跟 s_a 是没有关系的,所以是没有关系的,所以是没有关系的,所以 s_a 的累积奖励应该是的累积奖励应该是的累积奖励应该是 \frac{3}{4} $。

12.4.2 使用Cirtic训练Actor
学习出Critic $ V_{\pi_\theta}(s) $后,给定一个状态$ s $,其可以产生分数$ V_{\pi_\theta}(s) $ ,基线 $ b $可设成$ V_{\pi_\theta}(s) $ , 因此A可设成$ G^{\prime}-V_{\pi_{\boldsymbol{\theta}}}(s) $。而由于智能体的随机性,有很多动作可能被执行,这里对这个动作的结果平均下来就得到$ V_{\pi_\theta}(s_t) $,$ G^{\prime}_t $表示的是,在$ s_t $这个环境下,执行动作$ a_t $后,得到的累计奖励。最后得到$ A_t $,如果$ G^{\prime}_t > V_{\pi_\theta}(s_t) $,$ A_t > 0 $,代表这个动作$ a_t $要比随机动作的效果好;若$ G^{\prime}_t < V_{\pi_\theta}(s_t) $,$ A_t < 0 $,代表这个动作$ a_t $效果并不好。
最后一个优化,讲动作$ a_t 的奖励期望也使用随机动作的平均值代替,其值为的奖励期望也使用随机动作的平均值代替,其值为的奖励期望也使用随机动作的平均值代替,其值为 r_t+V^\theta(s_{t+1}) ,即将,即将,即将 G^{\prime}t 替换成替换成替换成 r_t+V^\theta(s{t+1}) ,最终得到的,最终得到的,最终得到的 A_t = r_t+V^\theta(s_{t+1}) - V^\theta(s_{t}) $。这个方法就叫做优势Actor-Critic(advantage Actor-Critic)。

最后给出一个训练 Actor-Critic的技巧,由于最初的输入都是图片,使用CNN。Actor网络和Actor-Critic网络的前面几层是可以共用的。

13.神经网络压缩
**网络压缩(network cimpression)**是对大的网络模型进行简化缩小,例如减少参数,但是保证模型的使用效率并不减少很多。下面介绍五个网络压缩的技术;
- 网络剪枝
- 知识蒸馏
- 参数量化
- 网络架构设计
- 动态计算
13.1 网络剪枝
**网络剪枝(network prunning)**就是把网络中的一些不起作用的参数剪掉,从而达到简化网络的效果。其进行剪枝的过程如下,首先将预训练的大网络进行参数重要性评估,去掉不重要的参数,进行网络微调,如果网络足够小就结束过程,如果还不够小就接着评估这个新的网络,然后继续去除不重要的参数,继续微调和判断网络是否足够小,重复上面的过程即可。
对于剪枝问题,可以进行权重剪枝和神经元剪枝,其中权重剪枝的效果并不是很好,为什么呢?是因为如果单纯的对权重参数进行剪枝,计算时将会非常麻烦,进行GPU计算加速都是使用矩阵,而剪枝完之后的矩阵就会很不规则,一种优化的方式就是将剪枝掉的参数设置为0,但是这样本质上参数还差被报错着,并并没有真正的简化网络。因此通常都是使用神经元剪枝。

有一个问题,为什么我们不直接一开始就直接训练一个小网络,而是训练一个大网络呢?有“ 彩票假说 ”试图解释了这个原因。我们可以将一个大网络看作许多小网络的集合,其中某个小网络可能经过训练可以达到最终的效果。

例如,对于原始大网络中,只有使用了开始的随机初始化权重可以训练出达到效果的小网络,而不适用前面大网络随机初始化的参数,重新进行初始化参数的网络就无法训练成功。

13.2 知识蒸馏
**知识蒸馏(knowledge distillation)**也是让网络变小的方法。其思路是,使用大的网络作为教师,我们训练的网络作为学生。在训练学生网络的时候,以教师网络的输出作为参考进行学习。那么为什么知识蒸馏会有效果呢?一个解释就是教室网络可以为学生网络提供直接使用原始数据训练以外的额外信息。例如在下面识别数字1时,会给到数字1和数字7和9之间的关系信息。

当使用知识蒸馏的教师网络也可以不是一个大网络,也可也是多个网络的集合,通过多个网络进行**集成(ensemble)**组成。其中集成网络最终的输出结果可以是每个小网络投票或者平均化得到的结果。

下面介绍一个使用知识蒸馏的技巧,其实就是稍微修改一下sofemax函数,将每个输出都除上一个T,的得到公式$ y_i^{\prime}=\frac{exp(y_i/T)}{\sum_jexp(y_j/T)} $。使得最后的分类结果比例更加平滑,从而可以学到更多的信息。

13.3 参数量化
** 参数量化(parameter quantization) **本质上就是使用更少的空间来存储参数。例如可以使用8bit来存储原来使用16bit存储的参数、使用哈夫曼编码对参数进行压缩。也可以使用**权重聚类(weight clustering)**对参数进行压缩。例如在下面的聚类中一开始有4类(这个类的数量也是超参数),让后通过计算每个类的平均值,使用平均值类代替原本类中数值,这样就可以减少参数存储,例如在下图中一开始需要20个数值,现在只需要存储4个数值,只需要两位即可。

如何对权重聚类进行参数的更新呢?如果先把网络训练完,在做权重聚类的话就会导致聚类后参数和聚类前的参数大小差异过大。一个解决方法是将训练中参数的差异考虑到loss函数中,要求网络中不同类的参数越接近越好。
13.4 网络架构设计
通过合适的网络架构就可以减少网络的参数,这里主要介绍**深度可分离卷积(depthwise separable convolution)**,其分为两步**深度卷积(depthwise convolution)**和**逐点卷积(Pointwise Convolution)**。对于一个标准的两个通道的输入,其中的过滤器也都是两个通道,下图中有四个过滤器,最终得到通道数为4的特征图。

在深度可分离卷积中第一步进行深度卷积,分别对每个通道进行卷积运算,得到每个通道内部之间的信息。

第二步就是进行逐点卷积,使用四个通道数为2,大小为1x1的滤波器,要注意的是逐点卷积使用的一定是大小为1x1的滤波器。然后进行卷积运算,同样得到通道数数为4的特征图。逐点卷积计算得到的是不同通道之间的信息。

下面对比原始方法和深度可分离卷积之间的参数数量差异,下图中k为卷积核(正方形)的边长,I为输入通道数,O是输出通道数。通过相比可以得知,当k越大时,使用深度可分离卷积这种架构的参数相对于原始方法的参数个数是成倍的减少的。通常输出通道O的数量较大,影响较小。

其实在深度可分离卷积之前就有减少神经元层的参数, 用**低秩近似(lowrankapproximation)**就可以减少一层网络的参数量。 例如,在下面的例子中,原始的一层神经网络参数量为 $ N * M $,使用低秩近似增加一个线性层就可以将参数数量变成 $ K * M + K * N
$,因此就可以减少网络层的参数。

13.5 动态计算
对于上面的四种方法其目的都是为减少网络的参数从而使网络变小,而**动态计算(dynamic computation)**是为了可以自由的调整网络的计算量。为什么需要控制网络的计算量,是因为有些条件的限制,如不同设备的算力有限,有时候我们需要决定网络计算的算力投入,从而控制网络进行动态计算。
对于动态计算可以有动态深度和动态宽度两个。动态深度例如在下面的分类识别网络中,可以在每一次的输出都加上一个最终的分类器,根据实际情况就决定最终从哪层输出然后进行分类。关于动态深度的训练,可以将每一层的交叉熵加起来得到最终的损失值L,$ L=e_{1}+e_{2}+\cdots+e_{L} $,根据这个损失值来训练整个网络。

对于动态宽带,如何进行训练可以参考论文“Slimmable Neural Networks” 。

有时候我们需要让网络自己决定什么时候结束,例如下面的例子中,对于不同难度的图片其需要进行网络计算的层数也不同。在上面的图片只需要一层就可以得到结果,而对于下面的图片识别了两层之后仍然得不到猫这个分类结果。关于自决定动态计算网络如何训练,可以参考论文 “SkipNet: Learning Dynamic Routing in Convolutional Networks”、Runtime Neural Pruning和“BlockDrop: Dynamic Inference Paths in Residual Networks”。

14.终身学习
14.1 灾难性遗忘
在我们想象中的人工智能应该是可以不断学习新的任务然后提升解决问题,这种学习方式就是**终生学习 (LifeLong Learning,LLL) **,其也叫持续学习(continous learning)、无止尽学习(never-ending learn ing)、增量学习(incremental learning)。
其进行网络的训练其实就是如下面的框架所示,假设一开始通过数据训练模型,然后上线之后又得到用户的反馈并得到新的数据,然后再使用新的数据训练旧的模型,接着不断进行循环训练即可。

但是终生学习并不是不断训练模型那样简单,例如再QA任务中,把20QA作为20个任务进行终身学习的训练,可以得到任务5的准确率在过了任务5训练之后的训练,得到的准确率非常低。可以得知在后面的训练过程中参数已经被更改到和任务5没有太大关系了。这种情况就叫做灾难性遗忘 (catastrophic forgetting),其表现形式就是无法记住前面的任务,一边学一边忘。

对于解决终身学习灾难性遗忘的最简单的方法就是,直接将所有任务的数据放在一起同时训练,这种方法叫做多任务学习(multitask learning),但是这种方法在任务数据量大的时候就不适合使用。那么为什么不把每一个任务都训练成一个模型,但是这样做也是有问题的的,这样做回产生许多的模型,对机器的存储也是问题。
同时终身学习和前面的迁移学习有一定的共通之处,迁移学习注重的是经过旧任务训练过后的模型在新任务上的表现,而终生学习注重的是模型在解决新任务之后还能不能回去解决旧任务。
14.2 评估方法
假如有T个任务,一开始对模型进行参数的初始化,然后每对一个任务训练前后都记录对其他任务的预测准确性,可以得到如下的表格。对于评估指标有三个:
- Accuracy(准确率):模型的准确率,$ \mathrm{Accuracy}=\frac{1}{T}\sum_{i=1}^TR_{T,i} $。
- Backward Transfer(后向迁移):是模型在后续时间点相对于当前时间点的表现提升,$ \text{Backward Transfer}=\frac{1}{T-1}\sum_{i=1}^{T-1}R_{T,i}-R_{i,i} $。
- Forward Transfer(前向迁移):是模型在当前时间点相对于前一个时间点的表现提升,$ \text{Forward Transfer}=\frac{1}{T-1}\sum_{i=2}^TR_{i-1,i}-R_{0,i} $。

14.3 主要解法
对于终身学习中灾难性遗忘的主要解决方法就是 **选择性的突触可塑性(selectivesynapticplasticity)**,其设计思路就是将网络中的某些参数固化,只让部分参数具有可塑性,这种方法又叫基于正则的方法。例如在下面的灾难性遗忘中,在进行任务迁移的时候,参数更新到了一个任务1预测精度较小的地方,但是这个操作有完全符合任务2的训练目的,这就产生了灾难性遗忘。
那么如何解决这个问题,解决思路是在网络中不同参数的重要性都是不同的,对之前任务重要的参数我们需要保留,而不重要的参数则不需要进行处理,最终得到新的损失函数。

接下来就是实现对$ b_i 数值如何设置的问题,当数值如何设置的问题,当数值如何设置的问题,当 b_i = 0 时,就回到了灾难性遗忘的问题;当时,就回到了灾难性遗忘的问题;当时,就回到了灾难性遗忘的问题;当 b_{i}=\infty 时,就会出现<fontstyle="color:rgba(0,0,0,0.9);">intransigence现象,导致无法完成新任务,只会记住旧任务。因此要设置合适的</font>时,就会出现<font style="color:rgba(0, 0, 0, 0.9);">intransigence现象,导致无法完成新任务,只会记住旧任务。因此要设置合适的</font>时,就会出现<fontstyle="color:rgba(0,0,0,0.9);">intransigence现象,导致无法完成新任务,只会记住旧任务。因此要设置合适的</font> b_i <fontstyle="color:rgba(0,0,0,0.9);">,其中大部分方法都是人为设置,那么如何设置</font><font style="color:rgba(0, 0, 0, 0.9);">,其中大部分方法都是人为设置,那么如何设置</font><fontstyle="color:rgba(0,0,0,0.9);">,其中大部分方法都是人为设置,那么如何设置</font> b_i $呢?
可以使用梯度偏移,通过对一个参数进行修改,判断对应梯度偏移的程度来判断一个参数是否对当前网络重要,对于越重要的参数,其$ b_i <fontstyle="color:rgba(0,0,0,0.9);">矩阵中的值应该越大;约不重要的参数,其</font><font style="color:rgba(0, 0, 0, 0.9);">矩阵中的值应该越大;约不重要的参数,其</font><fontstyle="color:rgba(0,0,0,0.9);">矩阵中的值应该越大;约不重要的参数,其</font> b_i $矩阵中的值应该越小。

当最终得到了$ b_i $矩阵,通过上面的损失函数训练出模型后,就可以得到下面的结果,即经过任务2的训练后,网络无论对于任务1还是任务2都有不错的准确率。

其实在上面的方法出现之前还有一个方法,叫做梯度回合记忆(gradientepisodic memory,MMD),它不是在参数上做限制,而是在梯度更新的方向上做限制。其类似于梯度下降算法中,对梯度增加动量,在这里也对任务2训练的参数更新增加任务1的更新“动量”。
但是这种方法违背终生学习的初衷,即不记录数据学会多个任务,这种方法还是需要存储过去任务的资料,当然这里只存储了少量的任务数据,且选择性的突触可塑性也会记录部分数据$ b_i $,因此在实操使也还可以接受。

15.元学习
15.1 元学习的概念
介绍元学习(meta learning)的概念,本质上就是学习如何去学习,可以这样理解就是这个模型就是为了学习出来一个可以产生出来其他学习模型的网络。 如下图中,函数F经过元学习,使用任务的训练数据学习,使得函数F可以产生分类器函数$ f^* $,通过输入任务的验证数据就可以得到最终的分类结果。可以这样理解,元学习就是函数F,输入是训练任务的的数据,输出的是另一个模型的函数。

15.2 元学习的三个步骤
明确概念:- 训练数据→训练任务(训练任务里的训练数据+测试数据)
- 测试数据→测试任务(包含训练数据+测试数据)
1.明确学习函数
让机器自己学习⇒**learnable components**$ \phi $- 网络架构
- 初始参数
- 学习率

2.定义损失函数
定义学习算法的损失函数, 把这些在学习算法里面想要它自学的东西统称为ϕ ,定义损失函数为$ L(\phi) $。对于每个训练任务中都含有训练资料和测试资料。
对于定义损失函数,元学习中我们需要大量的训练任务,此时就把得到所有训练任务的生成模型的损失函数值$ \mathrm{l} 的总和作为元学习任务的损失值。即∗∗模型∗∗的总和作为元学习任务的损失值。即**模型**的总和作为元学习任务的损失值。即∗∗模型∗∗ f_{\theta^{1*}} ∗∗性能越好时,说明学习算法∗∗**性能越好时,说明学习算法**∗∗性能越好时,说明学习算法∗∗ F_\theta ∗∗越好,此时损失函数L∗∗**越好,此时损失函数L**∗∗越好,此时损失函数L∗∗ (\theta) $越小。

而对于上面的二分类问题中,我们如何得到模型$ f_{\theta^{1*}} $ 的性能好坏呢?可以判断分类后个类型的概率分布是否均匀,若越均匀代表模型$ f_{\theta^{1*}} $性能越差。

3.优化
对于进行模型优化,已经知道需要求 $ L(\phi)=\sum_{n=1}^{N} l^n $ ,需要求$ \phi^*=\arg\min_{\phi} L(\phi) $, 如果知道如何计算$ \frac{\partial L(\phi)}{\partial \phi} $,则可以使用梯度下降算法;如果无法计算微分,则可以使用强化学习或者进化算法。由此可以得到如何去进行元学习。15.3 元学习和机器学习
对比元学习和机器学习,其**目标不同**,机器学习是要找到一个函数f,例如是一个分类器,可告诉我们分类的结果;而对于元学习,需要找到一个函数F,这个函数可以接受训练数据然后输出一个分类器f。
其使用数据不同,机器学习只需要训练数据就可以得到最终的分类器,而元学习则需要训练数据和验证数据才能得到最终的分类器。
其损失函数不同,在机器学习中我们使用$ \begin{aligned} L(\theta)=\sum_{k=1}^Ke_k \end{aligned} $ 表示损失函数,其中$ e_k 表示第k个训练样本的损失,其中的加和为所有训练数据在一个任务中的损失总和。在元学习里面,我们使用表示第k 个 训练样本的损失,其中的加和为所有训练数据在一个任务中的损失总和。在元学习里面,我们 使用表示第k个训练样本的损失,其中的加和为所有训练数据在一个任务中的损失总和。在元学习里面,我们使用 L(\phi)=\sum_{n=1}Nln $ 表示损失函数,其中的$ l^n $表示第n个测试样本中的损失,其中的和为在所有任务中的损失总和。
其训练过程也有差异,对于元学习,其需要计算$ l^n $,每个训练任务都需要进行一轮训练 + 测试,也就是一个回合,这个叫做内循环,而对于整个元学习的多个任务的计算,也就是多个外循环,这也叫做内循环。而对于机器学习只需要一轮的训练 + 测试即可。

15.4 元学习的实例算法
主要的元学习实例算法有 **模型诊断元学习(model-agnosticmeta-learning,MAML)**和MAML的变形Reptile。 这两个实例都是通过学习初始化的参数$ \theta^0 $,然后再开始梯度下降算法,最终通过不断更新得到合适的参数$ \boldsymbol{\theta}^{*} $。
当然MAML除了可以学习初始化的参数外,还可以学习优化器。例如在更新参数的时候,可以学习学习率、动量等参数。在文章 “Learning to learn by gradient descent by gradient descent”中就展示了对学习率这种超参数进行自动更新的方法。

也还可以训练网络架构,这部分的研究被称为神经网络架构搜索(NeuralArchi tecture Search,NAS)。例如在下面的例子中, 这个RNN架构每次会输出一个网络架构有关的参数,比如它会输出滤波器的高是多少,再输出过滤器的宽是多少,接着再输出步长是 多少等等。第一层第二层输出完了以后,接下来输出n+1层,再输出n+2层,以此类推,最终可以得到我们想要的网络架构。

15.5 元学习的应用
在元学习的应用中可以进行一个 N类别K样例下的分类任务。
那要怎么去找一系列的N类别K样例下的任务呢?在文章中最常见的一种做法是使用 Omniglot 当做基准。 它有 1623 个不同的字符,每一个字符 有20 个样例。可以只给定某个类型的一部分特征图片作为训练数据集,然后使用其他的特征图片作为验证集,来验证生成的分类模型性能是否较好。


更多推荐
所有评论(0)