# 显示卷积求导框架 **Repository Path**: anjiang2020_admin/seegradnet ## Basic Information - **Project Name**: 显示卷积求导框架 - **Description**: SeeGradNet——捕捉框架的本质:看见梯度,理解深度学习! 📖全称: SeeGradNet-Explicit Learning Framework 🎯使命: 让深度学习从"黑箱"变成"透明数学" 👥受众: 深度学习初学者、教育者、研究者 💡核心: 显式的前向链 + 显式的求导链 🏷️标语: See Every Gradient. Understand Every Step - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ ███████╗███████╗███████╗ ██████╗ ██████╗ █████╗ ██████╗ ███╗ ██╗███████╗████████╗ │ ██╔════╝██╔════╝██╔════╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗████╗ ██║██╔════╝╚══██╔══╝ │ █████╗ █████╗ █████╗ ██║ ███╗██████╔╝███████║██║ ██║██╔██╗ ██║█████╗ ██║ │ ██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║██╔══██╗██╔══██║██║ ██║██║╚██╗██║██╔══╝ ██║ │ ███████╗███████╗███████╗╚██████╔╝██║ ██║██║ ██║██████╔╝██║ ╚████║███████╗ ██║ │ ╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ │ │ │ ════════════════════════════════════════════════════════════════════════════════ │ │ │ │ 📖 全称: SeeGradNet - Explicit Learning Framework │ │ 🎯 使命: 让深度学习从"黑箱"变成"透明数学" │ │ 👥 受众: 深度学习初学者、教育者、研究者 │ │ 💡 核心: 显式的前向链 + 显式的求导链 │ │ 🏷️ 标语: "See Every Gradient. Understand Every Step." │ │ │ │ ════════════════════════════════════════════════════════════════════════════════ │ │ │ │ 代码即文档 · 训练即教学 · 理解即掌握 │ │ │ └───────────────────────────────────────────────────────────────────────────────────── ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ 传统框架教你怎么调用 │ │ 显式学习框架教你怎么思考 │ │ │ │ "不要把反向传播藏在 backward() 里, │ │ 把它写在 D_conv1, D_conv2, ... 里, │ │ 让每个初学者都能看懂。" │ │ │ │ —— 显式学习框架的哲学 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┘ 运行办法(python 3.6.9): python seegradnet.py SEEGRADNET 显式学习框架-让深度学习透明化 核心理念: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ 传统框架 vs 显式学习框架 │ │ ──────────── ────────────── │ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ 黑箱魔法 │ │ 透明数学 │ │ │ │ ┌───────────────┐ │ │ ┌───────────────┐ │ │ │ │ │ forward() │ │ │ │ predict_chain │ │ │ │ │ │ (前向计算) │ │ │ │ (看得见的计算)│ │ │ │ │ └───────────────┘ │ │ └───────────────┘ │ │ │ │ ┌───────────────┐ │ │ ┌───────────────┐ │ │ │ │ │ backward() │ │ │ │learn_chain│ │ │ │ │ │ (自动求导) │ │ ──── 显式化 ──── │ │ (看得见的求导) │ │ │ │ │ └───────────────┘ │ │ └───────────────┘ │ │ │ │ ↑ │ │ ↑ │ │ │ │ 用户看不到 │ │ 用户完全看到 │ │ │ └─────────────────────┘ └─────────────────────┘ │ │ │ │ 用户只能调用 用户可以阅读、修改、调试 │ │ model.fit(x, y) 每条链的每一步 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 初学者的学习路径: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ 从 "会用" 到 "懂原理" 的学习路径 │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 阶段 1: 看到完整的计算链 │ │ ────────────────────── │ │ │ │ 前向链: conv1 → tanh1 → conv2 → tanh2 → pool → flatten → │ │ fc1 → tanh3 → fc2 → tanh4 → fc3 → loss │ │ │ │ 求导链: D_loss → D_fc3 → D_tanh4 → D_fc2 → D_tanh3 → D_fc1 → │ │ D_flatten → D_pool → D_tanh2 → D_conv2 → D_tanh1 → D_conv1 │ │ │ │ 👀 初学者一眼就能看到:数据怎么流、梯度怎么传 │ │ │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 阶段 2: 理解每一层的数学 │ │ ────────────────────── │ │ │ │ Conv2d: y = W * x + b │ │ D_Conv2d: dx = conv_transpose(dy, W), dW = conv(dy, x) │ │ │ │ Tanh: y = tanh(x) │ │ D_Tanh: dx = dy * (1 - tanh²(x)) │ │ │ │ Linear: y = W @ x + b │ │ D_Linear: dx = dy @ W.T, dW = dy.T @ x │ │ │ │ 📐 初学者看到:每个层的计算公式和求导公式 │ │ │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 阶段 3: 自定义求导方式 │ │ ────────────────────── │ │ │ │ 用户可以写自己的 D_Layer: │ │ │ │ class D_MyLayer(D_Layer): │ │ def _derivative_impl(self, dout): │ │ # 用户自定义的求导逻辑 │ │ dx = self.custom_gradient(dout) │ │ return dx, {'weight': self.custom_weight_grad} │ │ │ │ ✏️ 初学者可以动手改:换个求导方式会怎样? │ │ │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 阶段 4: 理解整个训练过程 │ │ ────────────────────── │ │ │ │ def do(self, x, labels): │ │ # 1. 前向计算 - 看得见 │ │ for layer in predict_chain: │ │ x = layer.do(x) │ │ │ │ # 2. 计算损失 - 看得见 │ │ loss = self.loss._loss │ │ │ │ # 3. 求导数 - 看得见 │ │ dout = 1 │ │ for d_layer in learn_chain: │ │ dout = d_layer.derivative(dout) │ │ │ │ # 4. 更新参数 - 看得见 │ │ for layer in trainable_layers: │ │ layer.update(dW, db) │ │ │ │ return loss │ │ │ │ 🎯 初学者看到:完整的训练过程,没有隐藏步骤 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 本框架的核心优势: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ 显式学习框架的六大优势 │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ① 透明度 (Transparency) │ │ │ │ ──────────────────────── │ │ │ │ 每一步计算都看得见,没有黑箱 │ │ │ │ 前向链: conv1 → tanh1 → conv2 → ... │ │ │ │ 求导链: D_loss → D_fc3 → D_tanh4 → ... │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ② 可编辑性 (Editability) │ │ │ │ ──────────────────────── │ │ │ │ 用户可以修改任意层的求导方式 │ │ │ │ 可以在链中插入自定义层 │ │ │ │ 可以替换任何层的实现 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ③ 可调试性 (Debuggability) │ │ │ │ ────────────────────────── │ │ │ │ 可以在任意位置插入 print() │ │ │ │ 可以检查每一步的梯度值 │ │ │ │ 可以可视化每一层的输出 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ④ 灵活性 (Flexibility) │ │ │ │ ───────────────────── │ │ │ │ 每层独立选择优化器 (SGD/Momentum/Adam/AdamW) │ │ │ │ 每层独立设置学习率 │ │ │ │ 浅层和深层可以有不同的学习策略 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ⑤ 教育性 (Educational) │ │ │ │ ───────────────────── │ │ │ │ 初学者看到的是"数学公式"而不是"魔法" │ │ │ │ 前向和求导一一对应,理解"导数"的概念 │ │ │ │ 从"调库"到"写数学"的平滑过渡 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ ⑥ 可控性 (Controllability) │ │ │ │ ───────────────────────── │ │ │ │ 梯度爆炸时可以看到在哪一步爆炸 │ │ │ │ 可以在任意位置做梯度裁剪 │ │ │ │ 可以设计非标准的训练流程 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 代码即文档: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ 代码本身就是最好的文档 │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 你写的每一行代码,都在解释深度学习: │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ # 这是前向链:数据怎么流 │ │ │ │ self.forward_chain = [ │ │ │ │ self.conv1, # 卷积: 提取特征 │ │ │ │ self.tanh1, # 激活: 非线性 │ │ │ │ self.conv2, # 卷积: 更深特征 │ │ │ │ self.tanh2, # 激活: 非线性 │ │ │ │ self.pool, # 池化: 降维 │ │ │ │ self.flatten, # 展平: 准备全连接 │ │ │ │ self.fc1, # 全连接: 分类 │ │ │ │ self.tanh3, # 激活: 非线性 │ │ │ │ self.fc2, # 全连接: 分类 │ │ │ │ self.tanh4, # 激活: 非线性 │ │ │ │ self.fc3, # 全连接: 输出 │ │ │ │ self.loss # 损失: 计算误差 │ │ │ │ ] │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ # 这是求导链:梯度怎么传 │ │ │ │ self.derivative_chain = [ │ │ │ │ self.D_loss, # 损失对logits的导数: p - y │ │ │ │ self.D_fc3, # 全连接导数: dout @ W.T │ │ │ │ self.D_tanh4, # tanh导数: dout * (1 - tanh²) │ │ │ │ self.D_fc2, # 全连接导数: dout @ W.T │ │ │ │ self.D_tanh3, # tanh导数: dout * (1 - tanh²) │ │ │ │ self.D_fc1, # 全连接导数: dout @ W.T │ │ │ │ self.D_flatten, # 展平导数: reshape回原形状 │ │ │ │ self.D_pool, # 池化导数: upsample / pool_size │ │ │ │ self.D_tanh2, # tanh导数: dout * (1 - tanh²) │ │ │ │ self.D_conv2, # 卷积导数: 转置卷积 │ │ │ │ self.D_tanh1, # tanh导数: dout * (1 - tanh²) │ │ │ │ self.D_conv1 # 卷积导数: 转置卷积 │ │ │ │ ] │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ 每一行都告诉初学者:这个层做什么、怎么求导 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 与传统框架相比: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ 用户体验对比 │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────────────────────────────┐ │ │ │ 传统框架 (PyTorch/TensorFlow) │ │ │ │ ────────────────────────────── │ │ │ │ │ │ │ │ class Net(nn.Module): │ │ │ │ def forward(self, x): │ │ │ │ x = self.conv1(x) # 前向计算 │ │ │ │ x = self.tanh1(x) # 前向计算 │ │ │ │ ... │ │ │ │ return x │ │ │ │ │ │ │ │ # 训练 │ │ │ │ loss = criterion(output, y) │ │ │ │ loss.backward() # ← 黑箱!用户看不到求导过程 │ │ │ │ optimizer.step() # ← 黑箱!用户看不到参数更新 │ │ │ │ │ │ │ │ ❌ 求导过程是隐藏的 │ │ │ │ ❌ 用户无法修改求导方式 │ │ │ │ ❌ 调试困难 │ │ │ └───────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────────────────────┐ │ │ │ 显式学习框架 (Explicit Learning Framework) │ │ │ │ ───────────────────────────────────── │ │ │ │ │ │ │ │ self.forward_chain = [conv1, tanh1, ...] # 前向链 │ │ │ │ self.derivative_chain = [D_loss, D_fc3, ...] # 求导链 (完全可见!) │ │ │ │ │ │ │ │ # 训练 │ │ │ │ for layer in forward_chain: │ │ │ │ x = layer.do(x) # 每一步都看得见 │ │ │ │ │ │ │ │ dout = 1 │ │ │ │ for d_layer in derivative_chain: │ │ │ │ dout = d_layer.derivative(dout) # 每一步求导都看得见! │ │ │ │ │ │ │ │ for layer in trainable_layers: │ │ │ │ layer.update(dW, db) # 每一步更新都看得见! │ │ │ │ │ │ │ │ ✅ 求导过程完全透明 │ │ │ │ ✅ 用户可以修改任意 D_ 层 │ │ │ │ ✅ 每一步都可以调试 │ │ │ └───────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 代码架构图: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ SeeGradNet - 显式学习框架 │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ 预测链 (predict_chain) │ │ │ │ ────────────────────── │ │ │ │ conv1 → tanh1 → conv2 → tanh2 → pool → flatten → │ │ │ │ fc1 → tanh3 → fc2 → tanh4 → fc3 → loss │ │ │ │ │ │ │ │ 每一层都做一件事:predict() → 做预测 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ 学习链 (learn_chain) │ │ │ │ ──────────────────── │ │ │ │ D_loss → D_fc3 → D_tanh4 → D_fc2 → D_tanh3 → D_fc1 → │ │ │ │ D_flatten → D_pool → D_tanh2 → D_conv2 → D_tanh1 → D_conv1 │ │ │ │ │ │ │ │ 每一层都做一件事:learn() → 从误差中学习 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ │ │ step(x, labels) │ │ │ │ ──────────────── │ │ │ │ 1. 预测 → 得到预测结果 │ │ │ │ 2. 学习 → 从误差中学习梯度 │ │ │ │ 3. 成长 → 用梯度更新参数 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ 给初学者的礼物: # ============================================================ # 这就是你的第一个"看得懂"的深度学习框架! # ============================================================ # 1. 前向链 - 数据怎么流 forward_chain = [ Conv2d(1, 6, 5), # 输入1通道 → 输出6通道 Tanh(), # 激活函数 Conv2d(6, 16, 5), # 输入6通道 → 输出16通道 Tanh(), # 激活函数 AvgPool2d(2), # 2x2 池化,尺寸减半 Flatten(), # 展平为向量 Linear(2304, 120), # 全连接 Tanh(), Linear(120, 84), # 全连接 Tanh(), Linear(84, 10), # 输出10类 LogitLoss() # 计算损失 ] # 2. 求导链 - 梯度怎么传 (每一层都有对应的 D_ 层) derivative_chain = [ D_LogitLoss(loss), # dLoss/dlogits = p - y D_Linear(fc3), # dLoss/dW3, dLoss/dx3 D_Tanh(tanh4), # dLoss/dx4 = dout * (1 - tanh²) D_Linear(fc2), # dLoss/dW2, dLoss/dx2 D_Tanh(tanh3), # dLoss/dx3 = dout * (1 - tanh²) D_Linear(fc1), # dLoss/dW1, dLoss/dx1 D_Flatten(flatten), # 恢复形状 D_AvgPool2d(pool), # 上采样 D_Tanh(tanh2), # dLoss/dx2 = dout * (1 - tanh²) D_Conv2d(conv2), # 转置卷积 D_Tanh(tanh1), # dLoss/dx1 = dout * (1 - tanh²) D_Conv2d(conv1) # 转置卷积 ] # 3. 训练一步 def do(x, y): # 前向: 从左到右 for layer in forward_chain: x = layer.do(x) # 求导: 从右到左 (看! 每一行都是数学公式!) dout = 1 for d_layer in derivative_chain: dout = d_layer.derivative(dout) # 更新: 每层独立 for layer in trainable_layers: layer.update(dW, db) 最后一句话: ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ 传统框架教你怎么调用 │ │ 显式学习框架教你怎么思考 │ │ │ │ "不要把反向传播藏在 backward() 里, │ │ 把它写在 D_conv1, D_conv2, ... 里, │ │ 让每个初学者都能看懂。" │ │ │ │ —— 显式学习框架的哲学 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