2024/4/21周报

news2024/9/28 23:31:44

文章目录

  • 摘要
  • Abstract
  • 文献阅读
    • 题目
    • 问题
    • 贡献
    • 方法
      • 卷积及池化层
      • LSTM层
      • CNN-LSTM模型
    • 数据集
    • 参数设置
    • 评估指标
    • 实验结果
  • 深度学习
    • 使用GRU和LSTM进行时间预测
      • 1.库的导入&数据集
      • 2.数据预处理
      • 3.模型定义
      • 4.训练过程
      • 5.模型训练
  • 总结

摘要

本周阅读了一篇基于CNN-LSTM黄金价格时间序列预测模型的文章,文中提出了一种新的深度学习预测模型,用于准确预测黄金价格和走势。该模型利用卷积层提取有用知识和学习时间序列数据内部表示的能力,以及长短期记忆(LSTM)层识别短期和长期依赖关系的有效性。实验分析表明,利用LSTM层沿着额外的卷积层可以显著提高预测性能。此外,还使用LSTM以及GRU模型进行时间预测训练,并进行对比。

Abstract

This week, an article based on CNN-LSTM gold price time series forecasting model is readed, and a new deep learning forecasting model is proposed to accurately predict gold price and trend. The model uses the convolution layer to extract useful knowledge and learn the internal representation of time series data, and the long-term and short-term memory (LSTM) layer to identify the short-term and long-term dependencies. Experimental analysis shows that the prediction performance can be significantly improved by using LSTM layer along the additional convolution layer. In addition, LSTM and GRU models are also used for time prediction training and comparison.

文献阅读

题目

A CNN–LSTM model for gold price time-series forecasting

问题

1) 关于黄金价格和走势预测及其影响因素的研究已经进行了几十年,并提出了许多方法。经典的时间序列技术,如多元线性回归和著名的自回归综合移动平均(ARIMA)已被应用于黄金价格预测问题;
2) 除了经典的计量经济学和时间序列方法外,各种机器学习方法也被用来挖掘黄金价格的内在复杂性。然而,统计方法通常需要假设历史数据之间的平稳性和线性相关性;
3) 更复杂的机器学习方法似乎无法识别和捕捉黄金价格时间序列的非线性和复杂行为。因此,所有这些方法都不能保证开发可靠和稳健的预测模型。

贡献

1) 将CNN与LSTM组合,利用先进的深度学习技术预测黄金价格和走势。通过卷积层学习黄金价格数据内部表示的能力,再利用LSTM层来识别短期和长期依赖关系。
2) 为回归和分类问题提供了各种深度学习模型的详细性能评估。

方法

卷积层的特点是能够提取有用的知识并学习时间序列数据的内部表示,而LSTM网络则可以有效地识别短期和长期依赖关系。

提出的称为CNN-LSTM的模型由两个主要组件组成:第一个组件由卷积层和池化层组成,其中执行复杂的数学运算以开发输入数据的特征,而第二个组件利用LSTM和密集层生成特征。

卷积及池化层

卷积:
卷积层在原始输入数据和产生新特征值的卷积核之间应用卷积运算。输入数据必须具有结构化矩阵形式。

卷积核(滤波器)可以被认为是一个微小的窗口(与输入矩阵相比),其中包含矩阵形式的系数值。该窗口在输入矩阵上“滑动",对该指定窗口在输入矩阵上”遇到“的每个子区域(补丁)应用卷积操作。

通过对输入数据应用不同的卷积核,可以生成多个卷积特征,这些特征通常比输入数据的原始初始特征更有用,从而提高了模型的性能。

池化:
卷积层之后通常是非线性激活函数(例如,整流线性单元),然后是池化层。池化层是一种子采样技术,它从卷积特征中提取某些值并产生一个较低维度的矩阵。通过类似的过程,与在卷积层上执行的操作一样,池化层利用小滑动窗口,该小滑动窗口将卷积特征的每个补丁的值作为输入,并输出一个新值,该新值由池化层被定义为要执行的操作指定。

LSTM层

LSTM可以解决RNN梯度消失、无法学习长距离依赖关系等问题,是改进版的RNN。
LSTM的前向以及反向传播如下图所示:
在这里插入图片描述
在这里插入图片描述

如果几个LSTM层堆叠在一起,每个LSTM层的内存状态ct和隐藏状态ht都作为输入转发到下一个LSTM层。

CNN-LSTM模型

作者提出的CNN-LSTM模型有两个,分别记为CNN-LSTM1和CNN-LSTM2。
在这里插入图片描述

第一个CNN-LSTM 1由两个卷积层组成,分别为32和64个大小为(2,)的滤波器,然后是池化层,LSTM层和一个神经元的输出层。
第二个称为CNN-LSTM 2,由两个卷积层组成,分别为64和128个大小为(2,)的滤波器,然后是一个大小为(2,)的最大池化层,一个200个单元的LSTM层,一个32个神经元的密集层和一个神经元的输出层。

数据集

本研究中使用的数据涉及2014年1月至2018年4月的每日黄金价格(以美元计),这些数据来自http://finance.yahoo.com网站。
表1列出了描述性统计数据,包括用于描述分布性质的测量值:最小值、平均值、最大值、中位数、标准差(SD)、偏度和峰度:
在这里插入图片描述

下图显示了每日黄金价格:
在这里插入图片描述

数据分为训练集和测试集。训练集包括2014年1月至2017年12月(4年)的每日黄金价格。
测试集包含2018年1月至2018年4月(4个月)的每日价格。

参数设置

实验所用到的模型的所有参数设置如下表所示:
在这里插入图片描述

评估指标

所有评估模型的回归性能通过平均绝对误差(MAE)和均方根误差(RMSE)测量,分别定义为:
在这里插入图片描述

其中n是预测的数量,而ai和pi分别是i实例的实际值和预测值。

实验结果

使用了四个性能指标:准确性(Acc)、曲线下面积(AUC)、灵敏度(Sen)和特异性(Spe),下表分别显示了相对于预测范围4、6和9,所提出的CNN-LSTM模型相对于最先进的回归模型的性能。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

就预测期的所有值而言,CNN-LSTM1和CNN-LSTM2报告的整体表现最好。在金价预测问题上,CNN-LSTM2的预测效果明显优于所有预测模型,MAE和RMSE得分最低,其次是CNN-LSTM1。

深度学习

使用GRU和LSTM进行时间预测

使用的数据集是每小时能源消耗数据集,可以在Kaggle上找到。该数据集包含按小时记录的美国不同地区的电力消耗数据。

目标是创建一个模型,可以根据历史使用数据准确预测下一小时的能源使用情况。使用 GRU 和 LSTM 模型来训练一组历史数据,并在未见过的测试集上评估这两个模型。从特征选择和数据预处理开始,然后定义、训练并最终评估模型。

1.库的导入&数据集

import os
import time

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import torch
import torch.nn as nn
from torch.utils.data import TensorDataset, DataLoader

from tqdm import tqdm_notebook
from sklearn.preprocessing import MinMaxScaler

# Define data root directory
data_dir = "./data/"
print(os.listdir(data_dir))

在这里插入图片描述
以上为本实验所使用的数据集

pd.read_csv(data_dir + 'AEP_hourly.csv').head()

在这里插入图片描述
数据集规格如上图

2.数据预处理

按以下顺序读取这些文件并预处理这些数据:

1.获取每个单独时间步的时间数据并对它们进行概括:
一天中的某个小时,即 0 - 23
一周中的某一天,即。1 - 7
月份,即 1 - 12
一年中的某一天,即 1 - 365

2.将数据缩放到 0 到 1 之间的值:
当特征具有相对相似的规模和/或接近正态分布时,算法往往会表现更好或收敛得更快
缩放保留了原始分布的形状并且不会降低异常值的重要性

3.将数据分组为序列,用作模型的输入并存储其相应的标签:
序列长度或回顾周期是模型用于进行预测的历史数据点的数量
标签将是输入序列中最后一个数据点之后的下一个数据点

