激活层的反向传播和实现
- 一、ReLU的反向传播
- 二、Sigmoid的反向传播
看不懂blog: 深度学习10:反向传播1:计算图,反向求导,链式法则,加法,乘法节点反向传播(经典,比学会链式法则) 不要看这章及一下,推导都离不开上一章知识
blog 深度学习10:反向传播1:计算图,反向求导,链式法则,加法,乘法节点反向传播(经典,必学会链式法则)
现在将计算图应用到神经网络中。神经网络中一步重要的计算操作就是激活函数,下面就来讨论各种激活函数的反向传播,基于这些我们就可以用代码实现激活层的完整功能了。
一、ReLU的反向传播
对于 ReLU 函数:
f ( x ) = max ( 0 , x ) = { 0 , x ≤ 0 x , x > 0 f(x) = \max(0, x) = \begin{cases} 0, & x \leq 0 \\ x, & x > 0 \end{cases}f(x)=max(0,x)={0,x,x≤0x>0
其导数为:
f ′ ( x ) = { 0 , x ≤ 0 1 , x > 0 f'(x) = \begin{cases} 0, & x \leq 0 \\ 1, & x > 0 \end{cases}f′(x)={0,1,x≤0x>0
分为( x ≤ 0 (x \leq 0(x≤0) 和( x > 0 (x > 0(x>0) 两种情况分别讨论,反向传播的计算图如下:
ReLU层可以在代码中实现为一个类 Relu:
# ReLUclassRelu:# 初始化def__init__(self):# 内部属性,记录哪些x<=0# 它的作用是作为“开关”或者“掩码”,记录前向传播时哪些输入是小于等于0的。self.mask=None# 前向传播defforward(self,x):self.mask=(x<=0)y=x.copy()# 将x<=0的值为设为0y[self.mask]=0returny# 反向传播defbackward(self,dy):dx=dy.copy()# 将x<=0的值为设为0dx[self.mask]=0returndx二、Sigmoid的反向传播
在blog已经有sigmoid 深度学习1:基本概念,感知机,激活函数(阶跃,sigmoid,Tanh函数)
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1 + e^{-x}}f(x)=1+e−x1输入x 前向传播算出y步骤
步骤一: x 乘以 -1
步骤二: “指数函数”(或者更精确地说,“以 e 为底的指数函数”)
步骤三: 加1
步骤四: 取 -1次方
开始反向传播推导(一定区分推导过程临时定义y和最终y)
已知 y 的局部导数为 E
步骤四:这反向传播y = 1/u 的局部导数我差点没明白
这里需要正向传播算出u(临时变量,用于算u关于最终y的导数)并保存,就是1 + exp ( − x ) 1 + \exp(-x)1+exp(−x),才能知道最终y关于u的偏导− 1 ( 1 + exp ( − x ) ) 2 E -\frac{1}{(1 + \exp(-x))^2}E−(1+exp(−x))21E
步骤三: 加法,当前局部导数就是1,没变化 还是− 1 ( 1 + exp ( − x ) ) 2 E -\frac{1}{(1 + \exp(-x))^2}E−(1+exp(−x))21E
步骤二:
这里需要正向传播算出u(临时变量,用于算u关于y的导数,此刻u是-x,y是$\exp(-x)$),就是-x,才能知道u的e次方是exp ( − x ) \exp(-x)exp(−x),
最终y对y的导数是− 1 ( 1 + exp ( − x ) ) 2 E -\frac{1}{(1 + \exp(-x))^2}E−(1+exp(−x))21E
y对u的导数是:exp ( − x ) \exp(-x)exp(−x)
所以 最终y对u的导数就是 这两个链式相乘
算出最终y对u的偏导− 1 ( 1 + exp ( − x ) ) 2 exp ( − x ) E -\frac{1}{(1 + \exp(-x))^2} \exp(-x)E−(1+exp(−x))21exp(−x)E
步骤一: 链式法则,用− 1 ( 1 + exp ( − x ) ) 2 exp ( − x ) E -\frac{1}{(1 + \exp(-x))^2} \exp(-x)E−(1+exp(−x))21exp(−x)E✖ -1得到最终y对x的偏导1 ( 1 + exp ( − x ) ) 2 exp ( − x ) E \frac{1}{(1 + \exp(-x))^2} \exp(-x)E(1+exp(−x))21exp(−x)E
简化过程
转换成两个因子相乘
1 ( 1 + exp ( − x ) ) 2 exp ( − x ) E \frac{1}{(1 + \exp(-x))^2} \exp(-x)E(1+exp(−x))21exp(−x)E=1 ( 1 + exp ( − x ) ) ∗ e x p ( − x ) ( 1 + exp ( − x ) ) ∗ E \frac{1}{(1 + \exp(-x))} *\frac{exp(-x)}{(1 + \exp(-x))} * E(1+exp(−x))1∗(1+exp(−x))exp(−x)∗E
那第二个因子怎么变成f ( x ) f(x)f(x)呢?注意:
e − x 1 + e − x = ( 1 + e − x ) − 1 1 + e − x = 1 − 1 1 + e − x \begin{aligned} \frac{e^{-x}}{1 + e^{-x}} &= \frac{(1 + e^{-x}) - 1}{1 + e^{-x}} \\ &= 1 - \frac{1}{1 + e^{-x}} \end{aligned}1+e−xe−x=1+e−x(1+e−x)−1=1−1+e−x1
简化得:y就是f ( x ) = 1 1 + e − x f(x) = \frac{1}{1 + e^{-x}}f(x)=1+e−x1
结束反向传播推导
Sigmoid层可以在代码中实现为一个类 Sigmoid:
sigmoid引用 blog: 深度学习1:基本概念,感知机,激活函数(阶跃,sigmoid,Tanh函数)
# SigmoidclassSigmoid:# 初始化def__init__(self):# 定义内部属性,记录输出值y,用于反向传播时计算梯度self.y=None# 前向传播defforward(self,x):y=sigmoid(x)self.y=yreturny# 反向传播defbackward(self,dy):dx=dy*(1.0-self.y)*self.yreturndx