Bru*_* KM 11 python machine-learning neural-network conv-neural-network tensorflow
我希望在TensorFlow中实现类似于2D卷积的操作.根据我的理解,实现卷积的最常见方法是首先im2col对图像应用操作(参见此处 - " 作为矩阵乘法实现 " 小节) - 将图像转换为具有单独"块"的2D矩阵的操作.将内核应用为展平列的图像.
换句话说,上述链接资源的摘录解释了什么im2col做得很好:
[...]例如,如果输入为[227x227x3] (格式为高度x宽度x n_channels)并且要在步幅4处与11x11x3滤波器进行卷积,那么我们将采用[11x11x3]像素块输入并将每个块拉伸到一个大小为11*11*3 = 363的列向量中.在步长为4的输入中迭代此过程会给出(227-11)/ 4 + 1 = 55个沿宽度和高度的位置,从而导致的输出矩阵
X_col的im2col大小[363 X 3025],其中每列是一个伸出感受域和有55*55 =他们的3025在总的.请注意,由于感知字段重叠,因此输入卷中的每个数字都可以在多个不同的列中重复.
正如我从TensorFlow文档中所理解的那样,这也是内部完成的内容tf.nn.conv2d.
现在,我想im2col分别在TensorFlow中实现所述操作(因为我希望能够访问这个中间结果).由于这涉及以非平凡的方式复制值,我将如何为此操作自己构建相对有效的计算图?同样,如何实现反向操作?
您可以使用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))
Run Code Online (Sandbox Code Playgroud)
这给你,0.0因为它们是等价的。这不需要反向功能。
编辑:
正如我从 TensorFlow 文档中了解到的,这也是 tf.nn.conv2d 在内部完成的。
不,不是真的。例如,GPU 上的 TF 依赖于 CuDNN,它是一种更复杂的野兽(winograd、ptx 等)。只有在某些情况下,它采用了im2col类似的做法在这里对CPU和量化的版本在这里。
| 归档时间: |
|
| 查看次数: |
2177 次 |
| 最近记录: |