加法节点的反向传播只乘以1,输入的值原封不动地流向下一个节点
实现乘法节点的反向传播时,要保存正向传播的输入信号
#乘法层的实现
class MulLayer:
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
dy = dout * self.x
return dx,dy
#加法层的实现
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
#实现购买2个苹果和3个橘子的例子
apple = 100
apple_num = 2
orange = 150
orange_num = 3
tax = 1.1
#layer
mul_apple_layer = MulLayer()
mul_orange_layer = MulLayer()
add_apple_orange_layer = AddLayer()
mul_tax_layer = MulLayer()
#forward
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)
#backward
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)
715.0000000000001
110.00000000000001 2.2 3.3000000000000003 165.0 650
#ReLu层的实现
#forward和backward的参数为numpy数组
class Relu:
def __init__(self):
self.mask = None
def forward(self,x):
self.mask = (x<=0)
out = x.copy()
out[self.mask]=0
return out
def backward(self,dout):
dout[self.mask]=0
dx = dout
return dx
\[ y = \frac{1}{1+exp(-x)} \]
#sigmoid层实现
class Sigmoid:
def __init__(self):
self.out = None
def forward(self,x):
out = 1/(1+np.exp(-x))
self.out = out
return out
def backward(self,dout):
dx = dout*(1.0-self.out)*self.out
return dx
#Affine层实现
class Affine:
def __init__(self,W,b):
self.W = W
self.b = b
self.x = None
self.dW = None
self.db = None
def forward(self,x):
self.x = x
out = np.dot(x,self.W)+self.b
return out
def backward(self,dout):
dx = np.dot(dout,self.W.T)
self.dW = np.dot(self.x.t,dout)
self.db = np.sum(dout,axis=0)
return dx
from sourcecode.common.functions import cross_entropy_error
#Softmax-with-Loss层的实现
class SoftmaxWithLoss:
def __init__(self):
self.loss = None #损失
self.y = None #softmax的输出
self.t = None #监督数据(ont-hot vector)
def forward(self,x,t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y,self.t)
return self.loss
def backward(self,dout=1):
batch_size = self.t.shape[0]
dx = (self.y-self.t)/batch_size
return dx#向前传递的是单个数据的误差
原文:https://www.cnblogs.com/suqinghang/p/12263034.html