Tensorflow Strides Argument

时间:2016-01-06 20:56:26

标签: python neural-network convolution tensorflow conv-neural-network

我试图了解tf.nn.avg_pool,tf.nn.max_pool,tf.nn.conv2d中的 strides 参数。

documentation反复说

  

步幅:长度> gt的整数列表.4。输入张量的每个维度的滑动窗口的步幅。

我的问题是:

  1. 4+整数中的每一个代表什么?
  2. 为什么他们必须有步幅[0] = strides [3] = 1 for convnet?
  3. this example中,我们看到tf.reshape(_X,shape=[-1, 28, 28, 1])。为什么-1?
  4. 遗憾的是,使用-1重塑文档的示例并没有很好地转化为这种情况。

4 个答案:

答案 0 :(得分:217)

汇集和卷积操作在输入张量上滑动“窗口”。以tf.nn.conv2d为例:如果输入张量有4个维度:[batch, height, width, channels],则卷积在height, width维上的2D窗口上运行。

strides确定窗口在每个维度中的移动量。典型用法将第一个(批次)和最后一个(深度)步幅设置为1.

让我们使用一个非常具体的例子:在32x32灰度输入图像上运行2-d卷积。我说灰度,因为输入图像的深度= 1,这有助于保持简单。让图像看起来像这样:

00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...

让我们在一个示例(批量大小= 1)上运行2x2卷积窗口。我们将给卷积一个输出通道深度为8。

卷积的输入为shape=[1, 32, 32, 1]

如果您使用strides=[1,1,1,1]指定padding=SAME,则过滤器的输出将为[1,32,32,8]。

过滤器将首先为:

创建输出
F(00 01
  10 11)

然后是:

F(01 02
  11 12)

等等。然后它将移动到第二行,计算:

F(10, 11
  20, 21)

然后

F(11, 12
  21, 22)

如果指定[1,2,2,1]的步幅,则不会重叠窗口。它将计算:

F(00, 01
  10, 11)

然后

F(02, 03
  12, 13)

对于汇集运算符,步幅操作类似。

问题2:为什么对战斗机大步[1,x,y,1]

第一个是批处理:您通常不想跳过批处理中的示例,或者您不应该首先包含它们。 :)

最后1是卷积的深度:出于同样的原因,你通常不想跳过输入。

conv2d运算符更通用,因此可以创建将窗口沿其他维度滑动的卷积,但这不是convnet中的典型用法。典型的用途是在空间上使用它们。

为什么重塑为-1 -1是一个占位符,表示“根据需要调整以匹配完整张量所需的大小”。这是一种使代码与输入批量大小无关的方法,因此您可以更改管道,而无需在代码中的任何位置调整批处理大小。

答案 1 :(得分:16)

输入为4维,形式为:[batch_size, image_rows, image_cols, number_of_colors]

通常,Strides定义应用操作之间的重叠。在conv2d的情况下,它指定卷积滤波器的连续应用之间的距离。特定维度中的值1意味着我们在每一行/列应用运算符,值2表示每秒,依此类推。

Re 1)对于卷积而言重要的值是第2和第3,它们表示卷积滤波器沿行和列应用的重叠。 [1,2,2,1]的值表示我们希望在每隔一行和每列上应用过滤器。

重新2)我不知道技术限制(可能是CuDNN要求),但通常人们会沿着行或列维度使用步幅。在批量大小上进行操作并不一定有意义。不确定 最后一个维度。

重新3)为其中一个维度设置-1表示"设置第一个维度的值,以使张量中的元素总数保持不变"。在我们的例子中,-1将等于batch_size。

答案 2 :(得分:10)

让我们从1-dim案例中的步幅开始。

让我们假设您的input = [1, 0, 2, 3, 0, 1, 1]kernel = [2, 1, 3]卷积的结果为[8, 11, 7, 9, 4],这是通过在输入上滑动内核,执行逐元素乘法和总结一切。 Like this

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

这里我们按一个元素滑动,但没有什么能阻止你使用任何其他数字。这个数字是你的步伐。您可以将其视为通过仅获取每个第s个结果来对1-strided卷积的结果进行下采样。<​​/ p>

知道输入大小 i ,内核大小 k ,跨步 s 和填充 p 您可以轻松计算卷积的输出大小为:

enter image description here

这里||操作员指天花板操作。对于池化层s = 1。

N-dim case。

知道1-dim情况的数学,一旦你看到每个昏暗是独立的,n-dim情况就很容易了。因此,您只需单独滑动每个维度。这是一个example for 2-d。请注意,您不需要在所有维度上具有相同的步幅。因此,对于N-dim输入/内核,您应该提供N步。

所以现在很容易回答你的所有问题:

  1. 4+整数中的每一个代表什么?conv2dpool告诉您此列表代表每个维度之间的步幅。请注意,步幅列表的长度与内核张量的等级相同。
  2. 为什么他们必须有步幅[0] =步幅为3 = 1?。第一个维度是批量大小,最后一个维度是通道。没有必要跳过批次或渠道。所以你制作它们1.对于宽度/高度,你可以跳过一些东西,这就是它们可能不是1的原因。
  3. tf.reshape(_X,shape = [ - 1,28,28,1])。为什么-1? tf.reshape为您报道:
      

    如果形状的一个组件是特殊值-1,则计算该维度的大小,以使总大小保持不变。特别地,[-1]的形状变平为1-D。最多一个形状组件可以是-1。

答案 3 :(得分:2)

@dga在解释方面做得非常出色,我对此非常感激。以类似的方式,我想分享一下stride在3D卷积中的工作原理。

根据conv3d上的TensorFlow documentation,输入的形状必须按以下顺序:

[batch, in_depth, in_height, in_width, in_channels]

让我们使用一个示例从最右到左解释变量。假设输入形状为 input_shape = [1000,16,112,112,3]

input_shape[4] is the number of colour channels (RGB or whichever format it is extracted in)
input_shape[3] is the width of the image
input_shape[2] is the height of the image
input_shape[1] is the number of frames that have been lumped into 1 complete data
input_shape[0] is the number of lumped frames of images we have.

下面是有关如何使用步幅的摘要文档。

  

strides:长度大于等于5的整数的列表。长度为5的1-D张量。   每个输入维度的滑动窗口的步幅。必须   有strides[0] = strides[4] = 1

正如许多著作中所指出的那样,步幅仅表示窗口或内核距离最近的元素(无论是数据帧还是像素)有几步(这是措辞的解释)。

从上述文档中,3D跨度将如下所示=(1, X Y Z ,1) 。

文档强调了strides[0] = strides[4] = 1

strides[0]=1 means that we do not want to skip any data in the batch 
strides[4]=1 means that we do not want to skip in the channel 

strides [X]表示我们应在集总帧中进行多少次跳过。因此,例如,如果我们有16帧,则X = 1表示使用每帧。 X = 2表示每隔一帧使用一次,然后继续

步幅[y]和步幅[z]按照@dga的解释,所以我不会重做该部分。

但是,在keras中,您只需要指定3个整数的元组/列表,即可指定沿每个空间维度的卷积步幅,其中空间维度为stride [x],strides [y]和strides [z]。 strides [0]和strides [4]已经默认为1。

我希望有人觉得这有帮助!