【问题标题】:How can I visualize the weights(variables) in cnn in Tensorflow?如何在 Tensorflow 中可视化 cnn 中的权重(变量)?
【发布时间】:2016-02-20 09:38:55
【问题描述】:

训练完cnn模型后,我想可视化权重或打印权重,我该怎么办? 训练后我什至无法打印出变量。 谢谢!

【问题讨论】:

标签: python tensorflow


【解决方案1】:

要可视化权重,您可以使用tf.image_summary() 操作将卷积过滤器(或过滤器切片)转换为摘要原型,使用tf.train.SummaryWriter 将它们写入日志,并使用可视化日志TensorBoard.

假设您有以下(简化的)程序:

filter = tf.Variable(tf.truncated_normal([8, 8, 3]))
images = tf.placeholder(tf.float32, shape=[None, 28, 28])

conv = tf.nn.conv2d(images, filter, strides=[1, 1, 1, 1], padding="SAME")

# More ops...
loss = ...
optimizer = tf.GradientDescentOptimizer(0.01)
train_op = optimizer.minimize(loss)

filter_summary = tf.image_summary(filter)

sess = tf.Session()
summary_writer = tf.train.SummaryWriter('/tmp/logs', sess.graph_def)
for i in range(10000):
  sess.run(train_op)
  if i % 10 == 0:
    # Log a summary every 10 steps.
    summary_writer.add_summary(filter_summary, i)

完成此操作后,您可以启动 TensorBoard 以可视化 /tmp/logs 中的日志,您将能够看到过滤器的可视化。

请注意,此技巧将深度 3 过滤器可视化为 RGB 图像(以匹配输入图像的通道)。如果您有更深的过滤器,或者将它们解释为颜色通道没有意义,您可以使用tf.split() 操作在深度维度上拆分过滤器,并为每个深度生成一个图像摘要。

【讨论】:

  • 如果我只想打印出来怎么办?如何使用名称为 'weight' 的 name_scope ike "conv1" 访问变量?
  • 如果你只是想打印出变量,你可以将tf.Variable对象传递给sess.run(),它会返回一个包含权重的numpy数组。
  • @ Wuchen 下面是如何在“conv1”范围内获取变量“weight”——使用 tf.variable_scope('conv1') 作为 scope_conv: weights = tf.get_variable('weights')
  • 注意,后面的版本中语法已经改成tf.image_summary(tag, tensor, ...)
  • tf.image_summary 自 2016 年 11 月 30 日起已弃用,取而代之的是 tf.summary.image 参见。 github.com/tensorflow/tensorflow/blob/master/tensorflow/python/…
【解决方案2】:

就像@mrry 说的,你可以使用tf.image_summary。例如,对于cifar10_train.py,您可以将此代码放在def train() 下的某处。请注意如何访问范围 'conv1' 下的 var

# Visualize conv1 features
with tf.variable_scope('conv1') as scope_conv:
  weights = tf.get_variable('weights')

  # scale weights to [0 255] and convert to uint8 (maybe change scaling?)
  x_min = tf.reduce_min(weights)
  x_max = tf.reduce_max(weights)
  weights_0_to_1 = (weights - x_min) / (x_max - x_min)
  weights_0_to_255_uint8 = tf.image.convert_image_dtype (weights_0_to_1, dtype=tf.uint8)

  # to tf.image_summary format [batch_size, height, width, channels]
  weights_transposed = tf.transpose (weights_0_to_255_uint8, [3, 0, 1, 2])

  # this will display random 3 filters from the 64 in conv1
  tf.image_summary('conv1/filters', weights_transposed, max_images=3)

如果您想在一个漂亮的网格中可视化所有conv1 过滤器,您必须自己将它们组织到一个网格中。我今天做了,所以现在我想分享一个gist for visualizing conv1 as a grid

【讨论】:

  • 为我工作!谢谢
  • 如果channels是16,如何可视化呢?
  • @raptoravis 没有默认方式,也没多大意义。我猜这不是第一层。如果我想这样做,我会修改答案中的要点以显示 16 个网格,每个网格用于 1 个通道(灰度)
  • @etoropov 是的,你是对的,它适用于第二层。谢谢你的建议!
【解决方案3】:

您可以通过以下方式将值提取为 numpy 数组:

with tf.variable_scope('conv1', reuse=True) as scope_conv:
    W_conv1 = tf.get_variable('weights', shape=[5, 5, 1, 32])
    weights = W_conv1.eval()
    with open("conv1.weights.npz", "w") as outfile:
        np.save(outfile, weights)

请注意,您必须调整范围(在我的情况下为'conv1')和变量名(在我的情况下为'weights')。

然后归结为可视化 numpy 数组。如何可视化 numpy 数组的一个示例是

#!/usr/bin/env python

"""Visualize numpy arrays."""

import numpy as np
import scipy.misc

arr = np.load('conv1.weights.npb')

# Get each 5x5 filter from the 5x5x1x32 array
for filter_ in range(arr.shape[3]):
    # Get the 5x5x1 filter:
    extracted_filter = arr[:, :, :, filter_]

    # Get rid of the last dimension (hence get 5x5):
    extracted_filter = np.squeeze(extracted_filter)

    # display the filter (might be very small - you can resize the window)
    scipy.misc.imshow(extracted_filter)

【讨论】:

  • 我不得不在 python 3 中使用with open("conv1.weights.npz", "wb") as outfile:(注意 b)。
【解决方案4】:

使用tensorflow 2 API,有几种选择:

使用get_weights() 函数提取的权重。

weights_n = model.layers[n].get_weights()[0]

使用numpy() 转换函数提取偏差。

bias_n = model.layers[n].bias.numpy()

【讨论】:

    猜你喜欢
    • 2018-11-09
    • 2018-02-02
    • 2016-05-13
    • 1970-01-01
    • 2018-02-07
    • 2013-10-12
    • 2020-08-04
    • 2019-03-16
    • 1970-01-01
    相关资源
    最近更新 更多