2024/4/21周报

文章目录

  • 摘要
  • 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能节省很多时间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【热门话题】常用经典目标检测算法概述

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 常用经典目标检测算法概述1. 滑动窗口与特征提取2. Region-based方法R-CNN系列M…

心理学|变态心理学健康心理学——躯体疾病患者的一般心理特点

一、对客观世界和自身价值的态度发生改变 患者除了内部器官有器质或功能障碍外,他们的自我感觉和整个精神状态也会发生变化。使人改变对周围事物的感受和态度,也可以改变患者对自身存在价值的态度。这种主观态度的改变,可以使患者把自己置于人…

【Linux驱动层】iTOP-RK3568学习之路(三):字符设备驱动框架

一、总体框架图 二、字符设备相关函数 静态申请设备号 register_chrdev_region 函数原型:register_chrdev_region(dev_t from, unsigned count, const char *name) 函数作用:静态申请设备号,可以一次性申请多个连续的号,count指定…

Python读取influxDB数据库(二)(influxDB2.X版本)

1. influxDB连接 首先在浏览器中输入influxDB的IP和端口,然后输入账号密码进入到influxDB数据库来进行数据的相关操作: 里面的bucket相当于sql中的数据库,_measurement相当于sql中的表 2. 获取influxDB数据库的token方法 3. 写查询语句来查询…

新火种AI|号称“史上最强大开源模型”的Llama3,凭什么价值百亿美金?

作者:小岩 编辑:彩云 4月19日,Facebook母公司Meta重磅推出了Llama3。 即便大家现在对于大厂和巨头频繁迭代AI模型的行为已经见怪不怪,Meta的Llama3仍旧显得与众不同,因为这是迄今最强大的开源AI模型。 Meta推出了重…

Redis从入门到精通(二十一)Redis最佳实践(二)mset、pipeline、慢查询优化、内存划分

文章目录 前言7.2 批处理优化7.2.1 命令执行流程7.2.2 mset7.2.3 Pipeline7.2.4 集群下的批处理7.2.4.1 问题与解决方案7.2.4.2 基于Spring的串行化执行 7.3 服务器端优化7.3.1 持久化配置7.3.2 慢查询优化7.3.2.1 什么是慢查询7.3.2.2 如何查看慢查询 7.3.3 命令及安全配置7.3…

智慧安防边缘计算硬件AI智能分析网关V4算法启停的操作步骤

TSINGSEE青犀视频智能分析网关V4内置了近40种AI算法模型,支持对接入的视频图像进行人、车、物、行为等实时检测分析,上报识别结果,并能进行语音告警播放。硬件管理平台支持RTSP、GB28181协议、以及厂家私有协议接入,可兼容市面上常…

MySQL 基础语法(2)

文章目录 创建表查看表修改表表数据插入 本文为表结构相关的基础语言库相关的基础语句 创建表 CREATE TABLE table_name ( field1 datatype comment xxx, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;CREATE TABLE&#xff1…

算法竞赛相关问题总结记录

前言 日常在校生或者是工作之余的同学或多或少都会参加一些竞赛,参加竞赛一方面可以锻炼自己的理解与实践能力,也能够增加自己的生活费,竞赛中的一些方案也可以后续作为自己论文的base,甚至是横向课题的框架。在算法竞赛中算法的差别个人感觉差距都不大&…

创建一个空的maven项目,整合SpringBoot和Redis

创建一个空的maven项目,整合SpringBoot和Redis 创建空的maven项目 在最新版的idea中创建maven项目的时候会让选择模板 如下图: 我们选择quickstart快速开始模板,quickstart快速开始模板创建的maven项目里面什么都不带,只有一个…

便携式手提万兆网络协议测试仪

便携式手提万兆网络协议测试仪 平台简介 便携式手提万兆网络协议测试仪,以FPGA万兆卡和X86主板为基础,构建便携式的手提设备。 FPGA万兆卡是以Kintex-7XC7K325T PCIeX4的双路万兆光纤网络卡,支持万兆网络数据的收发和网络协议的定制设计。 …

微服务之.SpringCloud AlibabaSentinel实现熔断与限流

一、概述 1.1介绍 Sentinel是阿里巴巴开源的一款服务保护框架,目前已经加入SpringCloudAlibaba中。官方网站: 官网https://sentinelguard.io/zh-cn/ 从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开…

计算机服务器中了locked勒索病毒怎么办,locked勒索病毒解密工具流程步骤

随着网络技术的不断应用与发展,越来越多的企业离不开网络,网络大大提升了企业的办公效率水平,也为企业的带来快速发展,对于企业来说,网络数据安全成为了大家关心的主要话题。近日,云天数据恢复中心接到多家…

注意libaudioProcess.so和libdevice.a是不一样的,一个是动态链接,一个是静态

libaudioProcess.so是动态链接,修改需要改根文件系统,需要bsp重新配置 libdevice.a是静态链接,直接替换就行 动态链接文件修改 然后执行fw_update.sh

JAVA学习笔记29(集合)

1.集合 ​ *集合分为:单列集合、双列集合 ​ *Collection 接口有两个重要子接口 List Set,实现子类为单列集合 ​ *Map接口实现子类为双列集合,存放的King–Value ​ *集合体系图 1.1 Collection接口 1.接口实现类特点 1.collection实现…

射频识别技术助力产品分拣:提升效率与准确性

射频识别技术助力产品分拣:提升效率与准确性 RFID技术在产品分拣中具有重要的应用,它利用射频信号进行非接触式的自动识别,能够高效、准确地完成产品分拣工作。 在产品分拣中,RFID技术的主要应用方式是在产品上粘贴RFID电子标签&…

阿里云mysql8.0 this is incompatible withsql mode=only full group by

阿里云RDS中mysql5.6升级为8.0后,出现如下问题: ### Error querying database. Cause:java.sql.SQLSyntaxErrorException: Expression #1 of SELECT listis not in GROUP BY clause and contains nonaggregatedcolumn temp.product_id which is not fun…

电商平台数据有哪些(淘宝1688京东API)?如何进行电商平台数据分析?(内附测试方式)

电商平台数据是一个庞大且复杂的体系,涵盖了多个维度和类型。在淘宝、1688、京东等电商平台中,数据主要分为以下几个类别: 用户数据:包括用户属性(如年龄、性别、地域、职业等)、用户行为(如浏…

本地环境测试

1. 在 Anaconda Navigator 中,打开 Jupyter Notebook ,在网页中,点击进入本地环境搭建中创 建的工作目录,点击右上角的 New- 》 Folder ,将新出现的 Untitled Folder 选中,并使用左上角 的 Rename 按钮重…

CSS基础常用属性之字体属性(如果想知道CSS的字体属性知识点,那么只看这一篇就足够了!)

前言:在我们学习CSS的时候,主要学习选择器和常用的属性,而这篇文章讲解的就是最基础的属性之一——文字属性。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 废话不多说,让我们直…