deeplearing.ai 深度学习课程笔记

deeplearing.ai 深度学习课程笔记

一、神经网络与机器学习

  • 直观理解神经网络。随着神经网络层的加深,所提取的特征(函数)不断组合,最终得到更宏观、更复杂的所需要的特征。简单的例子比如房屋价值预测。基础特征可能是房间数,面积,邮编,交通等情况。当神经网络进行学习时,可能 hidden layer 中的某个神经元,实现的等效逻辑就是根据邮编和交通情况估计了房子是在富人区还是平民区,这个特征显然更有利于直接预测房屋的价格。
  • loss function (单个样本) 和 cost function (整个网络) 的选取:不同的问题不同的 loss function 和 cost function 可能影响最终的目标函数是不是为凸的,这也就最终决定了能不能保证最终的结果时最优的。比如对于二分类问题,理想的 loss function 为下式,而传统的均方根误差将导致最终的目标函数存在多个局部最优点。

                             

  • backwark propagation 反向递推,使用链式法则。下图以逻辑回归为例给出了计算过程。对于一般神经网络而言,由于其中每一个神经元的权重和使用的激活函数都是已知的,因此可以使用类似的方法进行求解。

  •  激活函数的选取。首先激活函数必须是非线性的,同时每个隐藏层神经元必须添加,因为如果没有非线性部分多个线性神经元的连接最终也只能得到线性函数,与单独一个神经元的特征(函数)作用是相同的。常用的激活函数有 sigmod, tanh, ReLU, Leaky ReLU。除了输出层的神经元,且实现的分类逻辑,一般激活函数都不会使用 sigmod,因为 sigmod 的输出均值是正的,而 sigmod 的输出是下一个神经元的输入,因此随着层数的加深,最终的计算结果将集中在正向饱和区,从而降低网络的收敛速度。因此,通常情况下,tanh 是严格优于 sigmod。不过 tanh 也存在饱和区,因此现代神经网络通常使用 ReLU 或 Leaky ReLU 作为激活函数。Leaky ReLU 负向斜率不是十分重要,通常假设为某个比较小的常数即可。 

 

  • 随机初始化。神经网络不能简单的将权重和偏差初始化为零,因为如此根据公式,每层的每个神经元其实在重复相同的操作,这将大幅降低神经网络的效率。同时由于饱和区的存在,通常应保证初始化的值尽可能的小,这通常采用乘以 0.01 之类的一个小数实现。
  • 超参数。常见的超参数有学习率,层数,每层的神经元数,迭代的数目,激活函数,正则化,mini-batch大小等等。
  • 大脑类比。大脑中的神经元通过接受其他神经元的输出,得到自己的输出。这和神经网路很像,但大脑神经元中的参数如何学习的,必然不是通过神经网络中的反向递推实现的,仍然是个谜。

