TensorFlow - tf.nn.conv2d

TensorFlow - tf.nn.conv2d

flyfish

函数说明原文
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

Computes a 2-D convolution given 4-D input and filter tensors.

Given an input tensor of shape [batch, in_height, in_width, in_channels] and a filter / kernel tensor of shape [filter_height, filter_width,

in_channels, out_channels], this op performs the following:

Flattens the filter to a 2-D matrix with shape [filter_height * filter_width * in_channels, output_channels].
Extracts image patches from the the input tensor to form a virtual tensor of shape [batch, out_height, out_width, filter_height * filter_width *

in_channels].
For each patch, right-multiplies the filter matrix and the image patch vector.
In detail,

output[b, i, j, k] =
sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
filter[di, dj, q, k]
Must have strides[0] = strides[3] = 1. For the most common case of the same horizontal and vertices strides, strides = [1, stride, stride, 1].

Args:

input: A Tensor. Must be one of the following types: float32, float64.
filter: A Tensor. Must have the same type as input.
strides: A list of ints. 1-D of length 4. The stride of the sliding window for each dimension of input.
padding: A string from: “SAME”, “VALID”. The type of padding algorithm to use.
use_cudnn_on_gpu: An optional bool. Defaults to True.
name: A name for the operation (optional).
Returns:

A Tensor. Has the same type as input

函数说明解释

给定4维的input tensor和filter tensor,计算二维卷积
input tensor的shape是[batch, in_height, in_width, in_channels]
filter/kernel tensor的shape是[filter_height, filter_width, in_channels, out_channels]

这个op(conv2d)执行了以下操作

1 将filter转为二维矩阵
它的shape是[filter_height * filter_width * in_channels, output_channels].

2 从input tensor中提取image patches,形成一个virtual tensor,
它的shape是[batch, out_height, out_width, filter_height * filter_width * in_channels].

3 filter矩阵和image patch向量相乘

Args:

input: A Tensor. type必须是以下几种类型之一: half, float32, float64.
filter: A Tensor. type和input必须相同
strides: A list of ints.一维,长度4, 每个input维度的滑动窗口的步长。
padding: A string from: “SAME”, “VALID”. 使用padding 算法的类型
use_cudnn_on_gpu: An optional bool. Defaults to True.

name: operation的名字,可选.
Returns:

A Tensor. 返回类型与input相同

摘自书籍《TensorFlow For Machine Intelligence》

import tensorflow as tf


sess = tf.InteractiveSession()
input_batch = tf.constant([
        [  # First Input (6x6x1)
            [[0.0], [1.0], [2.0], [3.0], [4.0], [5.0]],
            [[0.1], [1.1], [2.1], [3.1], [4.1], [5.1]],
            [[0.2], [1.2], [2.2], [3.2], [4.2], [5.2]],
            [[0.3], [1.3], [2.3], [3.3], [4.3], [5.3]],
            [[0.4], [1.4], [2.4], [3.4], [4.4], [5.4]],
            [[0.5], [1.5], [2.5], [3.5], [4.5], [5.5]],
        ],
    ])

kernel = tf.constant([  # Kernel (3x3x1)
        [[[0.0]], [[0.5]], [[0.0]]],
        [[[0.0]], [[1.0]], [[0.0]]],
        [[[0.0]], [[0.5]], [[0.0]]]
    ])

# NOTE: the change in the size of the strides parameter.
conv2d = tf.nn.conv2d(input_batch, kernel, strides=[1, 3, 3, 1], padding='SAME')
print(sess.run(conv2d))

输出结果

[[[[ 2.20000005]
[ 8.19999981]]

[[ 2.79999995]
[ 8.80000019]]]]

TensorFlow - tf.nn.conv2d_第1张图片

input tensor有4维信息:[batch, height, width, channels]

一般要求 strides的参数,strides[0] = strides[3] = 1

strides[0] 控制 batch
strides[1] 控制 height
strides[2] 控制 width
strides[3] 控制 channels

strides[0] = 1,在 batch 维度上的移动 1
strides[3] = 1,在 channels 维度上的移动 1

如果将上述例子更改为 strides=[1, 2, 2, 1]

