Propagación hacia atrás para encontrar derivadas variables
- En el pasado, solo sabíamos que la retropropagación se implementaba mediante la regla de la cadena.
- Estaba leyendo un libro hoy y descubrí que no podía calcular el valor calculado a partir de la imagen.
- Entonces hice los cálculos, lo registré y ejecuté el código en el libro.
- Libros relacionados:[Serie de programación de Turing] Introducción al aprendizaje profundo: teoría e implementación basada en Python
1. Ejercicios relacionados
2. Proceso de derivación
2.1 Fórmulas relacionadas
f = a ∗ bg = c ∗ dh = f + g = a ∗ b + c ∗ di = h ∗ e = ( f + g ) ∗ e = ( a ∗ b + c ∗ d ) ∗ e \begin{aligned} f&= a*b\\ g&=c*d\\ h&=f+g\\ &=a*b+c*d\\ i&=h*e\\ &=(f+g)*e\\ &=(a*b+c*d)*e \end{alineado}Fgramohi=a∗b=C∗d=F+gramo=a∗b+C∗d=h∗mi=( f+gramo )∗mi=( un∗b+C∗re )∗e
2.3 Resolver derivadas variables
-
i
- La derivada de la última capa se inicializa a
1
- La derivada de la última capa se inicializa a
-
e
∂ i ∂ e = ∂ i ∂ i ∗ ∂ i ∂ e = ∂ i ∂ i ∗ ∂ h ∗ e ∂ e = 1 ∗ h = a ∗ b + c ∗ d = 2 ∗ 100 + 150 ∗ 3 = 650 \begin {alineado} \frac{\partial i}{\partial e}&= \frac{\partial i}{\partial i}*\frac{\partial i}{\partial e}\\ &=\frac{\ i parcial}{\i parcial}*\frac{\h*e parcial}{\e parcial}\\ &=1*h\\ &=a*b+c*d\\ &=2*100+150 *3\\ &=650 \end{alineado}∂ mi∂yo _=∂yo _∂yo _∗∂ mi∂yo _=∂yo _∂yo _∗∂ mi∂h _∗e=1∗h=a∗b+C∗d=2∗100+150∗3=650 -
h
∂ i ∂ h = ∂ i ∂ i ∗ ∂ i ∂ h = ∂ i ∂ i ∗ ∂ h ∗ e ∂ h = 1 ∗ e = 1.1 \begin{aligned} \frac{\partial i}{\partial h}& = \frac{\partial i}{\partial i}*\frac{\partial i}{\partial h}\\ &=\frac{\partial i}{\partial i}*\frac{\partial h* e}{\partial h}\\ &=1*e\\ &=1.1 \end{aligned}∂h _∂yo _=∂yo _∂yo _∗∂h _∂yo _=∂yo _∂yo _∗∂h _∂h _∗e=1∗mi=1.1 -
f
yg
- Porque h = f + gh=f+gh=F+g , por lo que durante la propagación hacia atrás, la derivada se puede pasar directamente a la posición de suma.
- Entonces las derivadas de
f
y son ambasg
1.1
-
a
∂ f ∂ a = ∂ f ∂ f ∗ ∂ a ∗ b ∂ a = 1.1 ∗ b = 1.1 ∗ 100 = 110 \begin{aligned} \frac{\partial f}{\partial a}&= \frac{\partial f}{\partial f}* \frac{\partial a*b}{\partial a}\\ &=1.1*b\\ &=1.1*100\\ &=110 \end{aligned}∂ un∂f _=∂f _∂f _∗∂ un∂ un∗segundo=1.1∗b=1.1∗100=110 -
b
∂ f ∂ b = ∂ f ∂ f ∗ ∂ f ∂ b = 1.1 ∗ ∂ a ∗ b ∂ b = 1.1 ∗ a = 1.1 ∗ 2 = 2.2 \begin{aligned} \frac{\partial f}{\partial b} &= \frac{\partial f}{\partial f}* \frac{\partial f}{\partial b}\\ &=1.1* \frac{\partial a*b}{\partial b}\\ & =1.1*a\\ &=1.1*2\\ &=2.2 \end{alineado}∂ segundo∂f _=∂f _∂f _∗∂ segundo∂f _=1.1∗∂ segundo∂ un∗segundo=1.1∗a=1.1∗2=2.2 -
c
∂ g ∂ c = ∂ g ∂ g ∗ ∂ g ∂ c = 1.1 ∗ ∂ c ∗ d ∂ c = 1.1 ∗ d = 1.1 ∗ 3 = 3.3 \begin{aligned} \frac{\partial g}{\partial c} &= \frac{\partial g}{\partial g}* \frac{\partial g}{\partial c}\\ &=1.1* \frac{\partial c*d}{\partial c}\\ & =1.1*d\\ &=1.1*3\\ &=3.3 \end{alineado}∂c _∂g _=∂ g∂g _∗∂c _∂g _=1.1∗∂c _∂c _∗d=1.1∗d=1.1∗3=3.3 -
d
∂ g ∂ d = ∂ g ∂ g ∗ ∂ g ∂ d = 1.1 ∗ ∂ c ∗ d ∂ d = 1.1 ∗ c = 1.1 ∗ 150 = 165 \begin{aligned} \frac{\partial g}{\partial d} &= \frac{\partial g}{\partial g}* \frac{\partial g}{\partial d}\\ &=1.1* \frac{\partial c*d}{\partial d}\\ & =1.1*c\\ &=1.1*150\\ &=165 \end{alineado}∂ re∂g _=∂ g∂g _∗∂ re∂g _=1.1∗∂ re∂c _∗d=1.1∗C=1.1∗150=165
3. Implementación del código
3.1 Correspondencia de parámetros
parámetro | parámetros de código |
---|---|
a |
dapple_num |
b |
dapple |
c |
dorange |
d |
dorange_num |
e |
dall_price |
f |
dapple_price |
g |
dorange_price |
h |
dall_price |
i |
dprice |
3.2 Implementación del código
- Código relacionado
# 乘法类 class MulLayer: def __init__(self): self.x = None self.y = None def forward(self, x, y): """ :param x: 价格 :param y: 数量 或 税 :return: 总价 """ 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): """ 价格相加 :param x: 苹果总价 :param y: 句子总价 :return: 总价 """ out = x + y return out def backward(self, dout): """ 相加的求导直接传递,相当于乘以1 :param dout: 导数 :return: """ dx = dout * 1 dy = dout * 1 return dx, dy if __name__ == '__main__': apple,apple_num = 100,2 orange,orange_num = 150,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) dapple, dapple_num = mul_apple_layer.backward(dapple_price) dorange, dorange_num = mul_orange_layer.backward(dorange_price) # 总价 print("price:", int(price)) print("dprice:", dprice) print("dtax:", dtax) print("dall_price:", dall_price) # 苹果 print("dapple_price:", dapple_price) print("dapple_num:", int(dapple_num)) print("dapple:", dapple) # 橘子 print("dorange_price:", dorange_price) print("dorange_num:", int(dorange_num)) print("dorange:", dorange)
- resultado