二、Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization

  • train, develop, test set 的划分。之前由于数据量通常较小,通常的划分是 80%-20% 或者 60%-20%-20%。但随着数据量的不断增大,由于develop 的作用只是选取超参数,因此其实一定量的数据就已经足够了。因此针对大数据的划分,可能是 98%-1%-1%。同时,由于 test set 只是为了在最后给出得到的神经网络的无偏性能评估,因此如果需要评估结果,其实可以不设置 test set。
  • Bias Variance trade off:high bias low variance,欠拟合,模型复杂度不够;low bias high variance,过拟合,模型复杂度过高;high bias high variance,模型在某些区域欠拟合,又在某些区域过拟合,这在高维场景更常见。不过,对于不同任务 high 和 low 的判断是相对的。比如对于某些简单问题,人的错误率是0%,因此10%就是high;而对于复杂问题,10%有时也是可以接受的。
  • 正则化。解决high bias 最好的方法是增加模型复杂度(增加神经网络神经元数量),解决high variance 最好的方法是增加数据量。不过数据量是有成本的,因此正则化通常被用来解决模型复杂度过高的过拟合问题。同时由于正则化最终起到的作用就是将权重变得小一点,从而使更新更慢,所以也被称为 weight decay。

  • 避免over-fitting的方法。最简单的方法就是增加数据,对于图像数据,可以采用水平翻转,随机旋转,距离缩放来增加数据。还有比如早停(early stop)在训练误差还在下降,但验证误差已经开始上升的时候就停止训练。它可以避免选择超参数的困难,但它把最优化代价函数和避免过拟合两个问题融合在了一起,这使得很难清晰地分析各自地性能。最常使用的还是L2正则化和dropout,它们的思想都是限制某些节点的权重,从而起到将某些作用微小的节点筛选出来的作用。
  • 加速训练的几种方法。对数据进行归一化,因为不同特性的尺度跨度可能很大,这就可能造成梯度下降时参数来回震荡,降低训练速度。对于深度神经网络,只要权重稍微大于1,由于层数的增加,计算结果将呈指数的增加(exploding gradients);相反,如果权重稍微小于1,计算结果将指数的减少(vanishing gradients)。针对这个问题,现在还没有完善的解决方法,不过有很多方法可以减缓这个过程。比如对每一层的权重赋予一个不同的缩放因子,输入的节点越多缩放因子越小,可以参考 Xavier initialization。
  • mini-batch。由于现在深度学习任务的数据量都很大,如果每次迭代都使用所有的数据集做权重更新,这样速度太慢。一种更好的方式是将整个数据集分成若干份,每次更新只使用其中的一份。这样整个数据集使用一遍(one epoch),权重已经更新了若干次;当然,整个数据集能够重复循环几次,最终大幅加快训练速度。不过mini-batch也有两个弊端:第一个是损失函数的曲线不再是严格下降的,随着迭代的进行,损失函数可能会有小幅震荡,不过整体还是呈下降趋势;第二个是最终算法不会收敛,最终结果会在最优解周围震荡,不过batch-size越大震荡的范围就会越小。通常的batch-size是64,128,256,512(2的次幂)。
  • 动量梯度下降(gradient descent with momentum)。有时目标函数会呈现为很扁的椭圆,这时候传统的梯度下降将表现为下降方向来回的震荡,这极大地影响了训练地速度。这是指数加权平均的思想被用来加速这个过程,其基于 V = beta * V + (1 - beta) * new_data 使用过去的数据消除噪声找到趋势。在下面的图中,垂直方向的梯度下降由于多次求和趋向于零,而水平方向却得到的不断加强,从而提高收敛速度。最后还有几个数值理解,1 / (1 - beta) 为 beta 窗的长度,比如 beta=0.9,相当于取之前的 1 / (1 - beta) = 10 做平均;同时,由于最开始并没有数据做平均,会存在偏差,可以使用除以 1 - beta ^ t 进行修正,其中 t 表示当前计算的是第几帧。

  • 均方根传递(Root Mean Square prop, RMSprop)。同样用来解决梯度下降反向震荡的问题。借用指数加权平均相同的思想,它将下降快的变慢,下降慢的变快。

  • Adam(adaptive Momentum estimation)优化器。其将 momentum 和 RMSprop 相结合。其中 beta1 = 0.9,beta2 = 0.999,epsilon = 10 ^ -8。

  • 关于各种梯度下降算法的优化可能参考这篇文章:https://ruder.io/optimizing-gradient-descent/index.html,最后有中文版的连接
  • 超参数选择。不要使用网格去采样可行区域,因为你无法提前知道某个参数是主要的。如果使用网格,可能只有某些维度上的几个点是有效的,因为这些维度确定的情况下,其实其他维度取不同的值其实对最终的结果影响不大。一个好的采样方法就是在可行区域的随机采样,当然在得到一个相对较好的可行区域后,可以在这个子区域内继续采样,不过此时采样就可以更密集。
  • 超参数采样方法。不要简单的所有超参数都是用均匀的采样方法。比如学习率,0.0001-1,不用在这个范围内均匀采样,应该使用负指数的方式来处理,使得0.0001-0.001-0.01-0.1-1它们之间的采样点数差不多。这里面的原因就是对于学习率而言,越接近于零的学习率,最终结果对于学习率的变化越敏感。
  • Batch Normalization。在输入端我们通常使用归一化方法将多个输入样本进行归一化,这样梯度椭圆更接近圆,从而可以使用梯度下降方法更好地求解。BN 将这个思路用在了神经网络每一层输出上,通常在线性计算之后进行归一化,再使用非线性激活函数。这里需要强调地是BN是对多个样本进行地归一化,每一层的不同的神经元可以人为是样本经过处理之后的某个维度上的值,因此归一化是在每个神经元上针对多个样本的计算结果进行的。同时,如果所有结果都要求均值为零方差为1,可能降低特征的表示能力,因此通常在归一化之后再对其进行放缩,如果参数合适,归一化过程可以被抵消,相当于BN没有进行任何操作。同时由于BN会对结果归一化到零,原始线性函数中的偏移便不再需要。
  • BN起作用的原因。BN的效果除了前面提到的优化了梯度椭圆,更主要的原因是它排除了之前神经网络计算结果的影响。比如某一层网络,它的目的是根据输入努力优化得到一个最优的输出,不过不幸的是由于它的输入是前面神经网络的输出,是不断在变化的,因此后面的神经网络必须尝试兼容这些变化,这降低了训练的效率。而BN强制减少了这种前端网络输出的变化,从而能够加速网络的训练。同时,BN还有一个附加的好处,由于现代神经网络通常使用 mini-batch,这样在根据这些样本计算的均值和方差就存在偏差,这无形当中引入的噪声,这就与 dropout 的效果类似,因此起到了一些正则化的作用。但不要尝试用BN替代正则化,因为它的本意不是用来实现正则化的。
  • 预测中的BN。因为BN中的归一化操作需要多个样本来计算均值和方差,而在预测中,通常没有多个样本来计算。此时,通常的做法是在训练时对均值和方差进行估计,比如使用指数加权平均的方法,然后再预测时直接使用最后均值和方差的估计值来对预测的样本进行归一化。
  • softmax。softmax其实是一种特殊的神经网络层,它使用特殊的激活函数,将上一层的输出转换为对应分类类别的概率。和 hardmax(将最大值置为一,其他为零)对比,其通过指数函数将计算结果保证为正,再对所有结果进行归一化,从而得到分类概率。

