Kaggle首战斩获第三,看深度学习菜鸟团队如何一鸣惊人
Women in Data Science 与合作伙伴共同发起了 WiDS 数据马拉松竞赛(WiDS datathon)。赛题是创建一个能够预测卫星图像上油棕种植园存在情况的模型。
Planet 和 Figure Eight 慷慨地提供了卫星图像的带注释数据集,而该卫星图像是最近由 Planet 卫星拍摄的。该数据集图像具有 3 米的空间分辨率,并且每一副图像都基于是否含油棕种植园来标记(0 意为没有油棕种植园,1 意为存在一个油棕种植园)。
竞赛任务是训练一个模型,该模型能够输入卫星图像,输出包含油棕种植园图像的似然预测。在模型开发中,竞赛举办者提供带标签的训练和测试数据集。
详细信息参见:https://www.kaggle.com/c/widsdatathon2019
我和队友(Abdishakur、Halimah 和 Ifeoma Okoh)使用 fast.ai 框架来迎接这项赛题。非常感谢 Thomas Capelle 在 kaggle 上的启动内核,该内核为解决这个问题提供了诸多见解。
此外,还要感谢 fast.ai 团队,该团队创建了一门不可思议的深度学习课程,该课程简化了大量困难的深度学习概念。现在,深度学习初学者也可以赢得 kaggle 竞赛了。
课程地址:https://course.fast.ai/
从一个通俗易懂的深度学习指南开始
不要想着马上就能理解所有东西,这需要大量的练习。本指南旨在向深度学习初学者展示 fast.ai 的魅力。假定你了解一些 python 知识,也对机器学习稍有涉猎。这样的话,我们就走上了学习正轨。
(引用)本文展示的所有代码可在 Google Colaboratory 中找到:这是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行。你可以通过 Colaboratory 编写和执行代码,保存和分享分析,访问大量的计算资源,所有这些都是免费的。
代码参见:https://colab.research.google.com/drive/1PVaRPY1XZuPLtm01V2XxIWqhLrz3_rgX。
导入 fast.ai 和我们将要使用的其他库
输入库
获取竞赛数据
为了尽可能简洁明了,Abdishakur 上传竞赛数据文件至 dropbox.com。你可以在竞赛页面上找到这些数据。你需要接受竞赛规则,并在参赛后访问数据。
观察数据
我们在解决一个问题时首先要做的是观察可用数据。在想出解决方案之前,我们需要理解这个问题以及数据是什么样的。观察数据意味着理解数据目录的构成方式、数据标签以及样本图像是什么样的。
使用 pandas 库来读取数据。
训练模型所要使用的数据标签。
处理「图像分类数据集」和「表格数据集」的主要区别在于标签的存储方式。这里的标签指的是图像中的内容。在这个特定的数据集中,标签以 CSV 文件格式存储。
想要了解更多计算「分数」列的方法,点击:
https://success.figure-eight.com/hc/en-us/articles/201855939-How-to-Calculate- a-Confidence-Score。
我们将使用 seaborn 的 countplot 函数来观察训练数据的分布。我们从下图中看到,大约 14300 个图像中没有发现油棕种植园,而仅有 942 个图像中发现了油棕种植园。这就是所谓的不平衡数据集,但我们在这里不讨论这个深度学习问题。我们此刻正迈出了一小步。
统计两个类别的样本数。
训练数据集中分布
准备数据
提供的测试数据放置于两个不同的文件夹中: leaderboard 留出数据和 leaderboard 测试数据。由于竞赛要求提交这两种数据集的预测,所以我们将两者相结合。我们共获得 6534 副图像。
结合 leaderboard 留出数据和 leaderboard 测试数据。
我们将使用 fast.ai 的 DataBlock API 来构成数据,这是一种将数据集呈现给模型的简便方法。
创建一个 ImageList 来保留数据
我们将使用 ImageList 来保存训练数据,并使用 from_df 方法读取数据。这样做的原因是,我们将训练集信息储存在了名为 df 的 DataFrame 中。
接下来需要随机分割训练集,并保留 20% 作为验证集,从而在训练中监督模型性能。我们选择了一个 seed,以确保再一次训练时能得到相同的结果,通过相同的 seed,我们就能知道哪些改进是好的,哪些是坏的。
此外,我们同样还要把训练集的标签地址提供给 ImageList,并将数据与标签合并。
最后,还需要在数据上执行转换,通过设定 flipvert = True 将翻转图像,这能帮助模型识别不同朝向的图像。此外,还需要使用 imagenetstats 来归一化图像。
预览图像
如下是有或没有油棕种植园的卫星图像:
展示两个 Batch 的图像。
有油棕的图像标记为 1,没有油棕的标记为 0
训练我们的模型
现在,开始训练我们的模型。我们将使用卷积神经网络作为主体,并利用 ResNet 模型的预训练权重。ResNet 模型被训练用来对各种图像进行分类,不用担心它的理论和实现细节。现在,我们构建的模型以卫星图像作为输入,并输出这两个类别的预测概率。
卷积神经网络
搜索最佳模型学习率。
接下来,我们用 lr_find() 函数找到了理想的学习率,并使用 recorder.plot() 对其进行了可视化。
搜索最佳模型学习率。
我们将选择斜率最大的学习率,在这里我们选择的是 1e-2。
用学习率 1e-2 对模型展开 5 个周期的训练。
我们将使用 fitonecycle 函数对模型进行 5 个 epoch 的训练(遍历所有数据 5 次)。
训练和验证损失。
注意展示的 metrics,即 trainingloss 和 validloss。随着时间的推移,我们使用它们来监控模型的改进。
最佳模型是在第四个 epoch 时获得的。
训练阶段模型的输出; 训练和验证损失的变化过程。
在你进行训练和验证数据集时,fast.ai 只在内部挑选并保存你的最佳模型。
评估我们的模型
竞赛提交的材料是根据预测概率和观测目标 has_oilpalm 之间的 ROC 曲线来评估的。默认情况下,Fast.ai 不会附带这个指标,所以我们将使用 scikit-learn 库。
打印验证指标。
使用预训练模型和 fast.ai 的妙处在于,你可以获得很好的预测准确率。在我们的案例中,没有费多大力就获得了 99.44% 的准确率。
训练第一阶段的指标。
保存模型,并绘制关于预测的混淆矩阵。
使用混淆矩阵查看结果
绘制混淆矩阵
混淆矩阵是一种图形化的方式,可以查看模型准确或不准确的预测图像数量。
第一个训练阶段的混淆矩阵。
从这个矩阵中可以看出,模型准确地预测出有 2863 张图像中没有油棕,168 张图像中有油棕。10 张有油棕的图像被分类为没有,而 7 张没有油棕的图像则被分类为有油棕。
对这种简单的模型来说,这个结果不错了。接下来,我们搜索到了训练的理想学习率。
搜索理想的学习率。
我们在学习率 1e-6 和 1e-4 之间选择了一个学习率。
在 7 个 epoch 内,使用 1e-6 和 1e-4 之间的最大学习率来拟合模型。
对模型进行 7 个周期的训练,学习率应在 1e-6 和 1e-4 范围内。
训练和验证损失。
以图形方式观察训练指标,以监控每个训练周期后模型的性能。
训练阶段模型的输出; 训练和验证损失的变化过程。
保存模型的第二个训练阶段:
准确率、误差率和 AUC 分数
打印模型的准确率、误差率和 AUC 指标:
第二个训练阶段的指标。
如你所见,模型的准确率从 99.44% 上升到了 99.48%。误差率从 0.0056 降到了 0.0052。AUC 也从 99.82% 上升为 99.87%。
绘制混淆矩阵。
与我们绘制的上一个混淆矩阵相比,你会发现模型的预测效果更好了。
第二个训练阶段的混淆指标
之前有 7 张不含油棕种植园的图像被错误分类,现在降到了 3 张,这就是进步。
我们在训练和调参期间遵循了一种模式。大多数深度学习实验都遵循类似的迭代模式。
图像转换
我们将在数据上执行更多的图像转换,这应该是能提升模型效果的。图像转换的具体描述可以在 fast.ai 文档中找到:
应用不同的转换以提升模型效果
maxlighting:如果超参不为 None,那么以 plighting 为概率随机进行亮度、对比度的调整,且最大亮度不超过 max_lighting。
maxzoom:如果超参不小于 1,那么以 paffine 为概率随机放大 1 到 max_zoom 倍。
maxwarp:如果超参不为 None,那么以 paffine 为概率在-maxwarp 和 maxwarp 之间随机对称变换。
我们再一次搜索最优学习率:
搜索一个合理的学习率
我们选择的学习率是 1e-6
将模型训练 5 个周期。
训练 5 个周期
训练和验证损失
比较训练指标,并与过去的指标进行比较。我们的模型在这次迭代中略逊于 0.0169 和 0.0163。先不要泄气。
训练阶段模型的输出;在第 3 个 epoch 时得到最佳模型
保存模型训练的第三个阶段并打印出指标。如图所示,当前模型的准确率为 99.38,上一个阶段的准确率为 99.48%。AUC 分数从 99.87% 提高到了 99.91%,这是比赛评分的标准。
准确率、误差率和 AUC 分数
第三个训练阶段的指标
最终训练阶段
你可能注意到了,我们刚开始使用的图像大小为 164,然后逐渐增加到 256(如下所示)。这么做是为了利用 fast.ai 用于分类的渐进式图像大小缩放,即在一开始使用小图像,之后随着训练逐渐增加图像大小。如此一来,当模型早期非常不准确时,它能迅速看到大量图像并实现快速改进,而在后期训练中,它可以看到更大的图像,学到更多细粒度的差别。(详情请参见:现在,所有人都可以在 18 分钟内训练 ImageNet 了)
应用不同的变换来改进模型,将图像大小增加到 256
我们又发现了一个最佳学习率。
找到理想学习率
找到理想的学习率
以 1e-4 的学习率训练 5 个 epoch 以拟合模型。
以 1e-4 的学习率对模型训练 5 个周期
训练和验证损失
观察训练指标并与之前的指标对比。我们的模型有了小小的提升(损失从 0.169 降到了 0.168)。
模型训练阶段的输出。 在第 2 个 epoch 时得到最佳模型
保存模型最后的训练阶段并打印出指标。
准确率、误差率和 AUC 分数
如下所示,模型的准确率为 99.44%,优于上一个训练阶段 99.38% 的准确率。
第四个训练阶段的指标
准备一个竞赛提交文件
现在可以看到我们的模型对未见过的数据做出了多么好的预测。
准备一个 CSV 提交文件
将文件提交给 WiDS Datathon
你仍然可以参加 WiDS 竞赛并晚一点提交。进入参赛页面,点击「Join Competition」,了解比赛规则。现在你可以提交作品,看看自己会排到第几。
_根据模型预测对提交的作品进行打分 _
_
原文链接:https://towardsdatascience.com/how-a-team-of-deep-learning-newbies-
came-3rd-place-in-a-kaggle-contest-644adcc143c8 _
Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.
Support author:
Author's Filecoin address:
Or you can use Likecoin to support author: