A transparent deep learning framework with explicit predict and learn chains.
Project description
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ ███████╗███████╗███████╗ ██████╗ ██████╗ █████╗ ██████╗ ███╗ ██╗███████╗████████╗
│ ██╔════╝██╔════╝██╔════╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗████╗ ██║██╔════╝╚══██╔══╝
│ █████╗ █████╗ █████╗ ██║ ███╗██████╔╝███████║██║ ██║██╔██╗ ██║█████╗ ██║
│ ██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║██╔══██╗██╔══██║██║ ██║██║╚██╗██║██╔══╝ ██║
│ ███████╗███████╗███████╗╚██████╔╝██║ ██║██║ ██║██████╔╝██║ ╚████║███████╗ ██║
│ ╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝
│ │
│ ════════════════════════════════════════════════════════════════════════════════ │
│ │
│ 📖 全称: 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, ... 里, │ │ 让每个初学者都能看懂。" │ │ │ │ —— 显式学习框架的哲学 │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seegradnet-0.1.2.tar.gz.
File metadata
- Download URL: seegradnet-0.1.2.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e95a3e78cab46d5329d1362aa015b15dc48f550da02120486777658765301854
|
|
| MD5 |
ddfeaeb794b1a311b570b1c10a7d58cc
|
|
| BLAKE2b-256 |
c4b6798975e011e3175d93384eae259ff2f9ce013d1d3810fac172b42e94f894
|
File details
Details for the file seegradnet-0.1.2-py3-none-any.whl.
File metadata
- Download URL: seegradnet-0.1.2-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cd36ccaf674919fd8bf1ee77c30dd8e0b3ddc17e7c69720d07041d78f22411c
|
|
| MD5 |
c59bd8df3ffcb4d167e55246efc3e3d4
|
|
| BLAKE2b-256 |
39b1351211c79d955444028c91ae89f9fe3fdfeabde49007443108346b29e361
|