You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一nn.Module实例用于两个子网络时权重是否共享?如何实现权重独立?

问题

场景说明

我定义了如下PyTorch网络作为最简示例:

class Convolution_Layers(nn.Module):
  def __init__(self, in, out, kernel):
    super(Convolution_Layers, self).__init__()
  
    self.conv2d = nn.Conv2d(in_channels=in, out_channels=out, kernel_size=kernel)

    self.conv2d_layers = nn.Sequential(
      self.conv2d,
      nn.ReLU,
    )

  forward(self,x):
    return self.conv2d_layers(x)
    

class Network_Model(nn.Module):
  def __init__(self):
    super(Network_Model, self).__init__()
    self.basic_conv = Convolution_layers(1,1,3)

    self.subnetwk_1 = nn.ModuleList().append([self.basic_conv])
    self.subnetwk_2 = nn.ModuleList().append([self.basic_conv])

  def forward(self,x1,x2):
    out1, out2 = x1, x2
    for l in self.subnetwk_1:
      out1 = l(x1)
    for l in self.subnetwk_2:
      out2 = l(x2)
    return out1,out2

注:原代码存在两处小问题:forward方法缺少def关键字;实例化时类名拼写错误(Convolution_layers应为Convolution_Layers)。

疑问

  1. 由于subnetwk_1和subnetwk_2使用的是同一个Convolution_Layers实例,二者是否会共享权重?
  2. 我希望两个子网络的权重相互独立,但仅需定义一次基础卷积块并在多处复用,请问有更优实现方式?

解答

关于权重共享的问题

是的,subnetwk_1和subnetwk_2会完全共享权重。因为它们引用的是同一个Convolution_Layers实例self.basic_conv,PyTorch中Module的权重参数绑定在实例本身,所有对该实例的调用都会使用同一组权重,反向传播时梯度也会累积到这组权重上。

另外需要纠正代码中的一个错误:nn.ModuleList().append([self.basic_conv])的写法是无效的,append方法不会返回新的ModuleList,而是在原对象上修改,最终self.subnetwk_1和self.subnetwk_2会是None。正确写法应为:

self.subnetwk_1 = nn.ModuleList([self.basic_conv])
self.subnetwk_2 = nn.ModuleList([self.basic_conv])

实现独立权重的复用方案

要达成“定义一次基础块,多处复用且权重独立”的需求,推荐以下几种方式:

1. 直接多次实例化基础块

在父Module的__init__方法中创建多个独立的Convolution_Layers实例,基础块的定义只写一次:

class Network_Model(nn.Module):
  def __init__(self):
    super(Network_Model, self).__init__()
    # 创建两个独立实例,权重完全分离
    self.subnetwk_1 = nn.ModuleList([Convolution_Layers(1,1,3)])
    self.subnetwk_2 = nn.ModuleList([Convolution_Layers(1,1,3)])

  def forward(self,x1,x2):
    out1 = x1
    for l in self.subnetwk_1:
      out1 = l(out1)
    out2 = x2
    for l in self.subnetwk_2:
      out2 = l(out2)
    return out1,out2

2. 用工厂函数封装基础块创建

如果基础块的参数较多或需要在多个地方复用,可以用工厂函数统一管理实例创建逻辑:

def create_basic_conv(in_ch=1, out_ch=1, kernel=3):
    return Convolution_Layers(in_ch, out_ch, kernel)

class Network_Model(nn.Module):
  def __init__(self):
    super(Network_Model, self).__init__()
    self.subnetwk_1 = nn.ModuleList([create_basic_conv()])
    self.subnetwk_2 = nn.ModuleList([create_basic_conv()])

  def forward(self,x1,x2):
    out1 = x1
    for l in self.subnetwk_1:
      out1 = l(out1)
    out2 = x2
    for l in self.subnetwk_2:
      out2 = l(out2)
    return out1,out2

3. 动态实例化适配复杂场景

如果需要根据配置批量创建不同参数的块,可以结合配置列表动态生成:

class Network_Model(nn.Module):
  def __init__(self, conv_configs=[(1,1,3), (1,1,3)]):
    super(Network_Model, self).__init__()
    self.subnets = nn.ModuleDict()
    for i, cfg in enumerate(conv_configs):
        self.subnets[f"subnet_{i+1}"] = nn.ModuleList([Convolution_Layers(*cfg)])

  def forward(self,x1,x2):
    out1 = x1
    for l in self.subnets["subnet_1"]:
      out1 = l(out1)
    out2 = x2
    for l in self.subnets["subnet_2"]:
      out2 = l(out2)
    return out1,out2

内容的提问来源于stack exchange,提问作者wkacct acctwk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:11:16