码迷,mamicode.com
首页 > 其他好文 > 详细

PyTorch搭建一维线性回归模型

时间:2020-09-17 18:10:13      阅读:33      评论:0      收藏:0      [点我收藏+]

标签:编写   数据   val   item   错误   put   均方误差   使用   module   

参考的一位大神的Blog,记录一下,便于以后复习。我是初学者,难免有许多错误的地方,恳请各位大神批评指正。

关于线性回归的理论,有很多优秀的课程(比如:吴恩达的机器学习课程)可供参考,这里直接进行代码实现,并对必要的地方进行解释。

1 import torch as tc #简写成tc便于编写代码
2 import matplotlib.pyplot as plt #为了将数据可视化,需要画图
3 from torch import nn #引入PyTorch的神经网络库,便于使用神经网络的常用功能
4 from torch.autograd import Variable

  Tensor是Pytorch的一个完美组件(可以生成高维数组),但是要构建神经网络还是远远不够的,我们需要能够计算图的Tensor,那就是Variable。Variable是对Tensor的一个封装,操作和Tensor是一样的,但是每个Variable都有三个属性,Varibale的Tensor本身的.data,对应Tensor的梯度.grad,以及这个Variable是通过什么方式得到的.grad_fn。

  有时会将Tensor转化成Variable,这是因为PyTorch中Tensor(张量)只能放在CPU上运算,而Variable(变量)是可以用GPU进行加速计算的。 这就是为什么PyTorch加载图像的时候一般都会使用Variable(变量)。

1 x = tc.unsqueeze(tc.linspace(-1, 1, 100), dim = 1)
2 y = 3 * x + 10 + tc.rand(x.size())

  上面的两行代码用于产生接近y = 3x + 10的数据集,后面加上torch.rand()函数的原因是产生噪声。

  linspace是linear space的缩写,中文含义为线性等分向量,线性平分矢量,线性平分向量。从PyTorch的官方网站上找到了这个函数的详细说明:torch.linspace(startendsteps=100out=Nonedtype=Nonelayout=torch.strideddevice=Nonerequires_grad=False) → Tensor。函数的作用是,返回一个一维的tensor(张量),这个张量包含了从start到end,分成steps个线段得到的向量。常用的几个变量:start:开始值、end:结束值、steps:分割的点数,默认是100、dtype:返回值(张量)的数据类型。

  torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,默认是将a中所有为1的维度删掉,也可以通过dim指定位置,删掉指定位置的维数为1的维度;torch.unsqueeze()这个函数主要是对数据维度进行扩充,需要通过dim指定位置,给指定位置加上维数为1的维度。

1 plt.scatter(x.data.numpy(), y.data.numpy()) #绘制散点图
2 plt.show()

  上面两行代码将原始数据进行可视化。

 1 class LinearRegression(nn.Module):
 2     def __init__(self):
 3         super(LinearRegression, self).__init__()
 4         self.linear = nn.Linear(1,1)
 5     def forward(self, x):
 6         out = self.linear(x)
 7         return out
 8 
 9 if tc.cuda.is_available():
10     model = LinearRegression().cuda()
11 else:
12     model = LinearRegression()

  有了数据,就要开始定义模型了,上面的代码定义的是一个输入层和输出层都只有一维的模型,并且使用了“先判断后使用”的基本结构来合理使用GPU加速。

1 criterion = nn.MSELoss()
2 optimizer = tc.optim.SGD(model.parameters(), lr=1e-2)

  上面两行代码定义了损失函数和优化函数,这里使用均方误差作为损失函数,使用梯度下降进行优化。

 1 num_epochs = 1000
 2 for epoch in range(num_epochs):
 3     if tc.cuda.is_available():
 4         inputs = Variable(x).cuda()
 5         target = Variable(y).cuda()
 6     else:
 7         inputs = Variable(x)
 8         target = Variable(y)
 9 
10 
11     out = model(inputs)
12     loss = criterion(out, target)
13 
14 
15     optimizer.zero_grad()
16     loss.backward()
17     optimizer.step()
18 
19 
20     if(epoch + 1) % 20 == 0:
21         print(Epoch[{}/{}], loss:{:.6f}.format(epoch+1, num_epochs, loss.item()))
22 
23 
24     if(epoch + 1) % 200 == 0:
25         model.eval()
26         if tc.cuda.is_available():
27             predict = model(Variable(x).cuda())
28             predict = predict.data.cpu().numpy()
29         else:
30             predict = model(Variable(x))
31             predict = predict.data.numpy()
32         plt.plot(x.numpy(), y.numpy(), ro, label=Original Data)
33         plt.plot(x.numpy(), predict, label=Fitting Line)
34         plt.show()

  上面的代码是模型训练的过程。

  首先定义了迭代的次数,这里为1000次,先向前传播计算出损失函数,然后向后传播计算梯度,这里需要注意的是,每次计算梯度前都要记得将梯度归零,不然梯度会累加到一起造成结果不收敛。为了便于看到结果,每隔一段时间输出当前的迭代轮数和损失函数。接下来,通过model.eval()函数将模型变为测试模式,然后将数据放入模型中进行预测。最后,通过画图工具matplotlib看一下我们拟合的结果。为了便于看到中间过程,每个一段时间输出当前的拟合结果。

为了便于复制代码,这里附上完整的代码:

import torch as tc
import matplotlib.pyplot as plt
from torch import nn
from torch.autograd import Variable

x = tc.unsqueeze(tc.linspace(-1, 1, 100), dim = 1)
y = 3 * x + 10 + tc.rand(x.size())

plt.scatter(x.data.numpy(), y.data.numpy())
plt.show()

class LinearRegression(nn.Module):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(1,1)
    def forward(self, x):
        out = self.linear(x)
        return out

if tc.cuda.is_available():
    model = LinearRegression().cuda()
else:
    model = LinearRegression()

criterion = nn.MSELoss()
optimizer = tc.optim.SGD(model.parameters(), lr=1e-2)

num_epochs = 1000
for epoch in range(num_epochs):
    if tc.cuda.is_available():
        inputs = Variable(x).cuda()
        target = Variable(y).cuda()
    else:
        inputs = Variable(x)
        target = Variable(y)


    out = model(inputs)
    loss = criterion(out, target)


    optimizer.zero_grad()
    loss.backward()
    optimizer.step()


    if(epoch + 1) % 20 == 0:
        print(Epoch[{}/{}], loss:{:.6f}.format(epoch+1, num_epochs, loss.item()))


    if(epoch + 1) % 200 == 0:
        model.eval()
        if tc.cuda.is_available():
            predict = model(Variable(x).cuda())
            predict = predict.data.cpu().numpy()
        else:
            predict = model(Variable(x))
            predict = predict.data.numpy()
        plt.plot(x.numpy(), y.numpy(), ro, label=Original Data)
        plt.plot(x.numpy(), predict, label=Fitting Line)
        plt.show()

 

PyTorch搭建一维线性回归模型

标签:编写   数据   val   item   错误   put   均方误差   使用   module   

原文地址:https://www.cnblogs.com/morwing/p/12384673.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!