Label studio自动预标注功能的使用
1. 安装label studio 机器学习后端库
label studio支持基于重写其提供的api来实现模型预标注。 首先需要安装label studio的ml后端,如下步骤:
以下内容均假设label studio服务已经安装。 以下步骤在需要启动预标注模型后端的服务器执行,不需要与搭建label studio的服务器一致。只要保证两端能够正常通信即可。
-
从github克隆项目:
git clone https://github.com/heartexlabs/label-studio-ml-backend
-
安装项目:
cd label-studio-ml-backend
# Install label-studio-ml and its dependencies
pip install -U -e .
当然,还需要安装模型运行所依赖的库(若之前没安装的话),比如 torch,onnx,vino等。
2. 自定义机器学习后端
由于图像技术方面目标检测任务对预标注功能较为需求,以下目标检测任务为例。图像分类任务可以参照下面给的文档链接。
-
编写后端项目的推理代码,实现模型预测功能;
-
继承label_studio_ml.model.LabelStudioMLBase类,重写方法:
针对自动预标注功能,主要重写predict方法,将输出格式化成label studio所需的json格式(参考官方文档:https://labelstud.io/guide/predictions.html)。
【示例】
如需根据YOLOv4的预训练模型进行预标注,则推理代码如下:
# -*- coding: utf-8 -*- from yolo import YOLO from PIL import Image from label_studio_ml.model import LabelStudioMLBase from label_studio_ml.utils import get_image_size, get_single_tag_keys, get_image_local_path class MyModel(LabelStudioMLBase): def __init__(self, **kwargs): ''' loading models to global objects ''' super(MyModel, self).__init__(**kwargs) # 封装好的推理模型 self.detector = YOLO(img_size = 416, model_path = "model/model.onnx", cls_path = "model/classes.name", anchors_path = "model/yolo_anchors.txt", font_path = "model/simhei.ttf", confidence=0.6, infer_mode='vino') self.from_name, self.to_name, self.value, self.labels_in_config = get_single_tag_keys(self.parsed_label_config, 'RectangleLabels', 'Image') # 前端获取任务属性 self.labels_in_config = set(self.labels_in_config) # 前端配置的标签列表 def predict(self, tasks, **kwargs): assert len(tasks) == 1 image_path = get_image_local_path(tasks[0]['data'][self.value]) # 获取图片路径 image = Image.open(image_path) boxes, labels, confs = self.detector.detect_image(image) # 模型推理 results = [] # results需要放在list中再返回 img_width, img_height = get_image_size(image_path) # 用于转换坐标 for id, bbox in enumerate(boxes): label = labels[id] # 注意:后端和前端标签名保持一致 conf = confs[id] # 若模型不返回置信度,可指定一个默认值 x, y, w, h = bbox if label not in self.labels_in_config: print(label + ' label not found in project config.') continue # 忽略前端不需要的类别 results.append({ 'from_name': self.from_name, 'to_name': self.to_name, 'type': 'rectanglelabels', 'value': { 'rectanglelabels': [label], 'x': int(x / img_width * 100), # 坐标需要转换 'y': int(y / img_height * 100), # 数值类型返回整型 'width': int(w / img_width * 100), 'height': int(h / img_height * 100) }, 'score': int(conf*100) # }) avg_score = int(sum(confs) / max(len(confs), 1)) return [{ 'result':results, 'score': avg_score }]
【注意】:
(1) 针对同一类目标,后端返回的标签值和前端设置的标签值要保持一致;
(2) 坐标值要经过 ( 除以 宽度/高度 再乘以 100 ) 的换算,否则在前端的位置会出错;
(3) 坐标和置信度要以整型返回,否则会报错。
3. 启动机器学习后端
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SOmYNSs-1642579310211)(C:%5CUsers%5CCaiYichao%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20220114140751700.png#pic_center)]
-
组织后端项目
重写完方法后,后端项目(包括推理代码、依赖文件、权重)应在同一个文件夹下面。
【示例】通用目标检测后端,其中general_backend.py 为上一节所写的接口代码,也是初始化后端的目标脚本。
【注意】: 后端的目标检测命名,不能包含 ‘-’ 符号,否则后续在启动服务时会报错。可以使用 ‘_’ 符号代替。
-
初始化并创建后端服务
label-studio-ml init general_backend --script ./general_backend.py -p 9099
其中 general_backend 为服务名称,可以自行定义; -p 参数指定服务的端口号。
执行上述命令后,会在项目所在目录生成与所定义服务名称一致的 文件夹。然后,我们需要将服务调用依赖的所有python文件和目录移动到新生成的文件夹,但是权重文件所在的文件夹不用移动。 比如,该示例中就需要将 yolo.py, utils目录,nets目录移动到新生成的文件夹; 而model目录里面我放的是权重,所以不用移动。移动后,目录结构应该如下图所示:
左图为项目所在目录,其中general_backen为初始化后新生成的目录; 有图为新生成目录中的内容,包括自己移动进来的文件(新生成目录会重新生成一个目标脚本,所以genral_backend.py不用再次移动进来)。
-
启动后端服务
完成上述操作后,执行以以下命令启动服务:
label-studio-ml start general_backend # 暂时运行 # 或者 nohup label-studio-ml start genral_backend & # 持久化运行
成功后,会显示日志
4. label studio前端配置
-
按照常规流程在 label studio前端创建标注项目
针对该示例,应该创建配置标注内容为目标检测框:
然后,设置目标的标签。标签的类别数量可以比后端支持的类别多,也可以更少,但是同类别的标签名必须一致。
-
新建完毕项目上传好图片后,点击 “setting” --> “Machine Learning” --> “Add Modle” 绑定后端 url
在 URL栏绑定之前启动的后端服务地址,并且勾选 “Retrieve predictions when loading a task automatically” , 然后确定保存。
- 进行标注
然后,按照正常流程进行标注即可。每选中一张图片,后端模型会自动生成检测框,只需要审核、适当调整位置,并点 “Submit” 按钮即可完成标注。 预标注的 效果直接由后端模型的精度决定。