kaggle-浮游生物分类比赛一等奖---译文(第二部分)

接着上一篇的内容

Training

1)validation

我们使用分层抽样(stratified sampling)的方法,将已标注的数据集分出10%作为验证集(validation)。由于数据集过小,我们在验证集上的评估受到噪声的影响比较大,因此,我们也在排行榜上的其他模型上测试了我们的验证集。

2)training algorithm

所有的模型都是在加了Nesterov momentum的SGD优化算法上进行的。我们将momentum的系数设置为0.9。大多数模型需要24-48小时收敛。

对于大多数模型,我们通过215000步梯度下降可以学习。最终的学习率采用类似于 Krizhevsky et al的策略通过两次1/10的缩小进行调节,调节的步骤分别在第180000 和 205000步。我们一般使用0.003作为学习率的初始值。

同时我们也测试了Adam(使用的是第一个版本)作为Nesterov momentum的替代。结果:Adam能够加速两倍的收敛,但是最后的performance(相较于Nesterov momentum)会降低。所以我们放弃了Adam。

3)initialization

我们使用了Exact solutions to the nonlinear dynamics of learning in deep linear neural networks中提出的正交初始化策略(orthogonal initialization strategy)的一个变种。这使得我们可以根据我们的需要去增加网络的深度,而不会在收敛时遇到问题。

4)regularization

对于大多数模型,我们在全连接层使用dropout,dropout的概率设置为0.5。我们也在一些模型中在Convolution layers进行了dropout操作。

我们也尝试过Gaussian dropout(用multiplicative高斯噪声代替multiplicative伯努利噪声),但是发现performance和传统的dropout差不多。

在比赛快结束的时候,我们发现进行少量的weight decay对稳定大网络的训练过程有很大的帮忙(不仅仅是有regularizing作用)。对于包含大的全连接层的网络,如果不加weight decay的话,模型在训量的时候很容易发散。虽然可以通过适当的减小学习率来克服这一问题,但这无疑会降低训练速度。

Unsupervised and semi-supervised approaches

1)Unsupervised pre-training

由于test数据集很大,所以我们利用test数据集作为无监督学习的训练集来预训练网络。我们用CAE来预训练网络的Convolution layers。

与文献的表述一致,我们发现预训练网络可以作为一个很好地regularizer(增大train loss,但是提高validation score)。但是测试时将validation集进行augmentation时,得到得结果却不尽人意,下面会更进一步的讨论。

预训练使得我们可以进一步的扩充我们的模型,但是由于预训练网络耗费的时间不止一点半点,所以在最终使用的模型中,我们没有使用预训练。

在实验预训练的过程中,为了学习到好的特征表示,我们更倾向于max-pooling以及unpooling layers来获取特征的稀疏化表示。我们没有尝试denoising autoencoder的原因主要有两个:首先,根据Masci的实验结果,max-pooling 和 unpooling方法提供了很好的filters,获得了比denoising autoencoder更好的performance,并且以后将这两个layers进行组合是很容易的;其次,参考denoising autoencoder网络的结构,速度会减慢很多。

以下是几种不同的开始预训练网络时的策略:

  • 逐层贪心训练(greedy layerwise training) vs. 将deConvolutions连起来一起训练(training the full deconvolutional stack jointly,类似于end-to-end):我们发现jointly的方式能够获得更好的performance,但有时候需要先进行逐层贪心训练来初始化网络后,jointly方式才会起作用。
  • 使用tied weights(using tied weights) vs. 不使用tied weights(using untied weights):将Convolution和deConvolution中的weights设置为互为转置矩阵能够使得Autoencoder训练的更快。因此,我们只试验了tied weights。

我们在进行微调时也试验了一些不同的策略,我们发现如果保持相同的监督学习设置,随机初始化权重以及经过预训练初始化的网络在监督学习的performance上没有多大的差别。可能的原因是:在初始化dense layer的时候,可能dense layer的weights已经在一个合理的范围,使得在预训练阶段,Convolution layer会遗漏很多信息(feature)。

我们发现了两种方法来克服这个问题:

  • 暂时保持预训练层一段时间不变,仅仅训练dense layer(随机初始化)。如果只训练顶上几层网络,在反向传播的时候会非常快。
  • 在Convolution layer部分将学习率减半。使随机初始化的dense layer更快的适应预训练后的Convolution layer。在dense layer获得比较好的weights range之前,Convolution layer进行监督学习的时候weights不会有大的变化。

这两种方法得到的performance相差不大。

3)Pseudo-labeling

另一种从测试集获取数据信息的方式就是将pseudo-labeling 和 knowledge distillation进行组合(Distilling the Knowledge in a Neural Network)。模型在采用Pseudo-labeling方法训练时得到的performance超出了我们的预期,所以我们详细的研究了一下这个方法。

Pseudo-labeling的做法是将test数据集加入到train数据集以得到一个更大的数据集。而原来test数据集对应的标签(即Pseudo-labeling),就是基于之前训练集训练好的模型进行预测得到的。这样做可以让我们去训练一个更大的网络,因为Pseudo-labeling有regularizing的作用。

我们试验了硬指标 (one-hot coded)和软指标(predicted probabilities)两种方式。但很快就决定采用软指标,因为它得到的performance要更好。

另一个重要的细节就是权衡原始train数据集和test数据集(也就是Pseudo-labeled data)在最终数据集中的比重。我们大多是时候采用的方法是:在一个mini-batch中Pseudo-labeled data占33%,原始的train数据集占67%。

也可以让Pseudo-labeled data占67%,这样模型的regularizing的程度会更大,我们甚至必须削弱dropout或者剔除,不然会造成underfitting。

我们的方法和knowledge distillation不同的地方是,我们使用test set而非train set来迁移特征信息。另一个不同的地方则是knowledge distillation可以让更小的,更快的模型获得和大模型一样的performance,而Pseudo-labeling则可以让我们建造更大的网络来获取更好的performance。

我们认为pseudo-labeling能提高performance的原因是获得的更大的数据集(train+test set)以及data augmentation和test-time augmentation(接下来会讨论)。将pseudo-labeling data加入到train data中时,可以说其包含了所有数据的特性(test+train),所以在训练的时候能够更好获取数据信息,得到更好的performance。

Pseudo-labeling获得最大的performance的提升是在最开始的时候(提升了0.015)。在后面,我们试验的bags模型才得到0.003-0.009的提升。

本篇译文系作者原创,转载请先联系作者: 18254275587@163.com