比赛地址:https://www.kaggle.com/c/plant-pathology-2020-fgvc7/overview
参考kernel:https://www.kaggle.com/pestipeti/plant-pathology-2020-pytorch
pytorch-code:https://github.com/872699467/Plant-Pathology
题目描述
根据提供的图片,判断植物当前的健康状态,提交的内容为每个状态的概率。
示例图片
认知数据
植物的状态一共有4种,且已经用one-hot表示。每种类别的样本比例并不均衡,第二种明显少于其他种类。
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
if __name__ == '__main__':
train_df = pd.read_csv('data/train.csv')
print(train_df.head(5))
label = train_df.iloc[:, [1, 2, 3, 4]].values
label = label[:, 0] * 0 + label[:, 1] * 1 + label[:, 2] * 2 + label[:, 3] * 3
count = Counter(label)
x = [0, 1, 2, 3]
y = [count[i] for i in x]
fig = plt.figure(figsize=(6, 4), dpi=100)
ax = fig.subplots(1, 1)
ax.bar(x, y,label='label')
ax.set_xticks(np.arange(0, 5))
ax.set_xticklabels(['healthy', 'multiple_diseases', 'rust', 'scab'])
plt.show()
前5条数据
每种类别的柱状图
开始编码
一、采用5折交叉验证,本地的得分与kaggle公共的得分相差较大,推测是由于验证集数量过少导致的,所以采用交叉验证的方法。又由于每个类别的数量并不均衡,所以将原本的KFold交叉验证方法改成了StratifiedKFold。确保训练集和验证集的每个类别样本比例相同。两者方法的区别可参考https://www.jianshu.com/p/c84818b56fa0
二、数据增强,如果我们想要训练更多的epoch,为了模型不会过拟合,我们需要对训练集进行数据增强,这也是一种增加训练样本量的方法。
三、损失函数为softmax+cross entropy。作者原本使用的是sigmoid+Binary Cross Entropy,并没有解释原因。不过一般的分类任务其损失函数为交叉熵损失函数。
四、输入图片的大小,从256像素增加到512像素。高分辨率虽然增加了计算量,但是会提高模型的精度。
模型采用的预训练的resnet-18。
class PlantModel(nn.Module):
def __init__(self, pretrained, num_class=4):
super(PlantModel, self).__init__()
self.backbone = resnet18(pretrained=pretrained)
in_feature = self.backbone.fc.in_features
self.logit = nn.Linear(in_feature, num_class)
self.dropout = nn.Dropout(0.25)
def forward(self, x):
x = self.backbone.conv1(x)
x = self.backbone.bn1(x)
x = self.backbone.relu(x)
x = self.backbone.maxpool(x)
x = self.backbone.layer1(x)
x = self.backbone.layer2(x)
x = self.backbone.layer3(x)
x = self.backbone.layer4(x)
x = self.backbone.avgpool(x)
x = x.view(x.size(0), -1)
x = self.dropout(x)
out = self.logit(x)
return out
损失函数上述提到是softmax+CE
class DenseCrossEntropy(nn.Module):
def __init__(self):
super(DenseCrossEntropy, self).__init__()
def forward(self, y_pred, y_true):
y_pred = y_pred.float()
y_true = y_true.float()
logprobs = torch.log_softmax(y_pred, dim=-1)
loss = -y_true * logprobs
loss = torch.sum(loss)
return loss.mean()
其他关于数据读取、log记录等编码均已给出。
训练过程
训练集和验证集的收敛结果
将每折的验证集预测叠加,就是对训练集中所有数据的预测,再与数据集进行比较,auc得分为0.9954。但是最终提交的测试集得分只有0.919,还是有比较大的提升空间。
5-Folds CV score: 0.9954
提交结果
网友评论