独家 | kaggle季军新手笔记:利用fast.ai对油棕人工林图像进行快速分类(附代码)

简介: 一支深度学习的新手队如何在kaggle竞赛中获得第三名?

作者:Mercy Markus

翻译:陈之炎

校对:丁楠雅

本文约3700字,建议阅读10+分钟。

文章来源:微信公众号 数据派THU

一支深度学习的新手队如何在kaggle竞赛中获得第三名?


image.png

图:亚历山大·纳格斯塔德 (AlexanderNaglestad)

WiDS数据马拉松由女性数据科学工作者与她们的伙伴联合发起,她们面临的挑战是需要建立一个模型,来预测一批卫星图像中存在油棕人工林种植园的情况。

数据集是称为“行星”的人造卫星新近拍摄的经加注后的卫星图像数据集,该图像数据集具有3米的空间分辨率,每幅图像都是基于图像中是否存在油棕种植园进行标记的(0表示没有油棕种植园,1表示有油棕种植园)。任务是需要训练一个模型,该模型以卫星图像为输入,并输出对油棕种植园的图像预测的概率。竞赛创建者为模型开发提供了经过标记后的训练和测试数据集。

详情见这里:https://www.kaggle.com/c/widsdatathon2019

我的队友(Abundshakur,Halimah,和IfeomaOkoh)和我采用了fast.ai框架来应对这一挑战。感谢托马斯·卡贝尔(ThomasCapelle)提供了Kaggle上的入门内核,它给出了如何处理这个问题的深刻见解,同时也为fast.ai团队创造了一门神奇的深度学习课程,从而简化了许多复杂的深度学习的概念。现在,深度学习的初学者也可以赢得kaggle比赛了。

我们从一个简单易学的关于深度学习的教程开始吧

目前,无需为理解所有的东西而担心,文中会伴随着大量的练习。本教程旨在展示fast.ai对于深度学习的初学者来说的神奇之处,前提是假设读者会python语言,并且接触过一些ML(机器学习)。如果你已经具备上述技能,那我们就可以走上正轨了。

