带有最大池化的卷积神经网络(CNN)

我用Python实现了一个简单的CNN程序,可以在MNIST数据集上进行机器学习。我实现了三层:

  1. ConvPoolLayer,这一层进行卷积操作然后进行平均池化
  2. FullyConnectedLayer,这是一个全连接的隐藏层
  3. SoftmaxLayer,这一层基本上给出网络的softmax输出

我在ConvPoolLayer中实现了平均池化。以下是前向传播过程中进行平均池化的代码行:

# 'activation' 是来自卷积代码的3D激活的numpy数组(此处未显示)     skimage.measure.block_reduce(activation, block_size=(1, 1, 2, 2), func=np.mean) 

以下是相应的反向传播代码:

# delta 是从上层反向传播的3D错误矩阵的numpy数组delta = delta.repeat(2, axis=2).repeat(2, axis=3)

它所做的只是放大错误。

我的问题是,如何实现最大池化的反向传播而不损失性能?或者,有没有更好的方法可以避免函数调用?我在几次迭代后使用平均池化获得了大约90-95%的准确率,所以我想看看最大池化对性能的影响如何。

如果这里有任何NumPy技巧可以应用,我很乐意学习。我想自己理解CNN中发生的事情,为什么事情会这样运作,以及操作是否可以优化,所以使用框架对我来说不是一个选项。

谢谢帮助!


回答:

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

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

  2. 您对平均池化的反向传播并不完全正确。您应该将delta除以池化单元的数量(在您的例子中是4)。参见幻灯片11上的方程 http://www.slideshare.net/kuwajima/cnnbp

  3. 要传播最大池化,您需要将delta分配给前向传递中具有最高值的单元。因此,在池化层的向前传递过程中,通常会跟踪最大激活的索引(有时也称为开关),以便在反向传播期间梯度路由有效。参见 http://cs231n.github.io/convolutional-networks/#pool

实现这种方法的非常低效的方式:

#forwardactivationPrevious = 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)#backwarddelta = delta.repeat(2, axis=2).repeat(2, axis=3)delta = np.multiply(delta, mask)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注