三、Structuring Machine Learning Projects

  • 正交化。在神经网络没有获得需要的性能时应该通过如下顺序提高性能:1、如果在训练数据上性能不佳,通常需要可以通过使用更大的神经网络或者更换梯度下降算法来解决;2、如果在验证数据上表现不佳,通常可以使用正则化方法或者使用更大的训练集;3、如果在测试数据上性能不佳,可以尝试使用更大的测试数据;4、如果在现实使用中表现不佳,就需要修改验证数据或者损失函数。
  • 单一评价指标。在神经网络优化中,经常遇到从多个不同的参数训练的神经网络中挑选一个最优的。这时通常就需要将多个评价指标集中反映到一个参数上,这有利于最终的挑选。比如准确率和召回率,它们通常是相互冲突的,一个通常的做法是使用F1 score这个集合准确率和召回率的指标来挑选模型。
  • 莱曼-皮尔逊准则。在存在多个指标来评价要给神经网络时,一种有效的处理方式是,在限制其他指标满足要求的情况下,最优化剩下的一个指标。比如在召回率为95%的情况下,最优化准确率。
  • 验证集和测试集的选择。首先测试集和训练集应该反应现在很重要和未来可能重要的应用场景。不过最重要的保证,验证集和测试集来自同一个分布,只有来自同一分布,才能保证你在验证集上优化的网络能够在测试集上依然表现出色。
  • 修改评价指标或者验证测试数据集。有时会因为考虑不全使得优化目标并不能反映最终的应用场景。比如一个猫咪的二分类目标,并在最后发现即使一个算法性能更好,但是却错误划分了很多色情图片,这在最后应用的时候可能很大的影响用户体验。此时就需要修改评价指标,比如给那些色情图片却被误识别为猫的图片定一个更高的惩罚权重。又比如我们优化的数据集全部来自高清图片,但在应用时却发现很多需要检测的图片时低分辨率的,此时就是验证和测试数据集并不能反映最终的应用场景,此时就需要调整测试应用数据集,添加更多的低分辨率图片。
  • 人类性能比较。了解人类在某项神经网络任务中的性能的一个主要原因是,人类的性能给出了该项任务可能的最优性能的一个估计。这提供了一个简单的指导,当前我们应该优化bias还是variance。比如用同样一个检测结果,错误率在训练集上是8%,验证集上是10%;如果人能够做到1%,此时就应该通过增加网络层数来降低bias;但如果人只能做到7.5%,那此时就应该通过正则化来降低variance。
  • 机器超过人的领域。在线广告推荐,商品推荐,回归(预测A到B的时间),商业贷款审批

