Tensorflow卷积和numpy卷积的区别
Difference between Tensorflow convolution and numpy convolution
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_tf
和 Xconv_np
相等。
我的最终目标是在具有一维滤波器的矩阵上进行 运行 二维卷积,在每一行上使用相同的滤波器进行 运行s 1d 卷积。为了使这项工作(基本上是行上的一维卷积循环)我需要弄清楚为什么我的 np.convolve
和 tf.conv1d
给我不同的答案。
过滤器的顺序颠倒了。 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')
你看到的问题是因为TF并没有真正计算卷积。如果你看看convolution actually does的解释(检查卷积的视觉解释),你会看到第二个函数被翻转了:
- 用虚拟变量表达每个函数
- 体现其中一个功能(这是翻转)
- ..... 其他一些我不会在这里复制的东西。
除了那个翻转,TF 什么都能做。因此,您需要做的就是在 TF 或 numpy 中翻转内核。翻转 1d 的情况只是内核的相反顺序,对于 2d 你需要翻转两个轴(旋转内核 2 次)。
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')
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_tf
和 Xconv_np
相等。
我的最终目标是在具有一维滤波器的矩阵上进行 运行 二维卷积,在每一行上使用相同的滤波器进行 运行s 1d 卷积。为了使这项工作(基本上是行上的一维卷积循环)我需要弄清楚为什么我的 np.convolve
和 tf.conv1d
给我不同的答案。
过滤器的顺序颠倒了。 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')
你看到的问题是因为TF并没有真正计算卷积。如果你看看convolution actually does的解释(检查卷积的视觉解释),你会看到第二个函数被翻转了:
- 用虚拟变量表达每个函数
- 体现其中一个功能(这是翻转)
- ..... 其他一些我不会在这里复制的东西。
除了那个翻转,TF 什么都能做。因此,您需要做的就是在 TF 或 numpy 中翻转内核。翻转 1d 的情况只是内核的相反顺序,对于 2d 你需要翻转两个轴(旋转内核 2 次)。
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')