Tensorflow: Erro ao inicializar rnn bidirecional com célula LSTM

Criado em 18 jan. 2016  ·  3Comentários  ·  Fonte: tensorflow/tensorflow

Eu quero construir um modelo bi-rnn com tensorflow com célula LSTM, quando tento inicializar bidirectional_rnn,
dá: 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

Comentários muito úteis

Você precisa especificar diferentes escopos de variáveis ​​para as células 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)

Caso contrário, haverá uma colisão de nomes (ambas as células tentam usar o nome "BiRNN_FW / RNN / BasicLSTMCell / Linear / Matriz") e tf interpretará isso como se sua intenção fosse compartilhar os parâmetros nas duas células, o que não é o que você quer. TF lançará uma exceção porque você não disse explicitamente a ele para reutilizar variáveis ​​no segundo escopo: with variable_scope(name, reuse=True) .

Definir os escopos de variáveis, como acima, criará nomes exclusivos para as variáveis:
BiRNN_FW / RNN / BasicLSTMCell / forward / Linear / Matrix
BiRNN_FW / RNN / BasicLSTMCell / backward / Linear / Matrix

Leia o guia de variáveis ​​de compartilhamento para obter mais informações.

Todos 3 comentários

Você precisa especificar diferentes escopos de variáveis ​​para as células 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)

Caso contrário, haverá uma colisão de nomes (ambas as células tentam usar o nome "BiRNN_FW / RNN / BasicLSTMCell / Linear / Matriz") e tf interpretará isso como se sua intenção fosse compartilhar os parâmetros nas duas células, o que não é o que você quer. TF lançará uma exceção porque você não disse explicitamente a ele para reutilizar variáveis ​​no segundo escopo: with variable_scope(name, reuse=True) .

Definir os escopos de variáveis, como acima, criará nomes exclusivos para as variáveis:
BiRNN_FW / RNN / BasicLSTMCell / forward / Linear / Matrix
BiRNN_FW / RNN / BasicLSTMCell / backward / Linear / Matrix

Leia o guia de variáveis ​​de compartilhamento para obter mais informações.

Note que isso não vai acontecer mais porque as variáveis ​​são criadas dentro de ...Cell.__call__ e não em ...Cell.__init__ , portanto não precisa de um escopo para a construção das células, e vai lidar com o escopo da variável se dentro de bidirectional_rnn portanto, você não precisa definir o escopo sozinho.

Eu ainda estou tendo o mesmo problema. Alguma sugestão? Tentei a abordagem proposta pelos salões, mesmos resultados. Não retorne nenhuma 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,
length_length = encoder_inputs_length,
dtype = tf.float64, time_major = True)
)

