对于简单模型可以这么求
但是对于复杂的模型
这样w(权重)太多,不可能挨个写解析式,而且这些函数很多嵌套函数,写起来也十分麻烦
由于经过化简,均可以化简成
y = w*x +b的形式
所以每一层加一个非线性的函数(激活函数)
我们知道链式求导法则
反向传播 步骤
step1
先正向传播,算出loss
step2
通过链式求导法则,可以一步步向前算出最终要求的 loss对指定w的偏导数
例子
代码
import torch
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = torch.tensor([1.0])
###w的初始值为1.0
w.requires_grad = True
###w需要计算梯度
def f(x):
return w*x
def loss(x,y):
y_pred = f(x)
return (y_pred - y)**2
print("predict (before training)", 4, f(4).item())
for times in range(100):
for x,y in zip(x_data,y_data):
#随机梯度下降
l = loss(x,y)
#l是一个张量,tensor主要是建立计算图
#前向传播 l.item
l.backward()
#反向传播
#会自动将这条计算链路上的所有需要梯度的地方,都求出来,存到w中
#只要一做backward这个 l 计算图就释放了
print('\tgrad:', x, y, w.grad.item())
w.data = w.data - 0.01 * w.grad.data
#由于w中的grad也是一个计算图,所以这里要用到一个标量,故取data,这样就不会简历计算图
w.grad.data.zero_()
#将w中 梯度的数据全部清0
#w更新之后,导数还在
print('progress:', times, l.item()) # 取出loss使用l.item,不要直接使用l(l是tensor会构建计算图)
print("predict (after training)", 4, f(4).item())