Python 如何在两个张量之间进行元素卷积?

Python 如何在两个张量之间进行元素卷积?,python,tensorflow,keras,convolution,Python,Tensorflow,Keras,Convolution,我有两个张量,都是批量大小为N的图像,分辨率相同。我想把张量1的第一个图像和张量2的第一个图像卷积起来,把张量1的第二个图像和张量2卷积起来,依此类推。我希望输出是一个张量,有N个大小相同的图像。 我研究了如何使用tf.nn.conv2d,但似乎这个命令将接收一批N个图像,并使用单个过滤器进行卷积 我研究了一些例子,比如 但是,它们并不涉及多个图像和多个过滤器。您可以使用批处理维度作为可分离的通道,使用实际输入通道作为批处理维度来完成类似的操作。不过,我不确定它是否能很好地执行,因为它涉及到几个

我有两个张量,都是批量大小为N的图像,分辨率相同。我想把张量1的第一个图像和张量2的第一个图像卷积起来,把张量1的第二个图像和张量2卷积起来,依此类推。我希望输出是一个张量,有N个大小相同的图像。 我研究了如何使用tf.nn.conv2d,但似乎这个命令将接收一批N个图像,并使用单个过滤器进行卷积

我研究了一些例子,比如
但是,它们并不涉及多个图像和多个过滤器。

您可以使用批处理维度作为可分离的通道,使用实际输入通道作为批处理维度来完成类似的操作。不过,我不确定它是否能很好地执行,因为它涉及到几个换位(在TensorFlow中不是自由的)和通过大量通道的卷积,这并不是真正的优化用例。以下是它的工作原理:

import tensorflow as tf
import numpy as np
import scipy.signal

# Expects imgs with shape (B, H, W, C) and filters with shape (B, H, W, 1)
def batch_conv(imgs, filters, strides, padding, rate=None):
    imgs = tf.convert_to_tensor(imgs)
    filters = tf.convert_to_tensor(filters)
    b = tf.shape(imgs)[0]
    imgs_t = tf.transpose(imgs, [3, 1, 2, 0])
    filters_t = tf.transpose(filters, [1, 2, 0, 3])
    strides = [strides[3], strides[1], strides[2], strides[0]]
    # "do-nothing" pointwise filter
    pointwise = tf.eye(b, batch_shape=[1, 1])
    conv = tf.nn.separable_conv2d(imgs_t, filters_t, pointwise, strides, padding, rate)
    return tf.transpose(conv, [3, 1, 2, 0])

# Slow, loop-based version using SciPy's correlate to check result
def batch_conv_np(imgs, filters, padding):
    return np.stack(
        [np.stack([scipy.signal.correlate2d(img[..., i], filter[..., 0], padding.lower())
                   for i in range(img.shape[-1])], axis=-1)
         for img, filter in zip(imgs, filters)], axis=0)

# Make random input
np.random.seed(0)
imgs = np.random.rand(5, 20, 30, 3).astype(np.float32)
filters = np.random.rand(5, 20, 30, 1).astype(np.float32)
padding = 'SAME'
# Test
res_np = batch_conv_np(imgs, filters, padding)
with tf.Graph().as_default(), tf.Session() as sess:
    res_tf = batch_conv(imgs, filters, [1, 1, 1, 1], padding)
    res_tf_val = sess.run(res_tf)
print(np.allclose(res_np, res_tf_val))
# True

您可以使用,使用批处理维度作为可分离通道,使用实际输入通道作为批处理维度来完成类似的操作。不过,我不确定它是否能很好地执行,因为它涉及到几个换位(在TensorFlow中不是自由的)和通过大量通道的卷积,这并不是真正的优化用例。以下是它的工作原理:

import tensorflow as tf
import numpy as np
import scipy.signal

# Expects imgs with shape (B, H, W, C) and filters with shape (B, H, W, 1)
def batch_conv(imgs, filters, strides, padding, rate=None):
    imgs = tf.convert_to_tensor(imgs)
    filters = tf.convert_to_tensor(filters)
    b = tf.shape(imgs)[0]
    imgs_t = tf.transpose(imgs, [3, 1, 2, 0])
    filters_t = tf.transpose(filters, [1, 2, 0, 3])
    strides = [strides[3], strides[1], strides[2], strides[0]]
    # "do-nothing" pointwise filter
    pointwise = tf.eye(b, batch_shape=[1, 1])
    conv = tf.nn.separable_conv2d(imgs_t, filters_t, pointwise, strides, padding, rate)
    return tf.transpose(conv, [3, 1, 2, 0])

# Slow, loop-based version using SciPy's correlate to check result
def batch_conv_np(imgs, filters, padding):
    return np.stack(
        [np.stack([scipy.signal.correlate2d(img[..., i], filter[..., 0], padding.lower())
                   for i in range(img.shape[-1])], axis=-1)
         for img, filter in zip(imgs, filters)], axis=0)

# Make random input
np.random.seed(0)
imgs = np.random.rand(5, 20, 30, 3).astype(np.float32)
filters = np.random.rand(5, 20, 30, 1).astype(np.float32)
padding = 'SAME'
# Test
res_np = batch_conv_np(imgs, filters, padding)
with tf.Graph().as_default(), tf.Session() as sess:
    res_tf = batch_conv(imgs, filters, [1, 1, 1, 1], padding)
    res_tf_val = sess.run(res_tf)
print(np.allclose(res_np, res_tf_val))
# True

你可以将for循环用于图像和过滤器是否有多个通道?@ChrisMueller我想到了这一点,但在训练过程中计算成本不是很高吗?我还考虑过将批量缩小到1号,但这也有缺点that@jdehesa现在我正在尝试灰度图像,但理想情况下,我希望输入图像使用RGB,过滤器使用单通道。你可以使用for循环,图像和过滤器是否有多个通道?@ChrisMueller我想过,但不是吗培训期间计算费用昂贵?我还考虑过将批量缩小到1号,但这也有缺点that@jdehesa现在我正在尝试灰度图像,但理想情况下,我希望使用RGB作为输入图像,使用单通道作为过滤器。