上一篇博文用的是手动求导,更新权重和截距,本篇博文主要是借助Pytorch自动自动求导引擎。
计算图(Computation Graph)是PyTorch的核心,其为高效自动求导算法——反向传播(Back Propogation)提供了理论支持。其中torch.autograd是一套自动求导引擎,它能够根据输入和前向传播过程自动构建计算图,并执行反向传播。
#在创建tensor的时候指定requires_grad,三种方式
#(1)
a = t.randn(3,4, requires_grad=True)
#(2)
a = t.randn(3,4).requires_grad_()
#(3)
a = t.randn(3,4)
a.requires_grad=True

#原函数
def f(x):
'''计算y'''
y = x**2 * t.exp(x)
return y
#手动求导函数
def gradf(x):
'''手动求导函数'''
dx = 2*x*t.exp(x) + x**2*t.exp(x)
return dx
x = t.randn(3,4, requires_grad = True)
y = f(x)
y
#两者的对比,效果一样
y.backward(t.ones(y.size())) # gradient形状与y一致
x.grad
gradf(x)
案例对比,自动求导:
import torch as t
%matplotlib inline
from matplotlib import pyplot as plt
from IPython import display
import numpy as np
'''用autograd实现的线性回归最大的不同点就在于autograd不需要计算反向传播,可以自动计算微分'''
# 设置随机数种子,为了在不同人电脑上运行时下面的输出一致
t.manual_seed(1000)
def get_fake_data(batch_size=8):
''' 产生随机数据:y = x*2 + 3,加上了一些噪声'''
x = t.rand(batch_size,1) * 5
y = x * 2 + 3 + t.randn(batch_size, 1)
return x, y
# 随机初始化参数
w = t.rand(1,1, requires_grad=True)
b = t.zeros(1,1, requires_grad=True)
losses = np.zeros(500)
lr =0.005 # 学习率
for ii in range(500):
x, y = get_fake_data(batch_size=32)
# forward:计算loss
y_pred = x.mm(w) + b.expand_as(y)
loss = 0.5 * (y_pred - y) ** 2
loss = loss.sum()
losses[ii] = loss.item()
# backward:手动计算梯度
loss.backward()
# 更新参数
w.data.sub_(lr * w.grad.data)
b.data.sub_(lr * b.grad.data)
'''需要注意的是在每次反向传播之前要记得先把梯度清零。'''
# 梯度清零
w.grad.data.zero_()
b.grad.data.zero_()
if ii%50 ==0:
# 画图
display.clear_output(wait=True)
x = t.arange(0, 6).view(-1, 1).float()
y = x.mm(w.data) + b.data.expand_as(x)
plt.plot(x.numpy(), y.numpy()) # predicted
x2, y2 = get_fake_data(batch_size=20)
plt.scatter(x2.numpy(), y2.numpy()) # true data
plt.xlim(0,5)
plt.ylim(0,13)
plt.show()
plt.pause(0.5)
print(w.item(), b.item())
本文深入探讨PyTorch的自动求导引擎,通过计算图实现反向传播。文中通过三种方式创建带有`requires_grad`的张量,并通过案例对比展示自动求导的优势。
302

被折叠的 条评论
为什么被折叠?



