TensorFlow ConvNet 中的全连接层权重维度
Fully-connected layer weight dimensions in TensorFlow ConvNet
我一直在使用 TensorFlow 编写卷积网络的 this example,我对这种权重分配感到困惑:
weights = {
# 5x5 conv, 1 input, 32 outputs
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 5x5 conv, 32 inputs, 64 outputs
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# fully connected, 7*7*64 inputs, 1024 outputs
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 1024 inputs, 10 outputs (class prediction)
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
我们怎么知道 'wd1' 权重矩阵应该有 7 x 7 x 64 行?
稍后用于重塑第二个卷积层的输出:
# Fully connected layer
# Reshape conv2 output to fit dense layer input
dense1 = tf.reshape(conv2, [-1, _weights['wd1'].get_shape().as_list()[0]])
# Relu activation
dense1 = tf.nn.relu(tf.add(tf.matmul(dense1, _weights['wd1']), _biases['bd1']))
根据我的数学计算,池化层 2(conv2 输出)有 4 x 4 x 64 个神经元。
为什么我们要整形为 [-1, 7*7*64]?
从头开始工作:
输入 _X
的大小为 [28x28x1]
(忽略批次维度)。 28x28 灰度图像。
第一个卷积层使用PADDING=same
,所以它输出一个28x28的层,然后传递给一个max_pool
和k=2
,每个维度减少两倍, 从而产生 14x14 的空间布局。 conv1 有 32 个输出——所以完整的 per-example 张量现在是 [14x14x32]
.
这在 conv2
中重复,它有 64 个输出,导致 [7x7x64]
。
tl;dr:图像以 28x28 开始,每个 maxpool 在每个维度上将其缩小两倍。 28/2/2 = 7.
这道题要求你对深度学习卷积有很好的理解。
基本上,您的模型具有的每个卷积层都会减少卷积金字塔的横向面积。这种减少是由 卷积步长 和 max_pooling 步长 完成的。使事情复杂化的是,我们有两个基于 PADDING 的选项。
选项 1 - PADDING='SAME'
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
选项 2 - PADDING='VALID'
out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
对于 EACH 卷积和最大池调用,您将必须计算新的 out_height
和 out_width
。然后,在卷积的最后,将 out_height
、out_width
和最后一个卷积层的 depth 相乘。此乘法的结果是输出特征图大小,它是第一个全连接层的输入。
因此,在您的示例中,您可能只有 PADDING='SAME'
,卷积步幅为 1,最大池化步幅为 2,两次。最后,您只需将所有内容除以 4 (1,2,1,2)。
更多信息请访问 tensorflow API
我一直在使用 TensorFlow 编写卷积网络的 this example,我对这种权重分配感到困惑:
weights = {
# 5x5 conv, 1 input, 32 outputs
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 5x5 conv, 32 inputs, 64 outputs
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# fully connected, 7*7*64 inputs, 1024 outputs
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 1024 inputs, 10 outputs (class prediction)
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
我们怎么知道 'wd1' 权重矩阵应该有 7 x 7 x 64 行?
稍后用于重塑第二个卷积层的输出:
# Fully connected layer
# Reshape conv2 output to fit dense layer input
dense1 = tf.reshape(conv2, [-1, _weights['wd1'].get_shape().as_list()[0]])
# Relu activation
dense1 = tf.nn.relu(tf.add(tf.matmul(dense1, _weights['wd1']), _biases['bd1']))
根据我的数学计算,池化层 2(conv2 输出)有 4 x 4 x 64 个神经元。
为什么我们要整形为 [-1, 7*7*64]?
从头开始工作:
输入 _X
的大小为 [28x28x1]
(忽略批次维度)。 28x28 灰度图像。
第一个卷积层使用PADDING=same
,所以它输出一个28x28的层,然后传递给一个max_pool
和k=2
,每个维度减少两倍, 从而产生 14x14 的空间布局。 conv1 有 32 个输出——所以完整的 per-example 张量现在是 [14x14x32]
.
这在 conv2
中重复,它有 64 个输出,导致 [7x7x64]
。
tl;dr:图像以 28x28 开始,每个 maxpool 在每个维度上将其缩小两倍。 28/2/2 = 7.
这道题要求你对深度学习卷积有很好的理解。
基本上,您的模型具有的每个卷积层都会减少卷积金字塔的横向面积。这种减少是由 卷积步长 和 max_pooling 步长 完成的。使事情复杂化的是,我们有两个基于 PADDING 的选项。
选项 1 - PADDING='SAME'
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
选项 2 - PADDING='VALID'
out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
对于 EACH 卷积和最大池调用,您将必须计算新的 out_height
和 out_width
。然后,在卷积的最后,将 out_height
、out_width
和最后一个卷积层的 depth 相乘。此乘法的结果是输出特征图大小,它是第一个全连接层的输入。
因此,在您的示例中,您可能只有 PADDING='SAME'
,卷积步幅为 1,最大池化步幅为 2,两次。最后,您只需将所有内容除以 4 (1,2,1,2)。
更多信息请访问 tensorflow API