四、Convolutional Neural Networks

  • 卷积神经网络。对于图片的处理,如果使用之前的全连接网络,由于图片是二位的,因此只要图片的分辨率一高,对应网络的输入就会变得很大,造成需要训练的参数变得很大,这极大的增加了网络的复杂性,造成通常没有那么多的数据使得网络不过拟合。
  • 卷积操作。考虑到二维图片相邻像素之间存在着强相关性,且图片中存在的物体存在着平移不变性,同时基于传统计算机视觉的积累,传统的滤波操作,在CNN中叫卷积被很自然的引入。不同的卷积核可以被理解为在不同的尺度上(特征图上)寻找指定的特征。比如前端神经网络通常检测简单的点,边的特性,而后端的神经网络则将这些基础特征融合形成更复杂的特征,例如人脸检测中的嘴、鼻子、眼睛等等。同时需要注意的是,在信号处理或者某些数学领域,机器学习通常所说的卷积操作其实是 cross-correlation,而 convolution 在之前还有一个水平垂直方向分别反转的操作。
  • padding。padding 主要用来解决两个问题,一是每次卷积都会使原图像缩小(n-f+1),这很大程度上限制了卷积神经网络的深度,而是直接卷积操作将造成边缘的图像像素点比图像中间的像素点更少的被使用。因此在卷积操作之前通常使用padding——在图像四周添加0或其他像素点,来解决这两个问题。同时,由于卷积操作通常使用奇数的卷积核(f),此时若想保证图像大小不变,padding 的大小应该改为 n + 2p - f + 1 = n,p = (f - 1) / 2。
  • stride。处理之后的图像大小变为 (n + 2p - f + 1) / s。这里不用特意选取 s 保证这个算式为整数,仅仅将值向下取整即可。
  • 三维卷积。针对三维图像(输入的RGB图像或者中间得到的特征图),仅仅是将二维卷积核也换成三维的,同时保证卷积核与图像的通道数相同。进一步,通常不仅仅使用一个卷积核对图像进行卷积操作,如果使用多个卷积核,最终的输出特征图的通道数将等于使用的卷积核数。
  • 卷积操作总结。

  • 池化(pooling)。池化操作简单的针对每一个通道的数据取最大值(最大值用的远比平均值多)。同时,虽然其同样具有卷积核大小、stride和 padding(几乎不用),但是所有参数都是在训练前已经确定的,因此不需要训练。
  • 为什么卷积神经网络。主要是两点:一是参数共享,一个卷积核被用在了整幅图片上。当然如果整个数据集的图片左上角和右下角具有完全不同的分布,这实际上是不合适的,好在这种情况一般不会发生。二是稀疏连接,某个输出只与某一块相关,而与图像的其他部分无关。这两个特性很好的适配了图像的平移不变性和局部相关性。
  • LeNet-5

  • AlexNet.

  • VGG-16。

  • Residual Block。理论上随着深度网络层数的增加,神经网络的性能应该不断增加。但是实际中,随着层数的进一步增加,神经网络的性能却会出现下降。Residual Block(残差结构)通过将之前网络的结果直接叠加到之后的网络中,起码保证了随着网络层数的增加,神经网络的性能不会出现下降。
  • ResNet.

  • 1 * 1 卷积。1 * 1 卷积对于单通道图像是无意义的。不过随着神经网络层数的增加,特征图的通道数是在不断增加的。此时,1 * 1 卷积就能起到综合这些特征并进行组合的作用,主要的优势是它实现了神经网络的精简。
  • Inception Network。Inception Network 就是利用了 1 * 1 卷积,同时考虑在一层中使用多个不同的卷积核,并将得到的特征图进行拼接,从而获得更佳的特征提取效果。

  • 迁移学习(transfer learn)。一种快速有效的方式去训练自己的神经网络,是基于别人已经训练好的参数,在自己的数据集上进行 fine-tune。首先就是根据自己任务的输出,调整神经网络最后的输出层。如果可训练的数据集很小,那就只训练最后的输出层。不过,随着你的数据集的增加,你可以增加你训练的神经网络层数,直至重新训练整个神经网络。
  • 数据增强。镜像(mirroring)——水平翻转,随机裁剪(random cropping)——截取原图中的某一块,旋转(rotation),切变(shearing)——转平行四边形,局部扭曲(local warping),颜色漂移(color shifting)——独立调整图像RGB通道的值
  • 目标检测。目标检测与分类最大的区别就是需要给出检测目标在图片中的具体位置。在神经网络中,通过额外输出 x, y, w, h 四个变量来框定目标。并通过组合不同的输出损失函数得到最终的损失函数。
  • 关键点检测。关键点检测,比如人脸的关键点检测,人体的关键点检测,就是在 ConvNet 最后输出每个关键点的位置,具体操作方法与目标检测的 bounding box 的处理方法类似。
  • 滑窗目标检测。通过指定不同大小的滑窗,分别检测每个滑窗内是否存在目标实现目标的检测与定位。同时,可以通过卷积操作同时对一个大小的滑窗同时处理。

  • YOLO。YOLO将一张图片分为多个方格,每个方格负责检测其中的目标。由于某些目标可能跨越多个方格,因此其规定具体归属依据目标中心点进行。针对每个方格的检测与前面介绍的目标检测类似。对于具体的定位,一种有效的方式是最后的输出不针对整幅图像,而是针对这个具体的方格给出。其中假定具体方格左上角为 (0,0)点,如此 bx by 一定在 0 和 1 之间。但是 bw bh 就可能大于 1。
  • 交并比(intersection over union, IoU):目标检测的框与真实框,交集与并集的比例。通常认为 IoU 大于 0.5 就认为检测框是正确的。
  • 非极大值抑制(non-max suppresion)。NMS 只在预测时被使用,它用于去除那些重复检测的候选框。执行流程是:首先去除所有小于某个阈值的候选框,比如0.6;接着从所有剩下的候选框中找出概率最高的候选框作为一个有效的预测;然后去除剩下的候选框中与选定的候选框重叠很大的候选框,比如 IoU 大于 0.5;然后重复这个过程,直到不存在任何的候选框为止。对于多类别的检测,以上操作需要针对每一个类别分别计算一次。
  • 锚框(anchor boxes)。每一个网格指定多个不同形状的预选框,比如有一些是高的,有一些是宽的。然后每一个 anchor box 都可以用来检测指定网格中的某个目标,从而实现重叠目标的检测。针对重叠目标,在设置训练数据时,通常根据实际目标形状和锚框形状的相似性来进行分配,比如 IoU。
  • R-CNN。相比于前面提到的一步得到检测结果和候选框,R-CNN首先通过图像分割算法得到可能存在目标的候选框,再针对每个候选框进行分类和框的调整。但是R-CNN速度很慢,后续又推出了 Fast R-CNN,它通过上面提到的卷积操作,同时对所有的候选框进行处理。进一步,Faster R-CNN 使用卷积操作来进行图像分割,进一步加快候选框的提取速度。
  • 人脸认证(verification)和人脸识别(recognition)。认证是给一张图和一个人的信息,确定是否是匹配的。识别是给一张图,判断是否是某个数据库中所有存在的任何一个人。
  • one-shot learning。只基于给定的每个人的一张照片进行人脸识别。具体的实现方式是,通过神经网络训练得到一个比较两张图片相似性的函数,之后通过计算给定图片与数据库中所有图片的相似性,并与某个阈值进行比较,进行人脸识别。
  • Siamese Network。它与传统卷积神经网络类似,只是除去最后的输出层,而将最后全连接层的输出所为图片的编码。如此,在做人脸识别时,就可以根据所有的图片经过神经网络得到一个编码,最后比较这个编码是否与数据库中的某个编码类似来进行人脸识别。
  • Triple Loss。为了训练上面的 Siamese Network,一种有效的做法时选取三张图片,一张作为锚点,一张是与锚点相同的人作为正例,一张是不同的人作为反例。最终的代价函数就是保证相同人的距离小于不同人的距离+某个很小的值。这样可以避免神经网络将所有图片得到同一个编码,使得所有的距离都相同而满足要求。
  • 人脸认证。人脸认证可以同样使用上面提到的 Siamese Network,不过此时需要两张图片作为输入,然后用具有相同参数的两个神经网络编码这两张图片,最后添加一个编码差值的全连接层,得到一个分类结果——这两张图片到底是不是同一个人。
  • 风格迁移(neural style transfer)。根据一张内容图片和一张风格图片,生成一张内容为内容图片但是风格类似风格图片的图片。
  • 风格迁移代价函数。内容代价函数:取神经网络的某一层,比较生成图和内容图之间的误差。风格代价函数:取某一层得到的特征图的不同通道之间的乘积来描述图片的风格。通常风格代价函数会取多层结果的加权和。

  • 一维和三维卷积。

