背靠 fast.ai 库与视频教程,首战 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 和我们将要使用的其他库
![6d2c7baaaac30c16e73705e70dde0b36.png](https://i-blog.csdnimg.cn/blog_migrate/e8f01f547ab81e3d5ca77dec896a94f3.jpeg)
输入库
获取竞赛数据
为了尽可能简洁明了,Abdishakur 上传竞赛数据文件至 dropbox.com。你可以在竞赛页面上找到这些数据。你需要接受竞赛规则,并在参赛后访问数据。
![aff26833f7267231737b11598a351e68.png](https://i-blog.csdnimg.cn/blog_migrate/899f78a53dc2f3d0a79638c799beaf87.jpeg)
观察数据
我们在解决一个问题时首先要做的是观察可用数据。在想出解决方案之前,我们需要理解这个问题以及数据是什么样的。观察数据意味着理解数据目录的构成方式、数据标签以及样本图像是什么样的。
![d78dcac5f146a6d1e6d949c47995922e.png](https://i-blog.csdnimg.cn/blog_migrate/814f9e90bc388e7c33969b38988c2320.jpeg)
使用 pandas 库来读取数据。
![9ab1742d310d818ad4efe074f0f9f58a.png](https://i-blog.csdnimg.cn/blog_migrate/15601012cdd67b1ed842553f0be00a74.jpeg)
训练模型所要使用的数据标签。
处理「图像分类数据集」和「表格数据集」的主要区别在于标签的存储方式。这里的标签指的是图像中的内容。在这个特定的数据集中,标签以 CSV 文件格式存储。
想要了解更多计算「分数」列的方法,点击:
https://success.figure-eight.com/hc/en-us/articles/201855939-How-to-Calculate-a-Confidence-Score。
我们将使用 seaborn 的 countplot 函数来观察训练数据的分布。我们从下图中看到,大约 14300 个图像中没有发现油棕种植园,而仅有 942 个图像中发现了油棕种植园。这就是所谓的不平衡数据集,但我们在这里不讨论这个深度学习问题。我们此刻正迈出了一小步。
![bb3cb49e3609e41816d16e0dc80df3f8.png](https://i-blog.csdnimg.cn/blog_migrate/ae6b1789f68a9d87235834208e07037c.jpeg)
统计两个类别的样本数。
![0f4da6304fe2eb4425285e6bb4a7ba14.png](https://i-blog.csdnimg.cn/blog_migrate/9338a3b8b96a8d40698b4e2c01a29c8e.jpeg)
训练数据集中分布
准备数据
提供的测试数据放置于两个不同的文件夹中: leaderboard 留出数据和 leaderboard 测试数据。由于竞赛要求提交这两种数据集的预测,所以我们将两者相结合。我们共获得 6534 副图像。
![e3a396eee940531727db5a936111ad15.png](https://i-blog.csdnimg.cn/blog_migrate/8754b1bace8ccff5dc009fbbbb70f787.jpeg)
结合 leaderboard 留出数据和 leaderboard 测试数据。
我们将使用 fast.ai 的 DataBlock API 来构成数据,这是一种将数据集呈现给模型的简便方法。
![71cc78e266b44f8cf4752d28cb07d9a8.png](https://i-blog.csdnimg.cn/blog_migrate/b91b70b1e5f5237c3255aeb094ae2b34.jpeg)
创建一个 ImageList 来保留数据
我们将使用 ImageList 来保存训练数据,并使用 from_df 方法读取数据。这样做的原因是,我们将训练集信息储存在了名为 df 的 DataFrame 中。
接下来需要随机分割训练集,并保留 20% 作为验证集,从而在训练中监督模型性能。我们选择了一个 seed,以确保再一次训练时能得到相同的结果,通过相同的 seed,我们就能知道哪些改进是好的,哪些是坏的。
此外,我们同样还要把训练集的标签地址提供给 ImageList,并将数据与标签合并。
最后,还需要在数据上执行转换,通过设定 flip_vert = True 将翻转图像,这能帮助模型识别不同朝向的图像。此外,还需要使用 imagenet_stats 来归一化图像。
预览图像
如下是有或没有油棕种植园的卫星图像:
![2cb413bc8bf9584ce86b510041a558a4.png](https://i-blog.csdnimg.cn/blog_migrate/281d4765cbf8850c888c1863a48a580a.jpeg)
展示两个 Batch 的图像。
![5b930054b9905e37e218051c1965270b.png](https://i-blog.csdnimg.cn/blog_migrate/fef681aeeefefb37acbe078e3ca41b01.jpeg)
有油棕的图像标记为 1,没有油棕的标记为 0
训练我们的模型
现在,开始训练我们的模型。我们将使用卷积神经网络作为主体,并利用 ResNet 模型的预训练权重。ResNet 模型被训练用来对各种图像进行分类,不用担心它的理论和实现细节。现在,我们构建的模型以卫星图像作为输入,并输出这两个类别的预测概率。
![06677d612cfb04ae5ae667257c96d83c.png](https://i-blog.csdnimg.cn/blog_migrate/1344117b9544ee2c26904ca0e3a000aa.jpeg)
卷积神经网络
![99f38b4f39cda09bb6029ad6f3a157da.png](https://i-blog.csdnimg.cn/blog_migrate/23fc199629f7176488f8d2e16ddede3a.jpeg)
搜索最佳模型学习率。
接下来,我们用 lr_find() 函数找到了理想的学习率,并使用 recorder.plot() 对其进行了可视化。
![f06f5ffe63a2091510d6689bcf54b80b.png](https://i-blog.csdnimg.cn/blog_migrate/a1884cc29d5dab73ec455080cbb447be.jpeg)
搜索最佳模型学习率。
我们将选择斜率最大的学习率,在这里我们选择的是 1e-2。
![48faa65ed51a770b4185991365a5453c.png](https://i-blog.csdnimg.cn/blog_migrate/83d2b79168bc81d64d34568669a9366e.jpeg)
用学习率 1e-2 对模型展开 5 个周期的训练。
我们将使用 fit_one_cycle 函数对模型进行 5 个 epoch 的训练(遍历所有数据 5 次)。
![aa1f1cb63a62999235126d789a38221e.png](https://i-blog.csdnimg.cn/blog_migrate/e3f7310f66cc9b5a238c2c88a083d5b5.jpeg)
训练和验证损失。
注意展示的 metrics,即 training_loss 和 valid_loss。随着时间的推移,我们使用它们来监控模型的改进。
最佳模型是在第四个 epoch 时获得的。
![b448191bdded19cf91c3682a84f061d5.png](https://i-blog.csdnimg.cn/blog_migrate/16c1b7d280b75b53db59fd22730a2156.jpeg)
训练阶段模型的输出;训练和验证损失的变化过程。
在你进行训练和验证数据集时,fast.ai 只在内部挑选并保存你的最佳模型。
评估我们的模型
竞赛提交的材料是根据预测概率和观测目标 has_oilpalm 之间的 ROC 曲线来评估的。默认情况下,Fast.ai 不会附带这个指标,所以我们将使用 scikit-learn 库。
![fccd6a5f102298eae43e7924177a92d4.png](https://i-blog.csdnimg.cn/blog_migrate/b1d0c0ae594b861e9300d5716ca235f0.jpeg)
打印验证指标。
使用预训练模型和 fast.ai 的妙处在于,你可以获得很好的预测准确率。在我们的案例中,没有费多大力就获得了 99.44% 的准确率。
![eba3e065d5d18170315d64c5c996cd82.png](https://i-blog.csdnimg.cn/blog_migrate/b79a0cd14b8ddc9606865b559527134a.jpeg)
训练第一阶段的指标。
保存模型,并绘制关于预测的混淆矩阵。
![b3939a4cba07360466fa022fab5152a0.png](https://i-blog.csdnimg.cn/blog_migrate/a18b0702bac600e184e83690ff08de2f.jpeg)
使用混淆矩阵查看结果
![a04488fe3de857b44a9a58b8e3d24cbf.png](https://i-blog.csdnimg.cn/blog_migrate/bab1e786d578a44f400f97d607c64bba.jpeg)
绘制混淆矩阵
混淆矩阵是一种图形化的方式,可以查看模型准确或不准确的预测图像数量。
![a851bda1609856fd4e066cedcb9aee47.png](https://i-blog.csdnimg.cn/blog_migrate/a968a605f14d259fc93103faa0bcec9c.jpeg)
第一个训练阶段的混淆矩阵。
从这个矩阵中可以看出,模型准确地预测出有 2863 张图像中没有油棕,168 张图像中有油棕。10 张有油棕的图像被分类为没有,而 7 张没有油棕的图像则被分类为有油棕。
对这种简单的模型来说,这个结果不错了。接下来,我们搜索到了训练的理想学习率。
![bc1467f4cfabbd58c03b2c8eb881b6f7.png](https://i-blog.csdnimg.cn/blog_migrate/d205aa9ab0082f8030795f35f972b64f.jpeg)
搜索理想的学习率。
![3342861705b70c543e15999e62b1afdd.png](https://i-blog.csdnimg.cn/blog_migrate/342889a1009157c51285a338235f3904.jpeg)
我们在学习率 1e-6 和 1e-4 之间选择了一个学习率。
在 7 个 epoch 内,使用 1e-6 和 1e-4 之间的最大学习率来拟合模型。
![8d1cf7216cc66a61a4642fd6b60b1577.png](https://i-blog.csdnimg.cn/blog_migrate/ae9aa791ac62852a5081d66b0fdc6d3b.jpeg)
对模型进行 7 个周期的训练,学习率应在 1e-6 和 1e-4 范围内。
![a21a0684908a655eb3fb000e3f9810ec.png](https://i-blog.csdnimg.cn/blog_migrate/b04b1dd4680d643b1ab45160fe5ae4c8.jpeg)
训练和验证损失。
以图形方式观察训练指标,以监控每个训练周期后模型的性能。
![b944b0c638753128ca94c01e4c0c189a.png](https://i-blog.csdnimg.cn/blog_migrate/e4b81859cddd6e719dc34c56d9569b7b.jpeg)
训练阶段模型的输出;训练和验证损失的变化过程。
保存模型的第二个训练阶段:
![204f86f240cf274f3d435df0efa05031.png](https://i-blog.csdnimg.cn/blog_migrate/3ebe1bd6a228b0b9499100dec84faff9.jpeg)
准确率、误差率和 AUC 分数
打印模型的准确率、误差率和 AUC 指标:
![5860657c1f0e5754b25408cb922f7170.png](https://i-blog.csdnimg.cn/blog_migrate/9f53ffabc42e81d462100489feffaf3f.jpeg)
第二个训练阶段的指标。
如你所见,模型的准确率从 99.44% 上升到了 99.48%。误差率从 0.0056 降到了 0.0052。AUC 也从 99.82% 上升为 99.87%。
![5898bec19a1c5d8beaf1c1eceb6d85f8.png](https://i-blog.csdnimg.cn/blog_migrate/7d4b5e3e0e07473bd9b8ba4d1ef9652d.jpeg)
绘制混淆矩阵。
与我们绘制的上一个混淆矩阵相比,你会发现模型的预测效果更好了。
![54d7486db82256711ba16c829bf858f1.png](https://i-blog.csdnimg.cn/blog_migrate/7a125aaaafe117b8c2604401ec53692e.jpeg)
第二个训练阶段的混淆指标
之前有 7 张不含油棕种植园的图像被错误分类,现在降到了 3 张,这就是进步。
我们在训练和调参期间遵循了一种模式。大多数深度学习实验都遵循类似的迭代模式。
图像转换
我们将在数据上执行更多的图像转换,这应该是能提升模型效果的。图像转换的具体描述可以在 fast.ai 文档中找到:
![7c73023bb3cf49b0117084f540dbcc6a.png](https://i-blog.csdnimg.cn/blog_migrate/1950af965968308c7579e6e6553c65b4.jpeg)
应用不同的转换以提升模型效果
max_lighting:如果超参不为 None,那么以 p_lighting 为概率随机进行亮度、对比度的调整,且最大亮度不超过 max_lighting。
max_zoom:如果超参不小于 1,那么以 p_affine 为概率随机放大 1 到 max_zoom 倍。
max_warp:如果超参不为 None,那么以 p_affine 为概率在-max_warp 和 max_warp 之间随机对称变换。
我们再一次搜索最优学习率:
![bb9306606bcf73b459f01571e689552b.png](https://i-blog.csdnimg.cn/blog_migrate/c6d9336cf7d695e9c9ebf0ebffdccbdb.jpeg)
搜索一个合理的学习率
![5102c6371cea8c3e9e5752491d575cc8.png](https://i-blog.csdnimg.cn/blog_migrate/daf145b76c23646e44d84960cd3d64c5.jpeg)
我们选择的学习率是 1e-6
将模型训练 5 个周期。
![e8710812fd2d90508be15ad2e09102f8.png](https://i-blog.csdnimg.cn/blog_migrate/340b3fa879fea00af1a3be104740654b.jpeg)
![add14bb7944d35924aa907cf4c506711.png](https://i-blog.csdnimg.cn/blog_migrate/061cb50770eb41f599971fafbbb60f8c.jpeg)
训练和验证损失
比较训练指标,并与过去的指标进行比较。我们的模型在这次迭代中略逊于 0.0169 和 0.0163。先不要泄气。
![e635db4f8e1220052804bb2a44d2ef00.png](https://i-blog.csdnimg.cn/blog_migrate/07834230530adba389ec5be9f7c3ee96.jpeg)
训练阶段模型的输出;在第 3 个 epoch 时得到最佳模型
保存模型训练的第三个阶段并打印出指标。如图所示,当前模型的准确率为 99.38,上一个阶段的准确率为 99.48%。AUC 分数从 99.87% 提高到了 99.91%,这是比赛评分的标准。
![a53350d882c803d01368ebcf4979725b.png](https://i-blog.csdnimg.cn/blog_migrate/a0041b332e8fc79c0f4c9f0162484ce0.jpeg)
准确率、误差率和 AUC 分数
![55eb65a0dd57049f07d3ab7946e5da04.png](https://i-blog.csdnimg.cn/blog_migrate/4d91335b8ab67c053482eba8175329ec.jpeg)
第三个训练阶段的指标
最终训练阶段
你可能注意到了,我们刚开始使用的图像大小为 164,然后逐渐增加到 256(如下所示)。这么做是为了利用 fast.ai 用于分类的渐进式图像大小缩放,即在一开始使用小图像,之后随着训练逐渐增加图像大小。如此一来,当模型早期非常不准确时,它能迅速看到大量图像并实现快速改进,而在后期训练中,它可以看到更大的图像,学到更多细粒度的差别。(详情请参见:现在,所有人都可以在 18 分钟内训练 ImageNet 了)
![e5f0f813dd77d68692d85d6cc548b651.png](https://i-blog.csdnimg.cn/blog_migrate/7b7fe4a2fd1b74f4fd5f9ae1e617a74d.jpeg)
应用不同的变换来改进模型,将图像大小增加到 256
我们又发现了一个最佳学习率。
![ad0a34e84c002326592e258e88f01418.png](https://i-blog.csdnimg.cn/blog_migrate/53ee8edda30d665ca733b143e94280e0.jpeg)
找到理想学习率
![c07a1b36329ab0b8f32a1daeda819cd1.png](https://i-blog.csdnimg.cn/blog_migrate/27672564694c0107d58defe843e7fe02.jpeg)
找到理想的学习率
以 1e-4 的学习率训练 5 个 epoch 以拟合模型。
![d02623099d598b786efa212476c89152.png](https://i-blog.csdnimg.cn/blog_migrate/b6a2034d3c786a4dac1153d5da502fc5.jpeg)
以 1e-4 的学习率对模型训练 5 个周期
![62f64d437b74640b6773dffacd1f17e9.png](https://i-blog.csdnimg.cn/blog_migrate/ca0b46cb3ef1529a74993df7af240297.jpeg)
训练和验证损失
观察训练指标并与之前的指标对比。我们的模型有了小小的提升(损失从 0.169 降到了 0.168)。
![e2cfe3d47425b8265ffbf60309d0e20c.png](https://i-blog.csdnimg.cn/blog_migrate/5ae9b5aabfac7b46fa9afd2ec90ee8ed.jpeg)
模型训练阶段的输出。在第 2 个 epoch 时得到最佳模型
保存模型最后的训练阶段并打印出指标。
![5f11aa19bcec44590073c34308f4943a.png](https://i-blog.csdnimg.cn/blog_migrate/ed4ee1a5cef3526ca22750f4a021c98e.jpeg)
![58e1f33eaaf5478c5384539f8dd190e4.png](https://i-blog.csdnimg.cn/blog_migrate/3595e3aa1a5684c59e895b1e880784af.jpeg)
准确率、误差率和 AUC 分数
如下所示,模型的准确率为 99.44%,优于上一个训练阶段 99.38% 的准确率。
![f027b3d57ae4fd59f5bf93c8e1c8dfc7.png](https://i-blog.csdnimg.cn/blog_migrate/429e3af970854ae26a9fba607c1afd89.jpeg)
第四个训练阶段的指标
准备一个竞赛提交文件
现在可以看到我们的模型对未见过的数据做出了多么好的预测。
![dce91e94ce24b2c9e6719a9519a9286f.png](https://i-blog.csdnimg.cn/blog_migrate/bf331cf5f74b80001c173ce07a4019f6.jpeg)
准备一个 CSV 提交文件
将文件提交给 WiDS Datathon
你仍然可以参加 WiDS 竞赛并晚一点提交。进入参赛页面,点击「Join Competition」,了解比赛规则。现在你可以提交作品,看看自己会排到第几。
![8bfebae8ad85082d056124ba311d4f67.png](https://i-blog.csdnimg.cn/blog_migrate/5e2a937d1ad52c809e4dbf752be34e80.jpeg)
根据模型预测对提交的作品进行打分