讯飞叶菜病虫害图像识别挑战赛

简介: 讯飞叶菜病虫害图像识别挑战赛

一、赛事背景 农作物病虫害严重制约着农业生产,因为农作物病虫害种类多、密度大,极易造成农作物大量减产。同时由于传统人眼识别病虫害的方法速度较慢、准确度较低,会导致农药的滥用,破坏自然环境。如今随着精准农业和智慧农业概念的兴起和发展,利用信息技术辅助农业生产,实现对农作物病虫害的智能识别和检测,以减少不必要的农药喷施,对保护生态系统均衡,保障农作物安全生产,提高农作物的质量方面,有着十分重要的促进作用。


二、赛事任务 最为有效的病虫害识别方法是图片识别,本次大赛提供了大量农民在田间地头拍摄的叶菜的病虫害图片,参赛选手需基于提供的样本构建模型,实现叶菜的病虫害图像识别,即为图片分类。


初赛一阶段:6月21日到8月18日。


初赛二阶段:8月19日到8月20日。系统将在8月19日00:00更换测试数据,参赛队伍需要再次下载数据


三、评审规则 1.数据说明 本次比赛为参赛选手提供了叶菜的病虫害图像数据:包括图像及其所属病虫害标签。数据主体为农民在不同环境条件下拍摄的叶菜农作物图像,每张图像的主体突出度,背景复杂程度、光照条件,图像清晰度均存在一定差别。选手可自己搜集训练数据提升模型识别效果,需要将搜集的图片上传至官方云盘。图片已按类别放在不同文件夹内,文件夹名称即为图片的category_id。


1:用药不当

2:疫病

3:炭疽病

四、数据展示


image.pngimage.pngimage.png


基线分数


image.png

# 数据集解压
!cd 'data/data98431' && unzip -q bingchonghai.zip


数据EDA


image.png


数据预处理及读取


# 导入所需要的库
from sklearn.utils import shuffle
import os
import pandas as pd
import numpy as np
from PIL import Image
import paddle
import paddle.nn as nn
from paddle.io import Dataset
import paddle.vision.transforms as T
import paddle.nn.functional as F
from paddle.metric import Accuracy
import warnings
warnings.filterwarnings("ignore")
# 读取数据
train_images = pd.read_csv('work/train1.csv')
train_images = shuffle(train_images)
# 划分训练集和校验集
all_size = len(train_images)
# print(all_size)
train_size = int(all_size * 0.8)
train_image_list = train_images[:train_size]
val_image_list = train_images[train_size:]
df = train_image_list
train_image_path_list = df['image_id'].values
label_list = df['category_id'].values
label_list = paddle.to_tensor(label_list, dtype='int64')
train_label_list = paddle.nn.functional.one_hot(label_list, num_classes=3)
val_image_path_list = val_image_list['image_id'].values
val_label_list = val_image_list['category_id'].values
val_label_list = paddle.to_tensor(val_label_list, dtype='int64')
val_label_list = paddle.nn.functional.one_hot(val_label_list, num_classes=3)
# 定义数据预处理
data_transforms = T.Compose([
    T.Resize(size=(224, 224)),
    T.RandomRotation(90),
    T.RandomCrop(224),
    T.RandomHorizontalFlip(0.5),
    T.RandomVerticalFlip(0.5),
    T.Transpose(),    # HWC -> CHW
    T.Normalize(
        mean=[0, 0, 0],        # 归一化
        std=[255, 255, 255],
        to_rgb=True)    
])
# 构建Dataset
class MyDataset(paddle.io.Dataset):
    """
    步骤一:继承paddle.io.Dataset类
    """
    def __init__(self, train_img_list, val_img_list,train_label_list,val_label_list, mode='train'):
        """
        步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集
        """
        super(MyDataset, self).__init__()
        self.img = []
        self.label = []
        # 借助pandas读csv的库
        self.train_images = train_img_list
        self.test_images = val_img_list
        self.train_label = train_label_list
        self.test_label = val_label_list
        if mode == 'train':
            # 读train_images的数据
            for img,la in zip(self.train_images, self.train_label):
                self.img.append('data/data98431/bingchonghai/train/'+img)
                self.label.append(la)
        else:
            # 读test_images的数据
            for img,la in zip(self.test_images, self.test_label):
                self.img.append('data/data98431/bingchonghai/train/'+img)
                self.label.append(la)
    def load_img(self, image_path):
        # 实际使用时使用Pillow相关库进行图片读取即可,这里我们对数据先做个模拟
        image = Image.open(image_path)
        return image
    def __getitem__(self, index):
        """
        步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
        """
        image = self.load_img(self.img[index])
        label = self.label[index]
        # label = paddle.to_tensor(label)
        return data_transforms(image), paddle.nn.functional.label_smooth(label)
    def __len__(self):
        """
        步骤四:实现__len__方法,返回数据集总数目
        """
        return len(self.img)
