Tensorflow: uso de pesas entrenadas en un modelo dentro de otro, modelo diferente

Estoy tratando de entrenar un LSTM en Tensorflow utilizando minibatches, pero una vez finalizado el entrenamiento, me gustaría usar el modelo enviando un ejemplo a la vez. Puedo configurar el gráfico dentro de Tensorflow para entrenar mi red LSTM, pero luego no puedo usar el resultado entrenado de la manera que quiero.

El código de configuración se ve algo como esto:

#Build the LSTM model. cellRaw = rnn_cell.BasicLSTMCell(LAYER_SIZE) cellRaw = rnn_cell.MultiRNNCell([cellRaw] * NUM_LAYERS) cell = rnn_cell.DropoutWrapper(cellRaw, output_keep_prob = 0.25) input_data = tf.placeholder(dtype=tf.float32, shape=[SEQ_LENGTH, None, 3]) target_data = tf.placeholder(dtype=tf.float32, shape=[SEQ_LENGTH, None]) initial_state = cell.zero_state(batch_size=BATCH_SIZE, dtype=tf.float32) with tf.variable_scope('rnnlm'): output_w = tf.get_variable("output_w", [LAYER_SIZE, 6]) output_b = tf.get_variable("output_b", [6]) outputs, final_state = seq2seq.rnn_decoder(input_list, initial_state, cell, loop_function=None, scope='rnnlm') output = tf.reshape(tf.concat(1, outputs), [-1, LAYER_SIZE]) output = tf.nn.xw_plus_b(output, output_w, output_b) 

… Tenga en cuenta los dos marcadores de posición, input_data y target_data. No me he molestado en incluir la configuración del optimizador. Una vez finalizada la capacitación y cerrada la sesión de capacitación, me gustaría configurar una nueva sesión que utilice la red LSTM capacitada, cuya entrada es proporcionada por un marcador de posición completamente diferente, algo como:

 with tf.Session() as sess: with tf.variable_scope("simulation", reuse=None): cellSim = cellRaw input_data_sim = tf.placeholder(dtype=tf.float32, shape=[1, 1, 3]) initial_state_sim = cell.zero_state(batch_size=1, dtype=tf.float32) input_list_sim = tf.unpack(input_data_sim) outputsSim, final_state_sim = seq2seq.rnn_decoder(input_list_sim, initial_state_sim, cellSim, loop_function=None, scope='rnnlm') outputSim = tf.reshape(tf.concat(1, outputsSim), [-1, LAYER_SIZE]) with tf.variable_scope('rnnlm'): output_w = tf.get_variable("output_w", [LAYER_SIZE, nOut]) output_b = tf.get_variable("output_b", [nOut]) outputSim = tf.nn.xw_plus_b(outputSim, output_w, output_b) 

