with tutorial seq2seq neural network machine learning guide for experts example python machine-learning tensorflow lstm

python - tutorial - tensorflow seq2seq



Entradas LSTM para Tensorflow (1)

Estoy intentando crear una red LSTM en Tensorflow y estoy perdido en terminología / conceptos básicos. Tengo n ejemplos de series de tiempo así que X = x n , donde x i = [[x 1 1 x 1 2 , x 1 3 ], ..., [x m 1 x m 2 , x m 3 ]] y donde x yo soy un flotador Antes que nada quiero entrenar un modelo que, dado el inicio de una secuencia ([x 1 1 x 1 2 , x 1 3 ]), puedo predecir el resto de la secuencia. Luego, más tarde, espero incluir un clasificador para predecir a qué clase binaria pertenece cada x i .

Entonces mi problema es, ¿a qué alimentarlo desde el principio y sacar el final de mi modelo? Hasta ahora tengo algo que se parece a la siguiente

class ETLSTM(object): """docstring for ETLSTM""" def __init__(self, isTraining, config): super(ETLSTM, self).__init__() # This needs to be tidied self.batchSize = batchSize = config.batchSize self.numSteps = numSteps = config.numSteps self.numInputs = numInputs = config.numInputs self.numLayers = numLayers = config.numLayers lstmSize = config.lstm_size DORate = config.keep_prob self.input_data = tf.placeholder(tf.float32, [batchSize, numSteps, numInputs]) self.targets = tf.placeholder(tf.float32, [batchSize, numSteps, numInputs]) lstmCell = rnn_cell.BasicLSTMCell(lstmSize, forgetbias=0.0) if(isTraining and DORate < 1): lstmCell = tf.nn.rnn_cell.DropoutWrapper(lstmCell, output_keep_prob=DORate) cell = tf.nn.rnn_cell.MultiRNNCell([lstmCell]*numLayers) self._initial_state = cell.zero_state(batchSize, tf.float32) # This won''t work with my data, need to find what goes in... with tf.device("/cpu:0"): embedding = tf.get_variable("embedding", [vocab_size, size]) inputs = tf.nn.embedding_lookup(embedding, self._input_data) if(isTraining and DORate < 1): inputs = tf.nn.dropout(inputs, DORate)

EDITAR : Específicamente, ¿cómo terminar la función __init__ para que sea compatible con mis datos?


Un RNN predice el valor de N + 1 dados los valores de 1 a N hasta el momento. (LSTM es solo una forma de implementar una célula RNN).

La respuesta corta es:

  • entrena tu modelo usando propagación hacia atrás en tus secuencias completas [[x 1 1 x 1 2 , x 1 3 ], ..., [x m 1 x m 2 , x m 3 ]]
  • ejecute su modelo entrenado hacia adelante al comienzo de su secuencia [x 1 1 x 1 2 , x 1 3 , ...] luego muestree desde el modelo para predecir el resto de su secuencia [x m 1 x m 2 , x m 3 , ...].

La respuesta más larga es:

Su ejemplo solo muestra la inicialización del modelo. También necesita implementar una función de entrenamiento para ejecutar la propagación hacia atrás, así como una función de muestra que predice los resultados.

Los siguientes fragmentos de código son mix & match y solo tienen fines ilustrativos ...

Para el entrenamiento simplemente alimente en sus secuencias completas con inicio + descanso en su iterador de datos.

Por ejemplo, en el código de ejemplo tensorflow / models / rnn / ptb_word_lm.py, el ciclo de entrenamiento calcula una función de costo para lotes de datos de entrada frente a objetivos (que son los datos de entrada cambiados por un paso de tiempo)

# compute a learning rate decay session.run(tf.assign(self.learning_rate_variable, learning_rate)) logger.info("Epoch: %d Learning rate: %.3f" % (i + 1, session.run(self.learning_rate_variable))) """Runs the model on the given data.""" epoch_size = ((len(training_data) // self.batch_size) - 1) // self.num_steps costs = 0.0 iters = 0 state = self.initial_state.eval() for step, (x, y) in enumerate(self.data_iterator(training_data, self.batch_size, self.num_steps)): # x and y should have shape [batch_size, num_steps] cost, state, _ = session.run([self.cost_function, self.final_state, self.train_op], {self.input_data: x, self.targets: y, self.initial_state: state}) costs += cost iters += self.num_steps

Tenga en cuenta que el iterador de datos en tensorflow / models / rnn / reader.py devuelve los datos de entrada como ''x'' y los objetivos como ''y'', que simplemente se desplazan un paso adelante de x. (Debería crear un iterador de datos como este que empaqueta su conjunto de secuencias de entrenamiento).

def ptb_iterator(raw_data, batch_size, num_steps): 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)

Después del entrenamiento, ejecuta el modelo hacia adelante para hacer predicciones de secuencias al alimentar al inicio de su secuencia start_x = [X1, X2, X3, ...] ... estos fragmentos asumen valores binarios que representan clases, tendrían que ajustar la función de muestreo para valores flotantes.

def sample(self, sess, num=25, start_x): # return state tensor with batch size 1 set to zeros, eval state = self.rnn_layers.zero_state(1, tf.float32).eval() # run model forward through the start of the sequence for char in start_x: # create a 1,1 tensor/scalar set to zero x = np.zeros((1, 1)) # set to the vocab index x[0, 0] = char # fetch: final_state # input_data = x, initial_state = state [state] = sess.run([self.final_state], {self.input_data: x, self.initial_state:state}) def weighted_pick(weights): # an array of cummulative sum of weights t = np.cumsum(weights) # scalar sum of tensor s = np.sum(weights) # randomly selects a value from the probability distribution return(int(np.searchsorted(t, np.random.rand(1)*s))) # PREDICT REST OF SEQUENCE rest_x = [] # get last character in init char = start_x[-1] # sample next num chars in the sequence after init score = 0.0 for n in xrange(num): # init input to zeros x = np.zeros((1, 1)) # lookup character index x[0, 0] = char # probs = tf.nn.softmax(self.logits) # fetch: probs, final_state # input_data = x, initial_state = state [probs, state] = sess.run([self.output_layer, self.final_state], {self.input_data: x, self.initial_state:state}) p = probs[0] logger.info("output=%s" % np.shape(p)) # sample = int(np.random.choice(len(p), p=p)) # select a random value from the probability distribution sample = weighted_pick(p) score += p[sample] # look up the key with the index logger.debug("sample[%d]=%d" % (n, sample)) pred = self.vocabulary[sample] logger.debug("pred=%s" % pred) # add the car to the output rest_x.append(pred) # set the next input character char = pred return rest_x, score