PyTorch中nn.Linear内部运行机制及两种写法差异解析
PyTorch中nn.Linear两种写法不等价的原因解析
首先得明确PyTorch里nn.Linear的核心运行逻辑:它的计算公式是 y = x @ W.T + b,其中:
W是形状为(out_features, in_features)的权重矩阵,默认用Kaiming均匀分布初始化;b是形状为(out_features,)的偏置向量,默认初始化为0(当bias=True时,这是默认配置)。
接下来拆解你提到的两种写法,就能明白它们为什么不等价:
第一种写法:两个独立的nn.Linear层相加
Wf = nn.Linear(x_size, o_size) Uf = nn.Linear(h_size, o_size) output = Wf(x) + Uf(h)
这个逻辑展开后是:
output = (x @ Wf_weight.T + Wf_bias) + (h @ Uf_weight.T + Uf_bias)
也就是:
output = x@Wf_weight.T + h@Uf_weight.T + (Wf_bias + Uf_bias)
这里的关键是:
Wf和Uf是两个完全独立的层,各自拥有一套独立的权重矩阵和偏置;- 训练过程中,这两套参数会被分别更新,彼此没有关联。
第二种写法:单个nn.Linear处理拼接张量
W = nn.Linear(x_size + h_size, o_size) output = W(torch.cat([x, h], dim=1))
展开后的计算逻辑是:
output = torch.cat([x, h], dim=1) @ W_weight.T + W_bias
把拼接后的张量拆开来,等价于:
output = x@W_weight[:, :x_size].T + h@W_weight[:, x_size:].T + W_bias
这里的特点是:
- 只有一套权重矩阵
W_weight,它被分成了对应x和h的两个子部分; - 只有一套偏置
W_bias,没有额外的相加操作。
两者不等价的核心原因
从数学公式上看,只要满足W_weight[:, :x_size] = Wf_weight、W_weight[:, x_size:] = Uf_weight、W_bias = Wf_bias + Uf_bias,两种写法就能得到相同结果,但实际中这三个条件几乎不可能满足:
- 初始化差异:PyTorch对每个
nn.Linear的权重都是独立初始化的,单个层的权重是整体初始化的,拆分后的子部分和两个独立层的权重初始值完全不同; - 参数更新差异:第一种写法的两套参数是分别优化的,第二种是对整个权重矩阵和单个偏置优化,训练过程中参数的变化方向和幅度完全独立;
- 偏置逻辑差异:即使偏置初始都是0,训练时第一种是两个偏置分别更新后相加,第二种是单个偏置更新,最终的偏置值也会不一样。
简单说,这两种写法本质上是使用了完全不同的参数集合,只是数学形式上看起来类似,实际运行和训练后的结果自然不等价。
内容的提问来源于stack exchange,提问作者Lolek
相关产品推荐
相关产品推荐

