当前位置: 首页 > news >正文

【论文源码实战】EdgeYOLO: 边缘设备友好的无锚框检测器

前言

这篇文章介绍了一种名为EdgeYOLO的高效、低复杂度且无锚点(anchor-free)的实时目标检测器,它基于最先进的YOLO框架,并能在边缘计算平台上实时运行。主要贡献包括:

  1. 设计了一个无锚点的目标检测器,能在边缘设备上实时运行,并在MS COCO2017数据集上达到50.6%的AP精度。

  2. 提出了一种更强大的数据增强方法,确保了训练数据的数量和有效性。

  3. 使用可重新参数化的结构来减少推理时间。

  4. 设计了一种损失函数,提高了对小目标的检测精度。

文章还详细介绍了EdgeYOLO的关键技术,包括增强的数据增强方法、轻量级解耦头(Lite-Decoupled Head)、分阶段损失函数(Staged Loss Function)以及针对小目标检测的优化。

总的来说,这篇文章提出了一种适用于边缘计算设备的高效实时目标检测器EdgeYOLO,通过一系列创新技术提高了小目标的检测精度,并在保持实时性的同时减少了模型的复杂度。未来的工作将进一步提高小目标的检测精度,并探索更高效的优化方法。

一、项目下载

git clone https://github.com/LSH9832/edgeyolo.git cd edgeyolo

二、环境配置

创建专属环境

conda create -n EdgeYOLO python=3.9

激活环境

conda activate EdgeYOLO

安装 Pytorch 环境

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple "torch-1.13.0+cu116-cp39-cp39-win_amd64.whl"pip install -i https://pypi.tuna.tsinghua.edu.cn/simple "torchvision-0.14.0+cu116-cp39-cp39-win_amd64.whl"

安装相关库

pip install -r requirements.txt

三、代码测试

python detect.py --weights ./weights/edgeyolo_coco.pth --source ./TestVideo/test.avi --fp16

四、使用自己的数据集进行训练

目前支持COCO、YOLO、VOC、VisDrone、DOTA五种格式的数据集

在这里我使用VOC格式的数据集。

数据库来源:gazebo中标准锥桶路障,纯手工标记,VOC格式,适用于需要在gazebo仿真环境中检验自动驾驶算法。

数据集划分

按照比例进行划分训练集、验证集、测试集。

# -*- coding:utf-8 -*-
# @author: 牧锦程
# @微信公众号: AI算法与电子竞赛
# @Email: m21z50c71@163.com
# @VX:fylaicaiimport os
import random
from tqdm import tqdmtrain_val_percent = 0.9  # 训练集和验证集的总比例
train_percent = 0.8  # 训练集占总比例的比例
Annotations_file_path = 'JPEGImages'
txt_save_path = 'ImageSets/Main'
total_xml = os.listdir(Annotations_file_path)if not os.path.exists(txt_save_path):os.makedirs(txt_save_path, exist_ok=True)num = len(total_xml)
list = range(num)
tv = int(num * train_val_percent)
tr = int(tv * train_percent)
train_val = random.sample(list, tv)
train = random.sample(train_val, tr)f_train_val = open(f'./{txt_save_path}/trainval.txt', 'w')
f_test = open(f'./{txt_save_path}/test.txt', 'w')
f_train = open(f'./{txt_save_path}/train.txt', 'w')
f_val = open(f'./{txt_save_path}/val.txt', 'w')for i in tqdm(list, unit="image", ncols=80, desc='划分数据'):name = total_xml[i].split(".")[0] + '\n'if i in train_val:f_train_val.write(name)if i in train:f_train.write(name)else:f_val.write(name)else:f_test.write(name)f_train_val.close()
f_train.close()
f_val.close()
f_test.close()

修改训练数据配置文件

./params/dataset/voc.yaml 中的相应参数

  1. dataset_path:数据集的路径

  2. names:类别

type: "voc"dataset_path: "F:/PersonalWebsite/PaperSourceCodeInterpretation/edgeyolo-main/VOCData"kwargs:suffix: "jpg"use_cache: truetrain:image_dir: "JPEGImages"anno_dir: "Annotations"label: "ImageSets/Main/train.txt"val:image_dir: "JPEGImages"anno_dir: "Annotations"label: "ImageSets/Main/val.txt"test:test_dir: "test"segmentaion_enabled: falsenames: ['barricade']

修改训练模型配置文件

./params/train/train_voc.yaml 中的相应参数

  1. model_cfg:模型的配置文件

  2. weights:预训练模型文件

  3. use_cfg:强制使用model_cfg而不是weights来构建模型

  4. output_dir:模型输出内容文件夹

  5. save_checkpoint_for_each_epoch:是否保存每一轮的模型

  6. log_file:日志文件

  7. dataset_cfg:数据集文件

  8. batch_size_per_gpu:batch_size

  9. device:GPU设备

  10. fp16:在训练时是否使用fp16

  11. input_size:训练的输入尺寸

