我在numpy中实现的多通道一维卷积有什么问题(与tensorflow相比)
What is wrong with my multi-channel 1d convolution implemented in numpy (compared with tensorflow)
为了确保理解TensorFlow的卷积运算,我在numpy中实现了多通道的conv1d。但是,我得到不同的结果,我看不到问题所在。与 conv1d 相比,我的实现似乎将重叠值加倍。
代码:
import tensorflow as tf
import numpy as np
# hand-written multi-channel 1D convolution operator
# "Data", dimensions:
# [0]: sample (2 samples)
# [1]: time index (4 indexes)
# [2]: channels (2 channels)
x = np.array([[1,2,3,4],[5,6,7,8]]).T
x = np.array([x, x+8], dtype=np.float32)
# "Filter", a linear kernel to be convolved along axis 1
y = np.array([[[2,8,6,5,7],[3,9,7,2,1]]], dtype=np.float32)
# convolution along axis=1
w1 = np.zeros(x.shape[:2] + y.shape[2:])
for i in range(1,x.shape[1]-1):
w1[:,i-1:i+2,:] += x[:,i-1:i+2,:] @ y
# check against conv1d:
s = tf.Session()
w2 = s.run(tf.nn.conv1d(x, padding='VALID', filters=y))
然而,这对 w1 和 w2 给出了不同的结果:
In [13]: w1 # Numpy result
Out[13]:
array([[[ 17., 53., 41., 15., 12.],
[ 44., 140., 108., 44., 40.],
[ 54., 174., 134., 58., 56.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[124., 412., 316., 156., 168.],
[134., 446., 342., 170., 184.],
[ 72., 240., 184., 92., 100.]]])
In [14]: w2 # Tensorflow result
Out[14]:
array([[[ 17., 53., 41., 15., 12.],
[ 22., 70., 54., 22., 20.],
[ 27., 87., 67., 29., 28.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[ 62., 206., 158., 78., 84.],
[ 67., 223., 171., 85., 92.],
[ 72., 240., 184., 92., 100.]]], dtype=float32)
在我的版本中,与 conv1d 相比,重叠索引(中间 2 个)似乎增加了一倍。但是,我不知道该怎么做,似乎除法在这里不是正确的,因为卷积是一个简单的乘加运算。
知道我做错了什么吗?提前致谢!
编辑:我得到与 padding='SAME'
相同的结果。
错误在for循环的+=
中。您计算 w1[:,1,:]
和 w1[:,2,:]
两次并将它们添加到自身。只需将 +=
替换为 =
,或者简单地执行:
>>> x @ y
array([[[ 17., 53., 41., 15., 12.],
[ 22., 70., 54., 22., 20.],
[ 27., 87., 67., 29., 28.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[ 62., 206., 158., 78., 84.],
[ 67., 223., 171., 85., 92.],
[ 72., 240., 184., 92., 100.]]], dtype=float32)
为了确保理解TensorFlow的卷积运算,我在numpy中实现了多通道的conv1d。但是,我得到不同的结果,我看不到问题所在。与 conv1d 相比,我的实现似乎将重叠值加倍。
代码:
import tensorflow as tf
import numpy as np
# hand-written multi-channel 1D convolution operator
# "Data", dimensions:
# [0]: sample (2 samples)
# [1]: time index (4 indexes)
# [2]: channels (2 channels)
x = np.array([[1,2,3,4],[5,6,7,8]]).T
x = np.array([x, x+8], dtype=np.float32)
# "Filter", a linear kernel to be convolved along axis 1
y = np.array([[[2,8,6,5,7],[3,9,7,2,1]]], dtype=np.float32)
# convolution along axis=1
w1 = np.zeros(x.shape[:2] + y.shape[2:])
for i in range(1,x.shape[1]-1):
w1[:,i-1:i+2,:] += x[:,i-1:i+2,:] @ y
# check against conv1d:
s = tf.Session()
w2 = s.run(tf.nn.conv1d(x, padding='VALID', filters=y))
然而,这对 w1 和 w2 给出了不同的结果:
In [13]: w1 # Numpy result
Out[13]:
array([[[ 17., 53., 41., 15., 12.],
[ 44., 140., 108., 44., 40.],
[ 54., 174., 134., 58., 56.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[124., 412., 316., 156., 168.],
[134., 446., 342., 170., 184.],
[ 72., 240., 184., 92., 100.]]])
In [14]: w2 # Tensorflow result
Out[14]:
array([[[ 17., 53., 41., 15., 12.],
[ 22., 70., 54., 22., 20.],
[ 27., 87., 67., 29., 28.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[ 62., 206., 158., 78., 84.],
[ 67., 223., 171., 85., 92.],
[ 72., 240., 184., 92., 100.]]], dtype=float32)
在我的版本中,与 conv1d 相比,重叠索引(中间 2 个)似乎增加了一倍。但是,我不知道该怎么做,似乎除法在这里不是正确的,因为卷积是一个简单的乘加运算。
知道我做错了什么吗?提前致谢!
编辑:我得到与 padding='SAME'
相同的结果。
错误在for循环的+=
中。您计算 w1[:,1,:]
和 w1[:,2,:]
两次并将它们添加到自身。只需将 +=
替换为 =
,或者简单地执行:
>>> x @ y
array([[[ 17., 53., 41., 15., 12.],
[ 22., 70., 54., 22., 20.],
[ 27., 87., 67., 29., 28.],
[ 32., 104., 80., 36., 36.]],
[[ 57., 189., 145., 71., 76.],
[ 62., 206., 158., 78., 84.],
[ 67., 223., 171., 85., 92.],
[ 72., 240., 184., 92., 100.]]], dtype=float32)