2017-05-12 21 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() 

我想第一個單元格從lstm2使用第一小區的重量和偏見從lstm1,第二小區重用重量和偏見的第二個單元格等,但我懷疑,因爲我呼籲rnn.LSTMCellreuse=True,權重&偏見的第一個細胞將一直重複使用。

  1. 如何確保重量正確重用?
  2. 如果他們不是,如何強制這種所需的行爲?

P.S.由於架構原因,我不想重複使用lstm1,我想創建一個具有相同權重的新多節點lstm2

+0

重用重量是什麼意思?你想建立一個有狀態的流程嗎? – dv3

+0

@ dv3不,我不需要國家的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方法來查看哪些變量被訪問。例如像這樣:

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) 

現在我們可以運行下面的修改後的代碼:

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 

此輸出指示lstm1lstm2單元格將使用相同的權重&偏差,兩者都有分開權重&第一個偏差和MultiRNNCell內的第二個單元。

另外,val_1val_2的輸出lstm1lstm2在優化期間是相同的。

我認爲MultiRNNCell在其內部創建命名空間cell_0,cell_1等。因此,lstm1lstm2之間的權重將被重新使用。