梯度函数决定学习规律
sin 和 tanh 之间的距离不是 0.76 到 3.06。是"自己打自己"和"方向从不出错"之间的距离。
一个失败的实验,一条意外的规律
Phase 1.0 的 RNN 实验测了 7 组 hidden_size,最佳 BLEU 3.06。到此为止,这是一个标准的调参实验。
然后我们做了一个看似无厘头的尝试:把 RNN 的激活函数从 tanh 换成 sin。
理由很朴素——sin 是周期函数。如果翻译本质是 hash 碰撞,周期函数天然支持"多桶"碰撞——同一个输出值可以从无限多个输入周期产生。tanh 只有一个桶(全局单调),sin 有无限个桶。理论上,多桶应该提供更多自由度。
结果:sin RNN 的最佳 BLEU = 0.76。 远低于 tanh 的 3.06。loss 从 6.32 跌到 6.19 就几乎不动了。
这不是"sin 比 tanh 差"这么简单。这个 0.76 里藏着一个更根本的问题。
梯度函数就是学习规律
神经网络的每一步训练都遵循同一个模式:
loss → 计算梯度 → 用梯度更新参数
而"计算梯度"这一步,激活函数的选择是决定性的一环。换个激活函数,就是换一套梯度规则——也就是换一种学习方式。
| 激活函数 | 梯度函数 | 梯度方向 | 学习特征 |
|---|---|---|---|
| tanh | tanh’(x) ∈ (0,1] | 永远为正,单调衰减 | 笨但稳——方向从不出错 |
| ReLU | 0 或 1 | 永远非负 | 莽但快——不衰减,但会死 |
| sin | cos(x) ∈ [-1,1] | 正负交替 | 聪明但自毁——自己否定自己 |
tanh’ 的范围是 (0,1]。值可以很小(接近饱和区),但符号不变。每一步梯度指向的方向,和全局最优方向一致。衰减只是让步子变小,不会让方向反了。
cos(x) 在每一个 π/2 的倍数处翻转符号。前半句学的方向,后半句亲手推翻。
模拟:为什么方向会反转
假设一段 RNN 的前激活值 z 随句子长度逐步偏移(模拟 W·h_{t-1} 的累积):
| 时间步 | z_t | tanh’(z) | 方向 | cos(z) | 方向 |
|---|---|---|---|---|---|
| 1 | 0.2 | +0.96 | → | +0.98 | → |
| 2 | 0.8 | +0.50 | → | +0.70 | → |
| 3 | 1.8 | +0.12 | → | −0.23 | ← |
| 4 | 2.5 | +0.02 | → | −0.80 | ← |
| 5 | 3.0 | +0.005 | → | −0.99 | ← |
tanh 所有时间步都往同一个方向推——力度越来越小,但方向一致。箱子被慢慢推到目标位置。
sin 在第 3 步翻转了方向。第 1-2 步往东推,第 3-5 步往西推。净位移接近零——箱子在原点附近来回跳舞。
这就是 BLEU=0.76 的根因。不是学不到东西,是学到的东西被自己亲手毁掉了。
好的梯度函数 = 自洽的向量场
把梯度想象成地形图上的箭头。每个参数位置都有一个箭头指向"下山"的方向——这就是向量场。
- tanh 的向量场:所有箭头指向同一个象限。可以弱,但方向一致。优化器只要跟着走,迟早到谷底。
- sin 的向量场:箭头来回翻转。优化器往前走两步,发现箭头指向回头了——刚走的路被否定。
“好的梯度函数"的标准不是"梯度够不够大”,而是"梯度方向是否和全局最优方向一致"。
tanh 的梯度小不是缺陷——它宁愿走得慢,也不走错方向。这是工程上的"慢就是快"。
loss 和 BLEU——两把不同的尺子
如果梯度函数的问题是方向,那还有一个更隐蔽的问题:梯度的方向是谁定的?
答案是 loss——CrossEntropy。但 CrossEntropy 追求的是"逐 token 预测精准",而 BLEU 考察的是"整句 n-gram 碰撞率"。两把尺子量的是不同的事。
H=512 跑 20 epoch 的铁证:
| epoch | loss | BLEU |
|---|---|---|
| 0 | 5.69 | 1.84 |
| 2 | 4.76 | 3.02 |
| 10 | 4.22 | 1.79 |
| 19 | 4.46 | 1.35 |
loss 持续下降(模型自认为越来越好),BLEU 在 epoch 2 达峰后一路衰退(实际翻译质量越来越差)。模型在 teacher forcing 的镜子里觉得自己很美,但别人看到的是东施效颦。
这意味着:即使我们选了一个"方向自洽"的梯度函数(如 tanh),梯度函数追的目标(loss)和最终评价标准(BLEU)之间存在结构性分歧。
BLEU 为什么不能直接当 loss
BLEU 的公式里有一个不可微的步骤——argmax。模型输出 logits 后,必须选一个词(argmax),然后在 n-gram 表里计数。argmax 是离散跳变:无论你把 cat 的概率从 0.4 提到 0.49,选出来的词不变——选的都是其他词。直到概率超过 0.51,argmax 的结果才会突然跳变。
所以 BLEU 对每个参数 W 的偏导链中,∂argmax/∂logits 这一项处处为零。整个梯度链直接断了。
全行业用 CrossEntropy 当 loss 不是因为 CE 比 BLEU “好”——是只有 CE 能传梯度。BLEU 更好,但数学不让你用。
Soft BLEU——让 BLEU 听到梯度的声音
如果把 argmax 换成 softmax,把硬 n-gram 计数换成概率加权:
$$\text{SoftBLEU} = \frac{\sum_{w} \min(p(w|ctx), c_{ref}(w))}{\sum_{w} p(w|ctx)}$$$p(w|ctx)$ 是模型预测 w 的连续概率。整条链可微——梯度可以直接从 BLEU 近似值流回模型参数。
训练时与 CrossEntropy 混合:
$$L_{total} = \lambda \cdot L_{CE} + (1-\lambda) \cdot (1 - \text{SoftBLEU})$$λ 从 1.0 逐步降到 0.5,让模型从"学 token"平滑过渡到"学翻译"。
四层 Hash 碰撞框架
把翻译过程看作四次 hash 碰撞:
| 层次 | hash 空间 | 碰撞判定 | 参与梯度? |
|---|---|---|---|
| 1. Embedding | E 维向量 | token→向量 | ✅ CrossEntropy |
| 2. Hidden (RNN) 或 Attention (Transformer) | H 维向量 | 整句→压缩向量 / 选择性碰撞 | ✅ CrossEntropy |
| 3. Decoder output | V 维 logits | 向量→token | ✅ CrossEntropy |
| 4. BLEU | n-gram 表 | 输出←→参考 | ❌ 不可微 |
前三次碰撞都参与梯度。第四次——BLEU 碰撞——模型根本听不到。
RNN 的悲剧是第 2 层(时间轴压缩破坏信息结构),Transformer 换了第 2 层(Attention 选择性碰撞),但第 4 层的问题——BLEU 不参与梯度——Transformer 也没解决。
实验结果:SoftBLEU 突破 CE 天花板
H=512, E=128, seed=42, batch=64, 在纯 RNN 上对比 CE-only 和 SoftBLEU 混合损失:
$$L_{total} = \lambda \cdot L_{CE} + (1-\lambda) \cdot (1 - \text{SoftBLEU}), \quad \lambda = 0.5$$| epoch | CE-only BLEU | CE | SoftBLEU BLEU | mixed loss | SoftBLEU 值 |
|---|---|---|---|---|---|
| 0 | 2.71 | 6.14 | 2.49 | 3.47 | 0.204 |
| 1 | 2.44 | 5.38 | 3.21 | 3.07 | 0.234 |
| 2 | 2.26 | 5.08 | 1.81 | 2.92 | 0.237 |
| 3 | 2.52 | 4.88 | 2.88 | 2.82 | 0.238 |
| 4 | 2.17 | 4.74 | 2.59 | 2.75 | 0.239 |
SoftBLEU best BLEU = 3.21(epoch 1),CE-only best = 3.06(epoch 0)。首次突破纯 CE 天花板。
SoftBLEU 值自身从 0.204 → 0.239 逐步提升——模型在学会优化 BLEU 的 soft 近似。但提升幅度只有 +0.15,随后也陷入了过拟合。
向量化是关键。最初的 Python 循环版 2 小时跑不出一个 epoch(详见 第六篇)。用 scatter_add_ 替代 4 层 Python 循环后,5 epoch 仅需 5 分钟,速度提升 1000 倍。
这条路通向哪里
sin 实验的失败,不是告诉我们"sin 不好"。它告诉我们:梯度函数的选择不是调参——是选择一种学习规律。 一个不能自洽的梯度函数,再大的模型也救不回来。
tanh 的梯度方向自洽,但目标是 loss 而非 BLEU。模型沿着 loss 的梯度方向走得太远,BLEU 反而掉进了过拟合的沟。这条沟就是 Soft BLEU 要填的。
Transformer 换了更聪明的碰撞策略(QK^T = 多头注意力),但梯度函数依然是 CrossEntropy。如果 Soft BLEU 能在 RNN 上证明可行——哪怕只提升 0.5 个 BLEU——那它在 Transformer 上的效果只会更大。
因为方向对了。从"梯度方向自洽"到"梯度目标对齐",这条规律不看模型架构。
May the Code be with us.
License: GPLv3
本文《SameTime》系列采用 GNU 通用公共许可证第三版 (GNU General Public License v3.0) 协议进行开源发布与分发。允许任何形式的复制、修改和分发,但必须继承相同的开源协议,承认在算力宇宙中所有的迭代与变异。