#train_loader
train_dataset = MyDataset(train_img_list=train_image_path_list, val_img_list=val_image_path_list, train_label_list=train_label_list, val_label_list=val_label_list, mode='train')
train_loader = paddle.io.DataLoader(train_dataset, places=paddle.CPUPlace(), batch_size=196, shuffle=True, num_workers=0)
#val_loader
val_dataset = MyDataset(train_img_list=train_image_path_list, val_img_list=val_image_path_list, train_label_list=train_label_list, val_label_list=val_label_list, mode='test')
val_loader = paddle.io.DataLoader(val_dataset, places=paddle.CPUPlace(), batch_size=196, shuffle=True, num_workers=0)


模型训练及保存


# 调用飞桨框架的VisualDL模块,保存信息到目录中。
callback = paddle.callbacks.VisualDL(log_dir='visualdl_log_dir')
callbacks = paddle.callbacks.EarlyStopping(
    'loss',
    mode='min',
    patience=50,
    verbose=1,
    min_delta=0,
    baseline=0.99,
    save_best_model=True)
from visualdl import LogReader, LogWriter
args={
    'logdir':'./vdl',
    'file_name':'vdlrecords.model.log',
    'iters':0,
}
# 配置visualdl
write = LogWriter(logdir=args['logdir'], file_name=args['file_name'])
#iters 初始化为0
iters = args['iters'] 
#自定义Callback
class Callbk(paddle.callbacks.Callback):
    def __init__(self, write, iters=0):
        self.write = write
        self.iters = iters
    def on_train_batch_end(self, step, logs):
        self.iters += 1
        #记录loss
        self.write.add_scalar(tag="loss",step=self.iters,value=logs['loss'][0])
        #记录 accuracy
        self.write.add_scalar(tag="acc",step=self.iters,value=logs['acc'])
# from work.se_resnext import SE_ResNeXt50_vd_32x4d
from work.res2net import Res2Net50_vd_26w_4s
# 模型封装
model_res = Res2Net50_vd_26w_4s(class_dim=3)
model = paddle.Model(model_res)
# 定义优化器
optim = paddle.optimizer.Adam(learning_rate=1e-4, parameters=model.parameters())
# 配置模型
model.prepare(
    optim,
    paddle.nn.CrossEntropyLoss(soft_label=True),
    Accuracy()
    )
model.load('work/Res2Net50_vd_26w_4s_pretrained.pdparams',skip_mismatch=True)
save_dir = '/home/aistudio/work'
# 模型训练与评估
model.fit(train_loader,
        val_loader,
        log_freq=1,
        save_freq=10,
        save_dir=save_dir,
        epochs=20,
        callbacks=[Callbk(write=write, iters=iters), callbacks],
        verbose=1,
        )
# 保存模型参数
# model.save('Hapi_MyCNN')  # save for training
model.save('Hapi_MyCNN1_res2', False)  # save for inference


模型预测


  • 模型融合与TTA


test time augmentation,TTA

可将准确率提高若干个百分点,它就是测试时增强(test time augmentation, TTA)。这里会为原始图像造出多个不同版本,包括不同区域裁剪和更改缩放程度等,并将它们输入到模型中;然后对多个版本进行计算得到平均输出,作为图像的最终输出分数。有作弊的嫌疑。这种技术很有效,因为原始图像显示的区域可能会缺少一些重要特征,在模型中输入图像的多个版本并取平均值,能解决上述问题。


模型融合


我可能是搞了一个比较邪的模型融合,哈哈哈,分别是单独训练,在预测的时候加权融合。

import os, time
import matplotlib.pyplot as plt
import paddle
from PIL import Image
import numpy as np
from paddle.vision import transforms
import time
import pandas as pd
import patta as tta
paddle.set_device('gpu:0')
model1 = paddle.jit.load("Hapi_MyCNN1")
model2 = paddle.jit.load("Hapi_MyCNN1_res2")
model = tta.ClassificationTTAWrapper(model, tta.aliases.ten_crop_transform(224,224))
def read_img(path):
    img = Image.open(path).convert('RGB')
    transform_valid = transforms.Compose([
        transforms.Resize((224, 224)),
        # transforms.Transpose(),
        transforms.ToTensor(),
        transforms.Normalize(
            mean=[0, 0, 0],  # 归一化
            std=[255, 255, 255],
            to_rgb=True)
    ])
    img_tensor = transform_valid(img).unsqueeze(0)
    return img_tensor
def infer_img(path, model1, model2):
    '''
    模型预测
    '''
    model1.eval()
    model2.eval()
    data = read_img(path)
    out = model1(data) * 0.4 +  model2(data) * 0.6
    # print(out[0])
    # print(paddle.nn.functional.softmax(out)[0]) # 若模型中已经包含softmax则不用此行代码。
    lab = np.argmax(out.numpy())  # argmax():返回最大数的索引
    # label_pre.append(lab)
    return int(lab) + 1