Esta segunda parte devuelve el siguiente error:

 tensorflow.python.framework.errors.InvalidArgumentError: You must feed a value for placeholder tensor 'Placeholder' with dtype float [[Node: Placeholder = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/cpu:0"]()]] 

… Presumiblemente porque el gráfico que estoy usando todavía tiene los marcadores de posición de entrenamiento antiguos adjuntos a los nodos LSTM entrenados. ¿Cuál es la forma correcta de ‘extraer’ el LSTM entrenado y colocarlo en un gráfico nuevo y diferente que tiene un estilo diferente de entradas? Las características de scope de Varible que Tensorflow parece abordar algo como esto, pero los ejemplos en la documentación hablan sobre el uso del scope variable como una forma de administrar nombres de variables para que la misma pieza de código genere subgrafos similares dentro del mismo gráfico. La función de ‘reutilización’ parece estar cerca de lo que quiero, pero no encuentro que la documentación de Tensorflow que se encuentra en el enlace anterior sea clara en lo que hace. A las celdas en sí no se les puede dar un nombre (en otras palabras,

 cellRaw = rnn_cell.MultiRNNCell([cellRaw] * NUM_LAYERS, name="multicell") 

no es válido), y aunque puedo dar un nombre a un seq2seq.rnn_decoder (), probablemente no podría eliminar el rnn_cell.DropoutWrapper () si usara ese nodo sin cambios.

Preguntas:

¿Cuál es la forma correcta de mover pesos LSTM entrenados de un gráfico a otro?

¿Es correcto decir que iniciar una nueva sesión “libera recursos”, pero no borra el gráfico integrado en la memoria?

Me parece que la función ‘reutilizar’ le permite a Tensorflow buscar fuera del scope de la variable actual las variables con el mismo nombre (existentes en un scope diferente), y usarlas en el scope actual. ¿Es esto correcto? Si es así, ¿qué sucede con todos los bordes del gráfico desde el scope no actual que se vincula a esa variable? Si no lo es, ¿por qué Tensorflow emite un error si intenta tener el mismo nombre de variable dentro de dos ámbitos diferentes? Parece perfectamente razonable definir dos variables con nombres idénticos en dos ámbitos diferentes, por ejemplo, conv1 / sum1 y conv2 / sum1.

En mi código, estoy trabajando dentro de un nuevo ámbito, pero el gráfico no se ejecutará sin que los datos se introduzcan en un marcador de posición desde el ámbito predeterminado inicial. ¿El ámbito predeterminado siempre está ‘dentro del scope’ por alguna razón?

Si los bordes de los gráficos pueden abarcar diferentes ámbitos, y los nombres en diferentes ámbitos no se pueden compartir a menos que se refieran al mismo nodo exacto, entonces, en primer lugar, eso parece anular el propósito de tener diferentes ámbitos. ¿Qué estoy entendiendo mal aquí?

¡Gracias!

¿Cuál es la forma correcta de mover pesos LSTM entrenados de un gráfico a otro?

Puede crear su gráfico de deencoding primero (con un objeto de ahorro para guardar los parámetros) y crear un objeto GraphDef que puede importar en su gráfico de entrenamiento más grande:

 basegraph = tf.Graph() with basegraph.as_default(): ***your graph*** traingraph = tf.Graph() with traingraph.as_default(): tf.import_graph_def(basegraph.as_graph_def()) ***your training graph*** 

asegúrese de cargar sus variables cuando inicie una sesión para un nuevo gráfico.

No tengo experiencia con esta funcionalidad, por lo que es posible que tenga que estudiarla un poco más.

¿Es correcto decir que iniciar una nueva sesión “libera recursos”, pero no borra el gráfico integrado en la memoria?

Sí, el objeto gráfico todavía lo mantiene

Me parece que la función ‘reutilizar’ le permite a Tensorflow buscar fuera del scope de la variable actual las variables con el mismo nombre (existentes en un scope diferente), y usarlas en el scope actual. ¿Es esto correcto? Si es así, ¿qué sucede con todos los bordes del gráfico desde el scope no actual que se vincula a esa variable? Si no lo es, ¿por qué Tensorflow emite un error si intenta tener el mismo nombre de variable dentro de dos ámbitos diferentes? Parece perfectamente razonable definir dos variables con nombres idénticos en dos ámbitos diferentes, por ejemplo, conv1 / sum1 y conv2 / sum1.

No, la reutilización es para determinar el comportamiento cuando se usa get_variable en un nombre existente, cuando es cierto devolverá la variable existente, de lo contrario devolverá una nueva. Normalmente tensorflow no debe arrojar un error. ¿Está seguro de que está usando tf.get_variable y no solo tf.Variable?

En mi código, estoy trabajando dentro de un nuevo ámbito, pero el gráfico no se ejecutará sin que los datos se introduzcan en un marcador de posición desde el ámbito predeterminado inicial. ¿El ámbito predeterminado siempre está ‘dentro del scope’ por alguna razón?

Realmente no veo lo que quieres decir. El no siempre tiene que ser usado. Si no se requiere un marcador de posición para ejecutar una operación, no tiene que definirlo.

Si los bordes de los gráficos pueden abarcar diferentes ámbitos, y los nombres en diferentes ámbitos no se pueden compartir a menos que se refieran al mismo nodo exacto, entonces, en primer lugar, eso parece anular el propósito de tener diferentes ámbitos. ¿Qué estoy entendiendo mal aquí?

Creo que su comprensión o uso de los ámbitos es defectuoso, ver más arriba