【Pipeline】林业病虫害防治AI昆虫识别项目
该节课程使用了百度与林业大学合作开发的林业病虫害防治项目中用到昆虫数据集。课程项目训练了一个YOLOv3模型,并基于它检测图像数据中的昆虫。

1 项目概述
1.1 原始项目简介
本项目基于百度AIStudio课程【手把手带你零基础入门深度学习-2.0版本】中课节12的内容——目标检测YOLOv3算法和AI识虫比赛改编。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
该节课程使用了百度与林业大学合作开发的林业病虫害防治项目中用到昆虫数据集。课程项目训练了一个YOLOv3模型,并基于它检测图像数据中的昆虫。目标检测YOLOv3算法课程讲解了YOLOv3的基础知识以及一些对昆虫数据集的预处理操作,AI识虫比赛课程则讲解了模型的“训练”、“评估”、“预测”步骤。本项目为了简化流程,只将Pipeline运用于AI识虫比赛的课程内容,故下文中出现的“原始项目”一词均指代AI识虫比赛
1.2 为什么使用Pipeline
Pipeline的详细介绍可参考Pipeline简介。
Op是Pipeline运行时的基本调度单位,Pipeline中的每一个节点都需要是一个Op。Op的具体介绍请查看Op详细介绍
2 构建并运行Pipeline
2.1 Pipeline构建思路
原始项目做的事情主要有“模型训练”、“模型评估”、“模型预测”。而针对一个原始项目,我们想基于它构建一个Pipeline,最重要的是以下2点。
构建Op:构建每个步骤对应的Op。可以设计一个函数来决定Op的运行逻辑,也可以让Op直接调用一个能完成该步骤的脚本文件。由于原始项目中已实现了所有步骤,所以本项目可以直接调用对应的脚本文件。
编排Op:设计Op之间的数据传递关系。原始项目中,“模型”以读写文件的形式在3个步骤间传递,那么对应的Op之间也应该合理的传递“模型”。以读写本地文件的方式传递,可拓展性较差,且不便于保存和管理”模型”。为了解决这个问题,我们可以利用Pipeline的特性,以输入Artifact和输出Artifact的形式传递”模型“。
关于Artifact:
Artifact是由Op生成的文件,在实际的Pipeline运行过程中,Op的输入和输出是以“Artifact”的形式保存和传递的。
Op在运行前,会从Artifact仓库把对应的文件下载到指定的输入存储路径下;Op在运行完后,会把指定的输出存储路径下的文件上传到Artifact仓库保存。
这样的机制能更科学的管理实验时运行的产出。更具体的描述可参考这里。
另外,我们也可以根据需要对原始项目的脚本进行优化。比如本项目优化了“模型训练”步骤,使它可以基于预训练模型进行训练。
至于具体如何构建Op,以及如何指定Op之间的关系,本文2.3将会介绍。现在我们先看下根据上述的设计思路,最终本项目设计出来的Pipeline的流程是怎样的。
2.2 Pipeline概述
2.2.1 Pipeline流程

