import torch
from torch.autograd import Variable

# 构造0-100之间的均匀数字作为时间变量x
x = Variable(torch.linspace(0,100).type(torch.FloatTensor))
# 时间点上的历史房价数据
rand = Variable(torch.randn(100)) * 10   # 均值为0,方差为10。 torch.randn(100)生成100个标准正态分布随机数
y = x + rand

x_train = x[: -10]  #倒数第10个元素之前的所有元素
x_test = x[-10:]    #最后面10个元素
y_train = y[: -10]
y_test = y[-10:]

# 训练数据点可视化
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(10,8))  #设定绘制窗口大小为10*8inch
#绘制数据,由于x和y都是Variable,需要用data获取它们包裹的Tensor,并转成Numpy
plt.plot(x_train.data.numpy(), y_train.data.numpy(),'o')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

PyTorch实例:房价预测

Varibale包含三个属性:

data:存储了Tensor,是本体的数据
grad:保存了data的梯度,本事是个Variable而非Tensor,与data形状一致
grad_fn:指向Function对象,用于反向传播的梯度计算之用。就是计算图中的箭头

 

2.模型设计及训练

# y = ax+b
#定义两个自动微分变量a和b
a = Variable(torch.rand(1),requires_grad = True)
b = Variable(torch.rand(1),requires_grad = True)
learning_rate = 0.0001 

for i in range(1000):
    predictions = a.expand_as(x_train) * x_train + b.expand_as(x_train) #使用expand_as提升a和b的尺寸,a.expand_as(x_train)是将a的维度调整为何x_train一致
    loss = torch.mean((predictions - y_train) ** 2)
    print('loss:',loss)
    loss.backward()   #对损失函数进行梯度反传
    a.data.add_(- learning_rate * a.grad.data)  #在PyTorch中,如果某个函数后加了'_',表明要用这个函数的计算结果更新当前的变量;例如a.data.add_(3)是将a.data的数值更新为a.data加上3
    b.data.add_(- learning_rate * b.grad.data)
    a.grad.data.zero_() #清空存储在变量a和b中的梯度信息,以免在backward的过程中反复不停地累加
    b.grad.data.zero_()


# 画出原始散点图和拟合后的直线
x_data = x_train.data.numpy()
plt.figure(figsize = (10,7))
xplot, = plt.plot(x_data, y_train.data.numpy(),'o')
yplot, = plt.plot(x_data,a.data.numpy()*x_data + b.data.numpy()) #绘制拟合直线图
plt.xlabel('X')
plt.ylabel('Y')
str1 = str(a.data.numpy()[0])+'x+'+str(b.data.numpy()[0])
plt.legend([xplot, yplot],['Data',str1])
plt.show()

PyTorch实例:房价预测

3.预测

predictions = a.expand_as(x_test)*x_test + b.expand_as(x_test)
predictions

PyTorch实例:房价预测

import numpy as np
x_data = x_train.data.numpy()
x_pred = x_test.data.numpy()
plt.figure(figsize = (10,7))
plt.plot(x_data, y_train.data.numpy(),'o') #训练数据
plt.plot(x_pred, y_test.data.numpy(),'s') #测试数据

x_data = np.r_[x_data, x_test.data.numpy()]
plt.plot(x_data,a.data.numpy()*x_data + b.data.numpy()) #绘制拟合数据
plt.plot(x_pred,a.data.numpy()*x_pred + b.data.numpy(),'o') #绘制预测数据
plt.xlabel('X')
plt.ylabel('Y')
str1 = str(a.data.numpy()[0])+'x+'+str(b.data.numpy()[0])
plt.legend([xplot, yplot],['Data',str1])
plt.show()

PyTorch实例:房价预测