Tensorflow卷积和numpy卷积的区别

5
import numpy as np
import tensorflow as tf

X_node    = tf.placeholder('float',[1,10,1])
filter_tf = tf.Variable( tf.truncated_normal([3,1,1],stddev=0.1) )

Xconv_tf_tensor = tf.nn.conv1d(X_node, filter_tf,1,'SAME')

X = np.random.normal(0,1,[1,10,1])
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    feed_dict = {X_node: X}
    filter_np = filter_tf.eval()
    Xconv_tf = sess.run(Xconv_tf_tensor,feed_dict)
    Xconv_np = np.convolve(X[0,:,0],filter_np[:,0,0],'SAME')

我正在尝试查看Tensorflow卷积的结果,以检查它是否按照我的意图执行。当我运行numpy卷积并将其与Tensorflow卷积进行比较时,答案不同。上面的代码是我运行测试的方法。我希望Xconv_tfXconv_np相等。
我的最终目标是在具有1维过滤器的矩阵上运行2D卷积,该过滤器对每行使用相同的1d卷积。为了使这个工作正常(基本上是一系列对行进行1d卷积的循环),我需要弄清楚为什么我的np.convolvetf.conv1d给出了不同的答案。

完全不同的数字。有些元素甚至符号都不同。这种差异绝对是显著的。 - unknown_jy
2个回答

11
你看到的问题是因为TensorFlow实际上并没有计算卷积。如果你查看卷积的实际作用的解释(查找卷积的视觉解释),你会发现第二个函数被翻转了:
  1. 用虚拟变量表示每个函数
  2. 反射其中一个函数(这就是翻转)
  3. ..... 还有其他一些我不会在这里复制的东西。
TF做了除了那个翻转之外的一切工作。因此,你只需要在TF或numpy中翻转内核。对于1D情况,翻转只是内核逆序,对于2D情况,你需要翻转两个轴(旋转内核两次)。
import tensorflow as tf
import numpy as np

I = [1, 0, 2, 3, 0, 1, 1]
K = [2, 1, 3]

i = tf.constant(I, dtype=tf.float32, name='i')
k = tf.constant(K, dtype=tf.float32, name='k')

data   = tf.reshape(i, [1, int(i.shape[0]), 1], name='data')
kernel = tf.reshape(k, [int(k.shape[0]), 1, 1], name='kernel')

res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'VALID'))
with tf.Session() as sess:
    print sess.run(res)
    print np.convolve(I, K[::-1], 'VALID')

在TF的反向传播中会发生什么?它会翻转内核吗? - Shachaf Zohar

3
滤波器的顺序被反转了。TensorFlow卷积实际上是相互关系。Numpy使用数学符号,TF使用机器学习论文中的符号,并且顺序被颠倒了。
这将打印出“True”。
filter_np2=filter_np[::-1,0,0]
np.allclose(np.convolve(X[0,:,0],filter_np2,'SAME'),  Xconv_tf.flatten())    np.convolve(X[0,:,0],filter_np2,'SAME')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接