我正在使用多个LSTM层来形成一个深度递归神经网络。我想在训练过程中监控每个LSTM层的权重。但是,我找不到如何将LSTM图层权重的摘要附加到TensorBoard。

关于如何做到这一点的任何建议?

代码如下:

cells = []

with tf.name_scope("cell_1"):
    cell1 = tf.contrib.rnn.LSTMCell(self.embd_size, state_is_tuple=True, initializer=self.initializer)
    cell1 = tf.contrib.rnn.DropoutWrapper(cell1,
                input_keep_prob=self.input_dropout,
                output_keep_prob=self.output_dropout,
                state_keep_prob=self.recurrent_dropout)
    cells.append(cell1)

with tf.name_scope("cell_2"):
    cell2 = tf.contrib.rnn.LSTMCell(self.n_hidden, state_is_tuple=True, initializer=self.initializer)
    cell2 = tf.contrib.rnn.DropoutWrapper(cell2,
                output_keep_prob=self.output_dropout,
                state_keep_prob=self.recurrent_dropout)
    cells.append(cell2)

with tf.name_scope("cell_3"):
    cell3 = tf.contrib.rnn.LSTMCell(self.embd_size, state_is_tuple=True, initializer=self.initializer)
    # cell has no input dropout since previous cell already has output dropout
    cell3 = tf.contrib.rnn.DropoutWrapper(cell3,
                output_keep_prob=self.output_dropout,
                state_keep_prob=self.recurrent_dropout)
    cells.append(cell3)

cell = tf.contrib.rnn.MultiRNNCell(
    cells, state_is_tuple=True)

output, self.final_state = tf.nn.dynamic_rnn(
    cell,
    inputs=self.inputs,
    initial_state=self.init_state)

最佳答案

tf.contrib.rnn.LSTMCell对象具有一个称为variablesproperty,可用于此目的。有一个窍门:该属性返回一个空列表,直到您的单元格通过tf.nn.dynamic_rnn为止。至少在使用单个LSTMCell时就是这种情况。我不能说MultiRNNCell。所以我希望这会起作用:

output, self.final_state = tf.nn.dynamic_rnn(...)
for one_lstm_cell in cells:
    one_kernel, one_bias = one_lstm_cell.variables
    # I think TensorBoard handles summaries with the same name fine.
    tf.summary.histogram("Kernel", one_kernel)
    tf.summary.histogram("Bias", one_bias)

然后您可能知道如何从那里开始,但是
summary_op = tf.summary.merge_all()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    train_writer = tf.summary.FileWriter(
        "my/preferred/logdir/train", graph=tf.get_default_graph())
    for step in range(1, training_steps+1):
        ...
        _, step_summary = sess.run([train_op, summary_op])
        train_writer.add_summary(step_summary)

查看我上面链接的TensorFlow文档,还有一个weights属性。我不知道有没有区别。并且,没有记录variables返回的顺序。我通过打印结果列表并查看变量名来弄清楚。

现在,MultiRNNCell根据其doc具有相同的variables属性,并说它返回所有图层变量。老实说,我不知道MultiRNNCell是如何工作的,所以我无法告诉您这些是MultiRNNCell的专有变量还是它是否包含进入它的单元格的变量。无论哪种方式,知道该属性的存在都是一个不错的提示!希望这可以帮助。

尽管已为大多数(所有?)RNN类记录了variables,但对于DropoutWrapper,它确实会中断。自r1.2起property has been documented,但访问该属性会在1.2和1.4中引起异常(看起来像1.3,但未经测试)。具体来说,
from tensorflow.contrib import rnn
...
lstm_cell = rnn.BasicLSTMCell(num_hidden, forget_bias=1.0)
wrapped_cell = rnn.DropoutWrapper(lstm_cell)
outputs, states = rnn.static_rnn(wrapped_cell, x, dtype=tf.float32)
print("LSTM vars!", lstm_cell.variables)
print("Wrapped vars!", wrapped_cell.variables)

将抛出AttributeError: 'DropoutWrapper' object has no attribute 'trainable'。从回溯(或长时间盯着DropoutWrapper source),我注意到variables是在DropoutWrapper's super RNNCell 的 super Layer 中实现的。头晕了吗?实际上,我们在这里找到了记录的variables属性。它返回(已记录的)weights属性。 weights属性返回(已记录的)self.trainable_weights + self.non_trainable_weights属性。最后是问题的根源:
@property
def trainable_weights(self):
    return self._trainable_weights if self.trainable else []

@property
def non_trainable_weights(self):
    if self.trainable:
        return self._non_trainable_weights
    else:
        return self._trainable_weights + self._non_trainable_weights

也就是说,variables不适用于DropoutWrapper实例。由于未定义trainable_weights,因此non_trainable_weightsself.trainable都不会。

更深一步,Layer.__init__self.trainable默认为True,但DropoutWrapper从未调用它。要在Github上引用TensorFlow贡献者,



因此,例如,要访问上述示例中的LSTM变量,lstm_cell.variables就足够了。

编辑:据我所知,迈克·汗(Mike Khan)的PR已合并到1.5中。现在,辍学层的variables属性返回一个空列表。

关于tensorflow - Tensorboard-可视化LSTM的权重,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47640455/

10-12 21:38