Back_Propagation反向传播
- 在说反向传播前先说一下前向传播
如下图节点中,MM为乘,ADD为加;结合公式可以明显的看出第一层的结果整体做为第二层的输入,然后在第二层中继续计算,如果还有第三层,第四层…以此类推。这个就是前向传播。
- 反向传播
如下图,蓝色的箭头是正向传播,红色的箭头是反向传播。
结合封装好的f函数,我们可以反向计算出 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z,以及 ∂ z ∂ w \frac{\partial z}{\partial w} ∂w∂z,
下图展示了,f函数封装的过程。
如下图,如果我们知道了x=2,w=3, ∂ z ∂ w \frac{\partial z}{\partial w} ∂w∂z=x, ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z=w, ∂ L ∂ z \frac{\partial L}{\partial z} ∂z∂L=5,
那么可以反向计算出 ∂ L ∂ x \frac{\partial L}{\partial x} ∂x∂L和 ∂ L ∂ w \frac{\partial L}{\partial w} ∂w∂L,知道了 ∂ L ∂ w \frac{\partial L}{\partial w} ∂w∂L那么我们就可以来更新梯度了。
代码如下:
import torch
x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]
w=torch.Tensor([1.0]) #用张量定义w
w.requires_grad=True #是否开启求梯度
def forward(x):
return x*w
def loss(x,y):
y_pred=forward(x)
return (y_pred-y)**2
for epoch in range(100):
for x,y in zip(x_data,y_data):
l=loss(x,y)
l.backward() #方向传播
print('\t grad:',x,y,w.grad.item())
w.data = w.data-0.01*w.grad.data #用反向传播生成的w更新w
w.grad.data.zero_() #初始化w的梯度,如果不初始化的话,求的梯度会一直累加
print("progress:",epoch,l.item())
print("predict (after training)",4,forward(4).item())