# DeepLearning **Repository Path**: G2002_1102/deep-learning ## Basic Information - **Project Name**: DeepLearning - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-24 - **Last Updated**: 2026-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 深度学习框架学习指南 ## 📚 目录 - [项目概述](#项目概述) - [模块结构](#模块结构) - [核心概念](#核心概念) - [代码阅读路径](#代码阅读路径) - [详细学习指南](#详细学习指南) - [实践建议](#实践建议) --- ## 项目概述 这是一个从零实现的**轻量级深度学习框架**,使用NumPy构建。它实现了神经网络的核心组件,包括: - ✅ 前向传播和反向传播 - ✅ 自动微分机制 - ✅ 多种层类型(全连接层) - ✅ 激活函数(Sigmoid、Linear) - ✅ 损失函数(均方误差) - ✅ 优化器(SGD) - ✅ 训练流程管理 ### 设计哲学 该框架采用**模块化设计**,将神经网络的各个组件解耦,便于理解和扩展。每个类职责单一,遵循面向对象的设计原则。 --- ## 模块结构 ``` DeepLearning/ ├── Operation.py # 基础运算单元(操作层) ├── Layer.py # 网络层和损失函数 ├── network.py # 神经网络容器 ├── optimizer.py # 优化器 ├── trainer.py # 训练器 ├── example.py # 使用示例 └── README.md # 本文档 ``` ### 模块依赖关系 ``` Operation.py (最底层) ↓ Layer.py (依赖 Operation) ↓ network.py (依赖 Layer) ↓ optimizer.py (依赖 network) ↓ trainer.py (依赖 network, optimizer) ``` --- ## 核心概念 ### 1. Operation(运算) **文件**: `Operation.py` Operation是框架的**最小计算单元**,代表一个数学运算。 #### 类层次结构 ``` Operation (基类) ├── ParamOperation (带参数的运算) │ ├── WeightMultiply (权重乘法: X @ W) │ └── BiasAdd (偏置加法: X + b) ├── Sigmoid (激活函数) └── Linear (线性激活) ``` #### 关键方法 - `forward(input_)`: 前向传播,计算输出 - `backward(output_grad)`: 反向传播,计算梯度 - `_output()`: 子类实现的具体前向逻辑 - `_input_grad(output_grad)`: 子类实现的梯度计算 #### 设计要点 ```python class Operation: def forward(self, input_): self.input_ = input_ # 保存输入用于反向传播 self.output = self._output() # 计算并保存输出 return self.output def backward(self, output_grad): # 链式法则:计算输入梯度 self.input_grad = self._input_grad(output_grad) return self.input_grad ``` ### 2. Layer(层) **文件**: `Layer.py` Layer是**多个Operation的组合**,代表神经网络中的一层。 #### 类层次结构 ``` Layer (基类) └── Dense (全连接层) Loss (损失函数基类) └── MeanSquaredError (均方误差) ``` #### Dense层的组成 ``` Dense层 = WeightMultiply + BiasAdd + Activation (X @ W) + ( + b) + (σ) ``` #### 工作流程 ```python # 前向传播 def forward(self, input_): for operation in self.operations: input_ = operation.forward(input_) return input_ # 反向传播 def backward(self, output_grad): for operation in reversed(self.operations): output_grad = operation.backward(output_grad) return output_grad ``` ### 3. NeuralNetwork(网络) **文件**: `network.py` NeuralNetwork是**多个Layer的容器**,管理整个网络的前向和反向传播。 #### 核心功能 - 组织层的顺序 - 批量数据的前向传播 - 梯度的反向传播 - 参数和梯度的访问接口 ### 4. Optimizer(优化器) **文件**: `optimizer.py` Optimizer负责**更新网络参数**以最小化损失。 #### SGD算法 ```python param = param - learning_rate * gradient ``` ### 5. Trainer(训练器) **文件**: `trainer.py` Trainer封装了**完整的训练循环**。 #### 训练流程 ``` for epoch in range(epochs): 1. 打乱数据 2. 分批训练: - 前向传播 - 计算损失 - 反向传播 - 更新参数 3. 定期评估 ``` --- ## 代码阅读路径 ### 🎯 推荐学习顺序 #### 第一阶段:理解基础(1-2小时) 1. **Operation.py** - 从最底层开始 - 阅读 `Operation` 基类 - 理解 `forward` 和 `backward` 的设计模式 - 研究 `WeightMultiply` 的矩阵运算和梯度推导 2. **Layer.py** - 理解层的概念 - 阅读 `Layer` 基类 - 重点看 `Dense` 如何组合多个Operation - 理解 `Loss` 类的设计 #### 第二阶段:理解网络架构(1小时) 3. **network.py** - 理解网络容器 - 看如何串联多个层 - 理解 `train_batch` 的完整流程 4. **optimizer.py** - 理解参数更新 - 阅读 `SGD` 的实现 - 理解学习率的作用 #### 第三阶段:理解训练流程(1小时) 5. **trainer.py** - 理解训练循环 - 看数据如何分批 - 理解epoch的概念 - 看验证过程 #### 第四阶段:实践应用(2-3小时) 6. **example.py** - 运行示例 - 逐行阅读代码 - 修改超参数观察效果 - 尝试添加新的层或激活函数 --- ## 详细学习指南 ### 📖 Operation.py 详解 #### 1. 为什么需要Operation? Operation将复杂的神经网络分解为**原子操作**,每个操作只需关心: - 如何计算输出(forward) - 如何计算梯度(backward) 这符合**链式法则**的要求,使得反向传播可以逐层进行。 #### 2. 关键代码解析 **WeightMultiply的前向传播** ```python def _output(self) -> ndarray: return np.dot(self.input_, self.param) # X @ W ``` - 输入形状: `(batch_size, input_dim)` - 权重形状: `(input_dim, neurons)` - 输出形状: `(batch_size, neurons)` **WeightMultiply的反向传播** ```python def _input_grad(self, output_grad): # dL/dX = dL/dY @ W^T return np.dot(output_grad, np.transpose(self.param, (1, 0))) def _param_grad(self, output_grad): # dL/dW = X^T @ dL/dY return np.dot(np.transpose(self.input_, (1, 0)), output_grad) ``` **数学推导**: - 前向: `Y = X @ W` - 反向: - `dL/dX = dL/dY @ W^T` - `dL/dW = X^T @ dL/dY` #### 3. Sigmoid激活函数 ```python def _output(self): return 1.0 / (1.0 + np.exp(-self.input_)) def _input_grad(self, output_grad): # σ'(x) = σ(x) * (1 - σ(x)) sigmoid_backward = self.output * (1.0 - self.output) return sigmoid_backward * output_grad ``` **为什么这样计算梯度?** - Sigmoid的导数有一个优雅的性质:`σ'(x) = σ(x)(1-σ(x))` - 根据链式法则:`dL/dx = dL/dσ * dσ/dx` --- ### 📖 Layer.py 详解 #### 1. Dense层的初始化 ```python def _setup_layer(self, input_): # 随机初始化权重和偏置 self.params.append(random.randn(input_dim, neurons)) # W self.params.append(random.randn(1, neurons)) # b # 构建操作序列 self.operations = [ WeightMultiply(self.params[0]), # X @ W BiasAdd(self.params[1]), # + b self.activation # σ ] ``` #### 2. 为什么需要first标志? ```python if self.first: self._setup_layer(input_) self.first = False ``` - 第一次前向传播时确定权重维度 - 避免重复初始化参数 #### 3. Loss类的设计 ```python class Loss: def forward(self, prediction, target): self.prediction = prediction self.target = target return self._output() def backward(self): return self._input_grad() ``` **MSE损失的梯度**: ```python def _input_grad(self): # d(MSE)/d(y_pred) = 2 * (y_pred - y_true) / n return 2.0 * (self.prediction - self.target) / n ``` --- ### 📖 network.py 详解 #### 1. 前向传播流程 ```python def forward(self, x_batch): x_out = x_batch for layer in self.layers: x_out = layer.forward(x_out) # 逐层传递 return x_out ``` #### 2. 反向传播流程 ```python def backward(self, loss_grad): grad = loss_grad for layer in reversed(self.layers): # 从后向前 grad = layer.backward(grad) ``` #### 3. 生成器的使用 ```python def params(self): for layer in self.layers: yield from layer.params # 惰性求值,节省内存 ``` --- ### 📖 optimizer.py 详解 #### SGD原理 ```python def step(self): for param, grad in zip(params, grads): param -= lr * grad ``` **为什么减去梯度?** - 梯度指向损失增加最快的方向 - 我们要最小化损失,所以沿负梯度方向更新 --- ### 📖 trainer.py 详解 #### 1. 批次生成 ```python def generate_batches(X, y, batch_size): for i in range(0, len(X), batch_size): yield X[i:i+batch_size], y[i:i+batch_size] ``` **为什么要分批?** - 减少内存占用 - 引入随机性,有助于逃离局部最优 - 更频繁的参数更新 #### 2. 训练循环 ```python for epoch in range(epochs): X_train, y_train = permute_data(X_train, y_train) # 打乱 for X_batch, y_batch in batches: loss = net.train_batch(X_batch, y_batch) # 前向+反向 optim.step() # 更新参数 ``` --- ## 实践建议 ### 🔧 扩展练习 #### 1. 添加ReLU激活函数 在 `Operation.py` 中添加: ```python class ReLU(Operation): def _output(self): return np.maximum(0, self.input_) def _input_grad(self, output_grad): return output_grad * (self.input_ > 0).astype(float) ``` #### 2. 添加交叉熵损失 在 `Layer.py` 中添加: ```python class CrossEntropy(Loss): def _output(self): # 实现交叉熵公式 pass def _input_grad(self): # 实现梯度计算 pass ``` #### 3. 添加Dropout层 ```python class Dropout(Layer): def __init__(self, drop_rate=0.5): super().__init__() self.drop_rate = drop_rate def _setup_layer(self, input_): self.mask = (np.random.rand(*input_.shape) > self.drop_rate).astype(float) self.operations = [] # Dropout不需要参数 ``` #### 4. 实现Adam优化器 在 `optimizer.py` 中添加: ```python class Adam(Optimizer): def __init__(self, net, lr=0.001, beta1=0.9, beta2=0.999): super().__init__(lr) self.net = net self.beta1 = beta1 self.beta2 = beta2 # 实现动量和自适应学习率 ``` ### 📊 实验建议 1. **比较不同激活函数** - Sigmoid vs ReLU vs Linear - 观察收敛速度和最终性能 2. **调整网络深度** - 1层 vs 2层 vs 3层 - 观察过拟合现象 3. **调整学习率** - 0.001, 0.01, 0.1 - 观察震荡和收敛 4. **批次大小的影响** - 16, 32, 64, 128 - 观察训练稳定性和速度 ### 🐛 调试技巧 1. **梯度检查** ```python # 数值梯度检查 epsilon = 1e-5 numerical_grad = (loss(x + epsilon) - loss(x - epsilon)) / (2 * epsilon) analytical_grad = compute_analytical_grad() print(f"差异: {abs(numerical_grad - analytical_grad)}") ``` 2. **监控损失曲线** ```python losses = [] for epoch in range(epochs): loss = trainer.train(...) losses.append(loss) import matplotlib.pyplot as plt plt.plot(losses) plt.xlabel('Epoch') plt.ylabel('Loss') plt.show() ``` 3. **打印中间结果** ```python # 在forward中添加 print(f"Layer input shape: {input_.shape}") print(f"Layer output shape: {output.shape}") ``` --- ## 常见问题 ### Q1: 为什么反向传播要从后向前? **A**: 因为链式法则要求先知道后一层的梯度才能计算当前层的梯度。数学上: ``` dL/dx_i = dL/dx_{i+1} * dx_{i+1}/dx_i ``` ### Q2: 为什么要保存input_和output? **A**: 反向传播时需要用到前向传播的中间结果。例如Sigmoid的梯度需要output来计算。 ### Q3: 为什么使用yield而不是返回列表? **A**: 生成器是惰性求值的,不会一次性将所有参数加载到内存,适合大规模网络。 ### Q4: 如何选择学习率? **A**: - 从较小的值开始(如0.01) - 如果损失下降太慢,增大学习率 - 如果损失震荡,减小学习率 - 可以使用学习率调度器 --- ## 进阶阅读 ### 推荐资源 1. **书籍** - 《深度学习》- Ian Goodfellow - 《动手学深度学习》- 李沐 2. **在线课程** - Coursera: Deep Learning Specialization - fast.ai: Practical Deep Learning 3. **框架源码** - PyTorch: https://github.com/pytorch/pytorch - NumPy官方文档: https://numpy.org/doc/ ### 下一步学习 1. 卷积神经网络(CNN) 2. 循环神经网络(RNN) 3. 注意力机制和Transformer 4. 正则化技术(BatchNorm, LayerNorm) 5. 高级优化器(Adam, RMSprop) --- ## 总结 通过这个框架的学习,你应该掌握: - ✅ 神经网络的前向和反向传播原理 - ✅ 自动微分的实现机制 - ✅ 模块化设计的思想 - ✅ 如何使用Python和NumPy实现深度学习算法 **记住**:理解比记忆更重要,实践比理论更有效。多动手修改代码、做实验,才能真正掌握深度学习的精髓! --- **Happy Learning! 🚀**