误差反向传播法
加法反向传播导数不变
乘法反向传播为前一级导数乘以后一级的结果并翻转,例如1.3*5=6.5
'''
误差反向传播中,加法节点反向传播只乘以1,所以输入值会原封不动地流向下一个节点。乘法的反向传播需要正向传播的输入信号值并翻转。
将加法节点称为加法层,乘法节点称为乘法层。
'''
#乘法层实现
class MuLayer:
def __init__(self):
self.x=None
self.y=None
def forward(self,x,y): #正向传播
self.x=x
self.y=y
out=x*y
return out
def backward(self,dout):
dx=dout*self.y #翻转x和y
dy=dout*self.x
return dx,dy
通过上面的代码实现下面的例子中的导数计算
#实现一个实例
apple=100
apple_num=2
tax=1.1
mul_apple_layer=MuLayer()
mul_tax_layer=MuLayer()
apple_price=mul_apple_layer.forward(apple,apple_num)
price=mul_tax_layer.forward(apple_price,tax)
print('正向传播价格为',price)
dprice=1
dapple_price,dtax=mul_tax_layer.backward(dprice)
dapple,dapple_num=mul_apple_layer.backward(dapple_price)
print('反向传播导数为',dapple,dapple_num,dtax) #分别为苹果,苹果个数和税的反向传播导数
结果:
加法层的实现:
#加法层的实现
class AddLayer:
def __init__(self):
pass
def forward(self,x,y):
out=x+y
return out
def backward(self,dout):
dx=dout*1
dy=dout*1
return dx,dy
现在通过加法层和乘法层来计算图中例子
#现在使用加法和乘法实现图中过程
apple=100
apple_num=2
orange=150
orange_num=3
tax=1.1
mul_apple_layer=MuLayer()
mul_orange_layer=MuLayer()
add_apple_orange_layer=AddLayer()
mul_tax_layer=MuLayer()
apple_price=mul_apple_layer.forward(apple,apple_num)
orange_price=mul_orange_layer.forward(orange,orange_num)
all_price=add_apple_orange_layer.forward(apple_price,orange_price)
price=mul_tax_layer.forward(all_price,tax)
dprice=1
dall_price,dtax=mul_tax_layer.backward(dprice)
dapple_price,dorange_price=add_apple_orange_layer.backward(dall_price)
dorange,dorange_num=mul_orange_layer.backward(dorange_price)
dapple,dapple_num=mul_apple_layer.backward(dapple_price)
print('总价格',price)
print('苹果个数的导数、苹果价格导数、橘子个数导数、橘子导数、税导数分别为',dapple_num,dapple,dorange,dorange_num,dtax)
结果: