【发布时间】:2017-08-24 13:27:48
【问题描述】:
我查看了来自 Keras 的以下示例:
MNIST 中的 MLP:https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py
MNIST 中的 CNN:https://github.com/fchollet/keras/blob/master/examples/mnist_cnn.py
我都在 CPU 上的 Theano 中运行。在 MLP 中,我的平均时间约为 每个 epoch 16 秒,总共有 669,706 个参数:
Layer (type) Output Shape Param #
=================================================================
dense_33 (Dense) (None, 512) 401920
_________________________________________________________________
dropout_16 (Dropout) (None, 512) 0
_________________________________________________________________
dense_34 (Dense) (None, 512) 262656
_________________________________________________________________
dropout_17 (Dropout) (None, 512) 0
_________________________________________________________________
dense_35 (Dense) (None, 10) 5130
=================================================================
Total params: 669,706.0
Trainable params: 669,706.0
Non-trainable params: 0.0
在 CNN 中,我从原始代码中消除了最后一个隐藏层。我还将优化器更改为 rmsprop 以使两种情况具有可比性,留下以下架构:
Layer (type) Output Shape Param #
=================================================================
conv2d_36 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
conv2d_37 (Conv2D) (None, 24, 24, 64) 18496
_________________________________________________________________
max_pooling2d_17 (MaxPooling (None, 12, 12, 64) 0
_________________________________________________________________
dropout_22 (Dropout) (None, 12, 12, 64) 0
_________________________________________________________________
flatten_17 (Flatten) (None, 9216) 0
_________________________________________________________________
dense_40 (Dense) (None, 10) 92170
=================================================================
Total params: 110,986.0
Trainable params: 110,986.0
Non-trainable params: 0.0
然而,这里的平均时间大约是 每个 epoch 340 秒! 尽管参数少了六倍!
为了对此进行更多检查,我将每层的过滤器数量减少到 4 个,留下以下架构:
Layer (type) Output Shape Param #
=================================================================
conv2d_38 (Conv2D) (None, 26, 26, 4) 40
_________________________________________________________________
conv2d_39 (Conv2D) (None, 24, 24, 4) 148
_________________________________________________________________
max_pooling2d_18 (MaxPooling (None, 12, 12, 4) 0
_________________________________________________________________
dropout_23 (Dropout) (None, 12, 12, 4) 0
_________________________________________________________________
flatten_18 (Flatten) (None, 576) 0
_________________________________________________________________
dense_41 (Dense) (None, 10) 5770
=================================================================
Total params: 5,958.0
Trainable params: 5,958.0
Non-trainable params: 0.0
现在时间是 每个 epoch 28 秒,尽管大约有 6000 个参数!!
这是为什么?直观地说,优化应该只取决于变量的数量和梯度的计算(由于相同的批量大小应该是相似的)。
对此有所了解? 谢谢
【问题讨论】:
-
你的直觉是错误的。查看您必须进行的计算次数。在密集层中,每个变量在一次乘法中使用一次(此处仅考虑前向传递),它将权重与输入相乘,仅此而已。另一方面,使用卷积,您的内核乘以输出值的次数,这意味着对于您的第一层,一个内核乘以 26*26 次,并且您有 32 个(如果每个都有 10 个变量)我没看错)。所以这里需要的计算能力不等于变量的个数。
-
谢谢@nassim,我明白了。然而,按照最后一个网络中的逻辑,前两个卷积层将执行 26*26*4+26*26*4=5408 次计算,将其添加到密集层计算中会产生大约 12000 次计算。这个数字甚至比不上第一个网络的 670000 次计算,那么为什么每个 epoch 的最后一个网络时间与第一个网络如此相似呢?
-
1) 您忘记了内核乘法不仅是“一次计算”,它还是元素矩阵乘法。因此,如果您的内核中有 10 个元素 --> 26*26*4*10。 2)我不是该领域的专家,但我认为做所有这些内核乘法比一个大矩阵乘法更昂贵...... idk它是如何在内部发生的,但我看到更多的I / O活动发生在你的计算上单元。 Dense真的很高效,在gpu/cpu上加载两个矩阵,计算,就是这样。
-
@nassim 你说得对,我忘记了内核的大小。然而,这提供了 60000 次计算,比 MLP 网络少 10 倍以上。我猜它是作为具有共享权重的稀疏矩阵实现的,因此能够像在 MLP 中一样加载到 gpu 中以进行前向传递。毕竟 CNN 的特点是稀疏连接和共享权重,除了避免过度拟合之外,这不正是为了让相同数量的神经元的训练更有效率吗?
标签: neural-network theano keras conv-neural-network