time-series - que - redes neuronales recurrentes
Cómo entrenar un RNN con células LSTM para la predicción de series de tiempo (3)
Creo que la Opción 1 es la más cercana a la implementación de referencia en /tensorflow/models/rnn/ptb/reader.py
def ptb_iterator(raw_data, batch_size, num_steps):
"""Iterate on the raw PTB data.
This generates batch_size pointers into the raw PTB data, and allows
minibatch iteration along these pointers.
Args:
raw_data: one of the raw data outputs from ptb_raw_data.
batch_size: int, the batch size.
num_steps: int, the number of unrolls.
Yields:
Pairs of the batched data, each a matrix of shape [batch_size, num_steps].
The second element of the tuple is the same data time-shifted to the
right by one.
Raises:
ValueError: if batch_size or num_steps are too high.
"""
raw_data = np.array(raw_data, dtype=np.int32)
data_len = len(raw_data)
batch_len = data_len // batch_size
data = np.zeros([batch_size, batch_len], dtype=np.int32)
for i in range(batch_size):
data[i] = raw_data[batch_len * i:batch_len * (i + 1)]
epoch_size = (batch_len - 1) // num_steps
if epoch_size == 0:
raise ValueError("epoch_size == 0, decrease batch_size or num_steps")
for i in range(epoch_size):
x = data[:, i*num_steps:(i+1)*num_steps]
y = data[:, i*num_steps+1:(i+1)*num_steps+1]
yield (x, y)
Sin embargo, otra opción es seleccionar un puntero en su matriz de datos al azar para cada secuencia de entrenamiento.
Actualmente estoy tratando de construir un modelo simple para predecir series de tiempo. El objetivo sería entrenar el modelo con una secuencia para que el modelo pueda predecir valores futuros.
Estoy usando las células tensorflow y lstm para hacerlo. El modelo está entrenado con propagación hacia atrás truncada a través del tiempo. Mi pregunta es cómo estructurar los datos para el entrenamiento.
Por ejemplo, supongamos que queremos aprender la secuencia dada:
[1,2,3,4,5,6,7,8,9,10,11,...]
Y desenrollamos la red para num_steps=4
.
Opción 1
input data label
1,2,3,4 2,3,4,5
5,6,7,8 6,7,8,9
9,10,11,12 10,11,12,13
...
opcion 2
input data label
1,2,3,4 2,3,4,5
2,3,4,5 3,4,5,6
3,4,5,6 4,5,6,7
...
Opcion 3
input data label
1,2,3,4 5
2,3,4,5 6
3,4,5,6 7
...
Opcion 4
input data label
1,2,3,4 5
5,6,7,8 9
9,10,11,12 13
...
Cualquier ayuda sería apreciada.
Después de leer varios blogs de introducción de LSTM, por ejemplo, Jakob Aungiers , la opción 3 parece ser la correcta para LSTM sin estado.
Si sus LSTM necesitan recordar los datos hace más tiempo que sus num_steps
, puede entrenarse de manera estable. Para ver un ejemplo de Keras, consulte la publicación en el blog de Philippe Remy "Stateful LSTM in Keras" . Sin embargo, Philippe no muestra un ejemplo para un tamaño de lote mayor que uno. Supongo que en su caso se podría usar un tamaño de lote de cuatro con LSTM con estado con los siguientes datos (escritos como input -> label
):
batch #0:
1,2,3,4 -> 5
2,3,4,5 -> 6
3,4,5,6 -> 7
4,5,6,7 -> 8
batch #1:
5,6,7,8 -> 9
6,7,8,9 -> 10
7,8,9,10 -> 11
8,9,10,11 -> 12
batch #2:
9,10,11,12 -> 13
...
Por esto, el estado de, por ejemplo, la segunda muestra en el lote # 0 se reutiliza correctamente para continuar el entrenamiento con la segunda muestra del lote # 1.
Esto es de alguna manera similar a su opción 4, sin embargo, no está utilizando todas las etiquetas disponibles allí.
Actualizar:
En extensión a mi sugerencia donde batch_size
es igual a num_steps
, Alexis Huet da una respuesta para el caso de batch_size
es un divisor de num_steps
, que puede usarse para num_steps
más num_steps
. Lo describe muy bien en su blog.
Estoy a punto de aprender LSTM en TensorFlow e intentar implementar un ejemplo que (afortunadamente) intenta predecir algunas series de tiempo / series de números generadas por una simple función de matemáticas.
Pero estoy usando una forma diferente de estructurar los datos para la capacitación, motivados por el aprendizaje no supervisado de representaciones de video usando LSTM :
Opción 5:
input data label
1,2,3,4 5,6,7,8
2,3,4,5 6,7,8,9
3,4,5,6 7,8,9,10
...
Además de este documento, intenté inspirarme con los ejemplos de RNN de TensorFlow dados. Mi solución completa actual se ve así:
import math
import random
import numpy as np
import tensorflow as tf
LSTM_SIZE = 64
LSTM_LAYERS = 2
BATCH_SIZE = 16
NUM_T_STEPS = 4
MAX_STEPS = 1000
LAMBDA_REG = 5e-4
def ground_truth_func(i, j, t):
return i * math.pow(t, 2) + j
def get_batch(batch_size):
seq = np.zeros([batch_size, NUM_T_STEPS, 1], dtype=np.float32)
tgt = np.zeros([batch_size, NUM_T_STEPS], dtype=np.float32)
for b in xrange(batch_size):
i = float(random.randint(-25, 25))
j = float(random.randint(-100, 100))
for t in xrange(NUM_T_STEPS):
value = ground_truth_func(i, j, t)
seq[b, t, 0] = value
for t in xrange(NUM_T_STEPS):
tgt[b, t] = ground_truth_func(i, j, t + NUM_T_STEPS)
return seq, tgt
# Placeholder for the inputs in a given iteration
sequence = tf.placeholder(tf.float32, [BATCH_SIZE, NUM_T_STEPS, 1])
target = tf.placeholder(tf.float32, [BATCH_SIZE, NUM_T_STEPS])
fc1_weight = tf.get_variable(''w1'', [LSTM_SIZE, 1], initializer=tf.random_normal_initializer(mean=0.0, stddev=1.0))
fc1_bias = tf.get_variable(''b1'', [1], initializer=tf.constant_initializer(0.1))
# ENCODER
with tf.variable_scope(''ENC_LSTM''):
lstm = tf.nn.rnn_cell.LSTMCell(LSTM_SIZE)
multi_lstm = tf.nn.rnn_cell.MultiRNNCell([lstm] * LSTM_LAYERS)
initial_state = multi_lstm.zero_state(BATCH_SIZE, tf.float32)
state = initial_state
for t_step in xrange(NUM_T_STEPS):
if t_step > 0:
tf.get_variable_scope().reuse_variables()
# state value is updated after processing each batch of sequences
output, state = multi_lstm(sequence[:, t_step, :], state)
learned_representation = state
# DECODER
with tf.variable_scope(''DEC_LSTM''):
lstm = tf.nn.rnn_cell.LSTMCell(LSTM_SIZE)
multi_lstm = tf.nn.rnn_cell.MultiRNNCell([lstm] * LSTM_LAYERS)
state = learned_representation
logits_stacked = None
loss = 0.0
for t_step in xrange(NUM_T_STEPS):
if t_step > 0:
tf.get_variable_scope().reuse_variables()
# state value is updated after processing each batch of sequences
output, state = multi_lstm(sequence[:, t_step, :], state)
# output can be used to make next number prediction
logits = tf.matmul(output, fc1_weight) + fc1_bias
if logits_stacked is None:
logits_stacked = logits
else:
logits_stacked = tf.concat(1, [logits_stacked, logits])
loss += tf.reduce_sum(tf.square(logits - target[:, t_step])) / BATCH_SIZE
reg_loss = loss + LAMBDA_REG * (tf.nn.l2_loss(fc1_weight) + tf.nn.l2_loss(fc1_bias))
train = tf.train.AdamOptimizer().minimize(reg_loss)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
total_loss = 0.0
for step in xrange(MAX_STEPS):
seq_batch, target_batch = get_batch(BATCH_SIZE)
feed = {sequence: seq_batch, target: target_batch}
_, current_loss = sess.run([train, reg_loss], feed)
if step % 10 == 0:
print("@{}: {}".format(step, current_loss))
total_loss += current_loss
print(''Total loss:'', total_loss)
print(''### SIMPLE EVAL: ###'')
seq_batch, target_batch = get_batch(BATCH_SIZE)
feed = {sequence: seq_batch, target: target_batch}
prediction = sess.run([logits_stacked], feed)
for b in xrange(BATCH_SIZE):
print("{} -> {})".format(str(seq_batch[b, :, 0]), target_batch[b, :]))
print(" `-> Prediction: {}".format(prediction[0][b]))
La salida de muestra de esto se ve así:
### SIMPLE EVAL: ###
# [input seq] -> [target prediction]
# `-> Prediction: [model prediction]
[ 33. 53. 113. 213.] -> [ 353. 533. 753. 1013.])
`-> Prediction: [ 19.74548721 28.3149128 33.11489105 35.06603241]
[ -17. -32. -77. -152.] -> [-257. -392. -557. -752.])
`-> Prediction: [-16.38951683 -24.3657589 -29.49801064 -31.58583832]
[ -7. -4. 5. 20.] -> [ 41. 68. 101. 140.])
`-> Prediction: [ 14.14126873 22.74848557 31.29668617 36.73633194]
...
El modelo es un autoencoder LSTM que tiene 2 capas cada uno.
Desafortunadamente, como puede ver en los resultados, este modelo no aprende la secuencia correctamente. Puede ser que esté cometiendo un grave error en algún lugar, o que los pasos de entrenamiento 1000-10000 sean muy pocos para un LSTM. Como dije, también estoy empezando a entender / usar los LSTM correctamente. Pero espero que esto le pueda dar alguna inspiración con respecto a la implementación.