PyTorch神经网络进行气温预测

前言

学习用Pytorch搭建一个两层的神经网络,用来进行气温预测。本次一共用了两种方法,一种手动构建,另一种运用Pytorch中的nn模块进行构建。

一、处理数据

1.数据读取

import pandas as pd
import matplotlib.pyplot as plt
features = pd.read_csv('temps.csv')

读取到的数据如图所示

其中

  • year,month,day,week分别表示具体的时间
  • temp_2:前天的最高温度值
  • temp_1:昨天的最高温度值
  • average:在历史中,每年的这一天的平均最高温度值
  • actual:真实值(标签值)
  • friend:可能是朋友的猜测值

2.数据可视化(画图)

首先将数据转换为datatime格式,以便进行作图

# 处理时间数据
import datetime

# 分别得到年、月、日
years =features['year']
months = features['month']
days = features['day']

# datatime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

格式转换后进行作图

# 指定画布风格
plt.style.use('fivethirtyeight')

# 设置布局 画出一个2行2列,10 × 10 的子图
fig, ((ax1, ax2),(ax3, ax4)) = plt.subplots(nrows = 2, ncols = 2, figsize = (10, 10))
fig.autofmt_xdate(rotation = 45) # x轴字体倾斜度

#标签值(实际值)
ax1.plot(dates, features['actual'])
ax1.set_xlabel('');ax1.set_ylabel('Temperature');ax1.set_title('Max Temp')

#昨天
ax2.plot(dates, features['temp_1'])
ax2.set_xlabel('');ax2.set_ylabel('Temperature');ax2.set_title('Previous Max Temp')

#前天
ax3.plot(dates, features['temp_2'])
ax3.set_xlabel('Date');ax3.set_ylabel('Temperature');ax3.set_title('Two Days Prior Max Temp')

#friend
ax4.plot(dates, features['friend'])
ax4.set_xlabel('Date');ax4.set_ylabel('Temperature');ax4.set_title('Friend Estimate')
# 自动调节子图参数,设置图像边界和子图之间的额外边距
plt.tight_layout(pad = 2) 

结果如图所示

3.数据编码

由于week中是用字符串进行表示的,因此将其进行编码(采用独热编码

# 独热编码
features = pd.get_dummies(features)

部分编码展示

4.设置标签及数据归一化

设置标签

# 标签
labels = np.array(features['actual'])

# 在特征中去掉标签
features = features.drop('actual', axis = 1)

#保存表头
feature_list = list(features.columns)

#转换成数组格式
features = np.array(features)

数据归一化(归一化后,网络训练效果会更好)

from sklearn import preprocessing
input_features = preprocessing.StandardScaler().fit_transform(features) # 数据标准化

二、构建网络模型

1.手动构建

转换数据为tensor格式
x = torch.tensor(input_features, dtype = float)
y = torch.tensor(labels, dtype = float)
参数初始化

其中中间因此层设置128个神经元,学习率设置为0.001

weights = torch.randn((14,128), dtype = float, requires_grad = True)
biases = torch.randn(128, dtype = float, requires_grad = True)
weights2 = torch.randn((128,1), dtype = float, requires_grad = True)
biases2 = torch.randn(1, dtype = float, requires_grad = True)

learning_rate = 0.001
losses = []
训练网络

其中损失的计算是计算平方值

for i in range(2000):
    # 计算隐层
    hidden = x.mm(weights) + biases
    # 加入激活层
    hidden = torch.relu(hidden)
    # 预测结果
    predictions = hidden.mm(weights2) + biases2
    # 计算损失
    loss = torch.mean((predictions - y)**2)
    losses.append(loss.data.numpy())
    
    # 打印损失值
    if i % 100 == 0:
        print('loss:', loss)
    # 反向传播计算
    loss.backward()
    
    #更新参数
    weights.data.add_(- learning_rate * weights.grad.data)
    biases.data.add_(- learning_rate * biases.grad.data)
    weights2.data.add_(- learning_rate * weights2.grad.data)
    biases2.data.add_(- learning_rate * biases2.grad.data)
    
    # 清空梯度
    weights.grad.data.zero_()
    biases.grad.data.zero_()
    weights2.grad.data.zero_()
    biases2.grad.data.zero_()

结果

loss: tensor(5353.6918, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(155.1765, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(147.2493, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(144.3641, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(142.8384, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(141.9417, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(141.3566, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(140.9472, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(140.6487, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(140.4174, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(140.2319, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(140.0813, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.9572, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.8522, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.7632, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.6864, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.6200, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.5621, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.5116, dtype=torch.float64, grad_fn=<MeanBackward0>)
loss: tensor(139.4669, dtype=torch.float64, grad_fn=<MeanBackward0>)

2.利用库进行构建

构建模型
  • batch_size :一次读取数据个数
  • Sigmoid : 激活函数(和上面的Relu类似)
  • cost:计算均方误差,采用MSELoss损失函数计算(均方误差)
  • optimizer:优化器,采用Adam
  • input_size = input_features.shape[1]
    hidden_size = 128
    output_size = 1
    batch_size = 16
    my_nn = torch.nn.Sequential(
        torch.nn.Linear(input_size,hidden_size),
        torch.nn.Sigmoid(),
        torch.nn.Linear(hidden_size, output_size),
    )
    cost = torch.nn.MSELoss(reduction = 'mean')
    optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)
    
    训练网络

    此处和之前不同的是,每次训练按顺序取16个数据进行训练,不是取全部数据

三、预测训练结果

由于没有数据,测试集直接使用训练集进行测试

x = torch.tensor(input_features, dtype = torch.float)
predict = my_nn(x).data.numpy()
# 转换日期格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

# 创建一个表格来存日期和其对应的标签数值
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})

# 同理,再创建一个来存日期和其对应的模型预测值
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]

test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]

test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]

predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predict.reshape(-1)}) 

# 真实值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')

#预测值
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = '60')
plt.legend()
# 图名
plt.xlabel('Date');plt.ylabel('Maximum Temperature(F)');plt.title('Actual and Predicted Values');

结果如图所示,根据图示可以看出,预测结果基本符合变化趋势,而且也没有完全符合真实值,没有过拟合。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值