ValueError Traceback (última chamada mais recente)
no()
20 entradas = encoder_inputs_embedded,
21 sequence_length = encoder_inputs_length,
---> 22 dtype = tf.float32, time_major = True)
23)
24

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc em bidirecional_dynamic_rnn (cell_fw, cell_bw, entradas, sequence_length, initial_state_fw, initial_state_fw, initial_state_state_fw, initial_state_bm , time_major, escopo)
348 initial_state = initial_state_fw, dtype = dtype,
349 parallel_iterations = parallel_iterations, swap_memory = swap_memory,
-> 350 time_major = time_major, scope = fw_scope)
351
352 # Direção para trás

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc em dynamic_rnn (célula, entradas, comprimento_de_sequência, estado_inicial, tipo dt, paralelismo_iterações, memória_memória_de_troca, memória_de_temporada, escopo )
544 swap_memory = swap_memory,
Comprimento_de_sequência 545 = comprimento_de_sequência,
-> 546 dtipo = dtipo)
547
548 # Saídas de _dynamic_rnn_loop são sempre formadas [tempo, lote, profundidade].

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc em _dynamic_rnn_loop (célula, entradas, inicial_estado, paralelo_iterações, swap_memória, comprimento_de_sequência, dtype)
711 loop_vars = (tempo, output_ta, estado),
712 parallel_iterations = parallel_iterations,
-> 713 swap_memory = swap_memory)
714
715 # Descompacte a saída final se não estiver usando tuplas de saída.

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc em while_loop (cond, corpo, loop_vars, shape_invariants, parallel_iterations, back_prop, swap_memory, name)
2603 context = WhileContext (parallel_iterations, back_prop, swap_memory, name)
2604 ops.add_to_collection (ops.GraphKeys.WHILE_CONTEXT, contexto)
-> 2605 resultado = context.BuildLoop (cond, body, loop_vars, shape_invariants)
2606 resultado de retorno
2607

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc em BuildLoop (self, pred, body, loop_vars, shape_invariants)
2436 self.Enter ()
2437 original_body_result, exit_vars = self._BuildLoop (
-> 2438 pred, body, original_loop_vars, loop_vars, shape_invariants)
2439 finalmente:
2440 self.Exit ()

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc em _BuildLoop (self, pred, body, original_loop_vars, loop_vars, shape_invariants)
2386 estrutura = original_loop_vars,
2387 flat_sequence = vars_for_body_with_tensor_arrays)
-> 2388 body_result = body (* pack_vars_for_body)
2389 se não 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 em _time_step (tempo, output_ta_t, estado)
694 call_cell = call_cell,
695 state_size = state_size,
-> 696 skip_conditionals = True)
697 mais:
698 (saída, novo_estado) = call_cell ()

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc em _rnn_step (tempo, comprimento_de_sequência, comprimento_mínimo_sequência, comprimento_sequência_máx, comprimento_de_sequência_de_calar, tamanho_de_saída_de_corrência, estado, tamanho_condicional )
175 # etapas. Isso é mais rápido quando max_seq_len é igual ao número de desenrolamentos
176 # (que é típico para dynamic_rnn).
-> 177 new_output, new_state = call_cell ()
178 nest.assert_same_structure (estado, novo_estado)
179 new_state = nest.flatten (new_state)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc em()
682
683 input_t = nest.pack_sequence_as (estrutura = entradas, flat_sequence = input_t)
-> 684 call_cell = lambda: célula (input_t, estado)
685
686 se comprimento_de_sequência não for Nenhum:

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc em __call __ (auto, entradas, estado, escopo)
336 # i = input_gate, j = new_input, f = forget_gate, o = output_gate
337 lstm_matrix = _linear ([entradas, m_prev], 4 * self._num_units, bias = True,
-> 338 escopo = escopo)
339 i, j, f, o = array_ops.split (
340 valor = lstm_matrix, num_or_size_splits = 4, eixo = 1)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc em _linear (args, output_size, bias, bias_start, escopo)
745 com vs.variable_scope (escopo) como outer_scope:
746 pesos = vs.get_variable (
-> 747 "pesos", [total_arg_size, output_size], dtype = dtype)
748 se len (args) == 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 em get_variable (nome, forma, dtype, inicializador, regularizador, treinável, coleções, dispositivo_de_variação, particionador , validate_shape, custom_getter)
986 coleções = coleções, 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 em get_variable (self, var_store, nome, forma, dtype, inicializador, regularizador, treinável, coleções , caching_device, partitioner, validate_shape, custom_getter)
888 coleções = coleções, 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 em get_variable (self, name, shape, dtype, inicializador, regularizador, reutilizar, treinável, coleções , caching_device, partitioner, validate_shape, custom_getter)
346 reutilizar = reutilizar, treinável = treinável, coleções = coleções,
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 in _true_getter (nome, forma, dtype, inicializador, regularizador, reutilizar, treinável, coleções, armazenamento_dispositivo , particionador, validate_shape)
331 inicializador = inicializador, regularizador = regularizador, reutilizar = reutilizar,
332 treinável = treinável, coleções = coleções,
-> 333 caching_device = caching_device, validate_shape = validate_shape)
334
335 se custom_getter não for Nenhum:

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc in _get_single_variable (self, name, shape, dtype, inicializador, regularizador, partition_info, reuse, trainable , coleções, caching_device, validate_shape)
637 "Você quis dizer definir reuse = True no VarScope?"
638 "Originalmente definido em: \ n \ n% s"% (
-> 639 nome, "" .join (traceback.format_list (tb))))
640 found_var = self._vars [nome]
641 se não shape.is_compatible_with (found_var.get_shape ()):

ValueError: A variável bidirecional_rnn / fw / lstm_cell / pesos já existe, não permitida. Você quis dizer definir reuse = True no VarScope? Definido originalmente em:

Arquivo "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", linha 747, em _linear
"pesos", [total_arg_size, output_size], dtype = dtype)
Arquivo "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", linha 338, em __call__
escopo = escopo)
Arquivo "", linha 24, em
time_major = True

Esta página foi útil?
0 / 5 - 0 avaliações