有没有办法在TensorFlow中反转图形?

时间:2018-03-30 14:04:40

标签: python tensorflow

正如标题所说,我正在寻找一种方法来扭转TensorFlow图的流程。这样做的原因是,我希望在给定训练图的输出的logit向量的情况下可视化图的隐藏层。

例如,假设我有如下给出的完全连通图(受MNIST启发):

inputs = tf.placeholder(dtype=tf.float32, shape=[None, 784])
hidden_w1 = tf.get_variable('w1', [784,100], initializer=tf.random_normal_initializer)
hidden_b1 = tf.get_variable('b1', [100], initializer=tf.random_normal_initializer)
a1 = tf.matmul(inputs, hidden_w1) + hidden_b1
z1 = tf.nn.relu(a1)

hidden_w2 = tf.get_variable('w2', [100,100], initializer=tf.random_normal_initializer)
hidden_b2 = tf.get_variable('b2', [100], initializer=tf.random_normal_initializer)
a2 = tf.matmul(z1, hidden_w2) + hidden_b2
z2 = tf.nn.relu(a2)

output_w = tf.get_variable('w3', [100,10], initializer=tf.random_normal_initializer)
output_b = tf.get_variable('b3', [10], initializer=tf.random_normal_initializer)
a3 = tf.matmul(z2, output_w) + output_b
output = tf.nn.relu(a3)

loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=..., logits=output)
train_op = tf.train.AdamOptimizer().minimize(loss)

假设我现在训练此图并且想要在仅激活第一输出神经元时可视化隐藏的1。我这样做的方法是反转图形的流程,并从输出层通过反转图形提供张量[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],直到我最终得到hidden1层的输出。我试图看看是否有办法在TensorFlow中做到这一点,但似乎没有关于此的信息。我在其中构造它的方法是在运行图形时添加一个操作sess.run_reverse(),如下所示:

with tf.Session() as sess:
while training:
    sess.run(train_op, feed_dict={inputs:...})

# finished training, reverse graph
category_to_visualize = tf.one_hot(indices=0, depth=10)
sess.run_reverse(hidden1, feed_dict={output:category_to_visualize})

如果这种操作不存在或甚至无法获得,我会改为构建单独的运算符来反转图的流程,如下所示:

output_reversed = tf.placeholder(dtype=tf.float32, shape=[1,10])
z3_reversed = tf.nn.relu(output_reversed)
a3_reversed = tf.matrix_inverse(output_w)*(z3_reversed - output_b)

z2_reversed = tf.nn.relu(a3_reversed)
a2_reversed = tf.matrix_inverse(hidden_w2)*(z2_reversed - hidden_b2)

z1_reversed = tf.nn.relu(a2_reversed)
a1_reversed = tf.matrix_inverse(hidden_w1)*(z1_reversed - hidden_b1)

我意识到这种方法可能存在逻辑上的缺陷,使其无法实现。我忽略的一些事情是当输入低于0时,ReLu的奇异矩阵和未定义的反演(但是,ReLu可以用sigmoid代替整个输入空间的理论定义的反演)。但是,核心思想是给出一个类别的特征图可视化 - 如果允许一些假设,我认为这应该是可能的。

无论如何,请告诉我,我是否在这里错误思考,以及是否有办法扭转图表!

2 个答案:

答案 0 :(得分:1)

我认为你的逻辑存在缺陷。某些操作是不可逆转的。我的程序中有两个无法撤消的内容。

RELU

ReLU是一个将负输入变为零的函数,并保留正数。请考虑以下示例。

x = np.array([1, 2, -1, -2])
y = np.maximum(x, 0) # Numpy's version of relu

这给了我们[1, 2, 0, 0]。问题是否定的,即我们知道1212,但是,我们无法告诉{ {1}}曾经(甚至应该)。如果您使用的是泄漏的ReLU,那么就会有一个解决方案,但由于Matrix Multiplication它不是很有用。

矩阵乘法

矩阵乘法的问题是您需要对列和行的乘积求和。例如(不是用python编写的,只是矩阵):

0

你计算它的方法是:

[1, 2]   [ 7,  8,  9]
[3, 4] * [10, 11, 12]
[5, 6]

[[1], [2]]   [ [7],  8,  9]
[ 3 ,  4 ] * [[10], 11, 12]
[ 5 ,  6 ]
->
[1*7 + 2*10, ?, ?]
[         ?, ?, ?]
[         ?, ?, ?]

然后我们迭代列以获取其余值。这样做的问题是我们不知道总结为[27, ?, ?] [ ?, ?, ?] [ ?, ?, ?] ,或者他们的产品是什么,也就是说,你正试图解决27。实际上有无数种方法可以解决这个问题。只有更大的基质,例如您可能必须找到27 = ab+cd无法以神经网络发现有用的方式计算它。

结论

神经网络旨在处理和抽象数据。换句话说,它需要一些复杂的(像素网格)并使其更简单(整数)。向后做这件事并没有多大意义。 Tensorflow,不,任何机器学习库都不会这样做,因为它是不可能的,没有用。

如果你想要一些可以近似输入的东西,那么我建议使用GaNN或Generative Adversarial Neural Network。基本前提是你有两个神经网络,称为生成器和鉴别器。生成器被赋予一个随机数,旨在欺骗鉴别器。鉴别器被赋予输入数据集和生成器的图像,并期望在它们之间进行分析。

答案 1 :(得分:0)

还有另一种方法可以显示隐藏图层的激活,如本文所述:http://arxiv.org/pdf/1506.06579.pdf

检查以下帖子,了解它在MNIST数据集中的实现方式

https://medium.com/@awjuliani/visualizing-neural-network-layer-activation-tensorflow-tutorial-d45f8bf7bbc4

如果您需要进一步澄清,请在评论中告诉我。