Tensorflow RNN细胞分重

时间:2016-08-23 06:14:48

标签: python machine-learning tensorflow deep-learning recurrent-neural-network

我想知道在以下代码中是否共享了两个堆叠单元格的权重:

cell = rnn_cell.GRUCell(hidden_dim)
stacked_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * 2)

如果不共享,如何强制共享任何RNN?

注意: 我可能更想要在嵌套的输入到输出连接的RNN配置中共享权重,其中第一层被克隆多次用于第二层的每个输入(例如,第一层表示字母的句子而第二层表示从迭代收集的字第一层的输出)

1 个答案:

答案 0 :(得分:8)

您可以通过执行以下脚本来查看权重:

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

除了虚拟变量之外,你会看到它返回两组GRU权重:那些带有“Cell1”和那些带有“Cell0”的权重。

要使它们共享,您可以实现自己的继承自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

这样就可以共享两个GRUCell之间的变量。请注意,您需要注意形状,因为相同的单元格需要同时处理原始输入和输出。