为什么CNN比Keras中完全连接的MLP要慢?

时间:2017-03-30 14:37:01

标签: neural-network theano keras conv-neural-network

我查看了以下来自Keras的例子:

MNIST的MLP:https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py

MNN的CNN:https://github.com/fchollet/keras/blob/master/examples/mnist_cnn.py

我在Theano上运行CPU。在MLP中,我的平均时间大约<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

然而,这里的平均时间约为每个时期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

现在时间 28 s / epoch ,即使有大约6000个参数!!

这是为什么?直观地,优化应该仅取决于变量的数量和梯度的计算(由于相同的批量大小应该相似)。

对此有所了解? 谢谢

2 个答案:

答案 0 :(得分:2)

我假设所有卷积运算的内核大小为(3x3),并且输入2D数组通道大小为3。

对于conv2d_36,您将拥有:

  • 3 * 32 =所有通道的操作次数
  • 26 * 26 =每个通道的卷积运算次数
  • 3 * 3 =每个卷积的乘法次数

因此,排除所有求和(bias + conv internal),

  • 对于conv2d_36,您将进行3 * 32 * 26 * 26 * 3 * 3 =~ 585k个乘法运算
  • 对于conv2d_37,类似的32 * 64 * 24 * 24 * 3 * 3 =~ 10.6M乘法运算
  • 对于dense_40,因为没有卷积,所以它等于9216 * 10 = 92k乘法运算。

当我们将它们全部总结时,对于使用CNN的第二个模型,有~11.3M个单乘法运算。

另一方面,如果我们将其展平并应用MLP,

  • 对于dense_33层,将进行28 * 28 * 3 * 512 = 1.2M个乘法运算
  • 对于dense_34层,将进行512 * 512 = 262k个乘法运算
  • 对于dense_35层,将进行512 * 10 = 5k个乘法运算

当我们总结所有这些时,对于带有MLP的第一个模型,有~1.5M个单乘法运算。

因此,仅CNN模型的乘法是MLP模型的7.5倍左右。考虑到各层之间的开销,其他操作成本(例如求和和内存复制/访问操作)似乎完全合理,因为CNN模型要像您提到的那样慢。

答案 1 :(得分:0)

卷积操作比密集层复杂得多。 卷积是将图像的每个元素添加到其本地邻居的过程,由内核加权。 每个卷积本质上都是一个多重嵌套循环。这意味着密集层需要相对于卷积层的一小部分时间。 Wikipedia有一个启发卷积操作的启发性例子。