我正在研究Tensorflow模型,其中应将单独的1d卷积应用于N个输入通道中的每一个。我玩过各种convXd函数。到目前为止,在将每个滤波器应用于每个通道的情况下,我已经做了一些工作,得到了N x N个输出,我可以从中选择一个对角线。但这似乎效率很低。关于如何仅使滤波器i与输入通道i卷积的任何想法?感谢您的任何建议!
说明我的最佳工作示例的代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
# [batch, in_height, in_width, in_channels]
X_size = [5, 109, 2, 1]
# [filter_height, filter_width, in_channels, out_channels]
W_size = [10, 1, 1, 2]
mX = np.zeros(X_size)
mX[0,10,0,0]=1
mX[0,40,1,0]=2
mW = np.zeros(W_size)
mW[1:3,0,0,0]=1
mW[3:6,0,0,1]=-1
X = tf.Variable(mX, dtype=tf.float32)
W = tf.Variable(mW, dtype=tf.float32)
# convolve everything
Y = tf.nn.conv2d(X, W, strides=[1, 1, 1, 1], padding='VALID')
# now only preserve the outputs for filter i + input i
Y_desired = tf.matrix_diag_part(Y)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(Y.shape)
Yout = sess.run(fetches=Y)
# Yes=desired output, No=extraneous output
plt.figure()
plt.subplot(2,2,1)
plt.plot(Yout[0,:,0,0])
plt.title('Yes: W filter 0 * X channel 0')
plt.subplot(2,2,2)
plt.plot(Yout[0,:,1,0])
plt.title('No: W filter 0 * X channel 1')
plt.subplot(2,2,3)
plt.plot(Yout[0,:,0,1])
plt.title('No: W filter 1 * X channel 0')
plt.subplot(2,2,4)
plt.plot(Yout[0,:,1,1])
plt.title('Yes: W filter 1 * X channel 1')
plt.tight_layout()
这是修订版,其中包含使用depthwise_conv2d的建议:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
# [batch, in_height, in_width, in_channels]
X_size = [5, 1, 109, 2]
# [filter_height, filter_width, in_channels, out_channels]
W_size = [1, 10, 2, 1]
mX = np.zeros(X_size)
mX[0,0,10,0]=1
mX[0,0,40,1]=2
mW = np.zeros(W_size)
mW[0,1:3,0,0]=1
mW[0,3:6,1,0]=-1
X = tf.Variable(mX, dtype=tf.float32)
W = tf.Variable(mW, dtype=tf.float32)
Y = tf.nn.depthwise_conv2d(X, W, strides=[1, 1, 1, 1], padding='VALID')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
Yout = sess.run(fetches=Y)
plt.figure()
plt.subplot(2,1,1)
plt.plot(Yout[0,0,:,0])
plt.title('Yes: W filter 0 * X channel 0')
plt.subplot(2,1,2)
plt.plot(Yout[0,0,:,1])
plt.title('Yes: W filter 1 * X channel 1')
plt.tight_layout()
答案 0 :(得分:0)
听起来像您在寻找depthwise convolution。这将为每个输入通道构建单独的过滤器。不幸的是,似乎没有内置的1D版本,但是大多数1D卷积实现无论如何都只是在幕后使用2D。您可以执行以下操作:
inp = ... # assume this is your input, shape batch x time (or width or whatever) x channels
inp_fake2d = inp[:, tf.newaxis, :, :] # add a fake second spatial dimension
filters = tf.random_normal([1, w, channels, 1])
out_fake2d = tf.nn.depthwise_conv2d(inp_fake2d, filters, [1,1,1,1], "valid")
out = out_fake2d[:, 0, :, :]
这将添加大小为1的“伪”第二空间维度,然后对过滤器进行卷积(在伪维度中也为大小1,在该方向上没有任何卷积),最后再次移除伪造维度。请注意,滤波器张量中的第四个维度(也是大小1)是每个输入通道的滤波器数量。由于每个通道只需要一个单独的过滤器,因此该数字为1。
我希望我正确理解了这个问题,因为我对您的输入X
首先是4D感到困惑(通常您将1D卷积用于3D输入)。但是,您也许可以使它适应您的需求。