问题
To ensure my understanding of TensorFlow's convolution operations, I implemented conv1d with multiple channels in numpy. However, I get different results, and I cannot see the problem. It seems my implementation is doubling the overlapped values compared with conv1d.
Code:
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))
However, this gives different results for w1 and 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)
It seems that in my version, the overlapping indexes (the middle 2) get doubled, compared to conv1d. However, I can't figure out what to do differently, it doesn't seem that dividing would be the right thing here, as convolution is a straightforward multiply-add operation.
Any ideas what I did wrong? Thanks in advance!
Edit: I get the same result with padding='SAME'
.
回答1:
The mistake is in +=
in the for-loop. You compute the w1[:,1,:]
and w1[:,2,:]
twice and add them to themselves. Just replace +=
with =
, or simply do:
>>> 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)
来源:https://stackoverflow.com/questions/59521443/what-is-wrong-with-my-multi-channel-1d-convolution-implemented-in-numpy-compare