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

PyTorch中如何同步训练GNN内部实例化的线性神经网络

问题解答

你当前给出的代码存在核心问题:将linear_NN的实例化逻辑写在了GNN的forward方法中,这会导致每次前向传播都会生成全新的linear_NN实例,参数无法持久化,自然也没法完成训练。正确的实现和训练流程如下:

第一步:修正模型类定义

要把内部子模型的实例化放到__init__方法中,这样PyTorch会自动把子模型的参数注册到父模型的参数列表中,不需要额外手动管理。

import torch
import torch.nn as nn
import torch.optim as optim

class linear_NN(nn.Module):
    def __init__(self, input_dim, out_dim):
        super().__init__()
        # 以下为线性网络的示例实现,可替换为你自己的逻辑
        self.fc1 = nn.Linear(input_dim, 128)
        self.act = nn.ReLU()
        self.fc2 = nn.Linear(128, out_dim)

    def forward(self, x, dim = 0):
        '''Forward pass'''
        x = self.fc1(x)
        x = self.act(x)
        x = self.fc2(x)
        return x
class GNN(nn.Module):
    def __init__(self, input_dim, n_hidden, out_dim, linear_in_dim, linear_out_dim):
        super().__init__()
        # GNN自身的层,以下为简化示例,可替换为你自己的GNN实现
        self.gnn_conv1 = nn.Linear(input_dim, n_hidden)
        self.gnn_conv2 = nn.Linear(n_hidden, out_dim)
        # 把linear_NN实例化放在__init__里,作为GNN的成员属性
        self.linear_submodel = linear_NN(linear_in_dim, linear_out_dim)

    def forward(self, h, dim = 0):
        '''Forward pass'''
        # 先跑GNN自身的前向逻辑
        h = self.gnn_conv1(h)
        h = nn.ReLU()(h)
        h = self.gnn_conv2(h)
        # 调用内部的线性子模型
        h = self.linear_submodel(h, dim)
        return h

第二步:训练流程

方案1:联合优化两个模型的所有参数(最常用)

因为子模型参数已经自动注册到GNN的参数列表里了,直接把GNN实例的所有参数传给优化器即可,训练逻辑和普通单模型完全一致:

# 模型实例化
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = GNN(input_dim=16, n_hidden=32, out_dim=64, linear_in_dim=64, linear_out_dim=10).to(device)

# 优化器直接传入model.parameters(),会自动包含GNN和内部linear_NN的所有参数
optimizer = optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()

# 正常训练循环
for epoch in range(100):
    model.train()
    # 这里替换成你自己的数据集加载逻辑
    x = torch.randn(32, 16).to(device) # batch_size=32,特征维度16
    y = torch.randint(0, 10, (32,)).to(device)
    
    optimizer.zero_grad()
    pred = model(x)
    loss = loss_fn(pred, y)
    loss.backward()
    optimizer.step()
    
    if epoch % 10 == 0:
        print(f"Epoch {epoch}, Loss: {loss.item():.4f}")

方案2:分开优化两个模型的参数(适配差异化训练策略场景)

如果需要给GNN和线性子模型设置不同的学习率、权重衰减等训练策略,可以分别提取两类参数传给不同的优化器:

model = GNN(input_dim=16, n_hidden=32, out_dim=64, linear_in_dim=64, linear_out_dim=10).to(device)

# 分别提取两类参数
gnn_params = list(model.gnn_conv1.parameters()) + list(model.gnn_conv2.parameters())
linear_params = model.linear_submodel.parameters()

# 两个优化器分别设置不同的超参数
optimizer_gnn = optim.Adam(gnn_params, lr=1e-3)
optimizer_linear = optim.Adam(linear_params, lr=5e-4)
loss_fn = nn.CrossEntropyLoss()

# 训练循环
for epoch in range(100):
    model.train()
    x = torch.randn(32, 16).to(device)
    y = torch.randint(0, 10, (32,)).to(device)
    
    optimizer_gnn.zero_grad()
    optimizer_linear.zero_grad()
    pred = model(x)
    loss = loss_fn(pred, y)
    loss.backward()
    # 两个优化器分别更新参数
    optimizer_gnn.step()
    optimizer_linear.step()
    
    if epoch % 10 == 0:
        print(f"Epoch {epoch}, Loss: {loss.item():.4f}")

内容的提问来源于stack exchange,提问作者Driss AL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:48:04