AI实战:使用LSTM做数值序列预测

该博客介绍了使用TensorFlow 2.x和Keras在Ubuntu上构建GRU模型进行数值序列预测的过程。核心代码包括数据加载、模型搭建(两层GRU,Dropout层和全连接层)、损失函数选择(SMAPE)、模型训练及验证。模型概览显示了参数数量和结构。此外,还提供了数据集划分、模型训练与测试的辅助函数。
摘要由CSDN通过智能技术生成

依赖环境

  • python3.x
  • tensorflow 2.x
  • Linux(我用的Ubuntu 18.04LTS)
  • numpy
  • pandas
  • sklearn

核心代码

搭建模型

  • 依赖库
import sys
import os
from tensorflow import keras
from tensorflow.keras.models import Model
import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np
import tensorflow as tf
from tensorflow.keras import backend as K

#tf2.0
gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
tf.config.experimental.set_virtual_device_configuration(gpus[0],[tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024*1)])

  • 核心模型代码
    #搭建模型
    model = keras.models.Sequential()
    model.add(keras.layers.GRU(units=256, return_sequences=True, activation='tanh', input_shape=(train_X.shape[1],1)))
    model.add(keras.layers.GRU(units=64, return_sequences=False))
    model.add(keras.layers.Dropout(0.5))
    model.add(keras.layers.Dense(n_forecast, activation='linear'))
    
    model.compile(loss=smape, optimizer=keras.optimizers.Adam())
    model.summary()

注意:
1、这里使用的是GRU,主要是数据量较少,数据量特别大的话建议使用LSTM;
2、隐藏层使用256层,可以根据需要自己定义,建议不要过大或者过小;
3、loss函数选取特别重要,有量纲的话用MAE、MSE、RMSE、Huber Loss(将MSE与MAE结合起来),无量纲的话使用SMAPE、NMB;

  • 整体代码
def rnn_model(data_name, n_input, n_forecast, train_data_path, test_data_path):
    
    
    #数据加载
    X, Y = load_data('train', train_data_path, n_input, n_forecast)
    
	
    #拆分数据集
    train_X, train_Y, valid_X, valid_Y = split_data(X, Y)
    
    
    #搭建模型
    model = keras.models.Sequential()
    model.add(keras.layers.GRU(units=256, return_sequences=True, activation='tanh', input_shape=(train_X.shape[1],1)))
    model.add(keras.layers.GRU(units=64, return_sequences=False))
    model.add(keras.layers.Dropout(0.5))
    model.add(keras.layers.Dense(n_forecast, activation='linear'))
    
    model.compile(loss=smape, optimizer=keras.optimizers.Adam())
    model.summary()
    
    
    #训练模型
    print('training model')
    batch_size = 32
    epochs = 1000
    model_dir = './model_res/'
    model_path = os.path.join(model_dir, 'lstm-%s-%d-%d.h5' %(data_name, n_input, n_forecast))
    callback = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
    checkpoint_callback = keras.callbacks.ModelCheckpoint(
                                filepath=model_path,
                                save_weights_only=True,
                                monitor='val_loss',
                                mode='min',
                                save_best_only=True)

    model.fit(x = train_X, 
            y = train_Y, 
            batch_size = batch_size, 
            epochs = epochs, 
            callbacks=[callback, checkpoint_callback], 
            verbose = 2, 
            shuffle = True, 
            validation_data = (valid_X, valid_Y))
    
    
    #测试模型
    test_X, test_Y = load_data('test', test_data_path, n_input, n_forecast)
    y_pred = model.predict(test_X)
    scores = calcu_smape(y_pred, test_Y)
    print('-'*50)
    print('evalate result:')
    print(data_name, 'n_input: %d, n_forecast: %d, %s: %.4f' % (n_input, n_forecast, model.metrics_names, scores))
    

loss函数

def smape(y_true, y_pred):
    return 2.0 * K.mean(K.abs(y_pred - y_true) / (K.abs(y_pred) + K.abs(y_true) + 1e-31)) #* 100

其他辅助函数

def split_data(X, Y):
    
    data_index = [i for i in range(len(X))]

    train_data_index, test_data_index = train_test_split(data_index, test_size=0.2, random_state=2021)
    
    X_train, X_eval = X[train_data_index], X[test_data_index]
    y_train, y_eval = Y[train_data_index], Y[test_data_index]
    
    return X_train, y_train, X_eval, y_eval

模型概览

n_input = 48, n_forecast = 48 时的模型概览:

Layer (type)                 Output Shape              Param #
=================================================================
gru (GRU)                    (None, 432, 256)          198912
_________________________________________________________________
gru_1 (GRU)                  (None, 96)                101952
_________________________________________________________________
dropout (Dropout)            (None, 96)                0
_________________________________________________________________
dense (Dense)                (None, 48)                4656
=================================================================
Total params: 305,520
Trainable params: 305,520
Non-trainable params: 0

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

szZack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值