Tensorflow: Obtuve un error al inicializar rnn bidireccional con la celda LSTM

Creado en 18 ene. 2016  ·  3Comentarios  ·  Fuente: tensorflow/tensorflow

Quiero construir un modelo bi-rnn con tensorflow con celda LSTM, cuando intento inicializar bidirectional_rnn,
da: ValueError: Over-sharing: Variable BiRNN_FW/RNN/BasicLSTMCell/Linear/Matrix already exists, disallowed. Did you mean to set reuse=True in VarScope?

import tensorflow as tf
from tensorflow.models.rnn import rnn, rnn_cell
from tensorflow.python.ops.constant_op import constant
import numpy as np

class Model(object):
    def __init__(self, batch_size, len_word, num_chars, dim_embed, dim_hidden):
        self.batch_size = batch_size
        self.dim_embed = dim_embed
        self.dim_hidden = dim_hidden
        self.num_chars = num_chars
        self.len_word = len_word

        with tf.device("/cpu:0"):
            self.embedding = tf.Variable(tf.random_uniform([num_chars, dim_embed], -0.1, 0.1), name='embedding')

        self.W_emb = tf.Variable(tf.random_uniform([dim_hidden*2, dim_embed], -0.1, 0.1), name='W_emb')
        self.b_emb = tf.Variable(tf.zeros([dim_embed]), name='b_emb')
        self.lstm_fw_cell = rnn_cell.BasicLSTMCell(dim_hidden)
        self.lstm_bw_cell = rnn_cell.BasicLSTMCell(dim_hidden)

    def build_model(self):
        inputs = tf.placeholder(tf.int32, [self.batch_size, self.len_word])
        input_length = tf.placeholder(tf.int64, [self.batch_size])
        lstm_state_fw = self.lstm_fw_cell.zero_state(self.batch_size, tf.float32)
        lstm_state_bw = self.lstm_bw_cell.zero_state(self.batch_size, tf.float32)

        with tf.device("/cpu:0"):
            embedded_input = tf.nn.embedding_lookup(self.embedding, tf.transpose(inputs))

        brnn_output = rnn.bidirectional_rnn(
            self.lstm_fw_cell, self.lstm_bw_cell,
            tf.unpack(embedded_input),
            sequence_length=input_length,
            initial_state_fw=lstm_state_fw,
            initial_state_bw=lstm_state_bw,
        )

        pooled_output = tf.reduce_sum( tf.pack(brnn_output), 0 )
        pooled_output = pooled_output / tf.expand_dims( tf.to_float(input_length) + 1e-6, 1)
        final_emb = tf.nn.xw_plus_b(pooled_output, self.W_emb, self.b_emb)
        final_emb = tf.nn.l2_normalize(final_emb, dim=1, epsilon=1e-7)

        return final_emb

Comentario más útil

Debe especificar diferentes alcances de variables para las celdas LSTM.

with tf.variable_scope('forward'):
    self.lstm_fw_cell = rnn_cell.BasicLSTMCell(dim_hidden)   
with tf.variable_scope('backward'):
    self.lstm_bw_cell = rnn_cell.BasicLSTMCell(dim_hidden)

De lo contrario, habrá una colisión de nombres (ambas celdas intentan usar el nombre "BiRNN_FW / RNN / BasicLSTMCell / Linear / Matrix") y tf interpretará esto como si su intención fuera compartir los parámetros en las dos celdas, que no es lo que quieres. TF lanzará una excepción porque no le ha dicho explícitamente que reutilice las variables en el segundo alcance: with variable_scope(name, reuse=True) .

La configuración de los alcances de las variables, como se indicó anteriormente, creará nombres únicos para las variables:
BiRNN_FW / RNN / BasicLSTMCell / adelante / Lineal / Matriz
BiRNN_FW / RNN / BasicLSTMCell / hacia atrás / Lineal / Matriz

Lea la guía Compartir variables para obtener más información.

Todos 3 comentarios

Debe especificar diferentes alcances de variables para las celdas LSTM.

with tf.variable_scope('forward'):
    self.lstm_fw_cell = rnn_cell.BasicLSTMCell(dim_hidden)   
with tf.variable_scope('backward'):
    self.lstm_bw_cell = rnn_cell.BasicLSTMCell(dim_hidden)

