主页 > IT业界  > 

(二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)

(二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录 前言一、数据集二、导入数据以及展示部分1.导入数据集以及对数据集进行处理2.展示数据(看看就好) 三(1)、搭建网络进行预测(理解版)三(2)、搭建网络进行预测(应用版)四、 对预测结果进行一个展示,蓝色真实值,红色预测值总结


前言

深度学习pytorch系列第二篇,第一篇实现的是分类任务,这篇是回归任务,大差不差,重在理解,具体的理解内容我都以注释的形式放在了代码中,方便大家阅读


一、数据集

想要复现的可以下载 链接:网盘链接 提取码:k6a4

二、导入数据以及展示部分 1.导入数据集以及对数据集进行处理 import numpy as np import pandas as pd import matplotlib.pyplot as plt import torch # 过滤警告 import warnings warnings.filterwarnings("ignore") # 读取数据 features = pd.read_csv('data/temps.csv') # #看看数据长什么样子 # print(features.head()) # print('数据维度:', features.shape) # 数据维度:(348, 9),348条数据,每条8个特征x,1个标签y # 处理时间数据 import datetime # 分别得到年,月,日 years = features['year'] months = features['month'] days = features['day'] # # # datetime格式 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] # 在打印的结果中,每个datetime.datetime对象的后面两个0表示小时和分钟,没有时默认为0 # print(dates[:5]) # 独热编码 # # 将字符串进行onehot # # 周一 周二 周三 周四 周五 周六 周天 # # 如果是周一,编码就是 # # 1000000 # Pandas库中的get_dummies函数,是一种独热编码(One-Hot Encoding)的方法 features = pd.get_dummies(features) # print(features.head(5)) # print(features.shape) # 此时的数据维度:(348, 15),多的7个是日期的七天 # 取标签 labels = np.array(features['actual']) # 在特征中去掉标签,features.drop,去掉标签列 features= features.drop('actual', axis = 1) # 名字单独保存一下,以备后患 feature_list = list(features.columns) # 转换成合适的格式 features = np.array(features) # print(features.shape) # print(features) """ 数据标准化 由于神经网络在训练的过程中具有倾向性,数值越大,认为越重要 # 但是在月份这种重要程度与数值无关的特征上,这种倾向性就会出错 # 因此进行标准化,使数据以零点为中心均匀分布 # (x-u)/σ # x-u 去均值 # /σ 除以标准差:让离散数据更加收敛 标准化通常是针对特征而不是标签的。 标准化的目的是使特征具有相同的尺度,以便模型能够更好地学习权重并提高模型的性能。 标签(也称为目标变量)通常不需要标准化,因为它们是模型试图预测的值,而不是用于学习权重的输入。 """ from sklearn import preprocessing input_features = preprocessing.StandardScaler().fit_transform(features) """ [ 0. -1.5678393 -1.65682171 -1.48452388 -1.49443549 -1.3470703 -1.98891668 2.44131112 -0.40482045 -0.40961596 -0.40482045 -0.40482045 -0.41913682 -0.40482045] 标准化处理后的数据以零点为中心,均匀分布 """

上述代码中的初始数据集为: 处理完成后的数据样貌:

2.展示数据(看看就好)

代码如下(示例):

# 该段是展示一下数据的样貌 plt.style.use('fivethirtyeight') # 设置布局 # 4个子图,两行两列 fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10)) # 坐标倾斜45度 fig.autofmt_xdate(rotation = 45) # 标签值 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') # # 朋友感觉的值 ax4.plot(dates, features['friend']) ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate') # 子图之间间隔多少 plt.tight_layout(pad=2) plt.show()

展示图如下:


三(1)、搭建网络进行预测(理解版)

该过程是一步一步构建网络,促进理解,后边会附上更为简单的网络结构

x = torch.tensor(input_features, dtype=float) y = torch.tensor(labels, dtype=float) # # 权重参数初始化 # (14, 128),将14个特征转成128个神经元,可以理解为转成128个特征 # requires_grad = True,是否求导,也就是是否记录梯度 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(1000): # 计算隐层 hidden = x.mm(weights) + biases # 加入激活函数,非线性映射 hidden = torch.relu(hidden) # 预测结果 :h1*w2+b2=预测值 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() # 更新参数 # grad.data 取梯度,然后乘以学习率,应该沿着梯度的反方向更新 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) # 每次迭代都得记得清空 # 每次迭代过程都是独立的,之前计算的梯度要清零 # 在torch中,如果不清零,梯度就会累加 weights.grad.data.zero_() biases.grad.data.zero_() weights2.grad.data.zero_() biases2.grad.data.zero_() print(predictions.shape) print(predictions) 三(2)、搭建网络进行预测(应用版)

实际应用中,往往会这样实现

# 更简单的构建网络模型 # 取特征个数 # 0是样本数;1是特征数 input_size = input_features.shape[1] # print(input_size) 14 有14个特征 # 隐层个数 hidden_size = 128 output_size = 1 batch_size = 16 # Sequential序列模块,按顺序执行 my_nn = torch.nn.Sequential( # 计算隐层,相当于wx+b,参数是自动更新的 torch.nn.Linear(input_size, hidden_size), # 激活函数 torch.nn.Sigmoid(), # 预测结果 :h1*w2+b2=预测值 torch.nn.Linear(hidden_size, output_size), ) # 计算损失 # reduction='mean 平均损失 cost = torch.nn.MSELoss(reduction='mean') # 优化器 # my_nn.parameters() 更新nn中所有参数 optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001) # ADM优化器,比SGD(梯度下降)效果好,效率高 # 训练网络 losses = [] # 迭代1000次 for i in range(1000): # 每次取一个batch的数据,每次只取一批数据 batch_loss = [] # MINI-Batch方法来进行训练 # for start in range(0, len(input_features), batch_size): # 从0开始,到整个数据结束,取batch,间隔是一个batch_size大小 for start in range(0, len(input_features), batch_size): end = start + batch_size if start + batch_size < len(input_features) else len(input_features) # 判断索引越界 xx = torch.tensor(input_features[start:end], dtype=torch.float, requires_grad=True) yy = torch.tensor(labels[start:end], dtype=torch.float, requires_grad=True) prediction = my_nn(xx) loss = cost(prediction, yy) # 通过优化器进行梯度清零 optimizer.zero_grad() # 反向传播 loss.backward(retain_graph=True) # 更新参数 optimizer.step() # 将每一个batch的损失相加 batch_loss.append(loss.data.numpy()) # 打印损失 if i % 100 == 0: losses.append(np.mean(batch_loss)) print(i, np.mean(batch_loss)) 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.show() # 图名 plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values'); # 层数越来越对,就会过拟合 # 什么是过拟合?过拟合(Overfitting)是指机器学习模型在训练数据上表现得很好,但在未见过的新数据上表现较差的现象。

总结

pytorch学习的第二篇啦,慢慢更新ing

标签:

(二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“(二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)