我正在研究蒲公英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]]
的输出大小?
认为第一个维度不会改变是否正确?
答案 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 = W1
和H2 = H1
。在您的情况下,F
为5,因此tf.nn.conv2d
必须为图像的每一侧添加两个零,P
为2,并且根据上面的等式输出宽度为{ {1}}。