2017-05-12 6 views
0

Ich möchte eine neue MultiRNNCell erstellen, während die alten Gewichte wiederverwendet werden.Wie kann man Gewichte in MultiRNNCell wiederverwenden?

Ab TensorFlow 1.1, wenn Sie MultiRNNCell erstellen, müssen Sie explizit neue Zellen erstellen. Um Gewichte wiederzuverwenden, müssen Sie ein reuse=True Flag angeben. In meinem Code habe ich zur Zeit:

import tensorflow as tf 
from tensorflow.contrib import rnn 

def create_lstm_multicell(): 
    lstm_cell = lambda: rnn.LSTMCell(nstates, reuse=tf.get_variable_scope().reuse) 
    lstm_multi_cell = rnn.MultiRNNCell([lstm_cell() for _ in range(n_layers)]) 
    return lstm_multi_cell 

Wenn ich eine erste Multizellen schaffen sollte die Funktion wie erwartet, und jede Zelle innerhalb mehrschichtiges Element hat unabhängige Gewichte und Vorurteile.

with tf.variable_scope('lstm') as scope: 
    lstm1 = create_lstm_multicell() 

Nun möchte ich gerne eine andere schaffen ein:

with tf.variable_scope('lstm') as scope: 
    scope.reuse_variables() 
    lstm2 = create_lstm_multicell() 

ich die erste Zelle von lstm2 möchten die Gewichte und Voreingenommenheit der ersten Zelle zu verwenden, um von lstm1, zweite Zelle Gewichtungen und Bias wiederzuverwenden der zweiten Zelle, etc. Aber ich vermute, dass, da ich rnn.LSTMCell mit reuse=True, Gewichte & Voreingenommenheiten der ersten Zelle wird die ganze Zeit wiederverwendet werden.

  1. Wie stelle ich sicher, dass die Gewichte ordnungsgemäß wiederverwendet werden?
  2. Wenn sie nicht sind, wie man dieses gewünschte Verhalten erzwingt?

P.S. Aus dem architektonischen Grund, den ich lstm1 nicht wiederverwenden möchte, möchte ich ein neues multicell lstm2 schaffen, das die gleichen Gewichte hat.

+0

was meinen Sie mit der Wiederverwendung Ihrer Gewichte? Willst du eine Stateful Lstm bauen? – dv3

+0

@ dv3 Nein, ich brauche nicht Statefu LSTM. Ich möchte nur, dass lstm1 und lstm2 sich identisch verhalten, d. H. Die Gewichte jeder Zelle in multicell sollten zwischen lstm1 und lstm2 identisch sein. –

Antwort

2

TL; DR

Es scheint, dass in dem Code aus der Frage Gewichtungen und Bias von Zellen richtig wiederverwendet werden. Multicells lstm1 und lstm2 werden das gleiche Verhalten haben, und Zellen in MultiRNNCell haben unabhängige Gewichte und Verzerrungen. I.e. in einem Pseudo-Code:

lstm1._cells[0].weights == lstm2._cells[0].weights 
lstm1._cells[1].weights == lstm2._cells[1].weights 

Längere Version

Die bisher keine endgültige Antwort ist, aber das ist das Ergebnis der Forschung, die ich bisher gemacht.

Es sieht aus wie ein Hack, aber wir können die get_variable Methode überschreiben, um zu sehen, auf welche Variablen zugegriffen wird. Zum Beispiel wie folgt aus:

from tensorflow.python.ops import variable_scope as vs 

def verbose(original_function): 
    # make a new function that prints a message when original_function starts and finishes 
    def new_function(*args, **kwargs): 
     print('get variable:', '/'.join((tf.get_variable_scope().name, args[0]))) 
     result = original_function(*args, **kwargs) 
     return result 
    return new_function 

vs.get_variable = verbose(vs.get_variable) 

Jetzt können wir die folgenden modifizierten Code ausführen:

def create_lstm_multicell(name): 
    def lstm_cell(i, s): 
     print('creating cell %i in %s' % (i, s)) 
     return rnn.LSTMCell(nstates, reuse=tf.get_variable_scope().reuse) 
    lstm_multi_cell = rnn.MultiRNNCell([lstm_cell(i, name) for i in range(n_layers)]) 
    return lstm_multi_cell 

with tf.variable_scope('lstm') as scope: 
    lstm1 = create_lstm_multicell('lstm1') 
    layer1, _ = tf.nn.dynamic_rnn(lstm1, x, dtype=tf.float32) 
    val_1 = tf.reduce_sum(layer1) 

with tf.variable_scope('lstm') as scope: 
    scope.reuse_variables() 
    lstm2 = create_lstm_multicell('lstm2') 
    layer2, _ = tf.nn.dynamic_rnn(lstm2, x, dtype=tf.float32) 
    val_2 = tf.reduce_sum(layer2) 

Die Ausgabe wird wie folgt aussehen (I entfernt sich wiederholende Linien):

creating cell 0 in lstm1 
creating cell 1 in lstm1 
get variable: lstm/rnn/multi_rnn_cell/cell_0/lstm_cell/weights 
get variable: lstm/rnn/multi_rnn_cell/cell_0/lstm_cell/biases 
get variable: lstm/rnn/multi_rnn_cell/cell_1/lstm_cell/weights 
get variable: lstm/rnn/multi_rnn_cell/cell_1/lstm_cell/biases 
creating cell 0 in lstm2 
creating cell 1 in lstm2 
get variable: lstm/rnn/multi_rnn_cell/cell_0/lstm_cell/weights 
get variable: lstm/rnn/multi_rnn_cell/cell_0/lstm_cell/biases 
get variable: lstm/rnn/multi_rnn_cell/cell_1/lstm_cell/weights 
get variable: lstm/rnn/multi_rnn_cell/cell_1/lstm_cell/biases 

Dieser Ausgang zeigt an, dass lstm1 und lstm2 Zellen die gleichen Gewichte verwenden & Verzerrungen, beide haben Gewichte & Verzerrungen für die erste und zweite Zellen in MultiRNNCell.

Zusätzlich sind val_1 und val_2 die Ausgänge lstm1 und lstm2 sind identisch während der Optimierung.

Ich denke MultiRNNCell erstellt Namespaces cell_0, cell_1 usw. innerhalb davon. Und deshalb werden die Gewichte zwischen lstm1 und lstm2 wiederverwendet.

Verwandte Themen