# models & weights------------------------------------------------------------------------------------------------------
model_cfg: "params/model/edgeyolo_tiny.yaml"         # model structure config file
weights: "output/train/edgeyolo_tiny_voc/best.pth"  # contains model_cfg, set null or a no-exist filename if not use it
use_cfg: false                                       # force using model_cfg instead of cfg in weights to build model# output----------------------------------------------------------------------------------------------------------------
output_dir: "output/train/edgeyolo_tiny_voc"        # all train output file will save in this dir
save_checkpoint_for_each_epoch: False                # save models for each epoch (epoch_xxx.pth, not only best/last.pth)
log_file: "log.txt"                                  # log file (in output_dir)# dataset & dataloader--------------------------------------------------------------------------------------------------
dataset_cfg: "params/dataset/voc.yaml"              # dataset config
batch_size_per_gpu: 2                                # batch size for each GPU
loader_num_workers: 4                                # number data loader workers for each GPU
num_threads: 1                                       # pytorch threads number for each GPU# device & data type----------------------------------------------------------------------------------------------------
device: [0]                                 # training device list
fp16: false                                          # train with fp16 precision
cudnn_benchmark: false                               # it's useful when multiscale_range is set zero# train hyper-params----------------------------------------------------------------------------------------------------
optimizer: "SGD"                                     # or Adam
max_epoch: 300                                       # or 400
close_mosaic_epochs: 15                              # close data augmentation at last several epochs# learning rate---------------------------------------------------------------------------------------------------------
lr_per_img: 0.00015625                               # total_lr = lr_per_img * batch_size_per_gpu * len(devices)
warmup_epochs: 5                                     # warm-up epochs at the beginning of training
warmup_lr_ratio: 0.0                                 # warm-up learning rate start from value warmup_lr_ratio * total_lr
final_lr_ratio: 0.05                                 # final_lr_per_img = final_lr_ratio * lr_per_img# training & dataset augmentation---------------------------------------------------------------------------------------
#      [cls_loss, conf_loss, iou_loss]
loss_use: ["bce", "bce", "giou"]  # bce: BCE loss. bcf: Balanced Focal loss. hyb: HR loss, iou, c/g/s iou is available
input_size: [640, 640]            # image input size for model
multiscale_range: 5               # real_input_size = input_size + randint(-multiscale_range, multiscale_range) * 32
weight_decay: 0.0005              # optimizer weight decay
momentum: 0.9                     # optimizer momentum
enhance_mosaic: false             # use enhanced mosaic method
use_ema: true                     # use EMA method
enable_mixup: true                # use mixup
mixup_scale: [0.5, 1.5]           # mixup image scale
mosaic_scale: [0.1, 2.0]          # mosaic image scale
flip_prob: 0.5                    # flip image probability
mosaic_prob: 1                    # mosaic probability
mixup_prob: 1                     # mixup probability
degrees: 10                       # maximum rotate degrees
hsv_gain: [0.0138, 0.664, 0.464]  # hsv gain ratio# evaluate--------------------------------------------------------------------------------------------------------------
eval_at_start: false              # evaluate loaded model before training
val_conf_thres: 0.001             # confidence threshold when doing evaluation
val_nms_thres: 0.65               # NMS IOU threshold when doing evaluation
eval_only: false                  # do not train, run evaluation program only for all weights in output_dir
obj_conf_enabled: true            # use object confidence when doing inference
eval_interval: 1                  # evaluate interval epochs# show------------------------------------------------------------------------------------------------------------------
print_interval: 100               # print result after every $print_interval iterations# others----------------------------------------------------------------------------------------------------------------
load_optimizer_params: true       # load optimizer params when resume train, set false if there is an error.
train_backbone: true              # set false if you only want to train yolo head
train_start_layers: 51            # if not train_backbone, train from this layer, see params/models/edgeyolo.yaml
force_start_epoch: -1             # set -1 to disable this option

模型训练

cfg:模型训练的配置文件

修改后直接运行 train.py 就行。

from edgeyolo import launch as train
import argparsedef make_parser():parser = argparse.ArgumentParser("EdgeYOLO train parser")parser.add_argument("-c", "--cfg", type=str, default="params/train/train_voc.yaml")# Not commendparser.add_argument("--default", action="store_true", help="use default train settings in edgeyolo/train/default.yaml")return parser.parse_args()if __name__ == '__main__':args = make_parser()train("DEFAULT" if args.default else args.cfg)

绘制训练过程图

  1. all:绘制所有曲线或 (--lr:学习率, --ap:准确度, --loss:损失)

  2. file:训练的输出文件夹路径

  3. save:是否保存图片

  4. format:保存图片的格式,支持多种格式同时保存【pdf png svg jpg eps】

  5. no-show:不使用plt.show()显示曲线

