如何在 MultiRNNCell 中重用权重?
How to reuse weights in MultiRNNCell?
我想在重用旧权重的同时创建一个新的 MultiRNNCell。
从 TensorFlow 1.1 开始,当您创建 MultiRNNCell 时,您必须明确地创建新的单元格。要重用权重,您必须提供 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
中第一个单元格的权重和偏差,第二个单元格重用第二个单元格的权重和偏差,等等。但我怀疑因为我用 reuse=True
调用 rnn.LSTMCell
, 第一个 单元格的权重和偏差将一直重复使用。
- 如何确保正确地重复使用权重?
- 如果不是,如何强制执行此所需行为?
P.S。出于架构原因,我不想重复使用 lstm1
,我想创建一个具有相同权重的新多单元 lstm2
。
TL;DR
似乎在代码中来自问题单元格的权重和偏差将被正确地重用。多单元 lstm1
和 lstm2
将具有相同的行为,并且 MultiRNNCell 内的单元将具有独立的权重和偏差。 IE。 伪代码:
lstm1._cells[0].weights == lstm2._cells[0].weights
lstm1._cells[1].weights == lstm2._cells[1].weights
更长的版本
到目前为止,这还不是一个确定的答案,但这是我迄今为止所做的研究的结果。
这看起来像是 hack,但我们可以覆盖 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
此输出表明 lstm1
和 lstm2
单元格将使用相同的权重和偏差,对于 MultiRNNCell 中的第一个和第二个单元格,两者都有单独的权重和偏差。
另外,作为lstm1
和lstm2
的输出的val_1
和val_2
在优化过程中是相同的。
我认为 MultiRNNCell 在其中创建了名称空间 cell_0
、cell_1
等。因此 lstm1
和 lstm2
之间的权重将被重用。
我想在重用旧权重的同时创建一个新的 MultiRNNCell。
从 TensorFlow 1.1 开始,当您创建 MultiRNNCell 时,您必须明确地创建新的单元格。要重用权重,您必须提供 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
中第一个单元格的权重和偏差,第二个单元格重用第二个单元格的权重和偏差,等等。但我怀疑因为我用 reuse=True
调用 rnn.LSTMCell
, 第一个 单元格的权重和偏差将一直重复使用。
- 如何确保正确地重复使用权重?
- 如果不是,如何强制执行此所需行为?
P.S。出于架构原因,我不想重复使用 lstm1
,我想创建一个具有相同权重的新多单元 lstm2
。
TL;DR
似乎在代码中来自问题单元格的权重和偏差将被正确地重用。多单元 lstm1
和 lstm2
将具有相同的行为,并且 MultiRNNCell 内的单元将具有独立的权重和偏差。 IE。 伪代码:
lstm1._cells[0].weights == lstm2._cells[0].weights
lstm1._cells[1].weights == lstm2._cells[1].weights
更长的版本
到目前为止,这还不是一个确定的答案,但这是我迄今为止所做的研究的结果。
这看起来像是 hack,但我们可以覆盖 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
此输出表明 lstm1
和 lstm2
单元格将使用相同的权重和偏差,对于 MultiRNNCell 中的第一个和第二个单元格,两者都有单独的权重和偏差。
另外,作为lstm1
和lstm2
的输出的val_1
和val_2
在优化过程中是相同的。
我认为 MultiRNNCell 在其中创建了名称空间 cell_0
、cell_1
等。因此 lstm1
和 lstm2
之间的权重将被重用。