文章目录
- 基于梯度的推导和反向传播实现
- 一、Sigmoid 公式
- 二、完整代码类
- 三、backward 代码逐行详解
- 1. 函数定义
- 2. 核心梯度计算
- 3. 返回梯度
- 四、核心知识点
- 其他
- 交叉熵误差
基于梯度的推导和反向传播实现
一、Sigmoid 公式
原函数(前向)
σ ( x ) = y = 1 1 + e − x \sigma(x) = y = \frac{1}{1+e^{-x}}σ(x)=y=1+e−x1
导数公式(反向)
σ ′ ( x ) = y ( 1 − y ) \sigma'(x) = y(1-y)σ′(x)=y(1−y)
特点:无需重新计算指数,直接复用前向输出结果,计算高效。
二、完整代码类
importnumpyasnpclassSigmoid:# 前向传播:计算输出,保存结果用于反向传播defforward(self,x):self.out=1.0/(1.0+np.exp(-x))returnself.out# 反向传播:计算梯度defbackward(self,dout):dx=dout*(1.0-self.out)*self.outreturndx三、backward 代码逐行详解
1. 函数定义
def backward(self, dout):
- dout:上游梯度,神经网络后一层传递回来的梯度(链式法则输入)
- 作用:接收后续层的误差,向前传递
2. 核心梯度计算
dx = dout * (1.0 - self.out) * self.out
对应数学链式法则:d x = d o u t ⋅ σ ′ ( x ) dx = dout \cdot \sigma'(x)dx=dout⋅σ′(x)
- self.out:前向传播保存的 Sigmoid 输出y yy
- (1.0 - self.out) * self.out:Sigmoid 自带导数y ( 1 − y ) y(1-y)y(1−y)
- dx:当前层输入x xx的梯度,传递给前一层
3. 返回梯度
return dx
将计算完成的梯度传回上一层网络,完成反向传播、用于参数更新。
四、核心知识点
为什么保存 self.out?
反向传播不重复计算指数函数,节省算力,是神经网络的标准优化方式。梯度范围
Sigmoid 导数最大值为0.25,数值极小,深层网络极易出现梯度消失。万能公式
所有神经网络层反向传播通用逻辑:当前梯度 = 上游梯度 × 当前层导数
其他
交叉熵误差
多分类中的交叉熵误差
在多分类问题中,如果每个类别之间的定义是互斥的,那么任何样本都只能被标记为一种类别。
E = − 1 N ∑ i = 1 N log ( y i , t + ϵ ) E = -\frac{1}{N}\sum_{i=1}^{N} \log(y_{i,t} + \epsilon)E=−N1i=1∑Nlog(yi,t+ϵ)
- N:batch 样本数量
- y:第i个样本,正确类别的模型预测概率(由Softmax输出,取值0~1)
- ϵ = 10 − 7 \epsilon=10^{-7}ϵ=10−7:极小偏移值,防止log(0)出现负无穷,保证数值稳定
https://zhuanlan.zhihu.com/p/658116845
defcross_entropy_error(y,t):# 1. 维度兼容:单样本一维数据,统一转为 [1, 类别数] 二维格式,批量 / 单样本通用ify.ndim==1:t=t.reshape(1,t.size)y=y.reshape(1,y.size)# 在监督标签为one-hot-vector的情况下,转换为正确解标签的索引ift.size==y.size:t=t.argmax(axis=1)batch_size=y.shape[0]# 1e-7是为了防止计算崩溃因为log(0)是无穷return-np.sum(np.log(y[np.arange(batch_size),t]+1e-7))/batch_size