随机梯度下降
导入包,数据
%matplotlib inline
from fastai.basics import *
n=100
x = torch.ones(n,2)
x[:,0].uniform_(-1.,1)
x[:5]
tensor([[ 0.9955, 1.0000],
[-0.0753, 1.0000],
[ 0.4918, 1.0000],
[-0.0823, 1.0000],
[ 0.7418, 1.0000]])
a = tensor(3.,2); a
tensor([3., 2.])
y = x@a + torch.rand(n)
x[:,0]
tensor([ 0.9955, -0.0753, 0.4918, -0.0823, 0.7418, 0.5482, 0.0317, -0.0224,
-0.7323, 0.6282, 0.3766, -0.4949, -0.1994, -0.9810, 0.6939, 0.1182,
0.6041, -0.7308, -0.5721, 0.3003, -0.4328, -0.1355, -0.2422, -0.6378,
0.4063, -0.7544, -0.3286, 0.5062, 0.8027, -0.2050, -0.8538, 0.5771,
-0.4250, 0.3671, 0.3434, 0.4788, 0.9859, -0.7919, 0.1072, -0.8707,
-0.7484, -0.1305, 0.4626, 0.5997, 0.1537, -0.5728, 0.8755, 0.9620,
0.2826, 0.0041, 0.5956, -0.5758, 0.1405, 0.3512, -0.1403, 0.4057,
0.4607, -0.7323, -0.5207, 0.6755, 0.1890, 0.2442, -0.2409, 0.9330,
-0.3626, 0.1813, 0.3186, -0.2791, 0.2366, 0.0091, -0.1328, 0.9189,
-0.4149, 0.7616, 0.7230, 0.8930, -0.5025, -0.6394, -0.8798, 0.9016,
0.9926, 0.0196, -0.8414, 0.8805, -0.3590, -0.1537, -0.7058, -0.9996,
-0.8218, 0.4228, 0.6947, -0.4348, 0.4422, 0.6000, 0.4775, 0.8744,
-0.6983, -0.4930, 0.0187, -0.0805])
plt.scatter(x[:,0], y);
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AfHWvPDu-1583465017413)(output_8_0.png)]](https://i-blog.csdnimg.cn/blog_migrate/ea31b922a6f0748b72a4aca52b065dbd.png)
构造损失函数
def mse(y_hat, y): return ((y_hat-y)**2).mean()
a = tensor(-1.,1)
y_hat = x@a
mse(y_hat, y)
tensor(8.2766)
plt.scatter(x[:,0],y)
plt.scatter(x[:,0],y_hat);
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KcsldDtc-1583465017413)(output_12_0.png)]](https://i-blog.csdnimg.cn/blog_migrate/ef57976400905705c6c6a57e015dba1c.png)
训练
a = nn.Parameter(a); a
Parameter containing:
tensor([-1., 1.], requires_grad=True)
def update():
y_hat = x@a
loss = mse(y,y_hat)
if t % 10 == 0: print(loss)
loss.backward()
with torch.no_grad():
a.sub_(lr * a.grad)
a.grad.zero_()
lr = 1e-1
for t in range(100): update()
tensor(8.2766, grad_fn=<MeanBackward0>)
tensor(1.3620, grad_fn=<MeanBackward0>)
tensor(0.4088, grad_fn=<MeanBackward0>)
tensor(0.1706, grad_fn=<MeanBackward0>)
tensor(0.1088, grad_fn=<MeanBackward0>)
tensor(0.0928, grad_fn=<MeanBackward0>)
tensor(0.0886, grad_fn=<MeanBackward0>)
tensor(0.0875, grad_fn=<MeanBackward0>)
tensor(0.0873, grad_fn=<MeanBackward0>)
tensor(0.0872, grad_fn=<MeanBackward0>)
plt.scatter(x[:,0],y)
a.requires_grad_(False)
plt.scatter(x[:,0],x@a);
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tmWYbL2y-1583465017413)(output_18_0.png)]](https://i-blog.csdnimg.cn/blog_migrate/3993672664f36161defb854d42c63de0.png)
动画
from matplotlib import animation, rc
rc('animation', html='jshtml')
- 源代码使用的是‘a’直接画图,但这里不知道为什么报错(根据报错的信息,应该是自动求梯度的问题)
- 这里使用temp=a.data存储a的值,不带梯度的
- 注意:不能temp=a,这样temp只是a的副本,还是带梯度的,即使使用命令temp.requires_grad_(False),那么a的求梯度也会关闭
a = nn.Parameter(tensor(-1.,1))
temp = a.data
fig = plt.figure()
plt.scatter(x[:,0], y, c='orange')
line, = plt.plot(x[:,0], x@temp)
plt.close()
def animate(i):
update()
temp = a.data
line.set_ydata(x@temp)
return line,
animation.FuncAnimation(fig, animate, np.arange(0, 100), interval=20)