De lo contrario, habrá una colisión de nombres (ambas celdas intentan usar el nombre "BiRNN_FW / RNN / BasicLSTMCell / Linear / Matrix") y tf interpretará esto como si su intención fuera compartir los parámetros en las dos celdas, que no es lo que quieres. TF lanzará una excepción porque no le ha dicho explícitamente que reutilice las variables en el segundo alcance: with variable_scope(name, reuse=True) .

La configuración de los alcances de las variables, como se indicó anteriormente, creará nombres únicos para las variables:
BiRNN_FW / RNN / BasicLSTMCell / adelante / Lineal / Matriz
BiRNN_FW / RNN / BasicLSTMCell / hacia atrás / Lineal / Matriz

Lea la guía Compartir variables para obtener más información.

Tenga en cuenta que esto ya no sucederá porque las variables se crean dentro de ...Cell.__call__ y no en ...Cell.__init__ , por lo que no necesita un alcance para la construcción de las celdas, y manejará el alcance de la variable sí mismo dentro de bidirectional_rnn lo que no es necesario que lo amplíe usted mismo.

Sigo teniendo el mismo problema. ¿Alguna sugerencia? He probado el enfoque propuesto por salomons, mismos resultados. No devuelva ninguna tupla como resultado.
((encoder_fw_outputs,
encoder_bw_outputs),
(encoder_fw_final_state,
encoder_bw_final_state)) = (
tf.nn.bidirectional_dynamic_rnn (cell_fw = encoder_cell,
cell_bw = encoder_cell,
entradas = encoder_inputs_embedded,
longitud_secuencia = longitud_entradas_del_codificador,
dtype = tf.float64, time_major = True)
)