img_list = os.listdir('data/data98431/bingchonghai/test')
pre_list = []
for i in range(len(img_list)):
    a = time.time()
    pre_list.append(infer_img(path='data/data98431/bingchonghai/test/' + img_list[i], model1=model1, model2=model2))
    b = time.time()
    print(b-a)
img = pd.DataFrame(img_list)
img = img.rename(columns = {0:"image_id"})
img['category_id'] = pre_list
img.to_csv('submit123456.csv', index=False)


总结


大家可以看到,我们的基线分数并不高,所以这很可能是一个失败的基线,模型预测的效果并不好,这个的难点就是细粒度分类,每个类别之间的区分度不是很大,所以仅仅是用这种方式还不够,大家还可以尝试一下元学习等方法,或者是不使用最后的softmax进行分类,使用距离进行类别判断。


目录
相关文章
|
3月前
|
机器学习/深度学习 监控 算法
野生菌有毒无毒物种识别数据集野生菌智能识别分享
本数据集含1500张专家标注高清图像,覆盖5种典型野生菌(3种无毒、2种有毒),采用YOLO标准格式,支持物种识别与毒性判断双任务。适用于YOLO/Faster R-CNN等模型训练,助力野外识菌APP、食品安全预警与真菌科普。
|
4月前
|
机器学习/深度学习 人工智能 算法
4类马铃薯品质缺陷检测数据集(瘀伤薯/裂纹薯/发芽薯/正常马铃薯)分享
本数据集含2200张实拍图像,涵盖瘀伤薯、裂纹薯、发芽薯及正常马铃薯4类,YOLO标准格式,人工精标,适用于智能分拣、农业质检与目标检测研究。
|
9月前
|
存储 弹性计算 Cloud Native
2026年最新一期阿里云优惠券解析:五种主要优惠券类型、金额、领取及使用规则讲解
为了进一步降低用户的上云成本,2026年阿里云继续推出多种优惠券,以助力用户轻松实现数字化转型。本文将全面介绍阿里云目前提供的五种主要优惠券类型,包括老友专属福利券包、无门槛优惠券、出海补贴优惠券、迁云补贴优惠券以及按量达标代金券等,帮助用户深入了解这些优惠券的金额、领取及使用规则,从而更好地利用这些优惠,提升购买体验。
1276 13
|
3月前
|
机器学习/深度学习 监控 算法
养殖场鸡只计数监控9000张YOLO智慧养殖数据集
本数据集含9000张真实养殖场场景下精细标注的鸡只图像,采用YOLO标准格式,覆盖雏鸡至成鸡、多种姿态/光照/遮挡及密集群体,专为智慧养殖中的自动计数、健康监测与精准饲喂等任务设计,适配YOLO系列及Faster R-CNN等模型。
|
5月前
|
人工智能 算法 机器人
18类户外生活垃圾检测数据集(3000张)|YOLO训练数据集 智慧环卫 户外垃圾识别 城市治理 环境监测
本数据集含3000张真实户外场景图像,精细标注18类高频生活垃圾(如塑料瓶、口罩、零食袋等),适配YOLO系列模型。覆盖街道、社区等复杂环境,含小目标、遮挡与多变光照,标注精准、结构规范,助力智慧环卫、无人机巡检与城市环境监测等AI落地应用。
|
11月前
|
弹性计算 负载均衡 容灾
阿里云渠道商:弹性公网IP和固定公网IP区别在哪?
本文解析弹性公网IP与固定公网IP的核心区别,涵盖资源关系、生命周期、高可用性、成本模式及适用场景。EIP独立灵活,支持动态绑定与容灾切换,适合生产环境;固定IP则绑定实例,适用于简单短期需求。选型建议根据业务重要性与扩展需求决定。
|
6月前
|
机器学习/深度学习 人工智能 运维
4类牛行为检测数据集(3600张)|YOLO训练数据集 智慧养殖 行为识别 健康监测 精准饲喂 牧场数字化管理
本数据集含3600张真实场景牛行为图像,精准标注4类关键行为(喝水、进食、卧下、站立),专为YOLO系列模型优化,支持智慧养殖、健康监测、精准饲喂与牧场数字化管理,开箱即用,助力农业AI落地。
|
5月前
|
机器学习/深度学习 数据采集 人工智能
桑叶病害目标检测数据集(16000张)|YOLO训练数据集 智慧农业 病虫害识别 农业AI 作物病害检测
本数据集含16000张真实田间桑叶病害高清图像,YOLO标准格式,单类别(病害)边界框标注。覆盖多光照、多生长阶段及轻/中/重度病害场景,标注精准、结构规范,专为智慧农业病虫害识别与农业AI模型训练设计,即下即用
|
11月前
|
机器学习/深度学习 人工智能 缓存
面试官连问21题:Transformer底层原理与测试工程全解析!
Transformer是大模型的核心架构,掌握其原理有助于理解AI推理、设计测试策略、排查异常。本文梳理21个高频面试题,从测试开发视角解析模块化结构与关键机制,助力构建智能测试体系。
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
1116 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