第五章 误差反向传播法 第四节
简单层的实现
这个实现是以上一节的苹果例子。把要在计算图乘法节点称为“乘法层(MuLayer)”,加法节点称为“加法层(AddLayer)”
乘法层的实现
python代码
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
这个代码比较好理解,这里我就没有解释了
下面是运用刚才的类来实现购买苹果
from layer_naive import MulLayer
apple = 100
apple_num = 2
tax = 1.1
#layer
mul_apple_layer = MulLayer()
mul_tax_layer = MulLayer()
#forward
apple_price = mul_apple_layer.forward(apple,apple_num)
price = mul_tax_layer.forward(apple_price,tax)
# print(price)
#backward
deprice = 1
#x=200 y=1.1
dapple_price,dtax = mul_tax_layer.backward(deprice)
#x=100 y=2
dapple,dapple_num = mul_apple_layer.backward(dapple_price)
print(dapple_price)
print(dtax)
print(dapple)
print(dapple_num)
这个向后的函数是在向前的函数的基础之上建立的。因为在调用了向前函数以后,才能把对应的x和y会有值。
黑色的从右到左就是反向传播,线上面有对应的值。
加法层的实现
实现加法层的类
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
用乘法和加法类实现之前买苹果和橘子的例子
from layer_naive import *
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) #(4)
dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price) #(3)
dorange, dorange_num = mul_orange_layer.backward(dorange_price) #(2)
dapple, dapple_num = mul_apple_layer.backward(dapple_price) #(1)
print(price) # 715
print(dapple_num, dapple, dorange, dorange_num, dtax) # 110 2.2 3.3 165 650
代码虽然长但是并不是很复杂。
买苹果和橘子的反向传播和正向传示意图。