这篇文章是我的笔记分享,内容主要来自吴恩达老师的深度学习课程。^[AI中国官网-全球领先的线上AI教育、实践平台 (deeplearningai.net)]
这篇文章是叫定向搜索的改进,实际上是接续着上一篇束搜索 Beam search algorithm^[束搜索 Beam search]来讲的。本文的主要内容是 在实际应用中束搜索会存在的一些问题以及对应的改进方法。
现存问题
上一节我们提到束搜索要做的其实就是:
$$
\arg \max {y} \prod{t=1}^{T_{y}} P\left(y^{<t>} \mid x, y^{<1>}, \ldots, y^{<t-1>}\right)
$$
其中
$$
p\left(y^{(1)} \ldots y^{\left(T_{y}\right)} | (x)\right)=p\left(y^{(1)} \mid x\right) \times p\left(y^{(2)} \mid x, y^{(1)}\right) \times ... \times p\left(y^{(T y)}|x, y^{(1)} \ldots, y^{(T_y-1)}\right)
$$
这个计算公式在实际的计算过程中会产生两个问题。
- 计算下溢:首先在实际的计算过程当中,因为这些概率都是一个小于1的值。当多个小于1的值进行相乘的时候,很可能会出现数据下溢的情况。
- 判断失误:因为我们要求的是$\arg \max {y} \prod{t=1}^{T_{y}} P\left(y^{<t>} \mid x, y^{<1>}, \ldots, y^{<t-1>}\right)$,也就是说要对这个公式进行最大化计算。所以会造成一个问题,就是他会倾向于更短的句子。因为同样都是小于一的数字相乘,乘出来的数字会越来越小。$0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 $和$0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 \times 0.1 $哪个更小一目了然。当然实际过程中并不是每个概率都是0.1。但是短的句子总会取得较大的计算值这个是毋庸置疑的。所以输出通常会偏向于更短的句子。
解决计算下溢问题
解决计算下溢问题,我们通常是会进行一个取对数值计算。
$$
\arg \max {y} \sum{y=1}^{T_{y}} \log P\left(y^{<t>} \mid x, y^{<1>}, \ldots, y^{<t-1>}\right)
$$
将原来的乘积变成了一个对数计算的求和。
取对数之后不会改变数据的性质和相关关系,但压缩了变量的尺度,所以计算这个式子跟计算原来的式子结果是一样的。并且在有些情况下,取对数可以消除异方差,从而达到平稳化的目的,取对数之后会获得一个数值上更加稳定的算法。不容易在计算机中出现数值舍如的误差,或者说数值的下溢。
但是我们会发现虽然这个解决了一个问题,但是另一个问题还是没有解决。从小数字相乘变成小数的相加。由于对数值的计算,小数越来越多的时候也会越来越趋向于负无穷。但是这个问题我们可以结合着输出倾向更短这个问题一起来解决。
解决输出倾向问题
句子长短而导致输出结果受影响,这个我们可以加上一,。来消除句子长短造成的差异,即对其进行归一化。
$$
\frac{1}{T{y}} \sum{t=1}^{T_{y}} \log P\left(y^{<t>} \mid x, y^{<1>}, \ldots, y^{<t-1>}\right)
$$
除以句子长度对其进行归一化。
当然还有一种探索性的改进。
$$
\frac{1}{{T{y}}^{\alpha}} \sum{t=1}^{T_{y}} \log P\left(y^{<t>} \mid x, y^{<1>}, \ldots, y^{<t-1>}\right)
$$
相比于直接除以句子的长度$T_{y}$,往往会采取一种更柔和的方式,就是为其添加上一个指数项α,为其设定不同的数值。