根据上述的Pipeline构建思路,本项目的主要流程如上图所示,整个Pipeline由3类Op组成,分别为“模型训练”Op、“模型评估”Op、“模型预测”Op。
首先是“模型训练”Op,该Op的功能是,在指定的训练数据集上,训练一个YOLOv3模型,用户可以指定是否在预训练模型的基础上进行训练。模型训练完后,会保存训练完的模型,并作为输出Artifact传给下游的“模型评估”Op。
其次是“模型评估”Op,该Op通过将上游的“模型训练”Op的输出Artifact,即模型,指定为输入Artifact来获取这些训练好的模型。评估所使用的数据集由用户指定。评估阶段会计算每个模型在评估数据集上评估所得到的mAP,并将其写入到日志中。同时,该Op会将最好的模型(暂时规定为mAP最高的模型)保存下来。该模型也将作为输出传给下游的“模型预测”Op。
最后是“模型预测”Op,该Op会使用从”模型评估“Op得到的模型,在用户指定的预测数据集上进行预测,最终预测结果会以标注框的形式显示在图像数据上,并保存下来。
2.2.2 文件目录结构
为了更好的理解后面讲到的各个函数的参数的含义,需要先简单浏览一下本案例的文件的目录结构。
可点击链接昆虫检测下载项目代码
bug_detection/├── bug_detection.ppl├── pretrained_model│ └── yolo_epoch50.pdparams└── script ├── anchor_lables.py ├── box_utils.py ├── calculate_map.py ├── darknet.py ├── draw_anchors.py ├── draw_results.py ├── eval.py ├── image_utils.py ├── insects_reader.py ├── map_utils.py ├── multinms.py ├── predict.py ├── reader.py ├── train.py └── yolov3.py登录后复制
如上所示,pipeline.ppl构建了一个Pipeline;预训练模型存放在pretrained_model文件夹下;而script文件夹下存放了Python脚本,这些脚本文件是基于课程中的脚本文件修改的,其中除了主要的train.py、eval.py、preadict.py外,其他的文件主要包含了一些功能函数,它们的主要内容如下所示:
数据集由于过大,在AIStudio上需要以挂载的形式存在,因此不在该目录下。
本项目构建了专门处理数据集的Op,用户无需自行处理
2.3 构建Pipeline
想要构建Pipeline,通常需要先完成2个步骤。首先是构建Op,然后是编排Op。
构建Op:本项目首先将模型的“训练”、“评估”、“预测”这三个步骤,分别用一个函数进行封装。这些函数会构建并返回一个Op,而Op能完成对应的步骤。本文称这些函数为Op构建函数。
编排Op:有了Op之后,本项目定义了一个函数来编排这些Op,确定它们的关系,进而构建Pipeline。本文称该函数为Pipeline函数。
接下来本文将依次讲解Op构建函数和Pipeline函数,这两个函数通常我们会在ppl文件中定义,如本项目的pipeline.ppl文件。
2.3.1 构建Op
如上文所说,我们需要先构建Pipeline需要的Op。
本项目中,有3类Op,“模型训练”Op、“模型评估”Op、“模型预测”Op,它们分别由函数train()、evaluate()、predict()来构建并返回。
train()函数
train()函数的功能是根据参数构建并返回一个"模型训练"Op。该Op会训练一个模型并保存下来。它的代码如下所示:
def train(ds_dir, pretrain_model_path="", output_model_dir="train_output", epoch=1, batch_size=10, device="gpu"): return ScriptOp(name="Model Train Op", command=["python3", "script/train.py"], arguments=["--device", device, "--epoch", epoch, "--batch_size", batch_size, "--output_dir", output_model_dir, "--param_path", pretrain_model_path], inputs={"train_dataset": ds_dir}, outputs={"model": output_model_dir})登录后复制上述代码调用了ScriptOp的构造函数。通过command参数指定该Op完成“模型训练”这个步骤的方式为“运行train.py脚本”,而train.py的主要功能进行模型训练。
通过arguments参数可以指定传递给command命令的参数,这些参数最终传递给train.py,在运行脚本的时候被使用。具体来说,--ds_dir用来指定训练数据集的存储目录;--output_dir用来指定训练完成后模型保存的目录;而--param_path用来指定预训练模型的存储路径,这个参数是原始项目中所没有的。
而outputs指定了当train.py脚本执行完后,Op会将什么路径下的文件以Artifact的形式上传到Artifact仓库。
ScriptOp参数:
ScriptOp是一个Op类别,这里简单介绍一下ScriptOp的构造函数中比较重要的参数
command:指定Op执行什么样的命令
arguments:传递给command命令的参数
inputs:传递一个dict,其中key为输入的名称,value为输入Artifact。
outputs:传递一个dict,其中key为输出的名称,value为一个路径,在Op运行完后,路径下的文件会作为输出,被上传到Artifact仓库
关于ScripOp构造函数的参数详解或者其他参数,可以参考Pipeline编排详解
另外,关于上文提到的train.py,本项目在原始项目的基础上进行了优化:支持在通过参数指定预训练模型的基础上进行训练。添加的代码如下所示:
if args.param_path: state_dict = paddle.load(args.param_path) model.load_dict(state_dict)登录后复制
上述代码的args.param_path就是通过ScritpOp构造函数的arguments传递给command命令,再进而传递给train.py。
除了上述的train()函数的主要逻辑,它的参数列表如下所示:
evaluate()函数
evaluate()函数的功能是根据参数构建并返回一个”模型评估“Op,评估Op的主要功能是,对从上游的“模型训练”Op获取的模型进行评估,评估后会将结果写入日志中,同时评估Op还会将最好的模型以输出Artifact的形式保存下来。
def evaluate(ds_dir, model_inputs, output_model_dir="eval_output", device="gpu"): return ScriptOp(name="Evaluate Op", command=["python3", "script/eval.py"], arguments=["--output_dir", output_model_dir, "--model_names"] + list(model_inputs.keys()), inputs={**model_inputs, **{"eval_dataset": ds_dir}}, outputs={"model": output_model_dir} )登录后复制evaluate()函数构建Op的逻辑和train()函数类似。通过command让Op执行一个脚本,也就是eval.py脚本;通过arguments给命令传递参数。
inputs参数的作用是指定该Op运行时,有哪些数据以输入Artifact的形式传递给Op。在给该参数赋值时,除了指定输入的名称和内容,还可以选择是否指定输入的存放路径。
关于inputs和outputs参数的赋值,更详细的介绍可参考ScriptOp详解
eval.py脚本的主要内容与原始项目中train.py的模型评估部分相似,但有一定优化,优化后的eval.py可以对多个不同的YOLOv3模型进行评估,实现的代码如下所示:
weight_files = []for name in args.model_names: # 通过环境变量获取Artifact的存储路径 # os.getenv(name)的返回值是一个代表路径的字符串,如"./pretrained" weight_files.append(os.getenv(name)+'/param.pdparams') for params_file_path in weight_files: model = YOLOv3(num_classes=NUM_CLASSES) model_state_dict = paddle.load(params_file_path) model.load_dict(model_state_dict) model.eval()登录后复制
上述代码中,model_names是通过ScriptOp构造函数的arguments参数传递进来的。这些name的值为环境变量名,环境变量的值为待评估模型对应的Artifact的存储路径。具体原理可参考下面的注释。
关于inputs和outputs生成的环境变量:
在本项目中,所有Op的输入,也就是inputs,在赋值时都没有指定存放路径,这种情况下,Pipeline会自动生成一个路径用来存放Op的输入。
另外,对于所有Op的输入Artifact和输出Artifact,Pipeline会生成环境变量,用来保存这些Artifact的存储路径,用户也就可以通过这些环境变量来获取Artifact的存储路径,进而使用Artifact。环境变量名为Artifact的名称,即赋值时对应的key值。更具体的讲解可查看通过环境变量获取Artifact存储路径
最后,evaluate()函数的参数如下所示:
predict()函数
predict()函数的功能是构建并返会一个“模型预测”Op,该Op使用评估得出的最佳模型进行预测,预测的结果会以Bounding Box的形式标注在原图像中,并将标注后的图像保存到指定的目录下。
def predict(ds_dir, model_input, res_save_dir="predict_output", device="gpu"): return ScriptOp(name="Predict Op", command=["python3", "script/predict.py"], arguments=["--output_dir", res_save_dir], inputs={**model_input, **{"test_dataset": ds_dir}})登录后复制predict()函数构建Op的方式和上述的train()和evaluate类似,其中的command、arguments、inputs参数的功能与前面的用法一致,这里不过多赘述。
predict()函数的参数如下所示:
2.3.2 编排Op
有了Op之后,我们就可以通过一个Pipeline函数来编排这些Op。
本项目定义的了如下的pipeline_func函数,该函数可在pipeline.ppl中查看。
def pipeline_func(train_ds_dir="dataset/train", eval_ds_dir="dataset/val", predict_img_dir = "dataset/test/images", device="gpu"): # Prepare dataset. This Op is Specially built for AIStudio. dataset_op = unzip_dataset(train_ds=OutputResource(), eval_ds=OutputResource(), test_ds=OutputResource()) train_op1 = train(ds_dir=dataset_op.outputs["train_ds"], output_model_dir="train_output/no_pretrained", batch_size=batch_size, device=device) train_op2 = train(ds_dir=dataset_op.outputs["train_ds"], pretrain_model_path="pretrained_model/yolo_epoch50.pdparams", output_model_dir="train_output/pretrained", batch_size=batch_size, device=device) eval_op = evaluate(ds_dir=dataset_op.outputs["eval_ds"], model_inputs={"no_pretrained": train_op1.outputs["model"], "pretrained": train_op2.outputs["model"]}, output_model_dir="eval_output") predict_op = predict(ds_dir=dataset_op.outputs["test_ds"], model_input={"model": eval_op.outputs["model"]}, res_save_dir="predict_res")登录后复制如上代码所示,Pipeline先后调用了4种Op构建函数,其中第一个调用的unzip_dataset()函数是专门针对AIStudio的数据集挂载机制,而定义的数据集解压Op构建函数,它会解压挂在的数据集,并通过Artifact的方式将数据集传递给"训练"、"评估"、"预测"Op。
剩下的3中Op构建函数在上文介绍过,分别为train()、evaluate()、predict()。
首先我们调用了两次train()函数,传入不同的参数,先后构建两个“训练”Op,并分别赋值给train_op1和train_op2。这两个训练Op会分别输出两个训练后的模型,其中train_op2是基于预训练模型来训练的。
train_op1和train_op2的下游Op是evaluate()函数构建的eval_op,它对所有从train_op获得的模型进行评估,并将最好的模型作为输出传输到下游的predict_op。
train_op1.outputs["model"]为train_op1中名称为“model”的输出Artifact,这个名称是在train()函数中通过outputs参数指定的。具体原理可参考输出Artifact
predict_op由predict()函数构建,它会使用从上游获得的模型在指定的测试数据集上进行预测,并将结果以图片的形式保存下来。
和普通函数一样,pipeline_func也能传入参数,在本项目中,传入的4个参数中,前3个依次是训练、评估、预测3个数据集的存储路径,最后一个是用来决定运行时是用的是CPU还是GPU。
2.4 运行Pipeline
编排好一个Pipeline后,我们可以尝试运行Pipeline。
在定义了pipeline_func的pipeline.ppl文件中输入如下代码:
Run().create(pipeline_func)登录后复制
这行代码的主要作用是根据用户定义的Pipeline函数,运行对应的Pipeline,pipeline_func就是本项目定义的Pipeline函数。
2.4.1 在CodeLab运行
我们可以在CodeLab上,选择并跳转到.ppl文件的代码编辑页面,就可以通过界面交互的方式简单快捷的运行Pipeline。
本地调试
可以通过点击“调试”按钮的方式运行Pipeline,如下图所示。

