讲师中心 微信公众号
AI工具推荐 视频效率加速

PyTorch 自定义网络中权重矩阵未更新的根本原因与解决方案

冬墨酱_9755

冬墨酱_9755

发布时间:2026-02-23 10:54:18

|

699人浏览过

|

来源于php中文网

原创

PyTorch 自定义网络中权重矩阵未更新的根本原因与解决方案

本文深入解析 PyTorch 自定义网络中全局邻接矩阵(adjacency matrix)无法更新的典型错误:核心在于 nn.Parameter 的误用与计算图断裂,明确指出参数未参与前向传播即失去梯度路径,并提供可直接运行的修复方案。

本文深入解析 pytorch 自定义网络中全局邻接矩阵(adjacency matrix)无法更新的典型错误:核心在于 `nn.parameter` 的误用与计算图断裂,明确指出参数未参与前向传播即失去梯度路径,并提供可直接运行的修复方案。

在 PyTorch 中,模型参数能否被优化器更新,唯一决定性条件是该张量必须同时满足两个要求:

  1. 是 nn.Parameter 类型(从而自动注册到 model.parameters() 中);
  2. 在 forward 方法中被实际用于计算输出(从而构建完整的反向传播计算图)。

回顾原始代码,问题根源非常清晰:

  • ✅ self.subdiagonal_block 被正确定义为 nn.Parameter,具备可训练属性;
  • ❌ 但它从未在 forward 中被直接使用——而是被传入 make_subdiagonal_matrix() 构造 self.adjacency_matrix;
  • ❌ self.adjacency_matrix = self.make_subdiagonal_matrix().requires_grad_(True) 这行代码创建的是一个普通张量(Tensor),即使调用 .requires_grad_(True),它也不是 nn.Parameter,不会被 model.parameters() 收集,优化器完全“看不见”它;
  • ❌ 更关键的是,make_subdiagonal_matrix() 内部对 self.subdiagonal_block 的引用属于静态构造行为(发生在 __init__ 阶段),而非动态计算过程。因此,subdiagonal_block 的梯度无法回传——因为它没有参与任何 forward 中的运算节点。

? 简单验证:打印 list(model.parameters()) 会发现只有 subdiagonal_block,而 adjacency_matrix 不在其中;再检查 subdiagonal_block.grad 在反向传播后始终为 None,即可确认其未接入计算图。

PyTorch Linux版 2.11.0
PyTorch Linux版 2.11.0

PyTorch 2.11.0 历史版本下载,来自 PyPI 官方发布,适合旧项目兼容、实验复现和指定环境安装。

下载

✅ 正确实现:让参数真正“流动”起来

解决方案是彻底消除静态矩阵缓存,将邻接矩阵的构建逻辑移入 forward,并确保所有参与计算的张量均为 nn.Parameter 或其直接运算结果。以下是修复后的完整可运行类:

import torch
import torch.nn as nn

class SimpleDirectNetworkWithAdjacency(nn.Module):
    def __init__(self, input_dim, middle_dim, output_dim):
        super().__init__()
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.total_dim = input_dim + output_dim

        # 唯一可训练参数:子对角块(即实际权重)
        self.weight = nn.Parameter(torch.empty(output_dim, input_dim))
        nn.init.normal_(self.weight, mean=0.0, std=0.1)

    def forward(self, x):
        # x: [B, C, H, W] → flatten to [B, input_dim]
        B = x.size(0)
        x_flat = x.view(B, -1)  # shape: [B, input_dim]

        # 构建动态邻接矩阵(每次 forward 重建,确保计算图完整)
        # 上方块:input_dim × input_dim 零矩阵
        over_block = torch.zeros(self.input_dim, self.input_dim, device=x.device)
        # 右侧块:total_dim × output_dim 零矩阵(注意:total_dim = input_dim + output_dim)
        side_block = torch.zeros(self.total_dim, self.output_dim, device=x.device)
        # 拼接:[input_dim, input_dim] + [output_dim, input_dim] → [total_dim, input_dim]
        left_col = torch.cat([over_block, self.weight], dim=0)  # shape: [total_dim, input_dim]
        # 拼接:[total_dim, input_dim] + [total_dim, output_dim] → [total_dim, total_dim]
        adjacency = torch.cat([left_col, side_block], dim=1)  # shape: [total_dim, total_dim]

        # 扩展输入:[B, input_dim] → [total_dim, B](需转置以匹配 mm 维度)
        x_padded = torch.cat([
            x_flat.t(),  # [input_dim, B]
            torch.zeros(self.output_dim, B, device=x.device)
        ], dim=0)  # shape: [total_dim, B]

        # 矩阵乘法:adjacency @ x_padded → [total_dim, B]
        y_total = torch.mm(adjacency, x_padded)  # shape: [total_dim, B]
        # 提取输出 logits:最后 output_dim 行 → [output_dim, B] → 转置为 [B, output_dim]
        logits = y_total[-self.output_dim:].t()  # shape: [B, output_dim]

        return logits

⚠️ 关键注意事项

  • 禁止在 __init__ 中缓存非 nn.Parameter 的中间张量(如原代码中的 self.adjacency_matrix)。PyTorch 不跟踪此类对象的梯度。
  • 所有参与 forward 计算的可学习结构,必须源于 nn.Parameter 或其可微运算。torch.cat、torch.zeros 等操作本身不可学,但若其输入含 Parameter,则整个表达式可导。
  • 设备一致性:示例中显式使用 device=x.device,避免 CPU/GPU 不匹配导致的运行时错误。
  • 内存效率考量:本例每次 forward 重建大矩阵(如 784+10=794 维时达 794×794),虽逻辑正确,但实践中可考虑更高效的稀疏或分块实现——但绝不能以牺牲梯度流为代价。

✅ 验证是否生效

训练前加入以下断言,确保修复成功:

model = SimpleDirectNetworkWithAdjacency(input_dim=784, middle_dim=0, output_dim=10)
print("Trainable parameters:", list(model.named_parameters()))
# 应输出: [('weight', Parameter(...))]

# 模拟一次前向-反向
x = torch.randn(4, 1, 28, 28)
y_pred = model(x)
loss = y_pred.sum()
loss.backward()

print("weight.grad is not None:", model.weight.grad is not None)  # 应为 True

只要 weight.grad 不为 None,即证明梯度已正确回传,优化器后续调用 step() 即可更新权重。至此,基于全局邻接矩阵的自定义网络已具备完整可训练能力——参数定义、计算图连接、优化器集成,三者缺一不可。

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
pytorch是干嘛的
pytorch是干嘛的

pytorch是一个基于python的深度学习框架,提供以下主要功能:动态图计算,提供灵活性。强大的张量操作,实现高效处理。自动微分,简化梯度计算。预构建的神经网络模块,简化模型构建。各种优化器,用于性能优化。想了解更多pytorch的相关内容,可以阅读本专题下面的文章。

2283

2024.05.29

Python AI机器学习PyTorch教程_Python怎么用PyTorch和TensorFlow做机器学习
Python AI机器学习PyTorch教程_Python怎么用PyTorch和TensorFlow做机器学习

PyTorch 是一种用于构建深度学习模型的功能完备框架,是一种通常用于图像识别和语言处理等应用程序的机器学习。 使用Python 编写,因此对于大多数机器学习开发者而言,学习和使用起来相对简单。 PyTorch 的独特之处在于,它完全支持GPU,并且使用反向模式自动微分技术,因此可以动态修改计算图形。

68

2025.12.22

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

20

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

0

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

20

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

0

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

20

2026.10.22

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

0

2026.10.22

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn