Algoritmo de predicción LSTM para graduados en informática: predicción de acciones, predicción del tiempo, predicción del precio de la vivienda

0 Introducción

Hoy el senior les presentará los conceptos básicos de LSTM.

Algoritmo de predicción basado en LSTM: predicción de acciones, predicción del tiempo, predicción del precio de la vivienda

1 Uso de la red LSTM para la predicción de series temporales basada en Keras

El pronóstico de series de tiempo es un problema de pronóstico relativamente difícil.

A diferencia de los modelos de predicción de regresión comunes, la "dependencia serial" entre variables de entrada agrega complejidad a los problemas de series temporales.

Un tipo de red neuronal que está diseñada específicamente para manejar dependencias de secuencia se llama redes neuronales recurrentes (RNN). Debido a su excelente rendimiento durante el entrenamiento, la Red de Memoria a Corto Plazo (LSTM) es un tipo de red neuronal recurrente (RNN) ampliamente utilizada en el aprendizaje profundo.

En este artículo, presentaremos cómo utilizar el paquete de aprendizaje profundo keras en R para construir un modelo de red neuronal LSTM para lograr la predicción de series de tiempo.

  • Cómo establecer una red LSTM correspondiente para problemas de predicción de series de tiempo basados ​​en regresión, método de ventana y paso de tiempo.
  • Para secuencias muy largas, cómo mantener el estado de la red (memoria) sobre la secuencia al construir una red LSTM y usar la red LSTM para hacer predicciones.

2 Red de memoria larga y corta

Una red de memoria larga y corta, o red LSTM, es un tipo de red neuronal recurrente (RNN) que supera el problema del gradiente de desaparición mediante la "propagación hacia atrás en el tiempo" durante el entrenamiento.

Las redes LSTM se pueden utilizar para construir redes neuronales recurrentes a gran escala para manejar problemas de secuencias complejas en el aprendizaje automático y lograr buenos resultados.

Además de las neuronas, las redes LSTM también tienen módulos de memoria entre las capas de la red neuronal.

Un módulo de memoria tiene una composición especial que lo hace "más inteligente" que las neuronas tradicionales y puede generar recuerdos para las partes anterior y siguiente de la secuencia. Los módulos tienen diferentes "puertas" para controlar el estado y la salida del módulo. Una vez que se recibe y procesa una secuencia de entrada, cada puerta del módulo utiliza una unidad de activación en forma de S para controlar si está activada, cambiando así el estado del módulo y agregando información (memoria) al módulo.

Una unidad de activación tiene tres tipos de puertas:

  • Olvídate de Gate: decide qué información descartar.
  • Puerta de entrada: determina qué valores de la entrada se utilizan para actualizar el estado de la memoria.
  • Puerta de salida: determina el valor de salida en función del estado de la entrada y la memoria.

Cada unidad de activación es como una mini máquina de estados y los pesos de cada puerta de la unidad se obtienen mediante entrenamiento.

3 Estructura y principio de la red LSTM

La memoria a largo plazo, lo que llamamos LSTM, está diseñada específicamente para resolver un problema de larga data. Todos los RNN tienen una forma de cadena de módulos de red neuronal repetidos. En RNN estándar, este módulo estructural repetido tiene solo una estructura muy simple, como una capa tanh.

Insertar descripción de la imagen aquí

LSTM tiene la misma estructura, pero los módulos repetidos tienen una estructura diferente. En lugar de una única capa de red neuronal, hay cuatro que interactúan de una manera muy específica.

Insertar descripción de la imagen aquí

No te preocupes por los detalles aquí. Analizaremos el gráfico de análisis de LSTM paso a paso. Ahora, familiaricémonos con los iconos de los distintos elementos utilizados en el diagrama.

Insertar descripción de la imagen aquí

En la ilustración anterior, cada línea negra transporta un vector completo desde la salida de un nodo hasta la entrada de otros nodos. El círculo rosa representa operaciones puntuales, como la suma de vectores, y la matriz amarilla es la capa de red neuronal aprendida. Las líneas que se unen representan la conexión de los vectores y las líneas que se separan representan el contenido que se copia y luego se distribuye en diferentes ubicaciones.

3.1 Idea central de LSTM

La clave de LSTM radica en el estado completo de la celda (como se muestra a continuación) y la línea horizontal que pasa a través de la celda.

El estado celular se asemeja a una cinta transportadora. Opera directamente en toda la cadena, con solo unas pocas interacciones lineales pequeñas. Sería fácil que la información fluyera y permaneciera igual.

Insertar descripción de la imagen aquí
La puerta puede dejar pasar información de forma selectiva, principalmente a través de una capa neuronal sigmoidea y una operación de multiplicación punto por punto.

Insertar descripción de la imagen aquí
Cada elemento de la salida de la capa sigmoidea (que es un vector) es un número real entre 0 y 1, que representa el peso (o proporción) de dejar pasar la información correspondiente. Por ejemplo, 0 significa "no dejar pasar ninguna información" y 1 significa "dejar pasar toda la información".

LSTM logra la protección y el control de la información a través de tres de estas estructuras. Estas tres puertas son la puerta de entrada, la puerta de olvido y la puerta de salida.

3.2 Puerta del olvido

El primer paso en nuestro LSTM es decidir qué información descartaremos del estado de la celda. Esta decisión se toma a través de una capa llamada puerta del olvido. La puerta lee la suma y genera un valor entre 0 y 1 para cada número en el estado de la celda. 1 significa "conservarlo por completo" y 0 significa "desecharlo por completo".

Volvamos al ejemplo del modelo de lenguaje de predecir la siguiente palabra en función de lo que hemos visto. En este problema, el estado de la celda puede contener el género del sujeto actual, por lo que se puede elegir el pronombre correcto. Cuando vemos un tema nuevo, queremos olvidar el tema anterior.

Insertar descripción de la imagen aquí
en

Insertar descripción de la imagen aquí

Representa la salida de la capa oculta en el momento anterior,

Insertar descripción de la imagen aquí

Representa la entrada de la celda actual. σ representa la función sigmod.

3.3 Puerta de entrada

El siguiente paso es decidir cuánta información nueva agregar al estado de la celda. Implementar esto requiere dos pasos: primero, una capa sigmoidea llamada "capa de puerta de entrada" determina qué información debe actualizarse; una capa tanh genera un vector, que es el contenido alternativo para la actualización. En el siguiente paso, combinamos estas dos partes para actualizar el estado de la celda.

Insertar descripción de la imagen aquí

3.4 Puerta de salida

En última instancia, necesitamos determinar qué valor generar. Esta salida se basará en el estado de nuestra celda, pero también en una versión filtrada. Primero, ejecutamos una capa sigmoidea para determinar qué parte del estado de la celda se generará. A continuación, pasamos el estado de la celda a través de tanh (obteniendo un valor entre -1 y 1) y lo multiplicamos con la salida de la puerta sigmoidea, y terminamos generando solo la parte de la salida que determinamos.

En el ejemplo del modelo de lenguaje, dado que ve un pronombre, es posible que necesite generar información relacionada con un verbo. Por ejemplo, podría ser posible determinar si el pronombre es singular o negativo, de modo que si es un verbo, también sepamos la inflexión que debe sufrir el verbo.

Insertar descripción de la imagen aquí

4 Predicción del tiempo basada en LSTM

4.1 Conjunto de datos

Insertar descripción de la imagen aquí

Como se muestra arriba, las observaciones se registran cada 10 minutos, hay 6 observaciones en una hora y 144 (6x24) observaciones en un día.

Dada una hora específica, digamos que desea predecir la temperatura durante las próximas 6 horas. Para realizar esta predicción se eligió un período de observación de 5 días. Por lo tanto, cree una ventana que contenga las últimas 720 (5x144) observaciones para entrenar el modelo.

La siguiente función devuelve la ventana de tiempo anterior para el entrenamiento del modelo. El parámetro historial_tamaño es el tamaño de la ventana deslizante de información pasada. target_size es el paso de tiempo futuro que el modelo necesita aprender a predecir y también sirve como etiqueta que debe predecirse.

Las primeras 300.000 filas de datos se utilizan como conjunto de datos de entrenamiento a continuación y el resto se utiliza como conjunto de datos de validación. Un total de unos 2100 días de datos de entrenamiento.

4.2 Ejemplo de pronóstico

En el modelo de predicción de varios pasos, dados los valores de muestra pasados, se predice una serie de valores futuros. Para los modelos de varios pasos, los datos de entrenamiento nuevamente incluyen los últimos cinco días de registros muestreados cada hora. Sin embargo, el modelo aquí necesita aprender a predecir la temperatura durante las próximas 12 horas. Dado que los datos se muestrean cada 10 minutos, el resultado son 72 valores predichos.

future_target = 72
x_train_multi, y_train_multi = multivariate_data(dataset, dataset[:, 1], 0,
                                                 TRAIN_SPLIT, past_history,
                                                 future_target, STEP)
x_val_multi, y_val_multi = multivariate_data(dataset, dataset[:, 1],
                                             TRAIN_SPLIT, None, past_history,
                                             future_target, STEP)

Particionar el conjunto de datos

train_data_multi = tf.data.Dataset.from_tensor_slices((x_train_multi, y_train_multi))
train_data_multi = train_data_multi.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()