4.将输入和标签拆分为训练集和测试集。

# The scaler objects will be stored in this dictionary so that our output test data from the model can be re-scaled during evaluation
label_scalers = {}

train_x = []
test_x = {}
test_y = {}

for file in tqdm_notebook(os.listdir(data_dir)): 
    # Skipping the files we're not using
    if file[-4:] != ".csv" or file == "pjm_hourly_est.csv":
        continue
    
    # Store csv file in a Pandas DataFrame
    df = pd.read_csv('{}/{}'.format(data_dir, file), parse_dates=[0])
    # Processing the time data into suitable input formats
    df['hour'] = df.apply(lambda x: x['Datetime'].hour,axis=1)
    df['dayofweek'] = df.apply(lambda x: x['Datetime'].dayofweek,axis=1)
    df['month'] = df.apply(lambda x: x['Datetime'].month,axis=1)
    df['dayofyear'] = df.apply(lambda x: x['Datetime'].dayofyear,axis=1)
    df = df.sort_values("Datetime").drop("Datetime",axis=1)
    
    # Scaling the input data
    sc = MinMaxScaler()
    label_sc = MinMaxScaler()
    data = sc.fit_transform(df.values)
    # Obtaining the Scale for the labels(usage data) so that output can be re-scaled to actual value during evaluation
    label_sc.fit(df.iloc[:,0].values.reshape(-1,1))
    label_scalers[file] = label_sc
    
    # Define lookback period and split inputs/labels
    lookback = 90
    inputs = np.zeros((len(data)-lookback,lookback,df.shape[1]))
    labels = np.zeros(len(data)-lookback)
    
    for i in range(lookback, len(data)):
        inputs[i-lookback] = data[i-lookback:i]
        labels[i-lookback] = data[i,0]
    inputs = inputs.reshape(-1,lookback,df.shape[1])
    labels = labels.reshape(-1,1)
    
    # Split data into train/test portions and combining all data from different files into a single array
    test_portion = int(0.1*len(inputs))
    if len(train_x) == 0:
        train_x = inputs[:-test_portion]
        train_y = labels[:-test_portion]
    else:
        train_x = np.concatenate((train_x,inputs[:-test_portion]))
        train_y = np.concatenate((train_y,labels[:-test_portion]))
    test_x[file] = (inputs[-test_portion:])
    test_y[file] = (labels[-test_portion:])

数据规模print(train_x.shape):(980185, 90, 5)
为了提高训练速度,批量处理数据,这样模型就不需要频繁更新权重。Torch Dataset和DataLoader类对于将数据拆分为批次并对其进行混洗非常有用。

batch_size = 1024
train_data = TensorDataset(torch.from_numpy(train_x), torch.from_numpy(train_y))
train_loader = DataLoader(train_data, shuffle=True, batch_size=batch_size, drop_last=True)


使用gpu训练

# torch.cuda.is_available() checks and returns a Boolean True if a GPU is available, else it'll return False
is_cuda = torch.cuda.is_available()

# If we have a GPU available, we'll set our device to GPU. We'll use this device variable later in our code.
if is_cuda:
    device = torch.device("cuda")
else:
    device = torch.device("cpu")


3.模型定义

定义GRU以及LSTM模型

class GRUNet(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, n_layers, drop_prob=0.2):
        super(GRUNet, self).__init__()
        self.hidden_dim = hidden_dim
        self.n_layers = n_layers
        
        self.gru = nn.GRU(input_dim, hidden_dim, n_layers, batch_first=True, dropout=drop_prob)
        self.fc = nn.Linear(hidden_dim, output_dim)
        self.relu = nn.ReLU()
        
    def forward(self, x, h):
        out, h = self.gru(x, h)
        out = self.fc(self.relu(out[:,-1]))
        return out, h
    
    def init_hidden(self, batch_size):
        weight = next(self.parameters()).data
        hidden = weight.new(self.n_layers, batch_size, self.hidden_dim).zero_().to(device)
        return hidden

