【问题标题】:Implementing im2col in TensorFlow在 TensorFlow 中实现 im2col
【发布时间】:2018-01-15 04:10:46
【问题描述】:

我希望在 TensorFlow 中实现类似于 2D 卷积的操作。根据我的理解,实现卷积的最常见方法是首先对图像应用im2col 操作(参见here - 小节“作为矩阵乘法的实现”) - 一种转换的操作将图像转换为 2D 矩阵,其中将内核应用到的图像的单个“块”作为扁平列。

换句话说,上述链接资源的摘录解释了im2col 的优点:

[...] 例如,如果输入是 [227x227x3] (格式为高 x 宽 x n_channels) 并且要在步长 4 处与 11x11x3 滤波器进行卷积,那么我们将在输入中获取 [11x11x3] 个像素块,并将每个块拉伸成大小为 11*11*3 = 363 的列向量。在输入中以 4 的步幅迭代此过程得到 (227-11)/4+1 =沿宽度和高度的 55 个位置,导致大小为 [363 x 3025] 的 im2col 的输出矩阵 X_col,其中每一列都是拉伸的感受野,总共有 55*55 = 3025 个。请注意,由于感受野重叠,输入卷中的每个数字都可能在多个不同的列中重复。

据我从TensorFlow docs 了解到,tf.nn.conv2d 内部也是如此。

现在,我想在 TensorFlow 中单独实现上述im2col 操作(因为我希望能够访问这个中间结果)。由于这涉及以非平凡的方式复制值,我如何自己为这个操作构建一个相对有效的计算图?同样,如何实现反向操作?

【问题讨论】:

    标签: python machine-learning tensorflow neural-network conv-neural-network


    【解决方案1】:

    您可以使用extract_image_patches 轻松做到这一点。

    此函数将图像的每个filter_size x filter_size 补丁放入深度中,从而产生[batch_size, height, width, 9] 张量。

    要与 tf.nn.conv2d 进行比较,您可以为图像实现 Sobel 运算符

    import tensorflow as tf
    import numpy as np
    
    image = np.arange(10 * 10 * 1).reshape(1, 10, 10, 1)
    
    images = tf.convert_to_tensor(image.astype(np.float32))
    
    filter_size = 3
    sobel_x = tf.constant([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], tf.float32)
    sobel_x_filter = tf.reshape(sobel_x, [3, 3, 1, 1])
    
    image_patches = tf.extract_image_patches(images,
                                             [1, filter_size, filter_size, 1],
                                             [1, 1, 1, 1], [1, 1, 1, 1],
                                             padding='SAME')
    
    
    actual = tf.reduce_sum(tf.multiply(image_patches, tf.reshape(sobel_x_filter, [9])), 3, keep_dims=True)
    expected = tf.nn.conv2d(images, sobel_x_filter, strides=[1, 1, 1, 1], padding='SAME')
    
    with tf.Session() as sess:
        print sess.run(tf.reduce_sum(expected - actual))
    

    这会给你0.0,因为它们是等价的。这不需要反向函数。

    编辑

    正如我从 TensorFlow 文档中了解到的那样,这就是我们所做的 tf.nn.conv2d 内部也是如此。

    不,不是真的。例如,GPU 上的 TF 依赖于更多 complex beast (winograd, ptx, ...) 的 CuDNN。仅在某些情况下,它使用im2col 方法,例如 CPU 上的here 和量化版本here

    【讨论】:

      猜你喜欢
      • 2015-07-18
      • 2020-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多