Python 如何在两个张量之间进行元素卷积?
我有两个张量,都是批量大小为N的图像,分辨率相同。我想把张量1的第一个图像和张量2的第一个图像卷积起来,把张量1的第二个图像和张量2卷积起来,依此类推。我希望输出是一个张量,有N个大小相同的图像。 我研究了如何使用tf.nn.conv2d,但似乎这个命令将接收一批N个图像,并使用单个过滤器进行卷积 我研究了一些例子,比如Python 如何在两个张量之间进行元素卷积?,python,tensorflow,keras,convolution,Python,Tensorflow,Keras,Convolution,我有两个张量,都是批量大小为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作为输入图像,使用单通道作为过滤器。