ValueError Traceback (última llamada más reciente)
en()
20 entradas = encoder_inputs_embedded,
21 longitud_secuencia = longitud_entradas_del_codificador,
---> 22 dtype = tf.float32, time_major = True)
23)
24

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en bidirectional_dynamic_rnn (cell_fw, cell_bw, input, sequence_length, initial_state_fw, initial_state_bw_meitem, ds , time_major, alcance)
348 estado_inicial = estado_inicial_fw, dtype = dtype,
349 paralelas_iteraciones = paralelas_iteraciones, swap_memory = swap_memory,
-> 350 time_major = time_major, alcance = fw_scope)
351
352 # dirección hacia atrás

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en dynamic_rnn (celda, entradas, sequence_length, initial_state, dtype, paralelos_iterations, swap_memory, time_major, scope )
544 swap_memory = swap_memory,
545 longitud_secuencia = longitud_secuencia,
-> 546 dtype = dtype)
547
548 # Las salidas de _dynamic_rnn_loop siempre tienen forma de [tiempo, lote, profundidad].

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en _dynamic_rnn_loop (celda, entradas, initial_state, paralelos_iteraciones, swap_memory, sequence_length, dtype)
711 loop_vars = (tiempo, salida_ta, estado),
712 paralelas_iteraciones = paralelas_iteraciones,
-> 713 swap_memory = swap_memory)
714
715 # Desempaquete la salida final si no usa tuplas de salida.

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc en while_loop (cond, body, loop_vars, shape_invariants, paralelos_iterations, back_prop, swap_memory, nombre)
2603 context = WhileContext (paralelas_iteraciones, back_prop, swap_memory, nombre)
2604 ops.add_to_collection (ops.GraphKeys.WHILE_CONTEXT, contexto)
-> 2605 resultado = context.BuildLoop (cond, body, loop_vars, shape_invariants)
2606 devuelve el resultado
2607

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc en BuildLoop (self, pred, body, loop_vars, shape_invariants)
2436 self.Enter ()
2437 resultado_cuerpo_original, variables_salida = self._BuildLoop (
-> 2438 pred, cuerpo, original_loop_vars, loop_vars, shape_invariants)
2439 finalmente:
2440 auto.salida ()

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc en _BuildLoop (self, pred, body, original_loop_vars, loop_vars, shape_invariants)
2386 estructura = original_loop_vars,
2387 flat_sequence = vars_for_body_with_tensor_arrays)
-> 2388 body_result = body (* empaquetados_vars_para_cuerpo)
2389 si no es nest.is_sequence (body_result):
2390 body_result = [body_result]

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en _time_step (tiempo, salida_ta_t, estado)
694 call_cell = call_cell,
695 tamaño_estado = tamaño_estado,
-> 696 skip_conditionals = Verdadero)
697 más:
698 (salida, nuevo_estado) = call_cell ()

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en _rnn_step (tiempo, secuencia_length, min_sequence_length, max_sequence_length, zero_output, skip_size, call_cell, estado )
175 # pasos. Esto es más rápido cuando max_seq_len es igual al número de desenrollados
176 # (que es típico de dynamic_rnn).
-> 177 new_output, nuevo_state = call_cell ()
178 nest.assert_same_structure (estado, nuevo_estado)
179 estado_nuevo = nest.flatten (estado_nuevo)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc en()
682
683 input_t = nest.pack_sequence_as (estructura = entradas, flat_sequence = input_t)
-> 684 call_cell = lambda: cell (input_t, estado)
685
686 si sequence_length no es None:

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc en __call __ (auto, entradas, estado, alcance)
336 # i = entrada_puerta, j = nueva_entrada, f = olvidar_puerta, o = salida_puerta
337 lstm_matrix = _linear ([entradas, m_prev], 4 * self._num_units, bias = True,
-> 338 alcance = alcance)
339 yo, j, f, o = array_ops.split (
340 valor = lstm_matrix, num_or_size_splits = 4, eje = 1)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc en _linear (args, output_size, bias, bias_start, scope)
745 con vs alcance_variable (alcance) como alcance_externo:
746 pesos = frente a get_variable (
-> 747 "pesos", [total_arg_size, output_size], dtype = dtype)
748 si len (argumentos) == 1:
749 res = math_ops.matmul (args [0], pesos)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc en get_variable (nombre, forma, dtype, inicializador, regularizador, entrenable, colecciones, caching_device, particionador , validate_shape, custom_getter)
986 colecciones = colecciones, caching_device = caching_device,
987 particionador = particionador, validate_shape = validate_shape,
-> 988 custom_getter = custom_getter)
989 get_variable_or_local_docstring = (
990 "" "% s

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc en get_variable (self, var_store, name, shape, dtype, initializer, regularizer, trainable, collections , caching_device, particionador, validate_shape, custom_getter)
888 colecciones = colecciones, caching_device = caching_device,
889 particionador = particionador, validate_shape = validate_shape,
-> 890 custom_getter = custom_getter)
891
892 def _get_partitioned_variable (self,

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc en get_variable (self, name, shape, dtype, initializador, regularizador, reutilización, entrenable, colecciones , caching_device, particionador, validate_shape, custom_getter)
346 reutilización = reutilización, entrenable = entrenable, colecciones = colecciones,
347 caching_device = caching_device, particionador = particionador,
-> 348 validate_shape = validate_shape)
349
350 def _get_partitioned_variable (

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc en _true_getter (nombre, forma, dtype, inicializador, regularizador, reutilización, entrenable, colecciones, caching_device , particionador, validate_shape)
331 inicializador = inicializador, regularizador = regularizador, reutilización = reutilización,
332 entrenables = entrenables, colecciones = colecciones,
-> 333 caching_device = caching_device, validate_shape = validate_shape)
334
335 si custom_getter no es None:

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc en _get_single_variable (self, name, shape, dtype, initializer, regularizer, partition_info, reutilización, entrenable , colecciones, caching_device, validate_shape)
637 "¿Quería establecer reuse = True en VarScope?"
638 "Definido originalmente en: \ n \ n% s"% (
-> 639 nombre, "" .join (traceback.format_list (tb))))
640 found_var = self._vars [nombre]
641 si no es shape.is_compatible_with (found_var.get_shape ()):

ValueError: La variable bidirectional_rnn / fw / lstm_cell / weights ya existe, no permitida. ¿Quería establecer reuse = True en VarScope? Definido originalmente en:

Archivo "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", línea 747, en _linear
"pesos", [total_arg_size, output_size], dtype = dtype)
Archivo "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", línea 338, en __call__
alcance = alcance)
Expediente "", línea 24, en
time_major = Verdadero

¿Fue útil esta página
0 / 5 - 0 calificaciones