我试图了解tf.nn.avg_pool,tf.nn.max_pool,tf.nn.conv2d中的 strides 参数。
步幅:长度> gt的整数列表.4。输入张量的每个维度的滑动窗口的步幅。
我的问题是:
tf.reshape(_X,shape=[-1, 28, 28, 1])
。为什么-1?遗憾的是,使用-1重塑文档的示例并没有很好地转化为这种情况。
答案 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)
让我们假设您的input = [1, 0, 2, 3, 0, 1, 1]
和kernel = [2, 1, 3]
卷积的结果为[8, 11, 7, 9, 4]
,这是通过在输入上滑动内核,执行逐元素乘法和总结一切。 Like this:
这里我们按一个元素滑动,但没有什么能阻止你使用任何其他数字。这个数字是你的步伐。您可以将其视为通过仅获取每个第s个结果来对1-strided卷积的结果进行下采样。</ p>
知道输入大小 i ,内核大小 k ,跨步 s 和填充 p 您可以轻松计算卷积的输出大小为:
这里||操作员指天花板操作。对于池化层s = 1。
知道1-dim情况的数学,一旦你看到每个昏暗是独立的,n-dim情况就很容易了。因此,您只需单独滑动每个维度。这是一个example for 2-d。请注意,您不需要在所有维度上具有相同的步幅。因此,对于N-dim输入/内核,您应该提供N步。
如果形状的一个组件是特殊值-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。
我希望有人觉得这有帮助!