X-AnyLabeling 当前内置了许多通用模型,具体可参考 模型列表。
在启用 AI 辅助标定功能之前,用户需要先加载模型,并通过左侧菜单栏的 AI
标识按钮或直接使用快捷键 Ctrl+A
激活。
通常,当用户从模型下拉列表中选择对应的模型时,后台会检查当前用户目录下 ~/xanylabeling_data/models/${model_name}
是否存在相应的模型文件。如果存在,则直接加载;如果不存在,则会通过网络自动下载到指定目录。
请注意,X-AnyLabeling
当前内置的所有模型默认托管在 GitHub 的 release 仓库。因此,用户需要配置科学上网条件,并保持网络畅通,否则可能会下载失败。对于由于网络问题未能成功加载模型的用户,可参考以下步骤进行配置:
- 打开 model_zoo.md 文件,找到欲加载模型对应的配置文件。
- 编辑配置文件,修改模型路径,并根据需要选择性地修改其他超参数。
- 打开工具界面,点击加载自定义模型,选择配置文件所在路径即可。
已适配模型是指当前已经在 X-AnyLabeling 中适配过的模型,无须用户编写模型推理代码。具体可参考 模型列表。
以下以 YOLOv5s 模型为例,介绍加载自定义模型的步骤:
a. 模型转换
假设您已经训练好一个本地模型,首先将 PyTorch
训练模型转换为 ONNX
文件格式:
python export.py --weights yolov5s.pt --include onnx
注意:当前版本不支持动态输入,因此请勿设置 --dynamic
参数。此外,您可以通过 Netron 在线查看 onnx
文件,检查输入和输出节点信息,确保输入节点的第一个维度为1。
b. 模型配置
准备好 onnx
文件后,您可以浏览 模型列表 文件,找到并下载对应模型的配置文件。这里以 yolov5s.yaml 为例,其内容如下:
type: yolov5
name: yolov5s-r20230520
display_name: YOLOv5s Ultralytics
model_path: https://github.com/CVHub520/X-AnyLabeling/releases/download/v0.1.0/yolov5s.onnx
nms_threshold: 0.45
confidence_threshold: 0.25
classes:
- person
- bicycle
- car
...
字段 | 描述 | 是否可修改 |
---|---|---|
type |
模型类型标识,不支持自定义。 | ❌ |
name |
模型配置文件的索引名称,保留默认值即可。 | ❌ |
display_name |
在界面上模型下拉列表中显示的名称,可自行修改。 | ✔️ |
model_path |
模型加载路径,支持相对路径和绝对路径。 | ✔️ |
对于不同模型,X-AnyLabeling 提供了一些特有字段,具体可参考对应模型的定义。以下以 YOLO 模型为例,提供了一些超参数配置:
字段 | 描述 |
---|---|
classes |
模型的标签列表,需与训练时的标签列表一致。 |
filter_classes |
指定推理时使用的类别。 |
agnostic |
是否使用单类 NMS。 |
nms_threshold |
非极大值抑制的阈值,用于过滤重叠的目标框。 |
confidence_threshold |
置信度阈值,用于过滤置信度较低的目标框。 |
一个典型的参考示例如下:
type: yolov5
name: yolov5s-r20230520
display_name: YOLOv5s Custom
model_path: yolov5s_custom.onnx
nms_threshold: 0.60
confidence_threshold: 0.45
agnostic: True
filter_classes:
- person
- car
classes:
- person
- bicycle
- car
- ...
特别地,当使用低版本的 YOLOv5(v5.0 及以下)时,请在配置文件中指定 anchors
和 stride
字段,否则请删除这些字段。示例如下:
type: yolov5
...
stride: 32
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
此外:
- 对于
nms_threshold
和confidence_threshold
字段,v2.4.0
及以上版本支持直接从 GUI 界面进行设置,用户可根据需要修改。 - 对于分割模型,则可指定
epsilon_factor
参数来控制输出轮廓点的平滑程度,默认值为 0.005。
c. 模型加载
建议将 model_path
字段设置为当前 onnx
模型的文件名称,并将模型文件和配置文件放在同一目录下,使用相对路径进行加载,以避免路径中出现转义字符的影响。
最后,在菜单栏下方的模型下拉框选项中,找到 ...加载自定义模型
,然后导入上一步准备的配置文件即可完成自定义模型加载。
未适配模型指还未在 X-AnyLabeling 中适配过的模型即内置模型,需要用户参考以下实施步骤进行集成。
这里以多类别语义分割模型,可遵循以下实施步骤:
a. 训练及导出模型
导出 ONNX
模型,确保输出节点的维度为 [1, C, H, W]
,其中 C
为总的类别数(包含背景类)。
b. 定义配置文件
首先,在配置文件目录下,新增一个配置文件,如unet.yaml
:
type: unet
name: unet-r20240101
display_name: U-Net (ResNet34)
model_path: /path/to/best.onnx
classes:
- cat
- dog
- _background_
其中:
字段 | 描述 |
---|---|
type |
必填项,指定模型的类型,确保与现有模型类型不重复,以维护模型标识的唯一性。 |
name |
必填项,定义模型的索引,用于内部引用和管理,避免与现有模型的索引名称冲突。 |
display_name |
必填项,展示在用户界面的模型名称,便于识别和选择,同样需保证其独特性,不与其它模型重名。 |
以上三个字段为不可缺省字段。最后,可根据实际需要添加其它字段,如模型路径、模型超参、模型类别等。
c. 添加配置文件
其次,将上述配置文件添加到模型管理文件中:
...
- model_name: "unet-r20240101"
config_file: ":/unet.yaml"
...
d. 定义推理服务
在定义推理服务的过程中,继承 Model 基类是关键步骤之一,它允许你实现特定于模型的前向推理逻辑。具体地,你可以在模型推理服务路径下新建一个unet.py
文件,参考示例如下:
import logging
import os
import cv2
import numpy as np
from PyQt5 import QtCore
from PyQt5.QtCore import QCoreApplication
from anylabeling.app_info import __preferred_device__
from anylabeling.views.labeling.shape import Shape
from anylabeling.views.labeling.utils.opencv import qt_img_to_rgb_cv_img
from .model import Model
from .types import AutoLabelingResult
from .engines.build_onnx_engine import OnnxBaseModel
class UNet(Model):
"""Semantic segmentation model using UNet"""
class Meta:
required_config_names = [
"type",
"name",
"display_name",
"model_path",
"classes",
]
widgets = ["button_run"]
output_modes = {
"polygon": QCoreApplication.translate("Model", "Polygon"),
}
default_output_mode = "polygon"
def __init__(self, model_config, on_message) -> None:
# Run the parent class's init method
super().__init__(model_config, on_message)
model_name = self.config["type"]
model_abs_path = self.get_model_abs_path(self.config, "model_path")
if not model_abs_path or not os.path.isfile(model_abs_path):
raise FileNotFoundError(
QCoreApplication.translate(
"Model",
f"Could not download or initialize {model_name} model.",
)
)
self.net = OnnxBaseModel(model_abs_path, __preferred_device__)
self.classes = self.config["classes"]
self.input_shape = self.net.get_input_shape()[-2:]
def preprocess(self, input_image):
"""
Pre-processes the input image before feeding it to the network.
Args:
input_image (numpy.ndarray): The input image to be processed.
Returns:
numpy.ndarray: The pre-processed output.
"""
input_h, input_w = self.input_shape
image = cv2.resize(input_image, (input_w, input_h))
image = np.transpose(image, (2, 0, 1))
image = image.astype(np.float32) / 255.0
image = (image - 0.5) / 0.5
image = np.expand_dims(image, axis=0)
return image
def postprocess(self, image, outputs):
"""
Post-processes the network's output.
Args:
image (numpy.ndarray): The input image.
outputs (numpy.ndarray): The output from the network.
Returns:
contours (list): List of contours for each detected object class.
Each contour is represented as a dictionary containing
the class label and a list of contour points.
"""
n, c, h, w = outputs.shape
image_height, image_width = image.shape[:2]
# Obtain the category index of each pixel
# target shape: (1, h, w)
outputs = np.argmax(outputs, axis=1)
results = []
for i in range(c):
# Skip the background label
if self.classes[i] == '_background_':
continue
# Get the category index of each pixel for the first batch by adding [0].
mask = outputs[0] == i
# Rescaled to original shape
mask_resized = cv2.resize(mask.astype(np.uint8), (image_width, image_height))
# Get the contours
contours, _ = cv2.findContours(mask_resized, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Append the contours along with their respective class labels
results.append((self.classes[i], [np.squeeze(contour).tolist() for contour in contours]))
return results
def predict_shapes(self, image, image_path=None):
"""
Predict shapes from image
"""
if image is None:
return []
try:
image = qt_img_to_rgb_cv_img(image, image_path)
except Exception as e: # noqa
logging.warning("Could not inference model")
logging.warning(e)
return []
blob = self.preprocess(image)
outputs = self.net.get_ort_inference(blob)
results = self.postprocess(image, outputs)
shapes = []
for item in results:
label, contours = item
for points in contours:
# Make sure to close
points += points[0]
shape = Shape(flags={})
for point in points:
shape.add_point(QtCore.QPointF(point[0], point[1]))
shape.shape_type = "polygon"
shape.closed = True
shape.fill_color = "#000000"
shape.line_color = "#000000"
shape.line_width = 1
shape.label = label
shape.selected = False
shapes.append(shape)
result = AutoLabelingResult(shapes, replace=True)
return result
def unload(self):
del self.net
e. 添加至模型管理
最后,我们仅需将实现好的模型类添加至对应的模型管理文件中即可。具体地,你可以打开 model_manager.py,将对应的模型类型字段(如unet
)添加至 CUSTOM_MODELS
列表中,同时在 _load_model
方法中初始化你的实例。参考示例如下:
...
class ModelManager(QObject):
"""Model manager"""
MAX_NUM_CUSTOM_MODELS = 5
CUSTOM_MODELS = [
...
"unet",
...
]
def __init__(self):
...
...
def _load_model(self, model_id):
"""Load and return model info"""
if self.loaded_model_config is not None:
self.loaded_model_config["model"].unload()
self.loaded_model_config = None
self.auto_segmentation_model_unselected.emit()
model_config = copy.deepcopy(self.model_configs[model_id])
if model_config["type"] == "yolov5":
...
elif model_config["type"] == "unet":
from .unet import UNet
try:
model_config["model"] = UNet(
model_config, on_message=self.new_model_status.emit
)
self.auto_segmentation_model_unselected.emit()
except Exception as e: # noqa
self.new_model_status.emit(
self.tr(
"Error in loading model: {error_message}".format(
error_message=str(e)
)
)
)
print(
"Error in loading model: {error_message}".format(
error_message=str(e)
)
)
return
...
...
- 如果是基于
SAM
的模式,请将self.auto_segmentation_model_unselected.emit()
替换为self.auto_segmentation_model_selected.emit()
以触发相应的功能。 - 模型类型字段需要与上述步骤b. 定义配置文件中定义的配置文件中的
type
字段保持一致。
本章节将向您展示一些将自定义模型转换为 ONNX 模型的具体示例,以便您快速集成到 X-AnyLabeling 中。
InternImage 引入了一个大规模卷积神经网络 (CNN) 模型,利用可变形卷积作为核心操作符,以实现大的有效感受野、自适应空间聚合和减少的归纳偏置,从而从大量数据中学习到更强、更鲁棒的模式。它在基准测试中超越了当前的 CNN 和视觉Transformer。
属性 | 值 |
---|---|
论文标题 | InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions |
发表单位 | 上海人工智能实验室,清华大学,南京大学等 |
发表时间 | CVPR 2023 |
请参考此 教程。
本教程为用户提供了一种使用 PaddleClas PULC (实用超轻量图像分类) 快速构建轻量、高精度和实用的人员属性分类模型的方法。该模型可广泛用于行人分析场景、行人跟踪场景等。
请参考此 教程。
本教程为用户提供了一种使用 PaddleClas PULC (实用超轻量图像分类) 快速构建轻量、高精度和实用的车辆属性分类模型的方法。该模型可广泛用于车辆识别、道路监控等场景。
请参考此 教程。
作者: Kaixuan Hu
请参考此 教程。
属性 | 值 |
---|---|
论文标题 | YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors |
发表单位 | 台湾中央研究院信息科学研究所 |
python export.py --weights yolov7.pt --img-size 640 --grid
注意: 运行此命令时必须包含
--grid
参数。
属性 | 值 |
---|---|
论文标题 | Efficient object detectors including Gold-YOLO |
发表单位 | 华为诺亚 |
发表时间 | NeurIPS23 |
$ git clone https://github.com/huawei-noah/Efficient-Computing.git
$ cd Detection/Gold-YOLO
$ python deploy/ONNX/export_onnx.py --weights Gold_n_dist.pt --simplify --ort
Gold_s_pre_dist.pt
Gold_m_pre_dist.pt
Gold_l_pre_dist.pt
DAMO-YOLO
是由阿里巴巴达摩院数据分析与智能实验室的 TinyML 团队开发的一种快速准确的目标检测方法。它通过引入新的技术,包括神经架构搜索 (NAS) 主干网、高效的重参数化通用-FPN (RepGFPN)、轻量级头部和 AlignedOTA 标签分配,并进行蒸馏增强,使其性能超过了最新的 YOLO 系列。更多细节请参阅 Arxiv 报告。这里不仅可以找到强大的模型,还可以找到从训练到部署的高效训练策略和完整工具。
属性 | 值 |
---|---|
论文标题 | DAMO-YOLO: A Report on Real-Time Object Detection |
发表单位 | 阿里巴巴集团 |
发表时间 | Arxiv22 |
$ git clone https://github.com/tinyvision/DAMO-YOLO.git
$ cd DAMO-YOLO
$ python tools/converter.py -f configs/damoyolo_tinynasL25_S.py -c damoyolo_tinynasL25_S.pth --batch_size 1 --img_size 640
实时检测变换器 (RT-DETR
,又称 RTDETR) 是已知的第一个实时端到端目标检测器。RT-DETR-L 在 COCO val2017 上达到了 53.0% AP,并在 T4 GPU 上达到了 114 FPS,而 RT-DETR-X 达到了 54.8% AP 和 74 FPS,速度和准确性都超过了同规模的所有 YOLO 检测器。此外,RT-DETR-R50 达到了 53.1% AP 和 108 FPS,准确性比 DINO-Deformable-DETR-R50 高 2.2% AP,FPS 快约 21 倍。
属性 | 值 |
---|---|
论文标题 | RT-DETR: DETRs Beat YOLOs on Real-time Object Detection |
发表单位 | 百度 |
发表时间 | Arxiv22 |
请参考此 文章。
分割一切模型 (SAM
) 从输入提示(如点或框)中生成高质量的物体掩码。它可用于生成图像中所有物体的掩码,并在 1100 万张图像和 11 亿个掩码的数据集上进行了训练。SAM 在各种分割任务中具有强大的零样本性能。
属性 | 值 |
---|---|
论文标题 | Segment Anything |
发表单位 | Meta AI 研究院,FAIR |
发表时间 | ICCV23 |
请参考这些 步骤。
EfficientViT
是一系列新的视觉模型,用于高效的高分辨率密集预测。它使用一种新的轻量级多尺度线性注意模块作为核心构建模块。该模块仅通过硬件高效操作实现全局感受野和多尺度学习。
属性 | 值 |
---|---|
论文标题 | EfficientViT: Multi-Scale Linear Attention for High-Resolution Dense Prediction |
发表单位 | 麻省理工学院 |
发表时间 | ICCV23 |
请参考这些 步骤。
SAM-Med2D
是为解决将最先进的图像分割技术应用于医学图像挑战而开发的专业模型。
属性 | 值 |
---|---|
论文标题 | SAM-Med2D |
发表单位 | OpenGVLab |
发表时间 | Arxiv23 |
请参考这些 步骤。
HQ-SAM
是增强版的任意物体分割模型 (SAM),旨在提高掩码预测质量,特别是针对复杂结构,同时保持 SAM 的效率和零样本能力。它通过改进的解码过程和在专用数据集上的额外训练来实现这一目标。
属性 | 值 |
---|---|
论文标题 | Segment Anything in High Quality |
发表单位 | 苏黎世联邦理工学院和香港科技大学 |
发表时间 | NeurIPS 2023 |
请参考此 教程。
EdgeSAM
是任意物体分割模型 (SAM) 的加速变体,优化用于在边缘设备上高效执行,同时性能几乎没有妥协。它在性能上比原版 SAM
提升了 40 倍,在边缘设备上的速度比 MobileSAM 快 14 倍,同时在 COCO 和 LVIS 数据集上的 mIoU 分别提高了 2.3 和 3.2。EdgeSAM 也是第一个在 iPhone 14 上能够运行超过 30 FPS 的 SAM 变体。
属性 | 值 |
---|---|
论文标题 | Prompt-In-the-Loop Distillation for On-Device Deployment of SAM |
发表单位 | 南洋理工大学 S-Lab,上海人工智能实验室 |
发表时间 | Arxiv 2023 |
请参考此 教程。
Grounding DINO
是一款最先进的 (SOTA) 零样本目标检测模型,擅长检测训练中未定义的物体。其独特的能力使其能够适应新物体和场景,使其在现实世界应用中具有高度的多样性。它在指称表达理解 (REC) 方面表现出色,能够基于文本描述识别和定位图像中的特定物体或区域。Grounding DINO 简化了目标检测,通过消除手工设计的组件(如非极大值抑制 (NMS)),简化了模型架构,增强了效率和性能。
属性 | 值 |
---|---|
论文标题 | Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection |
发表单位 | IDEA-CVR,IDEA-Research |
发表时间 | Arxiv23 |
请参考此 教程。
YOLO-World
通过引入视觉语言建模来增强 YOLO 系列,实现高效的开放场景目标检测,在各种任务中表现出色。
属性 | 值 |
---|---|
论文标题 | Real-Time Open-Vocabulary Object Detection |
发表单位 | 腾讯人工智能实验室,ARC 实验室,腾讯 PCG,华中科技大学 |
发表时间 | Arxiv 2024 |
$ git clone https://github.com/ultralytics/ultralytics.git
$ cd ultralytics
$ yolo export model=yolov8s-worldv2.pt format=onnx opset=13 simplify
RAM
是一款以其卓越图像识别能力著称的强大图像打标签模型。RAM 在零样本泛化方面表现出色,具有成本效益高和可复现的优点,依赖于开源和无注释数据集。RAM 的灵活性使其适用于广泛的应用场景,成为各种图像识别任务中的宝贵工具。
属性 | 值 |
---|---|
论文标题 | Recognize Anything: A Strong Image Tagging Model |
发表单位 | OPPO 研究院,IDEA-Research,AI Robotics |
发表时间 | Arxiv23 |
请参考此 教程。