python - 对每个输入 channel 应用不同的 conv1d 滤波器

标签 python tensorflow conv-neural-network

我正在研究一个 Tensorflow 模型,其中应将单独的一维卷积应用于 N 个输入 channel 中的每一个。我尝试过各种 convXd 函数。到目前为止,我已经得到了一些工作,其中每个滤波器应用于每个 channel ,产生 N x N 输出,我可以从中选择对角线。但这似乎效率很低。关于如何仅将滤波器 i 与输入 channel 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()

这是一个修订版本,其中包含使用深度明智_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()

最佳答案

听起来您正在寻找 depthwise convolution 。这为每个输入 channel 构建了单独的滤波器。不幸的是,似乎没有内置的 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)是每个输入 channel 的滤波器数量。由于您只想为每个 channel 使用一个单独的过滤器,因此该数字为 1。

我希望我正确理解了这个问题,因为我对您的输入 X 一开始就是 4D(通常您会使用 1D 卷积作为 3D 输入)这一事实感到有点困惑。不过,您也许可以根据您的需要进行调整。

关于python - 对每个输入 channel 应用不同的 conv1d 滤波器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54989687/

相关文章:

python - 类和对象上的 `__new__` 和 `__init__`

python - Keras 无效参数错误 : You must feed a value for placeholder tensor

python - 将 Facenet 模型 .pb 文件转换为 TFLITE 格式时出错

python - DSX 中的 tensorflow : Consuming prediction results fails due to list()

python - 如何在 Keras for AlexNet 训练之前加载 imagenet 权重?

python - 为什么 Keras Conv1D 层的输出张量没有输入维度?

python - 嵌套列表上的 min/max 函数如何工作?

python - 使用 Access ODBC 的 pyodbc fast_executemany 会使 Python 解释器崩溃

python - 在 Python 中添加持续时间

tensorflow - TensorFlow 中的上采样特征图