Transformer注意力层异常:输入向量变化对输出几乎无影响
Transformer注意力层异常问题分析
问题现象
实现Transformer的注意力层时出现以下异常:
- 修改输入向量
input对输出向量几乎无影响 - 修改
context会强烈影响输出 - 已单独测试Softmax函数,确认功能正常
原实现代码
public double[] Predict(double[] input, double[][] context) { double[] output = new double[qkvSize]; Q = new double[qkvSize]; K = new double[context.Length][]; V = new double[context.Length][]; //calculate q k v for (int i = 0; i < qkvSize; i++) { for (int j = 0; j < iSize; j++) { Q[i] += W_Q[i][j] * input[j]; } } for (int i = 0; i < context.Length; i++) { K[i] = new double[qkvSize]; V[i] = new double[qkvSize]; for (int j = 0; j < qkvSize; j++) { for (int k = 0; k < iSize; k++) { K[i][j] += W_K[j][k] * context[i][k]; V[i][j] += W_V[j][k] * context[i][k]; } } } preSoftMax = new double[context.Length]; //calculate attention w for (int i = 0; i < context.Length; i++) { for (int j = 0; j < qkvSize; j++) { preSoftMax[i] += Q[j] * K[i][j]; } } // 完全无用的冗余代码,可删除 for (int i = 0; i < preSoftMax.Length; i++) { preSoftMax[i] = preSoftMax[i]; } postSoftMax = Functions.SoftMax(preSoftMax); for (int i = 0; i < context.Length; i++) { for (int j = 0; j < qkvSize; j++) { output[j] += V[i][j] * postSoftMax[i]; } } return output; }
修改后的代码片段(输出符合预期,但不符合标准注意力逻辑)
for (int i = 0; i < context.Length; i++) { for (int j = 0; j < qkvSize; j++) { output[j] += V[i][j] * Q[j];// * postSoftMax[i]; } } return output;
原因分析
核心问题:缺少注意力分数缩放因子
标准Transformer的Scaled Dot-Product Attention要求,Q与K的点积结果必须除以√(qkvSize)。如果没有这一步,当qkvSize较大时,点积结果会变得非常大,经过Softmax后会形成近似one-hot的分布——某个位置的概率接近1,其余位置接近0。此时Q的微小变化很难撼动Softmax的输出分布,导致input(通过Q传递)对最终输出几乎没有影响;而context的变化会直接改变被选中的V向量,因此输出会被context强烈影响。修改后的代码本质是绕过注意力机制
你注释掉Softmax权重,直接用Q与V相乘求和,相当于把Q当成了每个V向量元素的权重。此时input的变化会直接反映到Q上,进而直接改变输出权重,所以看起来输出会随input变化,但这已经不是标准的注意力机制——它没有学习输入与上下文之间的关联权重,只是做了简单的加权求和。额外冗余代码
原代码中preSoftMax[i] = preSoftMax[i];这一行完全无意义,属于冗余代码,建议删除。
内容的提问来源于stack exchange,提问作者RB2k
相关产品推荐
相关产品推荐

