fastai深度学习官方教程代码笔记Lesson3-3

这部分课程主要是介绍了如何处理多分类问题,课程中采用了kaggle中的一个竞赛问题,卫星图像类别的预测问题。
课程内容:https://www.kaggle.com/hortonhearsafoo/fast-ai-v3-lesson-3-planet
竞赛题目:https://www.kaggle.com/c/planet-understanding-the-amazon-from-space

首先介绍构建数据集,以及处理多多标签的数据的方法

#jupyter设置,引入fastai库
%reload_ext autoreload
%autoreload 2
%matplotlib inline

from fastai.vision import *
#设置数据集路径
path = Path('/kaggle/input/')
path.ls()
#读取训练数据及其的标签,可以看出每张图片有多个标签
df = pd.read_csv(path/'train_v2.csv')
df.head()
#定义生成数据集的图像变换,参数允许上下翻转,10%的光照变换,1.05的最大缩放,以及不需要对称的仿射变换
tfms = get_transforms(flip_vert=True, max_lighting=0.1, max_zoom=1.05, max_warp=0.)
#定义随机数,保证每次训练结果一致
np.random.seed(42)
#这里使用ImageItemList来生成数据集,与直接用ImageDataBunch不同的是,这里用两步的方式来构建数据集
#这么做的用处在于可以先对数据进行分割,并且打好标签,
#之后可以对同一批分割好的数据进行不同的变换和尺寸大小,来进行不同的训练
src = (ImageItemList.from_csv(path, 'train_v2.csv', folder='train-jpg', suffix='.jpg')
       .random_split_by_pct(0.2)
       #多标签情况下,标签分割符是空格
       .label_from_df(sep=' '))
#这里对分割好的数据集进行变换,变换尺寸,并生成最终的数据集
data = (src.transform(tfms, size=128)
        .databunch(num_workers=0).normalize(imagenet_stats))
#展示数据集,可以看到每张图片上有1个或多个标签
data.show_batch(rows=3, figsize=(12,9))

其次介绍了如何对多标签的问题进行训练以及评价

#这里的网络结构还是采用resnet
#由于是多标签的分类问题,与之前的问题不同,并非从所有标签中选择概率最大的那个
#而是设定一个阈值,当概率超过这个阈值的时候,则认为图片属于这一类
arch = models.resnet50
#这里将准确率和F1分数重新定义( F1分数(F1_Score),又称平衡F分数(balanced F Score),它被定义为精确率和召回率的调和平均数。)
#准确率采用了多分类的准确率函数,设置了一个阈值,表示超过这个阈值的分组结果为正例,然后对比真实值,计算分类正确的个数
#F1分数设置同样的阈值,用于计算准确率和召回率,其用于的目标往往是一个one-hot编码的结果(一般是多分类问题)
acc_02 = partial(accuracy_thresh, thresh=0.2)
f_score = partial(fbeta, thresh=0.2)
#使用上述网络结构以及评价函数来初始化cnn网络
learn = create_cnn(data, arch, metrics=[acc_02, f_score], model_dir='/tmp/models')
#寻找学习率
learn.lr_find()
learn.recorder.plot()
#使用合适的学习率进行训练,slice(lr)定义了学习率的最大值到lr
lr = 0.01
learn.fit_one_cycle(5, slice(lr))
#最后保存模型
learn.save('stage-1-rn50')

最后还介绍了如何提升模型准确度的一些技巧

#之后对网络调整学习率进一步训练
#首先解冻网络的参数
learn.unfreeze()
#重新寻找合适的学习率
learn.lr_find()
learn.recorder.plot()
#由于学习率曲线没有陡峭下降的段落,这里选择的是使得损失函数较小的区间学习
learn.fit_one_cycle(5, slice(1e-5, lr/5))
#再次保存学习结果
learn.save('stage-2-rn50')
#为了提升准确率,这里重新产生数据集,将数据源变换为较大的图像尺寸256的数据集
data = (src.transform(tfms, size=256)
        .databunch(num_workers=0).normalize(imagenet_stats))
#重新给之前的学习器指定数据集
learn.data = data
#展示新的数据集的尺寸
data.train_ds[0][0].shape
#这里将之前训练的参数固定,只训练最后一层的参数(迁移学习)
learn.freeze()
#查找合适的学习率
learn.lr_find()
learn.recorder.plot()
#选择比较合适的一段区间进行训练,结果比之前的准确率有了提升
lr=1e-2/2
learn.fit_one_cycle(5, slice(lr))
#保存模型
learn.save('stage-1-256-rn50')
#将所有参数解冻
learn.unfreeze()
#使用另一个学习率重新进行完整的学习,可以发现准确率比上面的进一步提升
learn.fit_one_cycle(5, slice(1e-5, lr/5))
#打印损失函数
learn.recorder.plot_losses()
#保存模型
learn.save('stage-2-256-rn50')
#导出模型用于预测
learn.export()

你可能感兴趣的:(fastai深度学习官方教程代码笔记Lesson3-3)