Sequence Models

  • 序贯模型的例子。

  • 独热编码(one-hot)。使用一个字典,所有训练和测试数据中的词都在字典中。独热编码就是用一个与字典词数量相同的向量来表示每一个词,其中向量中表示该词在字典中的位置的地方为1,其他地方为0。
  • RNN。RNN从左到右依次输入各个序贯信息,每个信息将输入一个神经网络并输出一个下一层输入信息的 a 和当前层的输出 y。需要注意RNN每一层的神经网络结构和参数是公用的,同时上面提到的其实是最简单的单向RNN。考虑到针对某些任务,我们可以利用之后的信息来进行计算,有诸如双向RNN的算法。
  • RNN 反向推导。根据每一帧信息分别计算损失函数,然后计算每一步参数的调整,最后对所有调整进行加和,得到最终的调整值。

  • RNN 家族。为了处理情感分析(多对一),机器翻译(多对多,长度不同),音乐生成(一对多),存在很多RNN的变化形式。

  • 语言模型。语言模型能够根据所给的文字推断文字可能的概率。其RNN网络结构如下。

  • 采样模型。相比于语言模型,采样模型递归的生成一个句子,其基于之前的词生成随机选择生成下一个词。同时,除了将词作为基本单元,还可以使用字符空格来构成基本单元,这样可以简化字典的大小,但这样训练长度更长,训练难度也更大。
  • RNN 梯度消失。对于CNN,梯度消失是因为最后的梯度传到前层神经网络,梯度将可能过大或过小。而对于RNN,其原因是语言中可能存在相互影响的元素相隔很远,而RNN可能到需要使用这些信息时已经把这部分消息丢失了。对于梯度爆炸,可以使用诸如参数阈值限制参数的最大值的方式进行解决,而梯度消失则更复杂。
  • Gated Recurrent Unit (GRU)。为了解决RNN的梯度消失问题,一种常用的做法是使用一种传递门限的额外变量,它决定传递的信息是否被修改。如果判断这部分信息应该保持不变,那么即使间隔很远,这部分信息在被使用时还是能够得到保持。

  • LSTM (long short term memory)。与GRU类似,它使用三个门分别决定是否更新,忘记和输出对应的变量。

  • 双向RNN。有一些任务并不要求实时性,这时就可以利用之后的信息来做处理以提高性能。BRNN 具有双向的前向传递和反向传递,某一帧的输出有双方向的前向传递共同决定。

  • deep RNN。相比于在某一个迭代单位中构建复杂的神经网络,一种替代方案时通过多层RNN层叠的方式来构建deep RNN。

  • 词嵌入(word embedding)和词表示(word representation)。使用独热编码可以很方便地对词进行编码,但是这种表示方式能够很好的描述词之间的相似性,这就使得训练变得更加困难。一种好的方式是让相似的词表示具有更近的距离,从而能够更方便的从中学习。这就是词表示,一种朴素的方式是认为的指定一些特征,比如是否具有性别属性,是否是生物之类的。这样类似的词的表示将更为接近。
  • 词嵌入特性。词嵌入除了能够将相似的词聚集起来,它还学习了词之间的相互关系。比如它可以学到正与反,黑对白。即词嵌入能够学到词之间所表示的相对关系。
  • 嵌入矩阵。嵌入矩阵的每一列表示了某个词的词表示。比如词典中一共有10000个词,每个词提取了300个特征,那么嵌入矩阵的大小将是300*10000。还有一个简单的关系,使用嵌入矩阵乘以某个词的独热编码将得到这个词的词表示,就是得到嵌入矩阵某一列。
  • 获取嵌入矩阵。获取嵌入矩阵的方式是通过将文本中需要求解的词扣除,并通过神经网络训练来最大可能的预测缺省的词。而神经网络中的某个参数就是嵌入矩阵,因此当神经网络训练完毕,嵌入矩阵也就得到了。不过在求解过程中,可以使用不同的上下文来预测缺省的词,常用的比如前n个词,前后n个词,前1个词,附近的某个词等等。这也可以作为神经网络的某个超参数进行训练。

  • skip gram。skip gram 算法十分简单,在选取某个词作为上下文的基础上,随机的选择该词某个窗内的另一个词作为估计对象。网络结构就是通过嵌入矩阵将独热编码转换为词向量之后直接使用输入到单层 softmax 网络中估计结果。不过这个算法的主要问题是每一次 softmax 必须加和词典中的所有词,这在词典很大的时候速度很慢。一种改进的方式是层级 softmax。它通过树形结构(通常根据词频构建霍夫曼树)对整个词典进行划分,因此在每个节点处只有两个子节点需要 softmax。如此计算量变为词典大小的对数级。最后一点需要注意的是,为了避免最后的样本集中在某些经常出现的词,比如 the,of,在进行上下文采样时,通常会对词频进行均衡处理。

  • negative sample。为了从根本上解决 skip gram softmax 计算量的问题,negative sample 基于某个词选取一个匹配的词,并随机选取一些词作为正例和负例样本。最后通过上述类似的神经网络方法来预测这些词对是否匹配。对于大样本,负例通常选择 5-20,而小样本通常选择 2-5。同样在负例选择上,为了必须集中在一些常见的词,一种启发式的方法选取词频的 3/4 次方作为选择的概率。
  • GloVe 算法(global vectors for word representation)。好像就是简单的最小化一个词向量的线性组合与词对出现次数的差值。具体没太理解。
  • 情感分析应用。情感分析是 NLP 的一个重要的应用,它所给的评论推出该评论的好坏。一种简单的方式是将所有评论的词向量均平均直接预测。其原理是取平均相对于用一个向量表征了这条评论,而由于词向量已经很好的表征了词之间的相对关系,因此好评论和坏评论的向量通常分离。不过这种方法针对每个词进行处理,如果出现诸如 ***缺少好的***好的*** 之类的负正得负评论时,将给出错误的预测。通用的做法还是使用之前提到的多对一的 RNN 神经网络来进行预测。
  • 消除词向量的偏见。由于训练样本的关系,词向量可能学到某些带有偏见的关系。比如 man : computer_programmer,woman : homemaker,man : doctor,woman : nurse。而由于这些词向量被越来越广泛的应用于入学申请,申请贷款,因此被错误学习的偏见应该被去除。

  • 序贯模型。比如翻译,需要根据一种语言的序列生成另一种语言的序列,这个可以通过之前介绍的多对多RNN来实现。具体是将一种语言的序列依次输入到RNN中,然后再通过RNN依次输出翻译之后的结果。再比如图片描述,根据一张图片生成一句话描述这张图片中的场景。这个可以使用传统的CNN,去掉最后的分类或者分割层,把之前的全连接层结果作为图片的编码结果,然后输入到RNN中,依次输出图片的描述。
  • 机器翻译。从下图中,可以看出机器翻译的解码部分和语言模型(预测某句话出现的概率)十分相似。它们的差别就是语言模型基于随机或者无输入,而翻译基于需要翻译的语句。因此,机器翻译可以被理解为有条件的语言模型。从而机器学习的目标函数就是在给定语句的条件下,最大化生成语言的概率。

  • Beam Search 算法。为了得到条件最大概率翻译语言,一种有效的算法成为 Beam Search。其在翻译每个词时只选取其中最大的诺干个选项(这个参数称为 beam width)进入下一步的预测,从而压缩参数空间。比如 beam width = 3,那么算法将基于需要翻译的语句计算所有词典中的每个词出现在第一个位置的概率,并选取其中的 3 个概率最大候选项。之后算法基于这三个候选项,计算所有词典中的每个词出现在第二个位置的概率,如果词典中有 10000 个词,那么此时就有 3 * 10000 个可能项,同样从中选取 3 个概率最大的候选项。并以此类推,继续预测第三个位置的词。具体的过程如下图所示。这里,如果 beam width = 1,算法就退化为了贪婪搜索算法。

  • Beam Search 优化。首先由于 Beam Search 最大化序列的概率,而当序列很长时,由于每个词的概率都小于1,因此整个序列的概率将变得很小。因此,通常不是最大化序列的概率乘积,而是取对数从而计算概率对数和的最大值。同时由于每个词的概率都小于1,因此越短的序列更可能具有更大的概率。为了避免这种倾向,通常并不直接最大化上述目标函数,而是最大化上述目标函数与序列长度的某个次幂的商,次幂的推荐参数为 0.7。接下来是 beam width 的选择,常用的参数范围是 3 - 10,并且很少会使用比如 1000 之类很大的数。
  • Beam Search 错误分析。当出现翻译结果不正确时,因为算法涉及 RNN 和 Beam Search 两个算法。此时就需要确定应该优先提高哪个算法的性能,一个首先的方式就是比较机器翻译的结果和人工翻译的结果,哪个基于上述 RNN 算法得到的概率更好。如果人工更高,就说明是 Beam Search 由于 beam width 的关系提前选择了错误的翻译;而如果是机器翻译的更高,就说明本身的 RNN 算法存在问题,应该优先优化 RNN 算法。

  • Bleu Score。在机器翻译时,需要评价翻译结果的好坏。同时,由于一句话可能有多个合适的翻译,因此翻译结果与任何一个翻译相似都应该得到较高的得分。Bleu Score 选取某个长度(1,2 或者 3)的词序列作为计算单元,然后分别计算翻译结果中这些词单元出现的次数,以及这些词单元在每一个人工翻译中出现次数的最大值,然后用翻译结果词单元出现次数和与人工翻译词单元出现次数和之商。最后可以取多个长度的计算结果取平均,同时为了避免短翻译通常具有较高的得分,对短翻译进行额外的加权处理。

  • 注意力模型。之前所介绍的机器翻译算法,在翻译很长的句子的时候,性能会急剧下降。原因就是神经网络无法完整的将一大堆文字很好的进行编码,因此最终解码的结果不佳。不过,本质上在翻译某段文字时其实并不需要整段文字的信息,而只需要某部分信息就能进行很好的翻译。因此注意力模型在翻译某个词时,为 RNN 每个词的编码结果进行加权,从而为不同的结果赋予不同的权重,从而更好的得到翻译结果。

  • CTC 算法。在语音识别方面,任务是基于一段语言生成其中的文字。为了解决语言可能包含很多输入但输出的文字却很少的问题,CTC 让 RNN 输出多个重复的字母,确实输出的不同字母用 blank 隔开。

  • 启动词检测。启动器检测就是启动语音助手的词,比如 Hi Siri,小度小度。RNN 将启动词检测转化为了0-1检测。首先基于一段语言将它拆解为多个音节作为 RNN 的某个输入,然后当启动词刚被说完,标注 RNN 的输出将为1。最后为了平衡结果中 0 比 1 多很多的问题,通常在一个 1 后强制跟多个 1 来解决。

学完了,学习了很多,加油!

猜你喜欢

转载自blog.csdn.net/a40850273/article/details/103796704
今日推荐