2017-05-12 5 views
0

古い重みを再利用しながら新しいMultiRNNCellを作成したいと考えています。MultiRNNCellでウェイトを再利用するには?

MultiRNNCellを作成するときは、TensorFlow 1.1以降では、明示的に新しいセルを作成する必要があります。ウェイトを再利用するには、reuse=Trueフラグを指定する必要があります。私のコードでは、私は現在持っている:私は最初のマルチセルを作成するとき

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 

期待通りに機能が動作するはずですし、多層要素内のすべてのセルは、独立した重みとバイアスを持っています。

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

今、私は別のものを作成したいと思います:

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

私は重みとバイアスを再利用するために、lstm1から2番目のセルの最初のセルの重みとバイアスを使用するlstm2から最初のセルをしたいと思いますしかし、私はrnn.LSTMCellreuse=Trueと呼んでいるので、の最初のセルの重みが常に再利用されると考えています。

  1. ウェイトを正しく再利用するにはどうすればよいですか?
  2. そうでない場合は、この動作を強制するにはどうすればよいですか?

P. lstm1を再利用したくないというアーキテクチャ上の理由から、同じ重みを持つ新しいマルチセルlstm2を作成したいと思います。

+0

あなたの体重を再利用することはどういう意味ですか?あなたはステートフルなlstmを作りたいですか? – dv3

+0

@ dv3いいえ、私はstatefu LSTMは必要ありません。 lstm1とlstm2が同じように動作するようにします。つまり、マルチセルのすべてのセルの重みは、lstm1とlstm2の間で同じにする必要があります。 –

答えて

2

TL; DR

細胞の質問重みとバイアスからのコードに適切に再利用されるようです。マルチセルlstm1lstm2は同じ動作をし、MultiRNNCell内部のセルは独立した重みとバイアスを持ちます。私。 擬似コードに:

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

長いバージョン

これは、これまで決定的な答えはありませんが、それは私がこれまでの研究の成果です。

これはハックのようですが、get_variableメソッドをオーバーライドして、どの変数にアクセスしているか確認できます。たとえば、次のように:出力は(私は繰り返し行を削除)次のようになります

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) 

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 

この出力

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) 

今、私たちは、以下の変更されたコードを実行することができますlstm1lstm2のセルが同じ重みの&のバイアスを使用することを示しています。両方とも、最初のセルには離散ウェイト&のバイアスがありますMultiRNNCell内の2番目のセル。

さらに、lstm1lstm2の出力であるval_1val_2は、最適化時には同じです。

MultiRNNCellは、内部にcell_0cell_1などの名前空間を作成すると思います。したがって、lstm1lstm2の間の重みが再利用されます。

関連する問題