链接:https://www.zhihu.com/question/339723385
编辑:深度学习与计算机视觉
声明:仅做学术分享,侵删
论文中解释是:向量的点积结果会很大,将softmax函数push到梯度很小的区域,scaled会缓解这种现象。怎么理解将sotfmax函数push到梯度很小区域?还有为什么scaled是维度的根号,不是其他的数?
作者:TniL
https://www.zhihu.com/question/339723385/answer/782509914
1. 为什么比较大的输入会使得softmax的梯度变得很小?
对于一个输入向量 ,softmax函数将其映射/归一化到一个分布 。在这个过程中,softmax先用一个自然底数 将输入中的元素间差距先“拉大”,然后归一化为一个分布。假设某个输入 中最大的的元素下标是 ,如果输入的数量级变大(每个元素都很大),那么会非常接近1。
我们可以用一个小例子来看看 的数量级对输入最大元素对应的预测概率的影响。假定输入 ),我们来看不同量级的 产生的有什么区别。
时, ;
时, ;
时, (计算机精度限制)。
我们不妨把 在不同取值下,对应的的全部绘制出来。代码如下:
得到的图如下所示:
可以看到,数量级对softmax得到的分布影响非常大。在数量级较大时,softmax将几乎全部的概率分布都分配给了最大值对应的标签。
然后我们来看softmax的梯度。不妨简记softmax函数为 ,softmax得到的分布向量 对输入 的梯度为:
把这个矩阵展开:
根据前面的讨论,当输入 的元素均较大时,softmax会把大部分概率分布分配给最大的元素,假设我们的输入数量级很大,最大的元素是 ,那么就将产生一个接近one-hot的向量 ,此时上面的矩阵变为如下形式:
也就是说,在输入的数量级很大时,梯度消失为0,造成参数更新困难。
注:softmax的梯度可以自行推导,网络上也有很多推导可以参考。
2. 维度与点积大小的关系是怎么样的,为什么使用维度的根号来放缩?
针对为什么维度会影响点积的大小,在论文的脚注中其实给出了一点解释:
假设向量 和 的各个分量是互相独立的随机变量,均值是0,方差是1,那么点积 的均值是0,方差是 。这里我给出一点更详细的推导:
对 , 和 都是随机变量,为了方便书写,不妨记 , 。这样有: , 。
则:
这样 , 的均值是0,方差是1,又由期望和方差的性质, 对相互独立的分量 ,有
,
以及
,
所以有 的均值 ,方差 。方差越大也就说明,点积的数量级越大(以越大的概率取大值)。那么一个自然的做法就是把方差稳定到1,做法是将点积除以 ,这样有:
将方差控制为1,也就有效地控制了前面提到的梯度消失的问题。
作者:Towser https://www.zhihu.com/question/339723385/answer/812013477
@lintongmao写的很好。用代码做一个数值实验就很清楚了:
from scipy.special import softmax
import numpy as np
def test_gradient(dim, time_steps=50, scale=1.0):
# Assume components of the query and keys are drawn from N(0, 1) independently
q = np.random.randn(dim)
ks = np.random.randn(time_steps, dim)
x = np.sum(q * ks, axis=1) / scale # x.shape = (time_steps,)
y = softmax(x)
grad = np.diag(y) - np.outer(y, y)
return np.max(np.abs(grad)) # the maximum component of gradients
NUMBER_OF_EXPERIMENTS = 5
# results of 5 random runs without scaling
print([test_gradient(100) for _ in range(NUMBER_OF_EXPERIMENTS)])
print([test_gradient(1000) for _ in range(NUMBER_OF_EXPERIMENTS)])
# results of 5 random runs with scaling
print([test_gradient(100, scale=np.sqrt(100)) for _ in range(NUMBER_OF_EXPERIMENTS)])
print([test_gradient(1000, scale=np.sqrt(1000)) for _ in range(NUMBER_OF_EXPERIMENTS)])
程序输出:
不带 scaling 的两组(可以看到 dim=1000 时很容易发生梯度消失):
[0.059398546712975064, 0.2498360169388831, 0.008179271245615127, 0.16985040166173004, 0.00017518204173572194]
[0.037403200843576845, 1.8829382497642655e-11, 6.995490600791854e-06, 1.3460521586239338e-10, 5.498179689311655e-11]
带 scaling 的两组(dim=1000 时梯度流依然稳定):
[0.23435524441068933, 0.10572976561186455, 0.09711877538913292, 0.059005529454577245, 0.15737320167534957]
[0.12238213059896091, 0.09907377893252199, 0.09771834771001327, 0.08899382001739972, 0.1312868174831885]
作者:Temp https://www.zhihu.com/question/339723385/answer/1844269544
感觉可以一句话总结:如果计算softmax的元素方差太大,将会导致softmax结果稀疏,进而导致梯度稀疏
☆ END ☆
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。
↓扫描二维码添加小编↓