当前位置: 首页 > news >正文

天气数据集2-应用RNN做天气预测

二、用循环神经网络做天气(温度)预测

本项目是基于Pytorch的 RNN&GRU模型,用于预测未来温度

  • 数据集: https://mp.weixin.qq.com/s/08BmF4RnnwQ-jX5s_ukDUA

  • 项目代码: https://github.com/disanda/b_code/tree/master/Weather_Prediction

  1. RNN
  • 模型本质是用于预测数据的时序关系

  • 模型的输入和输出是”序列长度可变的”

以下是Pytorch的RNN输入和输出样例

import torchinput_size = 10 #输入数据的维度
output_size= 1  #输出数据的维度
num_layers= 3 #有几层rnnrnn_case = torch.nn.RNN(input_size, output_size, num_layers, batch_first=True)batch_size = 4 #模型可以批处理数据序列
seq_length1 = 5 #序列长度为5,即输入一个序列的5个连续点
seq_length2 = 9 #序列长度为9,即输入一个序列有9个连续点x1 = torch.randn(batch_size,seq_length1,input_size)
x2 = torch.randn(batch_size,seq_length2,input_size)h1_0 = torch.zeros(num_layers,batch_size,output_size)
h2_0 = torch.zeros(num_layers,batch_size,output_size)y1, h1_1 = rnn_case(x1,h1_0)  
# y1.shape = (batch_size, seq_length1, output_size)  
# h1_1.shape = (num_layers, batch_size, output_size) y2, h2_1 = rnn_case(x2,h2_0)
# y2.shape = (batch_size, seq_length1, output_size)  
# h2_1.shape = (num_layers, batch_size, output_size) #如果通过前n-1个数据预测第n个数据
y1_out = y1[:,-1,:]
y2_out = y2[:,-1,:]
  1. 数据预处理

2.1 输出数据特征

pandas下是frame的列(columns)

import pandas as pd
import matplotlib.pyplot as pltcsv_path = "mpi_saale_2021b.csv"
data_frame = pd.read_csv(csv_path)
print(data_frame.columns)# Index(['Date Time', 'p (mbar)', 'T (degC)', 'rh (%)', 'sh (g/kg)', 'Tpot (K)',
#        'Tdew (degC)', 'VPmax (mbar)', 'VPact (mbar)', 'VPdef (mbar)',
#        'H2OC (mmol/mol)', 'rho (g/m**3)', 'wv (m/s)', 'wd (deg)', 'rain (mm)',
#        'SWDR (W/m**2)', 'SDUR (s)', 'TRAD (degC)', 'Rn (W/m**2)',
#        'ST002 (degC)', 'ST004 (degC)', 'ST008 (degC)', 'ST016 (degC)',
#        'ST032 (degC)', 'ST064 (degC)', 'ST128 (degC)', 'SM008 (%)',
#        'SM016 (%)', 'SM032 (%)', 'SM064 (%)', 'SM128 (%)'], dtype='object')

2.2 删掉一些特征

data = df.drop(columns=['Date Time']) #去掉字符串特征# 去掉其他degC特征
deg_columns = df.filter(like='degC').columns 
filtered_list = [item for item in deg_columns if item != 'T (degC)']
data = data.drop(columns=pd.Index(filtered_list))
#print(data.columns)

2.3 数据标准化

可以把所有特征看成不同货币,完成货币的计量统一


# 标准化特征
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
#print(data_scaled)

2.4 序列化和Pytorch批处理

  • y = f(x): x是输入,y是输出,f是模型

  • x序列化, 目的是一个数据单位是一个序列(n-1个数据,每个数据有n个特征)

  • 制作y标签,即预测值(第n个数据的”温度”特征)


# 创建序列数据
X, y = [], []for i in range(len(data_scaled) - sequence_length):X.append(data_scaled[i:i+sequence_length-1])  # 前9个时间步的特征y.append(data_scaled[i+sequence_length-1, 1])  #  第10个时间步的第2个特征'T (degC)'作为目标X = np.array(X)
y = np.array(y)# 转换为 PyTorch 张量
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 默认为 CPU
X = torch.tensor(X, dtype=torch.float32).to(device)
y = torch.tensor(y, dtype=torch.float32).to(device)# 划分训练集和测试集
dataset = TensorDataset(X, y)
train_size = int(0.8 * len(dataset))
#test_size = len(dataset) - train_size
#train_dataset, test_dataset = random_split(dataset, [train_size, test_size])train_dataset = TensorDataset(*dataset[:train_size])
test_dataset = TensorDataset(*dataset[train_size:])train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=False, drop_last=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, drop_last=True)
  1. 超参数选择
  • input_size = len(data.columns)

  • hidden_size = 64

  • output_size = 1

  • num_layers = 2

  • num_epochs = 30

  • learning_rate = 5e-5 #0.001

  • batch_size = 8

  • sequence_length = 8 # 输入9个特征,预测第10个特征

  • model_type =‘RNN’ # GRU

  1. 模型

4.1 模型设计

单独放一个文件夹,解耦程序


