转自AI Studio,原文链接:【小白教程】PaddleX的大白菜危害检测训练、预测以及服务端Serving部署 - 飞桨AI Studio

1、项目背景介绍

我国白菜种植面积大,2015年,白菜种植面积261.8万公顷,2016年白菜种植面积262.73万公顷。 大白菜产量大,且多采用大面积种植方案,但由于人力资源及成本问题难以对大规模菜叶一一进行大白菜叶子的健康和潜在感染检测判断。 随着计算机视觉技术的发展,以及无人化、自动化农田运营理念的提出,利用图像识别技术及目标检测技术实现农产品的自动检测的需求呼之欲出,可通过计算机视觉的方法对菜叶情况进行分析,可以实现早期病害预警,减少人力资源成本以及降低财产损失。

本项目基于飞桨场景应用开发套件--PaddleX进行模型训练,十分钟快速完成全流程开发。

PaddleX是飞桨提供的全流程开发工具。它集飞桨核心框架、模型库、工具及组件等深度学习开发所需全部能力于一身,将智能视觉领域的四大任务:图像分类、目标检测、语义分割、实例分割的数据读取、数据增强、超参配置、训练评估等进行模块化抽象,并全流程打通,并提供简明易懂的Python API,方便用户根据实际生产需求进行直接调用或二次开发。

考虑产业实践的真实诉求,飞桨团队还为大家实现了一个基于PaddleX开发的可视化前端界面,提供Windows、Linux、Mac系统的一键安装包,让大家可以快速领略PaddleX可以为产业带来的效用。大家还可以基于PaddleX开发各种各样满足自己需求的产品。

PaddleX项目地址:https://github.com/PaddlePaddle/PaddleX

PaddleX文档链接:https://github.com/PaddlePaddle/PaddleX#paddlex-使用文档

PaddleX可视化模型训练客户端下载:https://www.paddlepaddle.org.cn/paddle/paddlex

PaddleX用户QQ群: 1045148026

前往GitHub给PaddleX点击Star,关注项目,即可随时了解PaddleX的最新进展

说了这么多 下面我们直接开干

2、数据集介绍

2.1 数据集简介

该项目包含两份数据集。
一份为原始数据集 大白菜病害数据集,该数据集包含大白菜叶子的健康和潜在感染图片,目的是将其用于由拉古纳马来亚大学学生进行的有关机器学习和疾病检测的本科论文研究。参与的学生是 Giane Apuada、JanPeter Virtucio 和 Dante Parra。 数据由训练数据集和测试数据集组成。训练 csv 数据集已被标记为包含疾病类别,例如背蛾、潜叶虫和霉菌。相应的图像也已正确命名以正确反映它们所包含的疾病类别。如果它们接触 x 种疾病,那么它们将在数据集上标记为“1”。否则标记为“0”。
另一份数据集白菜数据集在大白菜数据集的基础上,经过加工分割出训练集,测试集等产生的子训练集。

2.2 数据集处理

使用PaddleX进行训练对数据集的划分和格式具有一定要求,需要进行预处理。原始数据集中,批注都在csv中不好处理(实际是我太菜了),于是我取了个巧,我在本地使用PaddleX的可视化模型训练客户端对数据集进行了处理,之后将处理好的数据集文件全部打包上传。处理好的数据集如下图:

PS:在数据集大厅寻找时,我发现一个这样的数据集,看来是曾经有人这样做过,在这里我就直接用的他的数据集

小Tips:如果以后我们拿到的数据集不是VOC格式的,我们或许可以通过PaddleX的可视化模型训练客户端对数据集进行预处理,这样会省我们很多事,如果是标准的VOC格式,我们就用PaddleX的划分数据集的API。

2.3 数据集展示

展示数据集中图像的数量,类别,以及随机一张图像。

2.3.1 解压数据集

我们直接解压处理好的数据集

In [1]

!unzip -oq /home/aistudio/data/data129132/baicai.zip -d /home/aistudio/work/

!tree /home/aistudio/work/ -d #查看目录结构
/home/aistudio/work/
├── backmoth
├── leafminer
└── mildew