在Pipeline运行时,终端上会先后显示训练的进度、评估的结果、预测的结果,以及其他信息,具体如下所示。
训练Op运行时,终端输出的部分信息:

本地运行
调试过后,如果没有Bug,就可以正常运行了,本地运行和本地调试从结果来看稍有不同,这里暂不展开,有兴趣可以查看本地运行任务。
操作方式如下图所示:

点击运行后,会弹出一个界面,在这个界面可以选择“单次运行”还是“周期运行”。同时还可以指定想要传给Pipeline的参数。具体界面如下图所示:

本地运行的优势之一在于,可以将运行记录保存下来,每一次运行的参数、结果等信息,都会被记录,这有利于用户分析问题,也便于日后的复现。查看运行历史记录的界面在左侧的菜单栏,点击图标即可查看所有的记录。如下图所示:

再点击某一条记录,就可以查看详情。详情页面如下所示:

在CodeLab上,还可以在运行前通过可视化的方式查看Op之间的关系和每个Op的相关信息,具体方式可查看可视化
2.4.2 以命令行的方式运行
除了在CodeLab上以界面交互的方式运行,我们也能在终端以命令行的方式运行Pipeline。
输入如下命令可以以本地调试的方式运行:
ppl run create bug_detection.ppl --debug --show-log登录后复制
其中 bug_detection.ppl就是我们编写Pipeline的文件,--debug表示以调试的方式运行,--show-log会将脚本的输出显示在终端上。
同样,也可以不以调试的模式运行,只需去掉--debug即可,命令如下:
ppl run create bug_detection.ppl --show-log登录后复制
更多命令行的操作,如查看运行记录等,可查看命令行运行
相关攻略
常见报错解析:“Access Not Configured”故障排除指南 许多开发者和团队成员在使用OpenClaw集成飞书时,都曾遭遇过一个典型的中断提示:“access not configured”(访问未配置)。该提示会明确显示您的飞书账户ID及一组唯一的配对验证码,并指出需要联系机器人所有
OpenClaw 常用指令大全与使用详解 openclaw status:此命令是查看OpenClaw系统整体健康状态的核心指令,执行后即获取服务运行状况的全面报告,是日常运维的首要诊断工具。 openclaw gateway restart:在修改网关配置后,必须运行此指令以重启网关服务,使配置文
如何通过 OpenClaw 实现 Chrome 浏览器自动化操控 在软件开发与自动化测试领域,持续学习是常态。本文旨在详细介绍如何利用 OpenClaw 连接并控制一个已开启的 Chrome 浏览器实例,实现点击、文本输入、文件上传、页面滚动、屏幕截图以及执行 JavaScript 等自动化操作。整
项目概述 你是否希望将强大的 AI 助手带入日常聊天?本教程将指导你完成搭建流程,让你能在 QQ 上直接调用 OpenClaw 智能助手,实现无门槛的 AI 对话体验。 架构说明 ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ QQ 用户 │ ─
一 下载并安装Node js,全程保持默认设置 首先,请前往Node js官方网站的下载中心:https: nodejs org zh-cn download。根据您的操作系统(Windows Mac Linux)下载对应的安装程序。运行安装向导时,整个过程非常简单,您只需连续点击“下一步”按钮
热门专题
热门推荐
《洛克王国世界》呼唤独角兽的正确姿势 在《洛克王国世界》的主线任务中,有时会遇到需要精确输入特定角色名称的环节。其中一个关键节点,便是要准确拼写出独角兽“伊利斯”的真名。很多玩家稍不注意就可能记错或用错字,导致任务流程在此停滞不前。这篇指南将为你清晰解析正确的输入方法,助你快速通关。 《洛克王国世界
《洛克王国世界》风眠圣所“向上的方法”任务图文通关指南 在《洛克王国世界》的风眠圣所探险过程中,很多玩家会在“找到向上的方法”这一环节遭遇卡点。实际上,只要理清思路、明确顺序,完成这个挑战并不困难。本攻略将为你提供一套经过验证的详细图文流程,帮助你一次性顺利通过。 最后的关键操作非常简单:准确判断风
《洛克王国世界》叶冕魔力猫打法全攻略:高效通关技巧解析 在《洛克王国世界》的主线剧情推进中,挑战初始精灵首领叶冕魔力猫是一个重要环节。许多玩家在这个关卡遇到了困难,感觉难以突破。不必担心,这份详尽的实战打法指南将为你提供清晰的过关思路,帮助你轻松击败叶冕魔力猫。 核心挑战思路与强力精灵推荐 与叶冕魔
《洛克王国世界》罗隐捕捉指南:高效获取圣羽翼王挑战关键战宠 在《洛克王国世界》中,成功挑战传说精灵圣羽翼王是许多训练师的终极目标之一。选择合适的战宠至关重要,而罗隐以其出色的对抗能力,已成为公认的核心攻略选择。那么,这只关键的宠物究竟在哪里可以捕获?本文将为你提供详尽的罗隐捕捉位置图解与实用技巧。
速览 在《大店小二》中,如何高效使用元宝和银两是新手玩家普遍面临的难题。资源有限,如何将每一分投入转化为最大收益?本文将深入解析两类资源的最优使用策略,核心原则是:元宝投资于长期价值,银两专注于核心养成。 大店小二元宝与银两使用优先级攻略 1 元宝使用指南 首要建议:若非充值玩家,请勿将元宝大量用