val_data_multi = tf.data.Dataset.from_tensor_slices((x_val_multi, y_val_multi))
val_data_multi = val_data_multi.batch(BATCH_SIZE).repeat()

Trazar datos de puntos de muestra

def multi_step_plot(history, true_future, prediction):
    plt.figure(figsize=(12, 6))
    num_in = create_time_steps(len(history))
    num_out = len(true_future)

    plt.plot(num_in, np.array(history[:, 1]), label='History')
    plt.plot(np.arange(num_out)/STEP, np.array(true_future), 'bo',
           label='True Future')
    if prediction.any():
        plt.plot(np.arange(num_out)/STEP, np.array(prediction), 'ro',
                 label='Predicted Future')
    plt.legend(loc='upper left')
    plt.show()
for x, y in train_data_multi.take(1):
  multi_step_plot(x[0], y[0], np.array([0]))

Insertar descripción de la imagen aquí

La tarea aquí es un poco más compleja que la anterior, por lo que el modelo ahora consta de dos capas LSTM. Finalmente, dado que necesitamos predecir las próximas 12 horas de datos, la capa Densa generará 72.

multi_step_model = tf.keras.models.Sequential()
multi_step_model.add(tf.keras.layers.LSTM(32,
                                          return_sequences=True,
                                          input_shape=x_train_multi.shape[-2:]))
multi_step_model.add(tf.keras.layers.LSTM(16, activation='relu'))
multi_step_model.add(tf.keras.layers.Dense(72))

multi_step_model.compile(optimizer=tf.keras.optimizers.RMSprop(clipvalue=1.0), loss='mae')

tren

multi_step_history = multi_step_model.fit(train_data_multi, epochs=EPOCHS,
                                          steps_per_epoch=EVALUATION_INTERVAL,
                                          validation_data=val_data_multi,
                                          validation_steps=50)

Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

5 Predicción del precio de las acciones basada en LSTM

5.1 Conjunto de datos

Los datos bursátiles tienen un total de nueve dimensiones, a saber

Insertar descripción de la imagen aquí

5.2 Código de implementación

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
plt.rcParams['font.sans-serif']=['SimHei']#显示中文
plt.rcParams['axes.unicode_minus']=False#显示负号

def load_data():
    test_x_batch = np.load(r'test_x_batch.npy',allow_pickle=True)
    test_y_batch = np.load(r'test_y_batch.npy',allow_pickle=True)
    return (test_x_batch,test_y_batch)

#定义lstm单元
def lstm_cell(units):
    cell = tf.contrib.rnn.BasicLSTMCell(num_units=units,forget_bias=0.0)#activation默认为tanh
    return cell

#定义lstm网络
def lstm_net(x,w,b,num_neurons):
    #将输入变成一个列表,列表的长度及时间步数
    inputs = tf.unstack(x,8,1)
    cells = [lstm_cell(units=n) for n in num_neurons]
    stacked_lstm_cells = tf.contrib.rnn.MultiRNNCell(cells)
    outputs,_ =  tf.contrib.rnn.static_rnn(stacked_lstm_cells,inputs,dtype=tf.float32)
    return tf.matmul(outputs[-1],w) + b

#超参数
num_neurons = [32,32,64,64,128,128]

#定义输出层的weight和bias
w = tf.Variable(tf.random_normal([num_neurons[-1],1]))
b = tf.Variable(tf.random_normal([1]))

#定义placeholder
x = tf.placeholder(shape=(None,8,8),dtype=tf.float32)

#定义pred和saver
pred = lstm_net(x,w,b,num_neurons)
saver = tf.train.Saver(tf.global_variables())

if __name__ == '__main__':

    #开启交互式Session
    sess = tf.InteractiveSession()
    saver.restore(sess,r'D:\股票预测\model_data\my_model.ckpt')

    #载入数据
    test_x,test_y = load_data()

    #预测
    predicts = sess.run(pred,feed_dict={
    
    x:test_x})
    predicts = ((predicts.max() - predicts) / (predicts.max() - predicts.min()))#数学校准

    #可视化
    plt.plot(predicts,'r',label='预测曲线')
    plt.plot(test_y,'g',label='真实曲线')
    plt.xlabel('第几天/days')
    plt.ylabel('开盘价(归一化)')
    plt.title('股票开盘价曲线预测(测试集)')
    plt.legend()
	plt.show()
    #关闭会话
    sess.close()	

Insertar descripción de la imagen aquí

6 lstm predice el número de pasajeros aéreos

conjunto de datos

dirección de descarga del conjunto de datos de pasajeros de vuelos aéreos

https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv

Este conjunto de datos contiene el número de pasajeros aéreos cada mes desde 1949 hasta 1960, un total de 12*12=144 números.