3 directories

展示数据集

In [71]

with open("/home/aistudio/work//train_list.txt", "r") as trainList: 
    trainDatas = trainList.readlines()
    print('训练集图片数量: {}'.format(len(trainDatas)))

with open("/home/aistudio/work/test_list.txt", "r") as testList: 
    testDatas = testList.readlines()
    print('测试集图片数量: {}'.format(len(testDatas)))

with open("/home/aistudio/work/val_list.txt", "r") as valList: 
    valDatas = valList.readlines()
    print('验证集图片数量: {}'.format(len(valDatas)))
训练集图片数量: 2016
测试集图片数量: 287
验证集图片数量: 575

In [6]

# 从三种病害种类中各抽取一张图像进行可视化
import cv2    #导入库
import numpy as np 
import matplotlib.pyplot as plt
%matplotlib inline
img1_bgr = cv2.imread('work/backmoth/Backmoth1729.jpg')
plt.imshow(cv2.cvtColor(img1_bgr,cv2.COLOR_BGR2RGB))          
plt.show() 

img2_bgr = cv2.imread('work/leafminer/Leafminer58.jpg')
plt.imshow(cv2.cvtColor(img2_bgr,cv2.COLOR_BGR2RGB))
plt.show()

img3_bgr = cv2.imread('work/mildew/Mildew126.jpg')
plt.imshow(cv2.cvtColor(img3_bgr,cv2.COLOR_BGR2RGB))
plt.show()               

<Figure size 432x288 with 1 Axes>

<Figure size 432x288 with 1 Axes>

<Figure size 432x288 with 1 Axes>

3、模型选择

本任务是个图像分类任务,这里我们选择的模型是MobileNetV系列的模型。

MileNetV2是一个图像分类模型,其是基于深度分离卷积和倒置残差结构的网络,能更好地匹配移动和嵌入式设备。

MobileNetV3是在MobileNetV2的基础上提出的网络,其计算量小、参数少,相比其他轻量级网络,依然取得了较好的成绩;MobileNetV3_samll是使用百度基于蒸馏方法得到的MobileNetV3预训练模型,模型结构与MobileNetV3一致,但精度更高。PaddleX内置了20多种分类模型,查阅PaddleX 图像分类模型API了解更多分类模型。

相比较之下,我们选择MobileNetV3_samll。

PS:还有其他的模型,各位可以自己尝试一下。

3.1 安装PaddleX

In [ ]

pip install paddlex==2.1.0 -i https://mirror.baidu.com/pypi/simple

In [ ]

!pip install cython  
!pip install pycocotools

3.2 定义图像处理流程transforms

In [78]

#配置一下GPU
import matplotlib
matplotlib.use('Agg') 
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import warnings
warnings.filterwarnings("ignore")
import paddlex as pdx

In [79]

from paddlex import transforms as T
train_transforms = T.Compose([
    T.RandomCrop(crop_size=224),
    T.RandomHorizontalFlip(),
    T.Normalize()])

eval_transforms = T.Compose([
    T.ResizeByShort(short_size=256),
    T.CenterCrop(crop_size=224),
    T.Normalize()
])

3.3 定义dataset加载图像分类数据集

In [ ]

train_dataset = pdx.datasets.ImageNet(
    data_dir='/home/aistudio/work',
    file_list='/home/aistudio/work/train_list.txt',
    label_list='/home/aistudio/work/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
    data_dir='/home/aistudio/work',
    file_list='/home/aistudio/work/val_list.txt',
    label_list='/home/aistudio/work/labels.txt',
    transforms=eval_transforms)

In [ ]

num_classes = len(train_dataset.labels)
model = pdx.cls.MobileNetV3_small(num_classes=num_classes)

model.train(num_epochs=10,
            train_dataset=train_dataset,
            train_batch_size=32,
            eval_dataset=eval_dataset,
            lr_decay_epochs=[4, 6, 8],
            save_dir='output/mobilenetv3_small',
            use_vdl=True)

4、模型预测

In [86]

