可视化张量流中卷积层的输出
conv-neural-network
tensorflow
9
0

我正在尝试使用功能tf.image_summary可视化张量流中卷积层的输出。我已经在其他实例中成功使用了它(例如,可视化输入图像),但是在正确调整输出形状方面存在一些困难。我有以下转换层:

img_size = 256
x_image = tf.reshape(x, [-1,img_size, img_size,1], "sketch_image")

W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

因此, h_conv1的输出将具有[-1, img_size, img_size, 32]的形状。仅使用tf.image_summary("first_conv", tf.reshape(h_conv1, [-1, img_size, img_size, 1]))不能说明32个不同的内核,因此我基本上在这里对不同的功能图进行了tf.image_summary("first_conv", tf.reshape(h_conv1, [-1, img_size, img_size, 1]))

如何正确重塑它们?还是我可以使用另一个帮助器功能将此输出包括在摘要中?

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

如果有人想“跳”到numpy并可视化“那里”,这里有一个示例,显示如何显示Weightsprocessing result 。所有转换均基于mdaoust先前答案。

# to visualize 1st conv layer Weights
vv1 = sess.run(W_conv1)

# to visualize 1st conv layer output
vv2 = sess.run(h_conv1,feed_dict = {img_ph:x, keep_prob: 1.0})
vv2 = vv2[0,:,:,:]   # in case of bunch out - slice first img


def vis_conv(v,ix,iy,ch,cy,cx, p = 0) :
    v = np.reshape(v,(iy,ix,ch))
    ix += 2
    iy += 2
    npad = ((1,1), (1,1), (0,0))
    v = np.pad(v, pad_width=npad, mode='constant', constant_values=p)
    v = np.reshape(v,(iy,ix,cy,cx)) 
    v = np.transpose(v,(2,0,3,1)) #cy,iy,cx,ix
    v = np.reshape(v,(cy*iy,cx*ix))
    return v

# W_conv1 - weights
ix = 5  # data size
iy = 5
ch = 32   
cy = 4   # grid from channels:  32 = 4x8
cx = 8
v  = vis_conv(vv1,ix,iy,ch,cy,cx)
plt.figure(figsize = (8,8))
plt.imshow(v,cmap="Greys_r",interpolation='nearest')

#  h_conv1 - processed image
ix = 30  # data size
iy = 30
v  = vis_conv(vv2,ix,iy,ch,cy,cx)
plt.figure(figsize = (8,8))
plt.imshow(v,cmap="Greys_r",interpolation='nearest')
收藏
评论

我不知道一个辅助函数,但是如果您想查看所有过滤器,则可以将它们打包到一个图像中,并使用一些tf.transpose

因此,如果您的张量是images x ix x iy x channels

>>> V = tf.Variable()
>>> print V.get_shape()

TensorShape([Dimension(-1), Dimension(256), Dimension(256), Dimension(32)])

因此在此示例中ix = 256iy=256channels=32

首先切片1张图片,然后删除image尺寸

V = tf.slice(V,(0,0,0,0),(1,-1,-1,-1)) #V[0,...]
V = tf.reshape(V,(iy,ix,channels))

接下来在图像周围添加零填充的几个像素

ix += 4
iy += 4
V = tf.image.resize_image_with_crop_or_pad(image, iy, ix)

然后重塑形状,以使您拥有cy=4cx=8 ,而不是拥有32x通道的4x8通道。

V = tf.reshape(V,(iy,ix,cy,cx)) 

现在是棘手的部分。 tf似乎以numpy的默认C顺序返回结果。

如果将当前顺序展平,则在列出第二个像素的通道(递增ix )之前,将列出第一个像素的所有通道(在cxcy迭代)。遍历像素行( ix ),然后再递增到下一行( iy )。

我们想要将图像布置在网格中的顺序。因此,您要遍历图像的ix行( ix ),然后再沿着通道的行( cx )前进,当您击中通道的行尾时,便会前进至图像的下一行( iy ),然后运行图像中的行或行,您将递增到下一个通道行( cy )。所以:

V = tf.transpose(V,(2,0,3,1)) #cy,iy,cx,ix

我个人更喜欢np.einsum花式转置,为便于阅读,但它不是在tf 还没有

newtensor = np.einsum('yxYX->YyXx',oldtensor)

无论如何,既然像素顺序正确,我们可以安全地将其展平为2d张量:

# image_summary needs 4d input
V = tf.reshape(V,(1,cy*iy,cx*ix,1))

尝试在tf.image_summary上,您应该得到一个小图像网格。

以下是按照此处所有步骤操作后得到的图像。

在此处输入图片说明

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题