class LSTMNet(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, n_layers, drop_prob=0.2):
        super(LSTMNet, self).__init__()
        self.hidden_dim = hidden_dim
        self.n_layers = n_layers
        
        self.lstm = nn.LSTM(input_dim, hidden_dim, n_layers, batch_first=True, dropout=drop_prob)
        self.fc = nn.Linear(hidden_dim, output_dim)
        self.relu = nn.ReLU()
        
    def forward(self, x, h):
        out, h = self.lstm(x, h)
        out = self.fc(self.relu(out[:,-1]))
        return out, h
    
    def init_hidden(self, batch_size):
        weight = next(self.parameters()).data
        hidden = (weight.new(self.n_layers, batch_size, self.hidden_dim).zero_().to(device),
                  weight.new(self.n_layers, batch_size, self.hidden_dim).zero_().to(device))
        return hidden

两个模型在隐藏状态和层中将具有相同数量的维度,在相同数量的epoch和学习率上进行训练,并在完全相同的数据集上进行训练和测试。

将使用对称平均绝对百分比误差(SMAPE)来评估模型
KaTeX parse error: Unexpected end of input in a macro argument, expected ‘}’ at end of input: …y_i|+|y_i|)/2}

4.训练过程

def train(train_loader, learn_rate, hidden_dim=256, EPOCHS=5, model_type="GRU"):
    
    # Setting common hyperparameters
    input_dim = next(iter(train_loader))[0].shape[2]
    output_dim = 1
    n_layers = 2
    # Instantiating the models
    if model_type == "GRU":
        model = GRUNet(input_dim, hidden_dim, output_dim, n_layers)
    else:
        model = LSTMNet(input_dim, hidden_dim, output_dim, n_layers)
    model.to(device)
    
    # Defining loss function and optimizer
    criterion = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learn_rate)
    
    model.train()
    print("Starting Training of {} model".format(model_type))
    epoch_times = []
    # Start training loop
    for epoch in range(1,EPOCHS+1):
        start_time = time.perf_counter()
        h = model.init_hidden(batch_size)
        avg_loss = 0.
        counter = 0
        for x, label in train_loader:
            counter += 1
            if model_type == "GRU":
                h = h.data
            else:
                h = tuple([e.data for e in h])
            model.zero_grad()
            
            out, h = model(x.to(device).float(), h)
            loss = criterion(out, label.to(device).float())
            loss.backward()
            optimizer.step()
            avg_loss += loss.item()
            if counter%200 == 0:
                print("Epoch {}......Step: {}/{}....... Average Loss for Epoch: {}".format(epoch, counter, len(train_loader), avg_loss/counter))
        current_time = time.perf_counter()
        print("Epoch {}/{} Done, Total Loss: {}".format(epoch, EPOCHS, avg_loss/len(train_loader)))
        print("Time Elapsed for Epoch: {} seconds".format(str(current_time-start_time)))
        epoch_times.append(current_time-start_time)
    print("Total Training Time: {} seconds".format(str(sum(epoch_times))))
    return model

def evaluate(model, test_x, test_y, label_scalers):
    model.eval()
    outputs = []
    targets = []
    start_time = time.perf_counter()
    for i in test_x.keys():
        inp = torch.from_numpy(np.array(test_x[i]))
        labs = torch.from_numpy(np.array(test_y[i]))
        h = model.init_hidden(inp.shape[0])
        out, h = model(inp.to(device).float(), h)
        outputs.append(label_scalers[i].inverse_transform(out.cpu().detach().numpy()).reshape(-1))
        targets.append(label_scalers[i].inverse_transform(labs.numpy()).reshape(-1))
    print("Evaluation Time: {}".format(str(time.perf_counter()-start_time)))
    sMAPE = 0
    for i in range(len(outputs)):
        sMAPE += np.mean(abs(outputs[i]-targets[i])/(targets[i]+outputs[i])/2)/len(outputs)
    print("sMAPE: {}%".format(sMAPE*100))
    return outputs, targets, sMAPE