parser = argparse.ArgumentParser()parser.add_argument("-ap", "--ap", action="store_true")
parser.add_argument("-loss", "--loss", action="store_true")
parser.add_argument("-lr", "--lr", action="store_true",  default=True)
parser.add_argument("-a", "--all", action="store_true")parser.add_argument("-f", "--file", type=str, default='./output/train/edgeyolo_tiny_voc/log.txt')parser.add_argument("-s", "--save", action="store_true", default=True)
parser.add_argument("--format", type=str, default=DEFAULT_SUFFIX, nargs="+")
parser.add_argument("--no-show", action="store_true", default=True)

修改上述参数后,直接就运行 plot.py 函数就行。

根据loss图可以看出模型在50轮左右就已经被训练得很好了。

在这个绘图代码中,我遇到了一个问题

修改成下面的代码,就不会有误。

while epochs[idx-1] >= now_value:idx -= 1if abs(idx) == len(epochs):break

模型验证

修改后直接运行 evaluate.py 就行。

  1. weights:权重文件, 也可是tensorrt模型

  2. input-size:输入尺寸(高、宽)

  3. dataset:数据集配置文件路径

  4. device:gpu显卡

  5. save:保存验证的模型文件

  6. fp16:保存时是否使用fp16精度

  7. trt:如果使用的是TensorRT模型需要加上此选项

parser = argparse.ArgumentParser("EdgeYOLO evaluate parser")
parser.add_argument("-w", "--weights", type=str, default="./output/train/edgeyolo_tiny_voc/best.pth", help="weights")
parser.add_argument("-b", "--batch", type=int, default=2, help="batch size for each device")
parser.add_argument("-i", "--input-size", type=int, nargs="+", default=[640, 640], help="image input size")parser.add_argument("--dataset", type=str, default="params/dataset/voc.yaml", help="dataset config")
parser.add_argument("--device", type=int, nargs="+", default=[0], help="eval device")parser.add_argument("--no-obj-conf", action="store_true", help="for debug only, do not use it")
parser.add_argument("--save", action="store_true", default=True, help="save deploy model without optimizer params")
parser.add_argument('--fp16', action='store_true', help='half precision')
parser.add_argument('--trt', action='store_true', help='is tensorrt model')

现在你就可以使用 detect.py 函数进行推理了。

五、总结

EdgeYOLO是一个为边缘计算设备优化的实时目标检测器,它以较低的计算成本实现了高效率和高精度的目标检测,特别是在小目标识别方面表现出色。模型设计简洁,易于在边缘设备上部署,并且通过开源协作,支持社区进行进一步的改进和定制。此外,它还提供了不同规模的模型以适应不同的计算环境需求。

关于edgeyolo模型的相关代码、论文PDF、预训练模型、使用方法、训练数据集等,我都已打包好,供需要的小伙伴交流研究,获取方式如下:

关注公众号,回复:edgeyolo,即可获取edgeyolo相关代码、论文、预训练模型、使用方法示例

【论文源码实战】EdgeYOLO: 边缘设备友好的无锚框检测器

硬性的标准其实限制不了无限可能的我们,所以啊!少年们加油吧!


http://www.mrgr.cn/news/63996.html

相关文章:

  • Linux初阶——线程(Part3):POSIX 信号量 CP 模型变体
  • 【Unity基础】Unity中的UI系统
  • Spring JPA 集成 YashanDB:让数据管理变得轻松愉快
  • ST IoT Wireless 物联网与无线技术 研讨会
  • 数字后端零基础入门系列 | Innovus零基础LAB学习Day8
  • 『 C++ 』vector的常用接口介绍
  • Linux高阶——1027—守护进程
  • LeetCode207. 课程表(2024秋季每日一题 55)
  • Mybatis-plus入门教程
  • 【深度学习基础】常用图像卷积核类型
  • 基于STM32的智能水族箱控制系统设计
  • 大学城水电资源管理:Spring Boot解决方案
  • 俗人只知《老子》该书,却不知李耳其人,可悲
  • 大屏可视化管理系统建设方案书(word原件)
  • 六 在WEB中应用MyBatis(使用MVC架构模式)
  • 这篇文章,教你如何看清流量卡套路!
  • 服务端监控工具:Nmon使用方法
  • 【WebApi】C# webapi 后端接收部分属性
  • python 五子棋小游戏
  • 《深入浅出HTTPS​​​》读书笔记(3):HTTP本身的安全问题
  • Maven(20) 如何使用Maven进行版本管理?
  • Weblogic漏洞复现(Vulhub)
  • 项目实战:基于Linux的Flappy bird游戏开发
  • Mac下载 安装MIMIC-IV 3.0数据集
  • 数据分析SPSS面试题及参考答案
  • 机器学习在运维中的应用