You need to enable JavaScript to run this app. 能否在Pytorch或TensorFlow中对已冻结神经网络做宽度方向节点扩展
优惠活动
大模型
产品
解决方案
定价
更多

能否在Pytorch或TensorFlow中对已冻结神经网络做宽度方向节点扩展

冻结神经网络宽度扩展的实现方案

模型宽度扩展效果示意图

该操作在PyTorch和TensorFlow中都可以实现,以下是基于你提供的初始模型的PyTorch实现方案,TensorFlow实现思路一致,仅API调用有差异:


实现逻辑说明

  • PyTorch中全连接层nn.Linear的权重参数维度为(输出特征数, 输入特征数),偏置参数维度为(输出特征数,)
  • 扩展时优先保留原模型所有已冻结的权重值,仅对新增维度对应的参数做随机初始化
  • 通过梯度钩子强制原有权重对应的梯度在反向传播时清零,保证原有权重不会被更新,仅新增参数参与训练

完整实现代码

import torch
import torch.nn as nn

# 原模型定义及冻结流程
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.fc1 = nn.Linear(3, 5)  
        self.fc2 = nn.Linear(5, 3)
        self.fc3 = nn.Linear(3, 1)
    def forward(self,x):
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x       

# 初始化原模型并冻结所有参数
original_model = Net()
for param in original_model.parameters():
    param.requires_grad = False

# ---------------------- 模型宽度扩展 ----------------------
# 扩展后的维度配置
h1_new = 7 # 原5个节点+新增2个
h2_new = 4 # 原3个节点+新增1个
out_new = 2 # 原1个输出+新增1个

# 1. 扩展第一层fc1:输入维度3不变,输出从5扩展到7
extended_fc1 = nn.Linear(3, h1_new)
# 保留原fc1的权重和偏置
extended_fc1.weight.data[:5, :] = original_model.fc1.weight.data
extended_fc1.bias.data[:5] = original_model.fc1.bias.data
# 注册梯度钩子:反向传播时把原有5个节点对应的梯度置0
def freeze_original_out_grad(grad, original_dim):
    grad_clone = grad.clone()
    grad_clone[:original_dim] = 0.
    return grad_clone
extended_fc1.weight.register_hook(lambda grad: freeze_original_out_grad(grad, 5))
extended_fc1.bias.register_hook(lambda grad: freeze_original_out_grad(grad, 5))

# 2. 扩展第二层fc2:输入从5扩展到7,输出从3扩展到4
extended_fc2 = nn.Linear(h1_new, h2_new)
# 保留原fc2中对应原输入、原输出位置的权重
extended_fc2.weight.data[:3, :5] = original_model.fc2.weight.data
extended_fc2.bias.data[:3] = original_model.fc2.bias.data
# 注册梯度钩子:原有输出、原有输入对应的权重梯度清零
def fc2_grad_hook(grad, original_out, original_in):
    grad_clone = grad.clone()
    grad_clone[:original_out, :original_in] = 0.
    return grad_clone
extended_fc2.weight.register_hook(lambda grad: fc2_grad_hook(grad, 3, 5))
extended_fc2.bias.register_hook(lambda grad: freeze_original_out_grad(grad, 3))

# 3. 扩展输出层fc3:输入从3扩展到4,输出从1扩展到2
extended_fc3 = nn.Linear(h2_new, out_new)
# 保留原fc3的权重
extended_fc3.weight.data[:1, :3] = original_model.fc3.weight.data
extended_fc3.bias.data[:1] = original_model.fc3.bias.data
# 注册梯度钩子
def fc3_grad_hook(grad, original_out, original_in):
    grad_clone = grad.clone()
    grad_clone[:original_out, :original_in] = 0.
    return grad_clone
extended_fc3.weight.register_hook(lambda grad: fc3_grad_hook(grad, 1, 3))
extended_fc3.bias.register_hook(lambda grad: freeze_original_out_grad(grad, 1))

# 组装扩展后的新模型
class ExtendedNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = extended_fc1
        self.fc2 = extended_fc2
        self.fc3 = extended_fc3
    def forward(self, x):
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x

extended_model = ExtendedNet()

# ---------------------- 效果验证 ----------------------
test_input = torch.rand(5,3)
original_output = original_model(test_input)
extended_output = extended_model(test_input)

print("扩展后模型输出维度:", extended_output.shape) # 输出为torch.Size([5, 2]),符合要求
print("原有逻辑一致性验证误差:", torch.abs(original_output - extended_output[:,0].unsqueeze(1)).sum().item())
# 误差为0或极小浮点误差,证明原有冻结权重完全保留,未被修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 10:24:00