#time模块在Python 3.x版本中已经将clock()方法废弃。应该使用time.perf_counter()或者time.process_time()方法来代替clock()

5.模型训练

lr = 0.001
gru_model = train(train_loader, lr, model_type="GRU")

在这里插入图片描述

lstm_model = train(train_loader, lr, model_type="LSTM")

在这里插入图片描述
使用SMAPE评估模型
gru_outputs, targets, gru_sMAPE = evaluate(gru_model, test_x, test_y, label_scalers):

Evaluation Time: 26.02710079999997
sMAPE: 0.33592208657162453%

lstm_outputs, targets, lstm_sMAPE = evaluate(lstm_model, test_x, test_y, label_scalers):

Evaluation Time: 19.92910290000009
sMAPE: 0.38698768153562335%

两者性能相近,lstm较优,但区别不大。

总结

标准LSTM和GRU的差别并不大,但是都比tanh要明显好很多,所以在选择标准LSTM或者GRU的时候还要看具体的任务是什么。

使用LSTM的原因之一是解决RNN Deep Network的Gradient错误累积太多,以至于Gradient归零或者成为无穷大,所以无法继续进行优化的问题。GRU的构造更简单:比LSTM少一个gate,这样就少几个矩阵乘法。在训练数据很大的情况下GRU能节省很多时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法笔记:线性建堆

ACM大牛带你玩转算法与数据结构-课程资料 本笔记属于船说系列课程之一,课程链接: 哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep66799?csourceprivate_space_class_null&spm_id_from333.999.0.0 你也可以选择购买『船说系列课程-年度会…

IBM SPSS Statistics for Mac:强大的数据分析软件

IBM SPSS Statistics for Mac是一款功能强大的数据分析软件,专为Mac用户设计,提供了一系列专业的统计分析和数据管理功能。无论是科研人员、数据分析师还是学生,都能从中获得高效、准确的数据分析支持。 IBM SPSS Statistics for Mac v27.0.1…

Python与上位机开发day01

程序注释 程序注释主要是对代码进行解释说明,并不参与程序的运行 注释可以分为:单行注释和多行注释 1. 单行注释 单行注释以#开头,#后空一格后跟上注释的内容 # 这是单行注释 print(歪比巴卜)2. 多行注释 如果注释内容比较多的话,可以使用多行注释 多行注释以&…

电梯节能的推广意义

之前关于电梯能量回馈设备,小伍已经做了很多介绍,那么小伙伴们,他的推广意义你真的了解了么? 第一:节电降耗,电梯在运行过程中会产生大量的惯性能量,这些能量如果不被利用就会浪费。能量回馈技术…

SAP专家级实施商解读:SAP S/4HANA Cloud(PCE私有云) 的五大误解

五个关于SAP S/4HANA Cloud(PCE私有云)的重要疑问: ■ SAP太贵了? ■ SAP S/4HANA Cloud 只适用于大型企业? ■ ERP项目,尤其是 SAP 解决方案,太耗时了? ■ ERP项目/云项目没有优势&…

Sound Siphon for Mac:音频处理与录制工具

Sound Siphon for Mac是一款专为Mac用户设计的音频处理与录制工具,以其出色的性能、丰富的功能和简便的操作而备受赞誉。 Sound Siphon for Mac v3.6.8激活版下载 该软件支持多种音频格式,包括MP3、WAV、AAC、FLAC等,用户可以轻松导入各种音频…

一文扫盲(5):实验室管理系统的界面设计

本次带来第5期:实验室管理系统的设计,从系统定义、功能模块、界面构成和设计着力点四个方面讲解,大千UI工场愿意持续和大家分享,欢迎关注、点赞、转发。 一、什么是实验室管理系统 实验室管理系统是一种用于管理和监控实验室运作…

基于Springboot+Mybatis-Plus+mysql+html旅游网站

博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…

【每日算法】理论:深度学习基础 刷题:KMP算法思想

上期文章 【每日算法】理论:常见网络架构 刷题:力扣字符串回顾 文章目录 上期文章一、上期问题二、本期理论问题1、注意力机制2、BatchNorm 和 LayerNorm 的区别3、Bert 的参数量是怎么决定的。4、为什么现在的大语言模型都采用Decoder only架构&#x…

【CAD打开提示未处理异常C0000027(c0000027h)的两种解决方法。】

cad打开提示错误c0000027h的第一种解决方法 去掉区域里的beta语言勾选。 https://autodesk8.com/cad/86.html 如果第一种方法没解决,尝试第二种方法大概率能解决 点击autoremove的扩展功能,输入c0000027点击搜索,然后双击出现的这个按钮既可…

键盘打字练习游戏代码

效果图 部分代码 index.html <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width, initial-scale1.0" /> <meta http-equiv"…

初识java——jdk?环境变量?及关于安装jdk的步骤

文章目录 JDK的安装在安装JDK时遇到的问题&#xff1a; 背景知识一 什么是jdkjdk简介jdk文件详解&#xff1a;1 bin目录&#xff1a;2 lib目录&#xff1a;3 include目录.exe文件是可执行的应用程序&#xff0c;这个我们都清楚&#xff0c;但.dll文件又是做什么的呢&#xff1f…

论文笔记:Leveraging Language Foundation Models for Human Mobility Forecasting

SIGSPATIAL 2022 1intro 语言模型POI客流量预测 2 方法 3 实验

Uds诊断协议的请求和响应的寻址

一根总线上挂载着很多ECU&#xff0c;那么基于CAN协议UDS的诊断请求报文&#xff0c;诊断仪是如何发给ECU的&#xff1f;如何精准的找到想要诊断的那个ECU&#xff1f;ECU又是如何将诊断响应的报文返回给诊断仪&#xff1f; 在UDS协议中&#xff0c;规定了诊断请求和响应报文发…

macSubstrate:一款针对macOS的代码注入和打桩测试工具

关于macSubstrate macSubstrate是一款针对macOS的代码注入和打桩测试工具&#xff0c;该工具可以在macOS操作系统上实现进程间代码注入测试&#xff0c;其功能类似于iOS上的Cydia Substrate。 在该工具的帮助下&#xff0c;广大研究人员可以轻松将自己的安全测试插件&#xff…

8-云原生监控体系-PromQL-函数

Prometheus支持几个函数来操作数据。 文章目录 1. 函数语法解释2. count(v instant-vector)3. topk(n, v instant-vector)4. bottomk(n, v instant-vector)5. increase(v range-vector)6. rate(v range-vector)7. rate 和 increase8. irate(v range-vector)9. predict_linear(…

HubSpot流量转化:从访客到客户的转化策略

在当今数字化时代&#xff0c;企业营销获客的关键在于如何将网站访客转化为实际客户。作为HubSpot的合作伙伴&#xff0c;我们深知HubSpot软件在流量转化方面的强大功能。今天运营坛将带领大家深入探讨HubSpot流量转化的核心原理&#xff0c;并介绍如何利用个性化营销策略、构建…

【C++】友元--最全解析(友元是什么?我们应该如何理解友元?友元可以应用在那些场景?)

目录 一、前言 二、友元是什么&#xff1f; 三、友元的感性理解和分类 &#x1f95d;友元的感性理解 &#x1f34b;友元的三种分类 ✨友元 --- 全局函数 ✨友元 --- 成员函数 ✨友元 --- 类 四、友元函数的应用场景 &#x1f34d;操作符重载 :"<<" 与…

【苍穹外卖】HttpClient-快速理解入门

目录 HttpClient-快速理解&入门1. 需求2. 如何使用3. 具体示例4. 大致优点5. 大致缺点 HttpClient-快速理解&入门 1. 需求 在平常访问服务器里面的资源的时候&#xff0c;我们通常是通过浏览器输入网址&#xff08;或者在浏览器点击某个连接&#xff09;这种方式&…

更换本地yum源的步骤

更换本地yum源的流程与命令&#xff1a;