import paddlex as pdx
img_predit = '/home/aistudio/work/leafminer/Leafminer1.jpg'
model = pdx.load_model('/home/aistudio/data/output/mobilenetv3_small/best_model')
result = model.predict(img_predit)

print("Predict Result: ", result)
2022-04-26 08:48:42 [INFO]	Model[MobileNetV3_small] loaded.
Predict Result:  [{'category_id': 1, 'category': 'leafminer', 'score': 0.999624}]

4.1 导出训练模型

In [ ]

!paddlex --export_inference --model_dir=/home/aistudio/data/output/mobilenetv3_small/best_model --save_dir=./inference_model

5、模型评估

我们将训练过程可视化查看 

使用MobileNetV3_samll模型进行训练,最后模型精度达到0.9948 

PS:我太菜了 最后是借助的PaddleX GUI工具进行辅助查看的模型精度

6、HubServing轻量级服务化部署

注意:使用此方式部署,需确保自己Python环境中PaddleHub的版本高于1.8.0,因此需要将AI Studio中的Paddlehub升级。

部署模型的格式均为目录下包含__model__,__params__和model.yml三个文件,也就是inference_model目录下的文件格式。

In [ ]

!pip install paddlehub -U

模型转换

将PaddleX的Inference Model转换成PaddleHub的预训练模型,使用命令hub convert即可一键转换,对此命令的说明如下:

参数用途
--model_dir/-mPaddleX Inference Model所在的目录
--module_name/-n生成预训练模型的名称
--module_version/-v生成预训练模型的版本,默认为1.0.0
--output_dir/-o生成预训练模型的存放位置,默认为{module_name}_{timestamp}

In [ ]

!hub convert  --model_dir ./inference_model \
              --module_name hatdet \
              --module_version 1.0 

模型安装

将模型转换得到的.tar.gz格式的预训练模型压缩包,在进行部署之前需要先安装到本机,使用命令hub install一键安装

In [ ]

!hub install hatdet_1650935008.3757877/hatdet.tar.gz #这里需要随机应变 灵活一点 因为每一次压缩包所在的文件名不一样

模型部署

打开终端1,输入hub serving start -m hatdet完成大白菜检测模型的一键部署 

下面我们通过POST请求实现预测

In [95]


import requests
import json
import cv2
import base64
import numpy as np
import colorsys
import warnings
warnings.filterwarnings("ignore")
plt.figure(figsize=(12,8))

def cv2_to_base64(image):
    data = cv2.imencode('.jpg', image)[1]
    return base64.b64encode(data.tostring()).decode('utf8')


if __name__ == '__main__':
    # 获取图片的base64编码格式
    img1 = cv2_to_base64(cv2.imread("/home/aistudio/work/backmoth/Backmoth1.jpg"))
    img2 = cv2_to_base64(cv2.imread("/home/aistudio/work/mildew/Mildew1.jpg"))
    data = {'images': [img1, img2]}
    # data = {'images': [img1]}
    # 指定content-type
    headers = {"Content-type": "application/json"}
    # 发送HTTP请求
    url = "http://127.0.0.1:8866/predict/hatdet"
    r = requests.post(url=url, headers=headers, data=json.dumps(data))

    # 打印预测结果,注意,r.json()["results"]本身就是一个数组,要取到对应图片的预测结果,需指定元素位置,如r.json()["results"][0]
    print(r.json()["results"][0])
[{'category': 'backmoth', 'category_id': 0, 'score': 0.9794929623603821}]
<Figure size 864x576 with 0 Axes>

上面的预测结果 原图如下:

病害类型确实是:backmoth 预测正确

总结

这里选择的模型部署方式比较简单,我们还可以选择安卓部署,有硬件的我们还可使用PaddleLite进行部署,我们的选择很多,有兴趣的小伙伴可以试试

同时对于模型的选择 我们也还有其他的选择,比如尝试一下MobileNetV3_ssld

关于作者

湖北经济学院 2019级 计算机科学与技术专业 本科生 余卓凡(纯种小白一枚)

我在AI Studio上获得青铜等级,点亮1个徽章,来互关呀~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/879971

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