Tensorflow: Erreur lors de l'initialisation du rnn bidirectionnel avec la cellule LSTM

Créé le 18 janv. 2016  ·  3Commentaires  ·  Source: tensorflow/tensorflow

Je souhaite créer un modèle bi-rnn avec tensorflow avec une cellule LSTM, lorsque j'essaie d'initialiser bidirectionnel_rnn,
ça donne : 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

Commentaire le plus utile

Vous devez spécifier différentes étendues de variables pour les cellules 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)

Sinon, il y aura une collision de noms (les deux cellules essaient d'utiliser le nom "BiRNN_FW/RNN/BasicLSTMCell/Linear/Matrix") et tf interprétera cela comme si votre intention était de partager les paramètres dans les deux cellules, ce qui n'est pas ce que vous voulez. TF lèvera une exception car vous ne lui avez pas explicitement demandé de réutiliser les variables dans la deuxième portée : with variable_scope(name, reuse=True) .

La définition des portées des variables, comme ci-dessus, créera des noms uniques pour les variables :
BiRNN_FW/RNN/BasicLSTMCell/ avant /linéaire/matrice
BiRNN_FW/RNN/BasicLSTMCell/ arrière /linéaire/matrice

Lisez le guide Partage des variables pour plus d'informations.

Tous les 3 commentaires

Vous devez spécifier différentes étendues de variables pour les cellules 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)

