tf.nn.conv2d()对输入张量形状的影响是什么?

时间:2017-09-07 22:14:58

标签: python tensorflow deep-learning tensorboard

我正在研究蒲公英Mane的张量代码:https://github.com/dandelionmane/tf-dev-summit-tensorboard-tutorial/blob/master/mnist.py

他的卷积层具体定义为:

def conv_layer(input, size_in, size_out, name="conv"):
  with tf.name_scope(name):
    w = tf.Variable(tf.truncated_normal([5, 5, size_in, size_out], stddev=0.1), name="W")
    b = tf.Variable(tf.constant(0.1, shape=[size_out]), name="B")
    conv = tf.nn.conv2d(input, w, strides=[1, 1, 1, 1], padding="SAME")
    act = tf.nn.relu(conv + b)
    tf.summary.histogram("weights", w)
    tf.summary.histogram("biases", b)
    tf.summary.histogram("activations", act)
    return tf.nn.max_pool(act, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

我想弄清楚conv2d对输入张量大小的影响是什么。据我所知,前三个维度似乎没有变化,但输出的最后一个维度遵循w的最后一个维度的大小。

例如,?x47x36x64输入变为?x47x36x128,w形= 5x5x64x128

我也看到:?x24x18x128变为?x24x18x256,w形= 5x5x128x256

那么,输入的结果大小是:[a,b,c,d] [a,b,c,w.shape[3]]的输出大小?

认为第一个维度不会改变是否正确?

1 个答案:

答案 0 :(得分:1)

这适用于你的情况,因为使用了步幅和应用了填充。输出宽度和高度并不总是与输入相同。

查看主题的this excellent discussion。基本内容(从该链接几乎逐字逐句)是卷积层:

  • 接受大小为W1 x H1 x D1
  • 的输入音量
  • 需要四个超参数:
    • 过滤器数量K
    • 过滤器的空间范围F
    • 过滤器移动的步幅S
    • 零填充量P
  • 生成大小为W2 x H2 x D2的卷,其中:
    • W2 = (W1 - F + 2*P)/S + 1
    • H2 = (H1 - F + 2*P)/S + 1
    • D2 = K

当您在Tensorflow中处理批量数据时,它们通常具有形状[batch_size, width, height, depth],因此第一个维度(即批次中的样本数量)不应更改。

请注意,上面的填充量P对于TF来说有点棘手。当您将padding='same'参数提供给tf.nn.conv2d时,张量流将零填充应用于图像的两侧,以确保过滤器不会忽略图像的像素,但可能不会添加相同的数量填充到两边(我认为只有一个不同)。 This SO thread对该主题进行了一些很好的讨论。

一般情况下,如果步幅S为1(您的网络有),P = (F - 1) / 2的零填充将确保输出宽度/高度等于输入,即W2 = W1H2 = H1。在您的情况下,F为5,因此tf.nn.conv2d必须为图像的每一侧添加两个零,P为2,并且根据上面的等式输出宽度为{ {1}}。

相关问题