具有最大合并的卷积神经网络(CNN)

时间:2016-06-28 07:19:08

标签: python algorithm performance optimization machine-learning

我已经用Python实现了一个简单的CNN程序,可以通过机器学习MNIST数据集。我实施了3层:

  1. ConvPoolLayer,它会卷入然后意味着汇集
  2. FullyConnectedLayer,这是一个完全连接的隐藏层
  3. SoftmaxLayer,它基本上给出了网络的softmax输出
  4. 我在ConvPoolLayer中实现了平均池化。这是在前向传播期间意味着汇集的代码行:

    # 'activation' is a numpy array of 3D activations from the convolutional code (not shown here)     
    skimage.measure.block_reduce(activation, block_size=(1, 1, 2, 2), func=np.mean) 
    

    这里是等效的反向传播代码:

    # delta is a numpy array of 3D error matrices back-propagated from the upper layers
    delta = delta.repeat(2, axis=2).repeat(2, axis=3)
    

    它所做的只是提升错误。

    我的问题是,如何在不损失性能的情况下实现最大池化的反向传播?或者,没有函数调用有更好的方法吗?在使用平均池进行几次迭代后,我得到了约90-95%的准确度,因此我想看看最大池对性能的影响。

    如果有任何可以在这里应用的NumPy技巧,我很乐意学习它们。我想了解自己在CNN中发生了什么,为什么事情按照他们的方式工作,以及操作是否可以优化,所以使用框架对我来说不是一个选择。

    感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

  1. [updated]对于最大池使用的前向传播:

    skimage.measure.block_reduce(activation, block_size=(1, 1, 2, 2), func=np.max)

  2. 您对平均合并的反向传播并不完全正确。您应该根据合并单元格的数量来划分delta(在您的情况下为4)。请参阅http://www.slideshare.net/kuwajima/cnnbp

  3. 上幻灯片11中的等式
  4. 要传播最大池,您只需将delta指定给前向传递中具有最高值的单元格。因此,在汇集层的正向通过期间,通常跟踪最大激活的索引(有时也称为开关),使得梯度路由在反向传播期间是有效的。请参阅http://cs231n.github.io/convolutional-networks/#pool

  5. 实现此目的的效率非常低:

    #forward
    activationPrevious = np.copy(activation)
    skimage.measure.block_reduce(activation, block_size=(1, 1, 2, 2), func=np.max)
    maxs = activations.repeat(2, axis=2).repeat(2, axis=3)
    mask = np.equal(activationPrevious, maxs).astype(int)
    
    #backward
    delta = delta.repeat(2, axis=2).repeat(2, axis=3)
    delta = np.multiply(delta, mask)