文中的所有代码都可以在Google Colaboratory(https://colab.research.google.com/notebooks/welcome.ipynb)上获得,这是一个免费的Jupyter笔记本环境,无需安装,运行在云上。可以采用协作的方式编写和执行代码,存盘和共享分析结果,访问功能强大的计算资源,所有这些都是免费的。点击这里可以访问到我们将要使用到的代码。

导入fast.ai和将要用到的其他库

# This ensures that any edits to libraries you make are reloaded here automatically,
# and also that any charts or images displayed are shown in this notebook.
%reload_ext autoreload
%autoreload 2
%matplotlib inline导入库
# Import libraries
from fastai import *
from fastai.vision import *
from fastai.callbacks import CSVLogger, SaveModelCallback
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')

获取竞赛数据

为了尽可能地直观,Abdishakur将竞赛数据文件上传到dropbox.com,可以在这个竞赛页面上找到竞赛数据文件,而且只有接受竞争规则之后才能访问到这些数据文件。


# Get the data from dropbox link
!wget https://www.dropbox.com/s/6kltw0kqynlijxv/widsdatathon2019.zip
  
# The downloaded competition data is zipped, let us unzip it
!unzip widsdatathon2019.zip
# The training and testing data have already been seperated, Unzip them as well
!unzip train_images.zip
!unzip leaderboard_holdout_data.zip
!unzip leaderboard_test_data.zip

查看数据

在处理这个问题之前,首先要做的是查看可用的数据。在知道如何解决问题之前,我们首先需要了解问题和数据是什么样子。查看数据意味着了解数据目录的结构,标签是什么,以及一些示例图像是什么。

# Overview of the labels of the training data; 
df = pd.read_csv('data/traininglabels.csv')
df.head()

使用pandas库读取数据

image.png

训练模型过程中使用到的数据标签

处理图像分类数据集和表格数据集的主要区别在于标签的存储方式,这里的标签指的是图像中的内容。在这个特定的数据集中,标签存储在CSV文件中。

要了解如何计算分数列的详细信息,请访问此链接:https://success.figure-eight.com/hc/en-us/articles/201855939-How-to-Calculate-a-Confidence-Score

利用countplot函数来查看培训数据的分布情况,从图中可以看到:大约有14,300幅图片没有油棕榈种植园,而只有942幅图片有油棕榈种植园,这可以称为非均衡数据集,关于非均衡数据集这个深度学习问题,我们不打算在此讨论;目前,可以从这里开始起步:

sns.countplot(df.has_oilpalm)

对两类进行计数

image.png

训练数据集的分布情况

准备数据

所提供的测试数据位于两个独立的文件夹中,即排行榜预留数据(leaderboard holdout data)和排行榜测试数据(leaderboard test data)这两个文件夹。由于竞赛要求对两个数据集提交预测结果,所以我们将二者组合起来,这样一共得到6534张图片。

test_imgs = [i for i in test.iterdir()]
hold_imgs = [i for i in lb_test.iterdir()]
combined_test = test_imgs + hold_imgs
len(combined_test)

将排行榜预留数据(leaderboard holdout data )与排行榜测试数据(leaderboard test data)组合起来

采用fast.ai的DataBlock API来构造数据,这是向模型输送数据集的一种简易的方法。

src = (ImageList.from_df(df, path, folder='train_images')
      .random_split_by_pct(0.2, seed=14)
      .label_from_df('has_oilpalm')
      .add_test(combined_test))
      
data = (src.transform(get_transforms(flip_vert=True), size=164)
           .databunch()
           .normalize(imagenet_stats))

创建一个ImageList来保存数据

此步骤要点:

  • 利用ImageList的from_df方法来保存训练数据,这样做是因为将有关训练集的信息存储在名字为df的数据帧中,让它能找到训练图像所在的路径和保存图像的文件夹名称,train_images.
  • 接下来,使用随机分割来对训练集进行分割,留出20%的数据来监控模型在训练过程中的性能。选择一颗种子,以确保再次检查时能得到同样的结果,我们必须知道什么在起作用,什么不起作用。
  • 告诉ImageList在训练集中的数据的标签所在地,利用has_oilpalm方法将组合后的数据添加到测试数据中。
  • 最后,对数据进行转换,使用flip_vert = True翻转图像有助于模型识别图像。利用imagenet_stats对图像归一化处理。注意:这是一种转移学习技术,我要说的是需要保持操作尽可能简单。

图像预览

不管有没有油棕种植园,卫星图像是这样的:

data.show_batch(2)

显示2批图像

image.png

有油棕的图像标记为1,无油棕的图像标记为0

训练模型

现在开始训练模型,采用卷积神经网络骨干,并使用预先训练的权重,这个权重从一个已经训练好的图像分类的resnet模型中直接获得,无须担心这种方法的细节。目前为止,我们正在构建一个以卫星图像为输入并输出这两种分类的预测概率模型。

learn = create_cnn(data, models.resnet50, metrics=[accuracy, error_rate],
                  callback_fns=[ShowGraph, SaveModelCallback])
# View model architecture
learn.model()

卷积神经网络

learn.lr_find()
learn.recorder.plot()

找出最优的模型学习率

接下来,使用lr_find()找到理想的学习率,并利用recorder.plot().对它可视化。

image.png

找出最优的模型学习率

选择一个接近坡度最陡之处的学习速率,在这个示例中是1e-2。

learn.fit_one_cycle(5, slice(1e-2))

学习率为1e-2的5个循环的训练模型

利用fit_one_cycle函数对模型训练5个周期 (对所有数据训练5个周期)。

image.png

训练和验证损失

注意到显示出来的结果,如training_loss 和valid_loss没有?后续,会用它们来监控模型的改进。

在第四个循环,得到了最佳的模型。

image.png

训练模型的输出;训练和验证损失的过程

fast.ai在运行训练和验证数据集时,内部自动选取和保存最优的那个模型。

评估模型

竞赛组委会根据预测概率与观测目标has_oilpalm之间的工作特性曲线下的面积对参赛作品进行评价。通过以下开发者速成班、视频或Kaggle学习论坛的帖子,可以了解到更多关于AUC 的咨询。

开发者速成班:

https://developers.google.com/machine-learning/crash-course/classification/roc-and-auc

视频:

https://www.dataschool.io/roc-curves-and-auc-explained/ Kaggle

学习论坛:

https://www.kaggle.com/learn-forum/5378

默认情况下,Fast.ai没有提供这个评价标准的指标度量,所以我们将用到Scikit-Learning库。


from sklearn.metrics import roc_auc_score
def auc_score(y_score,y_true):
    return torch.tensor(roc_auc_score(y_true,y_score[:,1]))
probs,val_labels = learn.get_preds(ds_type=DatasetType.Valid) 
print('Accuracy',accuracy(probs,val_labels)),
print('Error Rate', error_rate(probs, val_labels))
print('AUC', auc_score(probs,val_labels))

打印出验证指标

使用预训练模型和fast.ai的优点是,可以得到一个非常好的预测精度,在这个示例中,在没有多做其他工作的情况下,获得了99.44%精确度。

image.png

训练第一阶段的指标

将模型存盘,绘制出预测的混淆矩阵。

learn.save('resnet50-stg1')

利用混淆矩阵查看结果

interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix(dpi=120)

绘制混淆矩阵

混淆矩阵是一种图形化的方法,用来查看模型准确或不准确预测的图像数量。

image.png

第一阶段训练的混淆矩阵

从这幅图中可以看出,模型准确地预测了2863幅没有油棕人工林的图像,对168幅油棕人工林的图像进行了正确的分类。将10幅含有油棕人工林的图像分类为无油棕人工林图像,并将7幅无油棕人工林图像分类为有油棕人工林图像。

对于一个简单的模型来说这个结果还不错。

接下来,找出这个训练迭代理想的学习率。


learn.lr_find()
learn.recorder.plot()

找出理想的学习率

image.png

选择介于1e-6和1e-4之间的一个学习率

利用介于1e-6和1e-4之间的一个学习率最大值对模型进行拟合。

learn.fit_one_cycle(7, max_lr=slice(1e-6,1e-4))

学习率在1e-6和1e-4的范围范围内,对模型进行7次循环训练

image.png

训练和验证损失

在每个训练周期后,以图形的方式观察训练指标,从而监测模型的性能。

image.png

训练模型的输出;训练和验证损失的进度

保存第二阶段的模型训练结果。

learn.save('resnet50-stg2')
probs,val_labels = learn.get_preds(ds_type=DatasetType.Valid) 
print('Accuracy',accuracy(probs,val_labels)),
print('Error Rate', error_rate(probs, val_labels))
print('AUC', auc_score(probs,val_labels))

准确度、误差率和AUC评分

打印出模型的精度、错误率和曲线下面的面积。

image.png

第二阶段训练指标

你会注意到,此时,模型的准确度从99.44%提高到99.48%,错误率从0.0056降低到0.0052,AUC也有改善,从99.82%提高到99.87%。


interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix(dpi=120)

绘制混淆矩阵

通过与我们绘制的上一个混淆矩阵的比较,可以发现模型做出了更精准的预测。

image.png

第二阶段训练的混淆矩阵

先前没有油棕种植园的7张图片被错误分类,现在降到了3张,性能有所提高。

你会注意到在训练过程中遵循了一个模式,在这个过程中调整了一些参数,这便是所谓的精调,绝大多数深度学习训练均遵循类似的迭代模式。

图像变换

我们将对数据执行更多的图像变换,通过这些变换对模型进行改进。

关于每种变换的详细描述,可以在fast.ai的相关文档中找到:https://docs.fast.ai/vision.transform.html

 tfms = get_transforms(flip_vert=True, max_lighting=0.1, max_zoom=1.05, max_warp=0.)
data = (src.transform(tfms, size=200)
        .databunch().normalize(imagenet_stats))

learn.data = data

data.train_ds[0][0].shape

应用不同的变换改进模型

hting:如果非空 None,则在概率p_lighting下使用由max_light控制的随机亮度和对比度变化。

max_zoom:如果非1,或是一个比1更小的数,则在概率p_affine下使用max_zoom到1之间的随机缩放比

max_warp:如果非空None,则使用概率p_affine应用-max_warp和max_warp之间的随机对称翘曲。

再次找出最优学习率:

learn.lr_find()
learn.recorder.plot()

找出理想的学习率

image.png

选择学习率为1e-6

循环训练模型5次:


learn.fit_one_cycle(5, 1e-6)

循环训练模型5次

image.png

训练和验证损失

将训练指标与先前的指标进行比较,模型在0.0169与0.0163之间的迭代稍差,但是不要失望。

image.png

训练模型的输出结果,在第3次迭代时获得了最佳模型

将第三阶段的训练模型保存,并打印出指标。可以注意到,目前,模型的准确度是99.38%,在前一阶段是99.48%,AUC评分从99.87%提高到99.91%,达到了比赛评分的标准。


learn.save('resnet50-stg3')
probs,val_labels = learn.get_preds(ds_type=DatasetType.Valid) 
print('Accuracy',accuracy(probs,val_labels)),
print('Error Rate', error_rate(probs, val_labels))
print('AUC', auc_score(probs,val_labels))

准确度、误差率和AUC评分

image.png

第三阶段训练指标

最终训练阶段

可以注意到,我们从最初图像大小size = 164的图像开始,然后逐渐递增,最终达到了 size = 256 。这样做是为了利用FAST.ai的累进图像大小进行分类,即在训练开始时使用小图像,并随着训练的进展逐渐增大大小。这样,即便模型早期训练时非常不准确,它也可以快速地看到大量图像并加快进度,在后续的训练中,可以看到更大的图像,从而了解更细粒度的区别。

若要阅读更多有关此信息,请访问此链接:https://www.fast.ai/2018/08/10/fastai-diu-imagenet/


tfms = get_transforms(flip_vert=True, max_lighting=0.1, max_zoom=1.05, max_warp=0.)
data = (src.transform(tfms, size=256)
        .databunch().normalize(imagenet_stats))

learn.data = data

data.train_ds[0][0].shape

应用不同的变换来改进模型

将图像大小增加到256

再次找出优化后的学习率:


learn.lr_find()
learn.recorder.plot()

找出理想的学习率

找出理想的学习率

image.png

learn.fit_one_cycle(5, slice(1e-4)) 

学习率设置为1e-4,训练模型5次循环

image.png

训练和验证损失

来看一下训练指标,并与过去的指标进行比较,模型略有改进,从0.0169提高到0.0168。

image.png

训练模型的输出,在第2次循环时获得最优的模型

将最后阶段的模型训练结果保存,并打印出指标:

learn.save('resnet50-stg4') 
probs,val_labels = learn.get_preds(ds_type=DatasetType.Valid) 
print('Accuracy',accuracy(probs,val_labels)),
print('Error Rate', error_rate(probs, val_labels))
print('AUC', auc_score(probs,val_labels))

准确度、误差率和AUC评分

你会注意到,模型的准确度现在是99.44%,比上一阶段的99.38%有所提高:

image.png

第四阶段训练指标

准备竞赛提交文件

现在可以看到模型是如何对数据进行预测的:

p,t = learn.get_preds(ds_type=DatasetType.Test)

p = to_np(p); 
p.shape

ids = np.array([f.name for f in (combined_test)]);
ids.shape

sample_sub = Path('data/SampleSubmission.csv')
df_sample = pd.read_csv(sample_sub)

sub = pd.DataFrame(np.stack([ids, p[:,1]], axis=1), columns=df_sample.columns)

sub.to_csv(path/'wids-notebook.csv', index=False)

准备CSV格式的提交文件

向WiDS数据马拉松提交文件

现在可以参加WiDS的竞赛,并提交参赛文件了,请转到此处(https://www.kaggle.com/c/widsdatathon2019)的竞赛页面,单击“加入竞赛”并接受竞赛规则,便可以提交参赛内容,如果你参加,看看你会排名第几。

image.png

我提交了自己的模型的预测之后

获得的私有和公开分数

免责声明:按照文章中的说明操作后,不会像我那样位列第三,为确保过程尽可能简单,请参看链接(https://www.kaggle.com/c/widsdatathon2019/discussion/82252)中Abdishakur的帖子。

原文标题:

How a team of deep learning newbies came 3rd place in a kaggle contest——Classifying images of oil palm plantations using fast.ai

原文链接:

https://towardsdatascience.com/how-a-team-of-deep-learning-newbies-came-3rd-place-in-a-kaggle-contest-644adcc143c8

译者简介

陈之炎,北京交通大学通信与控制工程专业毕业,获得工学硕士学位,历任长城计算机软件与系统公司工程师,大唐微电子公司工程师,现任北京吾译超群科技有限公司技术支持。目前从事智能化翻译教学系统的运营和维护,在人工智能深度学习和自然语言处理(NLP)方面积累有一定的经验。业余时间喜爱翻译创作,翻译作品主要有:IEC-ISO 7816、伊拉克石油工程项目、新财税主义宣言等等,其中中译英作品“新财税主义宣言”在GLOBAL TIMES正式发表。能够利用业余时间加入到THU 数据派平台的翻译志愿者小组,希望能和大家一起交流分享,共同进步

翻译组招募信息

工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

目录
相关文章
|
29天前
|
机器学习/深度学习 人工智能 并行计算
"震撼!CLIP模型:OpenAI的跨模态奇迹,让图像与文字共舞,解锁AI理解新纪元!"
【10月更文挑战第14天】CLIP是由OpenAI在2021年推出的一种图像和文本联合表示学习模型,通过对比学习方法预训练,能有效理解图像与文本的关系。该模型由图像编码器和文本编码器组成,分别处理图像和文本数据,通过共享向量空间实现信息融合。CLIP利用大规模图像-文本对数据集进行训练,能够实现zero-shot图像分类、文本-图像检索等多种任务,展现出强大的跨模态理解能力。
79 2
|
1月前
|
人工智能 开发者
MidJourney 替代品:为什么 FLUX.1 是终极 AI 图像生成工具
MidJourney 是目前流行的 AI 驱动图像生成工具,以其艺术风格和易用性闻名。然而,随着技术进步,其他模型如 FLUX.1、DALL·E 3 和 Stable Diffusion 3 也崭露头角,提供了更多定制选项和高质量输出。其中,FLUX.1 以其开源性质、卓越图像质量和开发者友好性脱颖而出,成为 MidJourney 的有力替代品。选择合适的工具应基于具体需求,FLUX.1 在灵活性和高性能方面表现优异。
|
6月前
|
人工智能 编解码 物联网
Stability AI推出新的AI图像生成模型Stable Cascade,对比 SD2.1 的算力成本降低了10倍左右!
Stability AI推出新的AI图像生成模型Stable Cascade,对比 SD2.1 的算力成本降低了10倍左右!
108 2
|
1月前
|
人工智能 Serverless
AI助理精准匹配------助力快速搭建Stable Difussion图像生成应用
【10月更文挑战第7天】过去在阿里云社区搭建Stable Diffusion图像生成应用需查阅在线实验室或官方文档,耗时且不便。现阿里云AI助理提供精准匹配服务,直接在首页询问AI助理即可获取详细部署步骤,简化了操作流程,提高了效率。用户可按AI助理提供的步骤快速完成应用创建、参数设置、应用部署及资源释放等操作,轻松体验Stable Diffusion图像生成功能。
|
16天前
|
人工智能 小程序
【一步步开发AI运动小程序】五、帧图像人体识别
随着AI技术的发展,阿里体育等公司推出的AI运动APP,如“乐动力”和“天天跳绳”,使云上运动会、线上健身等概念广受欢迎。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章分为四部分:初始化人体识别功能、调用人体识别功能、人体识别结果处理以及识别结果旋转矫正。下篇将继续介绍人体骨骼图绘制。
|
1月前
|
人工智能 Serverless
AI助理精准匹配,为您推荐方案——如何添加一个Stable Difussion图像生成应用
介绍了一种利用AI助手快速获取并搭建Stable Diffusion图像生成应用的方法。用户只需在阿里云官网向AI助手提出需求,即可获得详细的实施方案。随后,按照AI助手提供的方案,通过函数计算部署应用,并进行测试。此过程显著提升了开发效率。
797 2
AI助理精准匹配,为您推荐方案——如何添加一个Stable Difussion图像生成应用
|
29天前
|
人工智能
添加一个Stable Difussion图像生成应用,通过向AI助手简单的提问,即可快速搭建Stable Diffusion应用至自己的网站中,大幅提升开发效率。
添加一个Stable Difussion图像生成应用,通过向AI助手简单的提问,即可快速搭建Stable Diffusion应用至自己的网站中,大幅提升开发效率。
|
5月前
|
人工智能 算法 安全
“AI黏土人”一夜爆火,图像生成类应用何去何从?
【6月更文挑战第1天】“AI黏土人”一夜爆火,图像生成类应用何去何从?
|
3月前
|
人工智能 数据挖掘 语音技术
通义语音AI技术问题之说话人识别的两种类型分类如何解决
通义语音AI技术问题之说话人识别的两种类型分类如何解决
66 5
|
3月前
|
机器学习/深度学习 人工智能 PyTorch
"揭秘AI绘画魔法:一键生成梦幻图像,稳定扩散模型带你开启视觉奇迹之旅!"
【8月更文挑战第21天】稳定扩散(Stable Diffusion)是基于深度学习的模型,能根据文本生成高质量图像,在AI领域备受瞩目,革新了创意产业。本文介绍稳定扩散模型原理及使用步骤:环境搭建需Python与PyTorch;获取并加载预训练模型;定义文本描述后编码成向量输入模型生成图像。此外,还可调整参数定制图像风格,或使用特定数据集进行微调。掌握这项技术将极大提升创意表现力。
54 0

热门文章

最新文章