353. Kannada MNIST | Kannada-MNIST
首先,我要感谢 Kaggle 的比赛组织者 @inversion 以及创建 Kannada-MNIST 数据集的 @higgstachyon。这是一个非常有趣的挑战。
起初,我预计只是短暂参与,并实现我在 18 个月前为原始 MNIST 比赛构建的 CNN。然而,一旦我投入到这场比赛中,我发现了一个有趣的现象:公共排行榜的准确率远低于我的验证准确率,也远低于其他比赛。我在这里和这里发了几个帖子讨论这个问题。我是在结果公布前的最后几个小时写下这段文字的。这意味着我仍然不确定什么是最好的方法。我尝试了交叉验证,正如我分享的内核(例如这里)所做的那样。我还使用 Dig-MNIST 数据集进行验证,并尝试通过混合交叉验证的验证分数和 Dig-MNIST 样本外验证集的验证分数来获得验证分数。我没有使用 Dig-MNIST 数据进行训练,因为其他人报告说这并不能提高准确性。而且,我想把它作为一个留出集。使用交叉验证,我的公共分数达到了 0.9906,但无法超越这个分数。然后我开始尝试训练测试分割验证,并让单个模型在公共排行榜上达到 0.991,但我无法重现这个结果。
之后,我开始在 Keras 中使用 .h5 格式保存模型权重。最终,我能够通过保存的权重将单个模型的分数提高到 0.9908,但即使使用集成方法,我也无法超过 0.9910。最后几天,帮助我在公共排行榜上前进的是,得益于 @nandor65 在这个帖子中的一些非常有帮助的评论,我尝试了伪标记。基于 0.9908 模型的输出,我能够将单模型分数提高到 0.9916。然而,我不确定这有多可靠,因为使用相同设置运行基础模型大多数时候导致的分数在 0.9884 - 0.9898 左右。我认为伪标记是一种改进,但不确定改进了多少,如果存在对公共排行榜的过拟合,我怀疑伪标记会使情况变得更糟。我很晚才发现这个想法,而且我正在以退火学习率训练模型数百个 epoch。这意味着我决定没有时间重复整个交叉验证。
我还决定为我的两次比赛提交采取两种截然不同的方法。一种方法是使用完全交叉验证并集成几个 10 折交叉验证模型。另一种方法是使用多个模型的集成。这没有交叉验证,也没有来自训练数据的约定验证集。相反,我使用公共分数和留出集进行验证。我不建议在现实生活中使用这种方法。从 Kaggle 的角度来看,我非常接近排行榜的顶端,所以我试图调整一些东西,看看能不能让排名更高。通常建议使用最高的交叉验证分数和最高的公共分数作为比赛参赛作品,这也是我最终所做的。在最后几天,伪标记带我达到了 0.9924,并在公共排行榜上排名第 4。有趣的是,在这个过程结束时,我在 0.9924 公共分数上的留出验证分数 0.9282 略高于我在公共排行榜上得分为 0.9906 的交叉验证方法获得的 0.9272 留出分数。
我尝试调整了很多东西,比如批量大小、epoch 数量、起始学习率、模型架构,我尝试添加 conv1d 层。我尝试了去噪自动编码器,但结果并不好。我还尝试了对概率输出进行 KNN 和 SVC 堆叠。我也尝试将 PCA 输出添加到其中。使用 PCA 结果很糟糕,但不使用 PCA 的结果与未堆叠的结果大致相同,偶尔在留出集上略高。偶尔混合中的负权重会使留出分数更好,但过去我对负权重并不成功,所以我没有在最终参赛作品中追求它。我还在最后几个小时尝试实现 swish 激活,但我找到的版本似乎是为 tensorflow v1.x 准备的,我无法在 2.0 中使其工作。我不想在最后几个小时浪费在那上面,也许是我遗漏了一些简单的东西,我计划将来再回到这个问题。
我预计安全的 0.9906 分数在排名波动中不会受到太大影响(如果有的话),并希望它能进入前 30 名(在公共分数上大约是第 30 名)。我也希望不会有太大的波动,我排名第 4 的最佳公共分数能保持 +/- 1 的私人排行榜位置。
在最后几个小时,我突然想到尝试 mixup,这是一种混合图像的方法。我在这里找到了实现它的