标签:编写 数据 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
(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_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()
标签:编写 数据 val item 错误 put 均方误差 使用 module
原文地址:https://www.cnblogs.com/morwing/p/12384673.html