What is wrong with my multi-channel 1d convolution implemented in numpy (compared with tensorflow)

牧云@^-^@ 提交于 2020-01-24 09:27:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!