Kaggle Global Wheat 大赛YOLOv5解决方案

本文详细介绍了在Kaggle全球小麦检测大赛中使用YOLOv5进行目标检测的实战经验,包括Mosaic数据增强、YOLOv5x模型的选择、Weighted Box Fusion、TTA、NMS等技术的应用,以及假标签策略在处理噪声数据集中的重要性。尽管因license问题导致成绩取消,但作者从中获得了宝贵的经验,强调了在目标检测比赛中模型泛化能力的重要性。
摘要由CSDN通过智能技术生成

前言

最近在为秋招做准备,回顾到参加过的Kaggle比赛,发现还没有完整地整理一下代码。
我们HellooHalo组(没错就这么随性hhh<3)的最高名次曾经在锁榜后达到过前百,不过很可惜后面因为YoloV5的license is not MIT compliant,导致Notebook被删成绩取消。也算是我为什么很长时间不愿意去回顾这个项目的原因,实在太痛了。。
在这里插入图片描述

第二次rerun private testset后的leader board,还勉强踩了个银牌的尾巴。

Anyways,虽然槽点很多,但是作为YOLOv5的第一次实战,还是给我提供了不少宝贵的经验。
目前很多排行榜前列的大神都发表了他们的Notebook,这篇文章也会对其中有价值的tricks作出总结和提炼。可以点击这里查看

为什么要用YOLOv5?

江大白的YOLOv5总结
这篇文章对YOLOv5总结的非常好,感兴趣的朋友可以通读一下,收获很大。对于Global Wheat这个任务,最关键的性能提升体现在:

  1. Mosaic拼接数据增强。增强了对于小目标的检测效率。
  2. 可选的多个模型。这里我们用YOLOv5x,CSP结构赋予了很强的特征提取能力,它有着4个残差结构。
  3. 根据作者在github上发表的性能对比,YOLOv5比YOLOv3&4明显强,甚至强于当前的two-stage SOTA EfficientDet。(插一句,下一篇我打算写一片基于pytorch从头搭建EfficientDet的文章)
    在这里插入图片描述
    其实说这么多,还是因为discussion board上有大佬试出来YOLOv5的效果很好。。这种东西80%都是玄学,不可说。。

Notebook 代码

我将以Kaggle Notebook上的运行顺序详细介绍每一步的操作和注意事项,争取能帮助读者复用到其他的任务上。

导包和安装YOLOV5

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import os
from tqdm.auto import tqdm
import shutil as sh

!pip install --no-deps '../input/weightedboxesfusion/' > /dev/null

数据格式转化

好的我知道我前面留下来一个坑,就是各类型数据转化的代码和讲解,我会在一周内补上的。

def convertTrainLabel():    
    df = pd.read_csv('../input/global-wheat-detection/train.csv')
    # 取出bbox[xmin, ymin, w, h]格式
    bboxs = np.stack(df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))
    for i, column in enumerate(['x', 'y', 'w', 'h']):
        df[column] = bboxs[:,i]
    df.drop(columns=['bbox'], inplace=True)
    df['x_center'] = df['x'] + df['w']/2
    df['y_center'] = df['y'] + df['h']/2
    df['classes'] = 0
    from tqdm.auto import tqdm
    # 整理成df,格式看下面
    df = df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes']]
    index = list(set(df.image_id))
    
    # 在train的过程中按照val和train 分开放入不同的dir
    source = 'train'
    if True:
        for fold in [0]:
            val_index = index[len(index)*fold//5:len(index)*(fold+1)//5]
            for name,mini in tqdm(df.groupby('image_id')):
                if name in val_index:
                    path2save = 'val2017/'
                else:
                    path2save = 'train2017/'
                if not os.path.exists('convertor/fold{}/labels/'.format(fold)+path2save):
                    os.makedirs('convertor/fold{}/labels/'.format(fold)+path2save)
                with open('convertor/fold{}/labels/'.format(fold)+path2save+name+".txt", 'w+') as f:
                    row = mini[['classes','x_center','y_center','w','h']].astype(float).values
                    row = row/1024
                    row = row.astype(str)
                    for j in range(len(row)):
                        text = ' '.join
  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值