PyTorch的核心,一个是Tensor,它可以在GPU和CPU上进行计算。另一个就是自动求导了。
我们举个例子来看一下PyTorch强大的自动求导功能:
假设我们做一个最简单的线性回归:
我们的假设函数是:
{y}'=w*x
为了简单,我们考虑只有一个feature x,并且不考虑bias。
我们的训练数据为:

x y
1 2
2 4

则我们定义两条训练记录

x1 = torch.tensor(1)
y1 = torch.tensor(2)

x2 = torch.tensor(2)
y2 = torch.tensor(4)

接着我们定义weight值w,将它初始化为1.

w = torch.tensor(1.0)
w.requires_grad_(True)

需要注意的是我们对w调用了函数require_grad_(True) 这个函数打开了对w自动求导的开关。所有后续计算中用到w产生的tensor也会自动求导。
然后我们生成预测值y_hat:

y_hat1 = w*x1
y_hat2 = w*x2

然后我们利用y和y_hat来计算mes。因为我们只有2个训练样本,所以最后除以2.

mse_loss = ((y_hat1-y1)**2+(y_hat2-y2)**2)/2

最重要的一步,我们通过调用mse_loss这个tensor的backward(),PyTorch就会自动链式求导,从而得到w在我们设置的默认值1时的导数。

mse_loss.backward()

我们可以通过一个tensor的requires_grad属性来查看它当前是否处于自动求导状态:

print(w.requires_grad)

可以得到:

True

我们可以对一个处于自动求导后的tensor通过查看它的grad属性来查看它的倒数,通过grad_fn属性来查看一个tensor求导的最外层方法:

print("w grad function:\n",mse_loss.grad_fn)
print("w grad value:\n",w.grad)

可以得到:

w grad function:
 <DivBackward0 object at 0x000000000A806400>
w grad value:
 tensor(-5.)

完整代码如下:

import torch
x1 = torch.tensor(1)
y1 = torch.tensor(2)

x2 = torch.tensor(2)
y2 = torch.tensor(4)

w = torch.tensor(1.0)
w.requires_grad_(True)

y_hat1 = w*x1
y_hat2 = w*x2

mse_loss = ((y_hat1-y1)**2+(y_hat2-y2)**2)/2
mse_loss.backward()

print("w grad function:\n",mse_loss.grad_fn)
print("w grad value:\n",w.grad)

有些时候,比如你在用训练好的模型score的时候,这时你显然不想让weight值进行自动求导来浪费性能。你可以通过with torch.no_grad()语句来停止自动的求导计算,即使tensor的requires_grad属性为True:

print((w*2).requires_grad)
with torch.no_grad():
    print((w*2).requires_grad)

可以得到:

True
False

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: