1 时间序列模型入门: LSTM

news2025/4/8 15:04:39

0 前言

        循环神经网络(Recurrent Neural Network,RNN)是一种用于处理序列数据的神经网络。相比一般的神经网络来说,他能够处理序列变化的数据。比如某个单词的意思会因为上文提到的内容不同而有不同的含义,RNN就能够很好地解决这类问题。本质是一个全连接网络,但是因为当前时刻受历史时刻的影响。

      传统的RNN结构可以看做是多个重复的神经元构成的“回路”,每个神经元都接受输入信息并产生输出,然后将输出再次作为下一个神经元的输入,依次传递下去。这种结构能够在序列数据上学习短时依赖关系,但是由于梯度消失和梯度爆炸问题(梯度反向求导链式法则导致),RNN在处理长序列时难以达到很好的性能。而LSTM通过引入记忆细胞、输入门、输出门和遗忘门的概念(加号的引入),能够有效地解决长序列问题。记忆细胞负责保存重要信息,输入门决定要不要将当前输入信息写入记忆细胞,遗忘门决定要不要遗忘记忆细胞中的信息,输出门决定要不要将记忆细胞的信息作为当前的输出。这些门的控制能够有效地捕捉序列中重要的长时间依赖性,并且能够解决梯度问题。

备注:

输入门:输入的数据有多大程度进入模型;

输出门:控制当前时刻的内部状态 c​有多少信息需要输出给外部状态; 

遗忘门:控制上一个时刻的内部状态, ct−1​需要遗忘多少信息;

 1 模块介绍

数据: 2023“SEED”第四届江苏大数据开发与应用大赛--新能源赛道的数据

MARS开发者生态社区

解题思路: 总共500个充电站状, 关联地理位置,然后提取18个特征;把这18个特征作为时步不长(记得是某个比赛的思路)然后特征长度为1 (类比词向量的size).

y = LSTM(x,h0,c0)

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
#import tushare as ts
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset
from tqdm import tqdm

import matplotlib.pyplot as plt
import tqdm
import sys
import os
import gc
import argparse
import warnings
 
warnings.filterwarnings('ignore')


# 读取数据
train_power_forecast_history = pd.read_csv('../data/data1/train/power_forecast_history.csv')
train_power = pd.read_csv('../data/data1/train/power.csv')
train_stub_info = pd.read_csv('../data/data1/train/stub_info.csv')
 
test_power_forecast_history = pd.read_csv('../data/data1/test/power_forecast_history.csv')
test_stub_info = pd.read_csv('../data/data1/test/stub_info.csv')
 
# 聚合数据
train_df = train_power_forecast_history.groupby(['id_encode','ds']).head(1)
del train_df['hour']
 
test_df = test_power_forecast_history.groupby(['id_encode','ds']).head(1)
del test_df['hour']
 
tmp_df = train_power.groupby(['id_encode','ds'])['power'].sum()
tmp_df.columns = ['id_encode','ds','power']
 
# 合并充电量数据
train_df = train_df.merge(tmp_df, on=['id_encode','ds'], how='left')
 
### 合并数据
train_df = train_df.merge(train_stub_info, on='id_encode', how='left')
test_df = test_df.merge(test_stub_info, on='id_encode', how='left')


h3_code = pd.read_csv("../data/h3_lon_lat.csv")
train_df = train_df.merge(h3_code,on='h3')
test_df = test_df.merge(h3_code,on='h3')

def kalman_filter(data, q=0.0001, r=0.01):
    # 后验初始值
    x0 = data[0]                              # 令第一个估计值,为当前值
    p0 = 1.0
    # 存结果的列表
    x = [x0]
    for z in data[1:]:                        # kalman 滤波实时计算,只要知道当前值z就能计算出估计值(后验值)x0
        # 先验值
        x1_minus = x0                         # X(k|k-1) = AX(k-1|k-1) + BU(k) + W(k), A=1,BU(k) = 0
        p1_minus = p0 + q                     # P(k|k-1) = AP(k-1|k-1)A' + Q(k), A=1
        # 更新K和后验值
        k1 = p1_minus / (p1_minus + r)        # Kg(k)=P(k|k-1)H'/[HP(k|k-1)H' + R], H=1
        x0 = x1_minus + k1 * (z - x1_minus)   # X(k|k) = X(k|k-1) + Kg(k)[Z(k) - HX(k|k-1)], H=1
        p0 = (1 - k1) * p1_minus              # P(k|k) = (1 - Kg(k)H)P(k|k-1), H=1
        x.append(x0)                          # 由输入的当前值z 得到估计值x0存入列表中,并开始循环到下一个值
    return x


#kalman_filter()
train_df['new_label'] = 0
for i in range(500):
    #print(i)
    label = i
    #train_df[train_df['id_encode']==labe]['power'].values
    train_df.loc[train_df['id_encode']==label, 'new_label'] = kalman_filter(data=train_df[train_df['id_encode']==label]['power'].values)

### 数据预处理
train_df['flag'] = train_df['flag'].map({'A':0,'B':1})
test_df['flag'] = test_df['flag'].map({'A':0,'B':1})
 
def get_time_feature(df, col):
 
    df_copy = df.copy()
    prefix = col + "_"
    df_copy['new_'+col] = df_copy[col].astype(str)
 
    col = 'new_'+col
    df_copy[col] = pd.to_datetime(df_copy[col], format='%Y%m%d')
    #df_copy[prefix + 'year'] = df_copy[col].dt.year
    df_copy[prefix + 'month'] = df_copy[col].dt.month
    df_copy[prefix + 'day'] = df_copy[col].dt.day
    # df_copy[prefix + 'weekofyear'] = df_copy[col].dt.weekofyear
    df_copy[prefix + 'dayofweek'] = df_copy[col].dt.dayofweek
    # df_copy[prefix + 'is_wknd'] = df_copy[col].dt.dayofweek // 6
    df_copy[prefix + 'quarter'] = df_copy[col].dt.quarter
    # df_copy[prefix + 'is_month_start'] = df_copy[col].dt.is_month_start.astype(int)
    # df_copy[prefix + 'is_month_end'] = df_copy[col].dt.is_month_end.astype(int)
    del df_copy[col]
 
    return df_copy
 
train_df = get_time_feature(train_df, 'ds')
test_df = get_time_feature(test_df, 'ds')

train_df = train_df.fillna(999)
test_df = test_df.fillna(999)

cols = [f for f in train_df.columns if f not in ['ds','power','h3','new_label']]

# 是否进行归一化
scaler = MinMaxScaler(feature_range=(0,1))
scalar_falg = False
if scalar_falg == True:
    df_for_training_scaled = scaler.fit_transform(train_df[cols])
    df_for_testing_scaled= scaler.transform(test_df[cols])
else:
    df_for_training_scaled = train_df[cols]
    df_for_testing_scaled = test_df[cols]
#df_for_training_scaled
# scaler_label = MinMaxScaler(feature_range=(0,1))
# label_for_training_scaled = scaler_label.fit_transform(train_df['new_label']..values)
# label_for_testing_scaled= scaler_label.transform(train_df['new_label'].values)
# #df_for_training_scaled


class Config():
    data_path = '../data/data1/train/power.csv'
    timestep = 18  # 时间步长,就是利用多少时间窗口
    batch_size = 32  # 批次大小
    feature_size = 1  # 每个步长对应的特征数量,这里只使用1维,每天的风速
    hidden_size = 256  # 隐层大小
    output_size = 1  # 由于是单输出任务,最终输出层大小为1,预测未来1天风速
    num_layers = 2  # lstm的层数
    epochs = 10 # 迭代轮数
    best_loss = 0 # 记录损失
    learning_rate = 0.00003 # 学习率
    model_name = 'lstm' # 模型名称
    save_path = './{}.pth'.format(model_name) # 最优模型保存路径
    
config = Config()
x_train, x_test, y_train, y_test = train_test_split(df_for_training_scaled.values, train_df['new_label'].values,shuffle=False, test_size=0.2)

# 将数据转为tensor
x_train_tensor = torch.from_numpy(x_train.reshape(-1,config.timestep,1)).to(torch.float32)
y_train_tensor = torch.from_numpy(y_train.reshape(-1,1)).to(torch.float32)
x_test_tensor = torch.from_numpy(x_test.reshape(-1,config.timestep,1)).to(torch.float32)
y_test_tensor = torch.from_numpy(y_test.reshape(-1,1)).to(torch.float32)

# 5.形成训练数据集
train_data = TensorDataset(x_train_tensor, y_train_tensor)
test_data = TensorDataset(x_test_tensor, y_test_tensor)

# 6.将数据加载成迭代器
train_loader = torch.utils.data.DataLoader(train_data,
                                           config.batch_size,
                                           False)

test_loader = torch.utils.data.DataLoader(test_data,
                                          config.batch_size,
                                          False)


#train_df[cols]
# 7.定义LSTM网络
class LSTM(nn.Module):
    def __init__(self, feature_size, hidden_size, num_layers, output_size):
        super(LSTM, self).__init__()
        self.hidden_size = hidden_size  # 隐层大小
        self.num_layers = num_layers  # lstm层数
        # feature_size为特征维度,就是每个时间点对应的特征数量,这里为1
        self.lstm = nn.LSTM(feature_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x, hidden=None):
        #print(x.shape)
        batch_size = x.shape[0] # 获取批次大小 batch, time_stamp , feat_size
        
        # 初始化隐层状态
        if hidden is None:
            h_0 = x.data.new(self.num_layers, batch_size, self.hidden_size).fill_(0).float()
            c_0 = x.data.new(self.num_layers, batch_size, self.hidden_size).fill_(0).float()
        else:
            h_0, c_0 = hidden
            
        # LSTM运算
        output, (h_0, c_0) = self.lstm(x, (h_0, c_0))
        
        # 全连接层
        output = self.fc(output)  # 形状为batch_size * timestep, 1
        
        # 我们只需要返回最后一个时间片的数据即可
        return output[:, -1, :]
model = LSTM(config.feature_size, config.hidden_size, config.num_layers, config.output_size)  # 定义LSTM网络

loss_function = nn.L1Loss()  # 定义损失函数
optimizer = torch.optim.AdamW(model.parameters(), lr=config.learning_rate)  # 定义优化器


# 8.模型训练
for epoch in range(config.epochs):
    model.train()
    running_loss = 0
    train_bar = tqdm(train_loader)  # 形成进度条
    for data in train_bar:
        x_train, y_train = data  # 解包迭代器中的X和Y
        optimizer.zero_grad()
        y_train_pred = model(x_train)
        loss = loss_function(y_train_pred, y_train.reshape(-1, 1))
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format(epoch + 1,
                                                                 config.epochs,
                                                                 loss)

    # 模型验证
    model.eval()
    test_loss = 0
    with torch.no_grad():
        test_bar = tqdm(test_loader)
        for data in test_bar:
            x_test, y_test = data
            y_test_pred = model(x_test)
            test_loss = loss_function(y_test_pred, y_test.reshape(-1, 1))

    if test_loss < config.best_loss:
        config.best_loss = test_loss
        torch.save(model.state_dict(), save_path)

print('Finished Training')




train epoch[1/10] loss:293.638: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:41<00:00, 36.84it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:12<00:00, 73.96it/s]
train epoch[2/10] loss:272.386: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:49<00:00, 33.90it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:12<00:00, 77.56it/s]
train epoch[3/10] loss:252.972: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:43<00:00, 35.91it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:13<00:00, 70.65it/s]
train epoch[4/10] loss:235.282: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:45<00:00, 35.27it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:09<00:00, 93.71it/s]
train epoch[5/10] loss:219.069: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:34<00:00, 39.57it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:08<00:00, 103.92it/s]
train epoch[6/10] loss:203.969: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:30<00:00, 41.22it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:09<00:00, 95.62it/s]
train epoch[7/10] loss:189.877: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:35<00:00, 39.19it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:12<00:00, 77.61it/s]
train epoch[8/10] loss:176.701: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:52<00:00, 33.12it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:11<00:00, 81.34it/s]
train epoch[9/10] loss:164.382: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:41<00:00, 36.64it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:08<00:00, 112.27it/s]
train epoch[10/10] loss:152.841: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3727/3727 [01:25<00:00, 43.40it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 932/932 [00:09<00:00, 94.54it/s]

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

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

相关文章

抖音小店开店指南:流程、准备和营销策略一站解析

抖音小店已成为一个热门的社交电商平台&#xff0c;为商家提供了一个快速、方便、低成本的开店通道。下面四川不若与众将介绍抖音小店开店的流程和需要准备的工作&#xff0c;帮助商家顺利开启自己的电商之路。 一、开店准备工作&#xff1a; 1. 产品准备&#xff1a;确定出售…

系列十五、BeanDefinition

一、BeanDefinition 1.1、概述 BeanDefinition是一个接口&#xff0c;主要负责存储bean的定义信息&#xff0c;决定bean的生产方式&#xff0c;是一个定义态的bean&#xff0c;类似于说明书。后续BeanFactory就可以根据这些信息生产bean了。比如实例化&#xff1a;可以通过反射…

浅析基于物联网的远程抄表系统的设计及应用

安科瑞 华楠 摘 要&#xff1a;本文基于物联网的概念&#xff0c;使用 ZigBee、通用分组无线服务技术两种无线通信技术相结合的方式实现远程抄表并对数据进行存储和管理。此系统设计主要分为硬件方面的设计和软件方面的设计&#xff0c;硬件方面的设计需要完成三个部分的硬件制…

快速认识Linux的几个指令

我们先简单认识几个指令&#xff0c;为之后的指令学习打好基础 打开XShell并登录云服务器 01.pwd指令 pwd命令的作用是显示当前在Linux系统中所处的路径 02.ls指令 ls命令的作业是罗列出当前路径下的文件名&#xff08;即pwd的路径下&#xff09;&#xff0c;由于我们没有新…

人工智能-注意力机制之Transformer

Transformer 比较了卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;和自注意力&#xff08;self-attention&#xff09;。值得注意的是&#xff0c;自注意力同时具有并行计算和最短的最大路径长度这两个优势。因此&#xff0c;使用自注意力…

【H5 Canvas】一篇通

文章目录 Canvas的创建(HTMLCanvasElement)图形绘制&#xff1a;H5为Canvas对应的2D上下文Context提供了一系列的画图接口保存save、恢复restore、变换Transformations Canvas的创建(HTMLCanvasElement) 定义canvas HTML元素&#xff0c;默认长宽300x150 <canvas width&qu…

利用chart.js来完成动态网页显示拆线图的效果

<% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%><%! String list"[一月份, 二月份, 三月份,四月份, 五月份, 六月份, 七月]"; String label"我的一个折线图"; String data &qu…

RocketMq架构和源码解析

NameServer&#xff1a;作为注册中心&#xff0c;提供路由注册、路由踢出、路由发现功能&#xff0c;舍弃强一致&#xff0c;保证高可用&#xff0c;集群中各个节点不会实时通讯&#xff0c;其中一个节点下线之后&#xff0c;会提供另外一个节点保证路由功能。 Broker&#xf…

为什么网上大量程序员卡35岁年龄招聘,而从来不报道测试、技术支持、售前售后工程师呢?

其实&#xff0c;网上只报道程序员卡35岁&#xff0c;这个说法并不成立。 而是普遍卡35岁&#xff0c;但并没有明确的一个职业类别。 随便搜一下&#xff0c;一眼望过去&#xff0c;其实已经波及很多行业了。 但如果你把IT从业人员合并报道&#xff0c;确实容易给人一种“程序…

Docker Swarm总结+service创建和部署、overlay网络以及Raft算法(2/4)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

【Go实现】实践GoF的23种设计模式:备忘录模式

上一篇&#xff1a;【Go实现】实践GoF的23种设计模式&#xff1a;命令模式 简单的分布式应用系统&#xff08;示例代码工程&#xff09;&#xff1a;https://github.com/ruanrunxue/Practice-Design-Pattern–Go-Implementation 简介 相对于代理模式、工厂模式等设计模式&…

红队攻防实战系列一之metasploit

百目无她&#xff0c;百书质华&#xff0c;君当醒悟&#xff0c;建我中华 本文首发于先知社区&#xff0c;原创作者即是本人 前言 在红队攻防中&#xff0c;我们主要在外网进行信息收集&#xff0c;通过cms或者其他漏洞拿到shell&#xff0c;之后通过免杀木马将windows或lin…

【通讯协议】gRPC和Webhook

RPC&#xff08;Remote procedure Call&#xff09;之所以被称为“远程”&#xff0c;是因为在微服务架构下&#xff0c;当服务部署到不同的服务器上时&#xff0c;它可以实现远程服务之间的通信。从用户的角度来看&#xff0c;它的作用就像本地函数调用。 下图说明了gRPC的整…

java io 流,输入流和输出流;节点流和处理流;字节流和字符流

文章目录 java 中 IO 流分为几种?按照流的流向分&#xff0c;可以分为输入流和输出流&#xff1b;按照流的角色划分为节点流和处理流。IO流主要的分类方式有以下3种&#xff1a; java中的IO流也是工作中使用到比较频繁的一个内容&#xff0c;今天以这篇文章来了解它的概念和整…

第十七章 解读PyTorch断点训练(工具)

主要有以下几方面的内容&#xff1a; 对于多步长训练需要保存lr_schedule初始化随机数种子保存每一代最好的结果 简单详细介绍 最近在尝试用CIFAR10训练分类问题的时候&#xff0c;由于数据集体量比较大&#xff0c;训练的过程中时间比较长&#xff0c;有时候想给停下来&…

下一代图片压缩格式 AVIF

长期以来我们都在为了在网络上使用什么样的图片格式而进行纠结。我们所熟知的或者运用到 Web 应用中的图片格式无非就是 PNG、JPG、GIF、SVG 或者 WebP。 HEIC是一种图像格式&#xff0c;上线时间还比较短&#xff0c;只有4年左右。 自iOS 11和 macOS High Sierra&#xff08…

基于 Gin 的 HTTPS 代理 Demo

上次写了 基于 Gin 的 HTTP 代理 Demo 之后&#xff0c;对这方面还是蛮感兴趣的&#xff0c;所以就接着继续走下去。为了这个主题的内容&#xff0c;我斥巨资购入了一本二手的 《HTTP 权威指南》&#xff0c;因为我知道这本书里面有我想要的知识。在我还在大学的时候&#xff0…

Kerberos 高可用配置和验证

参考 https://cloud.tencent.com/developer/article/1078314 https://mp.weixin.qq.com/s?__bizMzI4OTY3MTUyNg&mid2247485861&idx1&snbb930a497f63ac5e63ed20c64643eec5 机器准备 Kerberos主 ip-172-31-22-86.ap-southeast-1.compute.internal 7.common2.hado…

美国季节性干旱数据集

美国季节性干旱数据集 美国干旱展望栅格数据集由国家气象局气候预测中心生成。它在每个月的最后一天发布&#xff0c;提供下个月的干旱前景信息。“美国季节性干旱展望”数据集每月发布一次&#xff0c;特别是每月的第三个星期四。该数据集对美国不同地区发生干旱的可能性进行…

Linux加强篇005-用户身份与文件权限

目录 前言 1. 用户身份与能力 2. 文件权限与归属 3. 文件的特殊权限 4. 文件的隐藏属性 5. 文件访问控制列表 6. su命令与sudo服务 前言 悟已往之不谏&#xff0c;知来者之可追。实迷途其未远&#xff0c;觉今是而昨非。舟遥遥以轻飏&#xff0c;风飘飘而吹衣。问征夫以…