结果输出
[[[[ 2.20000005]
[ 6.19999981]
[ 10.19999981]]

[[ 2.5999999 ]
[ 6.60000038]
[ 10.60000038]]

[[ 2.20000005]
[ 5.19999981]
[ 8.19999981]]]]

stride 大步,阔步; 步幅; 进展; 一跨(的宽度);

书中(《面向机器智能的tensorflow实践》)将stride 翻译为跨度

以下是书中对stride的解释

在计算机视觉中,卷积的价值体现在对输入(本例中为图像)降维的能力上。一幅2D图像的维数包括其宽度、高度和通道数。如果图像具有较高的维数,则意味着神经网络扫描所有图像以判断各像素的重要性所需的时间呈指数级增长。利用卷积运算对图像降维是通过修改卷积核的strides(跨度)参数实现的。

参数strides使得卷积核可跳过图像中的一些像素,从而在输出中不包含它们。实际上,说这些像素“被跳过”并不十分准确,因为它们仍然会对输出产生影响。

strides参数指定了当图像维数较高,且使用了较为复杂的卷积核时,积核遍历输入时,它利用这个跨度参数来修改遍历输入的方式。strides参数使得卷积核无需遍历输入的每个元素,而是可以直接跳过某些元素。

例如,假设需要计算一幅较大的图像和一个较大的卷积核之间的卷积运算。在这个例子中,图像的高度为6个像素,宽度为6个像素,而深度为1个通道(6×6×1),卷积核尺寸为(3×3×1)。

通过将kernel在input_batch上滑动,同时跨过(或跳过)某些元素,input_batch与kernel便结合在一起。kernel每次移动时,都将input_batch的一个元素作为中心。然后,位置重叠的值相乘,再将这些乘积相加得到卷积的结果。卷积就是通过这种逐点相乘的方式将两个输入整合在一起的。利用下图可更容易地将卷积运算可视化。

上图所体现的是与之前的代码完全但卷积核会跳过输入中的一些固定数目的元素。strides显著降低了输出的维数,而卷积核允许卷积使用所有的输入值。在输入数据中,没有任何元素在被跳过时被移除,但它仍然变成了一个形状更小的张量。

设置跨度是一种调整输入张量维数的方法。降维可减少所需的运算量,并可避免创建一些完全重叠的感受域。strides参数的格式与输入向量相同,即

(image_batch_size_stride、image_height_stride、image_width_stride、image_channels_stride)。第1个和最后一个跨度参数通常很少修改,因为它们会在tf.nn.conv2d运算中跳过一些数据,从而不将这部分数据予以考虑。如果希望降低输入的维数,可修改image_height_stride和image_width_stride参数

在对输入使用跨度参数时,所面临的一个挑战是如何应对那些不是恰好在输入的边界到达尽头的跨度值。非均匀的跨越通常在图像尺寸和卷积核尺寸与跨度参数不匹配时出现。如果图像尺寸、卷积核尺寸和strides参数都无法改变,则可采取对图像填充边界的方法来处理那些非均匀区域。

padding参数
边界填充 padding
当卷积核与图像重叠时,它应当落在图像的边界内。有时,两者尺寸可能不匹配,一种较好的补救策略是对图像缺失的区域进行填充,即边界填充。TensorFlow会用0进行边界填充,或当卷积核与图像尺寸不匹配,但又不允许卷积核跨越图像边界时,会引发一个错误。tf.nn.conv2d的零填充数量或错误状态是由参数padding控制的,它的值可以是SAME或VALID。
·SAME:卷积输出与输入的尺寸相同。这里在计算如何跨越图像时,并不考虑滤波器的尺寸。选用该设置时,缺失的像素将用0填充,卷积核扫过的像素数将超过图像的实际像素数。
·VALID:在计算卷积核如何在图像上跨越时,需要考虑滤波器的尺寸。这会使卷积核尽量不越过图像的边界。在某些情形下,可能边界也会被填充。
在计算卷积时,最好能够考虑图像的尺寸,如果边界填充是必要的,则TensorFlow会有一些内置选项。在大多数比较简单的情形下,SAME都是一个不错的选择。当指定跨度参数后,如果输入和卷积核能够很好地工作,则推荐使用VALID。

你可能感兴趣的:(深度学习)