En el siguiente programa, utilizamos los datos de 1949-1952 para predecir los datos de 1953, y los datos de 1950-1953 para predecir los datos de 1954, y así sucesivamente para entrenar el modelo.

código de predicción

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
import torch.nn as nn
from sklearn.preprocessing import MinMaxScaler
import os
 
# super parameters
EPOCH = 400
learning_rate = 0.01
seq_length = 4   # 序列长度
n_feature = 12   # 序列中每个元素的特征数目。本程序采用的序列元素为一年的旅客,一年12个月,即12维特征。
 
# data
data = pd.read_csv('airline-passengers.csv')   # 共 "12年*12个月=144" 个数据
data = data.iloc[:, 1:5].values        # dataFrame, shape (144,1)
data = np.array(data).astype(np.float32)
sc = MinMaxScaler()
data = sc.fit_transform(data)          # 归一化
data = data.reshape(-1, n_feature)     # shape (12, 12)
 
trainData_x = []
trainData_y = []
for i in range(data.shape[0]-seq_length):
    tmp_x = data[i:i+seq_length, :]
    tmp_y = data[i+seq_length, :]
    trainData_x.append(tmp_x)
    trainData_y.append(tmp_y)
 
# model
class Net(nn.Module):
    def __init__(self, in_dim=12, hidden_dim=10, output_dim=12, n_layer=1):
        super(Net, self).__init__()
        self.in_dim = in_dim
        self.hidden_dim = hidden_dim
        self.output_dim = output_dim
        self.n_layer = n_layer
        self.lstm = nn.LSTM(input_size=in_dim, hidden_size=hidden_dim, num_layers=n_layer, batch_first=True)
        self.linear = nn.Linear(hidden_dim, output_dim)
 
    def forward(self, x):
        _, (h_out, _) = self.lstm(x)  # h_out是序列最后一个元素的hidden state
                                      # h_out's shape (batchsize, n_layer*n_direction, hidden_dim), i.e. (1, 1, 10)
                                      # n_direction根据是“否为双向”取值为1或2
        h_out = h_out.view(h_out.shape[0], -1)   # h_out's shape (batchsize, n_layer * n_direction * hidden_dim), i.e. (1, 10)
        h_out = self.linear(h_out)    # h_out's shape (batchsize, output_dim), (1, 12)
        return h_out
 
train = True
if train:
    model = Net()
    loss_func = torch.nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    # train
    for epoch in range(EPOCH):
        total_loss = 0
        for iteration, X in enumerate(trainData_x):  # X's shape (seq_length, n_feature)
            X = torch.tensor(X).float()
            X = torch.unsqueeze(X, 0)                # X's shape (1, seq_length, n_feature), 1 is batchsize
            output = model(X)       # output's shape (1,12)
            output = torch.squeeze(output)
            loss = loss_func(output, torch.tensor(trainData_y[iteration]))
            optimizer.zero_grad()   # clear gradients for this training iteration
            loss.backward()         # computing gradients
            optimizer.step()        # update weights
            total_loss += loss
 
        if (epoch+1) % 20 == 0:
            print('epoch:{:3d}, loss:{:6.4f}'.format(epoch+1, total_loss.data.numpy()))
    # torch.save(model, 'flight_model.pkl')  # 这样保存会弹出UserWarning,建议采用下面的保存方法,详情可参考https://zhuanlan.zhihu.com/p/129948825
    torch.save({
    
    'state_dict': model.state_dict()}, 'checkpoint.pth.tar')
 
else:
    # model = torch.load('flight_model.pth')
    model = Net()
    checkpoint = torch.load('checkpoint.pth.tar')
    model.load_state_dict(checkpoint['state_dict'])
 
# predict
model.eval()
predict = []
for X in trainData_x:             # X's shape (seq_length, n_feature)
    X = torch.tensor(X).float()
    X = torch.unsqueeze(X, 0)     # X's shape (1, seq_length, n_feature), 1 is batchsize
    output = model(X)             # output's shape (1,12)
    output = torch.squeeze(output)
    predict.append(output.data.numpy())
 
# plot
plt.figure()
predict = np.array(predict)
predict = predict.reshape(-1, 1).squeeze()
x_tick = np.arange(len(predict)) + (seq_length*n_feature)
plt.plot(list(x_tick), predict, label='predict data')
 
data_original = data.reshape(-1, 1).squeeze()
plt.plot(range(len(data_original)), data_original, label='original data')
 
plt.legend(loc='best')
plt.show()

resultado de la operación

Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

7 finalmente

Supongo que te gusta

Origin blog.csdn.net/HUXINY/article/details/133024003
Recomendado
Clasificación