import torch.nn as nn
class WeatherRNN(nn.Module):def __init__(self, input_size, hidden_size, output_size, num_layers=1, model_type='RNN'):super(WeatherRNN, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersif model_type == 'RNN':self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True) # batch_first=True, nonlinearity = 'relu'elif model_type == 'GRU':self.rnn = nn.GRU(input_size, hidden_size, num_layers, batch_first=True)self.fc = nn.Linear(hidden_size, output_size)#self.dropout = nn.Dropout(p=0.2) 效果变差def forward(self, x, h0):out, hn = self.rnn(x, h0)#out = out[:, -1, :]#out = self.dropout(out)out = self.fc(out[:, -1, :])#out = torch.tanh(out)return out, hn

4.2 模型训练

  • 初始化: 1.模型,2.损失函数,3.优化器

  • 训练(前向传播): 输入输出 y= f(x)

  • 训练(反向传播): 输入输出 w’ = f’(x)


# 初始化模型、损失函数和优化器
model = models.WeatherRNN(input_size, hidden_size, output_size, num_layers, model_type = model_type).to(device)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 训练模型
model.train()
h0 = torch.zeros(num_layers, batch_size, hidden_size).to(device)
for epoch in range(num_epochs):for inputs, targets in train_loader:# print(inputs.shape)# print(targets.shape)# 训练时每次输入 sequence_length - 1 个数据,预测第 sequence_length 个数据output, hn = model(inputs, h0)   #inputs = [batch_size, sequence_length-1, features]h0 = hn.detach() # [layers, batch_size, hidden_size]#print(output.shape)#print(hn.shape)predictions = output[:, -1]loss = criterion(predictions, targets)optimizer.zero_grad()loss.backward() # retain_graph=Truemax_norm = 2.0  # 设定梯度的最大范数torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) # 使用clip_grad_norm_()函数控制梯度optimizer.step()print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.7f}')print("Training complete.")

4.3 模型评估


# 模型评估
model.eval()
test_loss = 0.0
h0 = torch.zeros(num_layers, batch_size, hidden_size).to(device)
with torch.no_grad():for inputs, targets in test_loader:#print(inputs.shape)#print(targets.shape)# 预测时每次输入 sequence_length - 1 个数据,预测第 sequence_length 个数据output, hn = model(inputs, h0)h0 = hn.detach()predictions = output[:, -1]loss = criterion(predictions, targets)test_loss += loss.item()test_loss /= len(test_loader)
print(f'Test Loss: {test_loss:.7f}')
  1. 小结 & 参考链接

后续可以扩张到股票型数据

5.1 调参

通过看 tain_loss, test_loss 调参
  • Hidden_size,Layer_nums: 与数据规模成正比, 本例应适当调低

  • Learn_rate: 变化过快或震荡可调低

  • Epoch: Loss 有效下降可以增大

5.2 技巧

  • 梯度更新限制
    max_norm = 2.0 # 设定梯度的最大范数
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) # 使用clip_grad_norm_()函数控制梯度

  • Dropout

    适用于参数规模更大的RNN, 不适用本例

5.3 参考链接:

  • 代码: https://blog.paperspace.com/weather-forecast-using-ltsm-networks/
  • 天气数据集: https://www.bgc-jena.mpg.de/wetter/

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 计算机网络 —— 运输层(四次挥手)
  • 【C++题解】1511. 数字之和为13的整数
  • 小程序中的模版语法
  • STM32理论 —— μCOS-Ⅲ(2/2):时间管理、消息队列、信号量、任务内嵌信号量/队列、事件标志
  • 代码随想录算法训练营第三十七天 | 56. 合并区间、738.单调递增的数字、968.监控二叉树、总结
  • 基于某评论的TF-IDF下的LDA主题模型分析
  • 2813. 子序列最大优雅度 Hard
  • 在线的、完全免费的、提供回放的技术传播方面的大会:Adobe DITA World 2024
  • 利用python爬虫采集苹果公司各产品销售收入统计报告
  • Git操作指南
  • tmega128单片机控制的智能小车设计
  • Dubbo源码解析-mock原理
  • Redis常见异常及优化方案
  • python面试题2:lambda是什么?有什么优点?(难度--简单)
  • SQL中distinct去重关键字的使用和count统计组合的使用
  • ----------
  • python3.6+scrapy+mysql 爬虫实战
  • Angular 4.x 动态创建组件
  • Docker容器管理
  • eclipse的离线汉化
  • JavaScript创建对象的四种方式
  • Javascript基础之Array数组API
  • Java超时控制的实现
  • JDK9: 集成 Jshell 和 Maven 项目.
  • js中forEach回调同异步问题
  • mysql外键的使用
  • python 装饰器(一)
  • Python语法速览与机器学习开发环境搭建
  • SpingCloudBus整合RabbitMQ
  • Swift 中的尾递归和蹦床
  • Vue全家桶实现一个Web App
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 工作手记之html2canvas使用概述
  • 构建工具 - 收藏集 - 掘金
  • 记录一下第一次使用npm
  • 模型微调
  • 物联网链路协议
  • 《码出高效》学习笔记与书中错误记录
  • gunicorn工作原理
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​ubuntu下安装kvm虚拟机
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (第61天)多租户架构(CDB/PDB)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (四)软件性能测试
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)Android学习笔记 --- android任务栈和启动模式
  • .gitignore文件---让git自动忽略指定文件