Tensorflow RNN 单元权重共享
Tensorflow RNN cells weight sharing
我想知道在下面的代码中两个堆叠单元格的权重是否共享:
cell = rnn_cell.GRUCell(hidden_dim)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
如果不共享,如何在任何 RNN 中强制共享?
注意:
我可能更想在嵌套的输入到输出连接的 RNN 配置中共享权重,其中第一层为第二层的每个输入克隆多次(例如,第一层代表字母,第二层代表从迭代中收集的单词的句子第一层的输出)
执行以下脚本可以看到权重没有共享:
import tensorflow as tf
with tf.variable_scope("scope1") as vs:
cell = tf.nn.rnn_cell.GRUCell(10)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
stacked_cell(tf.Variable(np.zeros((100, 100), dtype=np.float32), name="moo"), tf.Variable(np.zeros((100, 100), dtype=np.float32), "bla"))
# Retrieve just the LSTM variables.
vars = [v.name for v in tf.all_variables()
if v.name.startswith(vs.name)]
print vars
你会看到除了虚拟变量它 returns 两组 GRU 权重:"Cell1" 和 "Cell0".
要共享它们,您可以实现自己的单元格 class,它继承自 GRUCell
并始终通过始终使用相同的变量范围来重用权重:
import tensorflow as tf
class SharedGRUCell(tf.nn.rnn_cell.GRUCell):
def __init__(self, num_units, input_size=None, activation=tf.nn.tanh):
tf.nn.rnn_cell.GRUCell.__init__(self, num_units, input_size, activation)
self.my_scope = None
def __call__(self, a, b):
if self.my_scope == None:
self.my_scope = tf.get_variable_scope()
else:
self.my_scope.reuse_variables()
return tf.nn.rnn_cell.GRUCell.__call__(self, a, b, self.my_scope)
with tf.variable_scope("scope2") as vs:
cell = SharedGRUCell(10)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
stacked_cell(tf.Variable(np.zeros((20, 10), dtype=np.float32), name="moo"), tf.Variable(np.zeros((20, 10), dtype=np.float32), "bla"))
# Retrieve just the LSTM variables.
vars = [v.name for v in tf.all_variables()
if v.name.startswith(vs.name)]
print vars
这样两个GRUCells之间的变量是共享的。请注意,您需要注意形状,因为同一个单元格需要同时处理原始输入和自身的输出。
我想知道在下面的代码中两个堆叠单元格的权重是否共享:
cell = rnn_cell.GRUCell(hidden_dim)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
如果不共享,如何在任何 RNN 中强制共享?
注意: 我可能更想在嵌套的输入到输出连接的 RNN 配置中共享权重,其中第一层为第二层的每个输入克隆多次(例如,第一层代表字母,第二层代表从迭代中收集的单词的句子第一层的输出)
执行以下脚本可以看到权重没有共享:
import tensorflow as tf
with tf.variable_scope("scope1") as vs:
cell = tf.nn.rnn_cell.GRUCell(10)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
stacked_cell(tf.Variable(np.zeros((100, 100), dtype=np.float32), name="moo"), tf.Variable(np.zeros((100, 100), dtype=np.float32), "bla"))
# Retrieve just the LSTM variables.
vars = [v.name for v in tf.all_variables()
if v.name.startswith(vs.name)]
print vars
你会看到除了虚拟变量它 returns 两组 GRU 权重:"Cell1" 和 "Cell0".
要共享它们,您可以实现自己的单元格 class,它继承自 GRUCell
并始终通过始终使用相同的变量范围来重用权重:
import tensorflow as tf
class SharedGRUCell(tf.nn.rnn_cell.GRUCell):
def __init__(self, num_units, input_size=None, activation=tf.nn.tanh):
tf.nn.rnn_cell.GRUCell.__init__(self, num_units, input_size, activation)
self.my_scope = None
def __call__(self, a, b):
if self.my_scope == None:
self.my_scope = tf.get_variable_scope()
else:
self.my_scope.reuse_variables()
return tf.nn.rnn_cell.GRUCell.__call__(self, a, b, self.my_scope)
with tf.variable_scope("scope2") as vs:
cell = SharedGRUCell(10)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)
stacked_cell(tf.Variable(np.zeros((20, 10), dtype=np.float32), name="moo"), tf.Variable(np.zeros((20, 10), dtype=np.float32), "bla"))
# Retrieve just the LSTM variables.
vars = [v.name for v in tf.all_variables()
if v.name.startswith(vs.name)]
print vars
这样两个GRUCells之间的变量是共享的。请注意,您需要注意形状,因为同一个单元格需要同时处理原始输入和自身的输出。