Sinon, il y aura une collision de noms (les deux cellules essaient d'utiliser le nom "BiRNN_FW/RNN/BasicLSTMCell/Linear/Matrix") et tf interprétera cela comme si votre intention était de partager les paramètres dans les deux cellules, ce qui n'est pas ce que vous voulez. TF lèvera une exception car vous ne lui avez pas explicitement demandé de réutiliser les variables dans la deuxième portée : with variable_scope(name, reuse=True) .

La définition des portées des variables, comme ci-dessus, créera des noms uniques pour les variables :
BiRNN_FW/RNN/BasicLSTMCell/ avant /linéaire/matrice
BiRNN_FW/RNN/BasicLSTMCell/ arrière /linéaire/matrice

Lisez le guide Partage des variables pour plus d'informations.

Notez que cela n'arrivera plus car les variables sont créées à l'intérieur de ...Cell.__call__ et non dans ...Cell.__init__ , donc il n'a pas besoin de portée pour la construction des cellules, et il gérera la portée de la variable lui-même à l'intérieur de bidirectional_rnn , vous n'avez donc pas besoin de le définir vous-même.

J'ai toujours le même problème. Des suggestions? J'ai essayé l'approche proposée par salomons, mêmes résultats. Ne retourne aucun tuple en conséquence.
((encoder_fw_outputs,
encoder_bw_outputs),
(encoder_fw_final_state,
encoder_bw_final_state)) = (
tf.nn.bidirectionnel_dynamique_rnn(cell_fw=encoder_cell,
cell_bw=cellule_encodeur,
entrées=encoder_inputs_embedded,
sequence_length=encoder_inputs_length,
dtype=tf.float64, time_major=True)
)

ValueError Traceback (appel le plus récent en dernier)
dans()
20 entrées = 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 dans bidirectionnel_dynamic_rnn(cell_fw, cell_bw, entrées, sequence_length, initial_state_fw, initial_state_bw, dtype, parallel_iterations, swap_memory , time_major, étendue)
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 # Sens arrière

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc dans dynamic_rnn(cell, input, sequence_length, initial_state, dtype, parallel_iterations, swap_memory, time_major, scope )
544 swap_memory=swap_memory,
545 sequence_length=sequence_length,
--> 546 dtype=dtype)
547
548 # Les sorties de _dynamic_rnn_loop sont toujours formées [temps, lot, profondeur].

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc dans _dynamic_rnn_loop(cell, input, initial_state, parallel_iterations, swap_memory, sequence_length, dtype)
711 loop_vars=(heure, sortie_ta, état),
712 parallel_iterations=parallel_iterations,
--> 713 swap_memory=swap_memory)
714
715 # Décompressez la sortie finale si vous n'utilisez pas de tuples de sortie.

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc in while_loop(cond, body, 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, contexte)
-> 2605 result = context.BuildLoop(cond, body, loop_vars, shape_invariants)
2606 retour résultat
2607

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

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.pyc in _BuildLoop(self, pred, body, original_loop_vars, loop_vars, shape_invariants)
2386 structure=original_loop_vars,
2387 flat_sequence=vars_for_body_with_tensor_arrays)
-> 2388 body_result = body(*packed_vars_for_body)
2389 sinon 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 in _time_step(time, output_ta_t, state)
694 call_cell=call_cell,
695 state_size=state_size,
--> 696 skip_conditionals=True)
697 autre :
698 (sortie, new_state) = call_cell()

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc in _rnn_step(time, sequence_length, min_sequence_length, max_sequence_length, zero_output, state, call_cell, state_size, skip_conditionals )
175 # étapes. C'est plus rapide lorsque max_seq_len est égal au nombre de déroulements
176 # (ce qui est typique pour dynamic_rnn).
--> 177 new_output, new_state = call_cell()
178 nest.assert_same_structure(état, nouvel_état)
179 new_state = nest.flatten(new_state)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/rnn.pyc dans()
682
683 input_t = nest.pack_sequence_as(structure=entrées, flat_sequence=input_t)
--> 684 call_cell = lambda: cell(input_t, état)
685
686 si sequence_length n'est pas None :

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc dans __call__(self, entrées, état, portée)
336 # i = input_gate, j = new_input, f = forget_gate, o = output_gate
337 lstm_matrix = _linear([entrées, m_prev], 4 * self._num_units, bias=True,
--> 338 champ d'application = champ d'application)
339 i, j, f, o = array_ops.split(
340 value=lstm_matrix, num_or_size_splits=4, axis=1)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.pyc dans _linear(args, output_size, bias, bias_start, scope)
745 avec vs.variable_scope(scope) comme external_scope :
746 poids = vs.get_variable(
--> 747 "poids", [total_arg_size, output_size], dtype=dtype)
748 si longueur(args) == 1 :
749 res = math_ops.matmul(args[0], poids)

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc in get_variable(name, shape, dtype, initializer, regularizer, trainable, collections, caching_device, partitioner , validate_shape, custom_getter)
986 collections=collections, caching_device=caching_device,
987 partitioner=partitionneur, 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 in get_variable(self, var_store, name, shape, dtype, initializer, regularizer, trainable, collections , caching_device, partitionneur, validate_shape, custom_getter)
888 collections=collections, caching_device=caching_device,
889 partitioner=partitionneur, 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 in get_variable(self, name, shape, dtype, initializer, regularizer, reuse, trainable, collections , caching_device, partitionneur, validate_shape, custom_getter)
346 réutilisation=réutilisation, trainable=trainable, collections=collections,
347 caching_device=caching_device, partitioner=partitionneur,
--> 348 valid_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(name, shape, dtype, initializer, regularizer, reuse, trainable, collections, caching_device , partitionneur, valid_shape)
331 initializer=initializer, regularizer=regularizer, reuse=reuse,
332 entraînable=entrainable, collections=collections,
--> 333 caching_device=caching_device, validate_shape=validate_shape)
334
335 si custom_getter n'est pas Aucun :

/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/variable_scope.pyc in _get_single_variable(self, name, shape, dtype, initializer, regularizer, partition_info, reuse, trainable , collections, caching_device, validate_shape)
637 " Vouliez-vous définir reuse=True dans VarScope ? "
638 "Défini à l'origine à :\n\n%s" % (
--> 639 nom, "".join(traceback.format_list(tb))))
640 found_var = self._vars[nom]
641 sinon shape.is_compatible_with(found_var.get_shape()):

ValueError : la variable bidirectionnelle_rnn/fw/lstm_cell/weights existe déjà, non autorisée. Vouliez-vous définir reuse=True dans VarScope ? Initialement défini à :

Fichier "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", ligne 747, dans _linear
"poids", [total_arg_size, output_size], dtype=dtype)
Fichier "/home/cesar/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/contrib/rnn/python/ops/core_rnn_cell_impl.py", ligne 338, dans __call__
étendue=étendue)
Déposer "", ligne 24, dans
time_major=Vrai

Cette page vous a été utile?
0 / 5 - 0 notes