5. sigmoid、SiLU 与 SwiGLU
5.1 sigmoid:把实数压到 (0,1)
定义
\[ \sigma(x)=\frac{1}{1+e^{-x}} . \]它有几个立刻能看出的性质:\(x\to+\infty\) 时 \(e^{-x}\to0\),\(\sigma\to1\);\(x\to-\infty\) 时 \(\sigma\to0\);\(\sigma(0)=1/2\);且 \(\sigma(-x)=1-\sigma(x)\)(分子分母同乘 \(e^x\) 可验证)。
它还是“对数几率”的反函数:若 \(p=\sigma(x)\),则
\[ \frac{p}{1-p}=\frac{1/(1+e^{-x})}{e^{-x}/(1+e^{-x})}=e^{x}, \qquad x=\ln\frac{p}{1-p}. \]所以 sigmoid 把“logit”变成“概率”,和 softmax 在二分类时完全一致。
5.2 sigmoid 的导数
用链式法则,外层是 \(u^{-1}\),内层 \(u=1+e^{-x}\):
\[ \frac{d\sigma}{dx}=-(1+e^{-x})^{-2}\cdot(-e^{-x}) =\frac{e^{-x}}{(1+e^{-x})^2}. \]而 \(1-\sigma=\dfrac{e^{-x}}{1+e^{-x}}\),所以
\[ \boxed{\sigma'(x)=\sigma(x)\big(1-\sigma(x)\big).} \]这个形式非常省事:算过一次 \(\sigma\),导数只需一次乘法。
5.3 SiLU:\(x\) 乘上自己的门
SiLU(也叫 swish)定义为
\[ \operatorname{SiLU}(x)=x\,\sigma(x)=\frac{x}{1+e^{-x}} . \]它和 ReLU 的区别:负半轴不是硬的 0,而是一条平滑的负值小尾巴;在 \(x\approx-1.278\) 处取最小值约 \(-0.278\),然后趋于 0。这个“非单调”是故意的,让梯度在负区也有信息。
导数用乘积法则:
\[ \frac{d}{dx}\big(x\sigma(x)\big)=\sigma(x)+x\sigma'(x) =\sigma(x)+x\sigma(x)\big(1-\sigma(x)\big) =\sigma(x)\big(1+x(1-\sigma(x))\big). \]代码里只在前向用它,不手写导数;但知道它处处可导,能解释为什么比 ReLU 平滑。
5.4 SwiGLU:门控 MLP
普通两层 MLP 是 \(W_2\,\phi(W_1x)\)。SwiGLU 用两条并行的投影,一条当“门”,一条当“内容”,逐元素相乘:
\[ \boxed{\operatorname{MLP}(x)=W_{\text{down}}\Big(\operatorname{SiLU}(W_{\text{gate}}x)\odot(W_{\text{up}}x)\Big).} \]\(\odot\) 是逐元素乘。为什么这样设计?逐元素乘法让每个中间维度的“开关”由输入动态决定:\(\operatorname{SiLU}(g_i)\) 大就放行 \(u_i\),小就抑制。它比固定非线性多了一次乘法的交互能力。
维度:\(W_{\text{gate}},W_{\text{up}}\in\mathbb{R}^{3072\times1024}\),\(W_{\text{down}}\in\mathbb{R}^{1024\times3072}\)。三个矩阵共 \(9{,}437{,}184\) 参数,比“两个 \(4096\times1024\) 矩阵”的经典 4 倍 MLP(8.4M)略大,这是 SwiGLU 常见的 \(8/3\) 倍宽度调整。
是 SiLU(gate) * up,不是相加,也不是 SiLU(up) * gate。形状都对、代码不报错,但数值完全不同。
对应代码:model/mlp.go 的 MLP,model/tensor.go 的 SiLU。