Objekterkennungs-AI mit Label Studio & MMDetection trainieren
Etikettieren und Training benötigen etwas Klebstoff
Als ich vor einiger Zeit object detection AI trainierte war LabelImg eine sehr nützliche Werkzeug, aber die Exportfunktion von Label Studio in das COCO-Format wurde vom MMDetection-Framework nicht akzeptiert…
Es benötigte einige Werkzeuge und Skripte, um alles zum Laufen zu bringen.
Hier sind die fehlenden Teile und einige Skripte einige davon habe ich im Internet gefunden, andere habe ich selbst geschrieben.
Grundlegende Schritte
Das Vorbereiten, Trainieren und Verwenden von KI umfasst
- das Erhalten von Quelldaten (Bilder für Objekterkennung und Klassifizierung)
- das Labeln von Bildern und das Vorbereiten des Datensatzes
- das Entwickeln eines neuen Modells oder das Finden eines passenden bestehenden
- das Trainieren des Modells, manchmal mit Hyperparameter-Tuning
- das Verwenden des Modells, um Labels für neue Bilder vorherzusagen (ingerring)
Hier gebe ich genaue Schritte an, wie man Daten mit Label Studio labeln kann (Schritt 2) und trainieren mit mmdetection und torchvision (Schritt 4), und berühre die Inferenz (Schritt 5)
Label Studio
Es hat einige Open-Source-Roots im LabelImg-Programm aber wird jetzt zentral entwickelt und gewartet. Und es gibt natürlich eine Enterprise-Version.
Dennoch ist es für die Selbsthostung verfügbar, was sehr schön ist.
Konfigurieren und starten
Man kann Label Studio auf verschiedene Arten installieren und starten, zum Beispiel als pip-Paket, oder als Docker-Compose-Containergruppe. Hier verwende ich einen einzelnen Docker-Container.
Vorbereiten des Quellordners
mkdir ~/ls-data
sudo chown -R 1001:1001 ~/ls-data10
Lokale Speicherkonfiguration
mkdir ~/ai-local-store
mkdir ~/ai-local-labels
# setzen Sie einige zusätzliche Berechtigungen
In ~/ai-local-store speichern Sie die Bilddateien, ~/ai-local-labels - synchronisierte Labels.
Starten Sie den Docker-Container
docker run -it -p 8080:8080 \
-e LABEL_STUDIO_HOST=http://your_ip_address:8080/ \
-e LABEL_STUDIO_LOCAL_FILES_SERVING_ENABLED=true \
-e LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=/ai-local-store \
-e DATA_UPLOAD_MAX_NUMBER_FILES=10000000 \
-v /home/somename/ls-data:/label-studio/data \
-v /home/somename/ai-local-store:/ai-local-store \
-v /home/somename/ai-local-labels:/ai-local-labels \
heartexlabs/label-studio:latest \
label-studio \
--log-level DEBUG
LABEL_STUDIO_HOST - aufgrund der Umleitungen der LS-Web-Oberfläche. DATA_UPLOAD_MAX_NUMBER_FILES … Django beschränkte die Upload-Dateizahl auf 100 und hatte einen schrecklichen Effekt auf Label Studio, daher war es notwendig, diesen neuen Grenzwert anzugeben. Alle anderen Konfigurationen sind sehr gut in den Label Studio Dokumentationen dokumentiert.
Importieren der Konfiguration. In den Projekt-Einstellungen in der Cloud Storage fügen Sie eine Quellenspeicherung des Typs Lokale Dateien hinzu, ähnlich wie:
Vergessen Sie nicht, das Kästchen „Jedes Bucket-Objekt als Quelldatei behandeln“ zu markieren, wenn Sie planen, Bilder zu synchronisieren (ich glaube, ja, Sie tun das), nicht die JSONs. Wenn Sie bereits einige Labels für diese Bilder in einem separaten JSON haben, konfigurieren Sie einfach diese Cloud Storage. Nicht klicken Sie auf Sync. Und dann importieren Sie das JSON.
Konfigurieren Sie dasselbe für die Ziel-Cloud Storage und ai-local-labels - wenn Sie sie synchronisieren möchten.
Importieren von vorlabelierten Daten in Label Studio
Ich liebe das COCO JSON-Format. Auch das Pascal VOC. Aber sie sind nicht direkt mit Label Studio kompatibel, daher müssen Sie sie zunächst in das proprietäre Format von LS konvertieren.
Aber vorher - Sie werden wahrscheinlich den Datensatz filtern müssen. Vielleicht benötigen Sie nur einige Labels dort, nicht alle. Ich mag das filter.py Skript von coco-manager: https://github.com/immersive-limit/coco-manager/blob/master/filter.py
python filter.py --input_json instances_train2017.json --output_json filtered.json --categories person dog cat
python -m venv env
source env/bin/activate
git clone https://github.com/heartexlabs/label-studio-converter.git
cd label-studio-converter
pip install -e .
Konvertieren von COCO und setzen Sie den richtigen Ordner
label-studio-converter import coco -i your-input-file.json -o output.json
Importieren Sie die output.json, indem Sie in Label Studio auf den Import-Button klicken.
Labeln
Viel kreatives Arbeit wird hier geleistet.
Exportieren
Nachdem Sie im Label Studio auf den Export-Button geklickt und das COCO-Exportformat ausgewählt haben - schauen Sie sich die Datei an und bewundern Sie die Bildnamen. Sie würden so aussehen, wenn Sie die Labels vorher importiert haben, ohne den Basispfad der Bilder zu überschreiben
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "\/data\/local-files\/?d=\/iteration1001\/123.jpg"
},
Oder so, wenn Sie externe Cloud Storage synchronisiert haben.
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "http:\/\/localhost:8080\/data\/local-files\/?d=iteration1001\/123.jpg"
},
Diese sind nicht sehr schön. Wir möchten etwas wie
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "iteration1001/123.jpg"
},
Um die Dateinamen zu beheben, habe ich wundervolle Skripte verwendet. Sie überschreiben die result.json-Datei, also wenn Sie eine Sicherung vorher benötigen - sorgen Sie selbst dafür:
sed -i -e 's/\\\/data\\\/local-files\\\/?d=\\\///g' ~/tmp/result.json
sed -i "s%http:\\\/\\\/localhost:8080\\\/data\\\/local-files\\\/?d=%%" ~/tmp/result.json
sed -i "s%http:\\\/\\\/your_ip_address:8080\\\/data\\\/local-files\\\/?d=%%" ~/tmp/result.json
Backup der Label Studio Daten und Datenbank
Stoppen Sie vorsichtig Ihren Label Studio Docker-Container und führen Sie dann etwas wie aus:
cp ~/ls-data ~/all-my-backups
cp ~/ai-local-store ~/all-my-backups
cp ~/ai-local-labels ~/all-my-backups
Zusammenführen
Manchmal muss man mehrere Datensätze in einen zusammenführen, besonders wenn man mehrere Iterationen durchführt.
Ich verwendete das COCO-merger Tool. Nachdem ich es installiert und mit dem -h-Parameter gestartet habe:
python tools/COCO_merger/merge.py -h
COCO Files Merge Usage
python -m COCO_merger.merge --src Json1.json Json2.json --out OUTPUT_JSON.json
Argument parser
usage: merge.py [-h] --src SRC SRC --out OUT
Merge two annotation files to one file
optional arguments:
-h, --help show this help message and exit
--src SRC SRC Path of two annotation files to merge
--out OUT Path of the output annotation file
Ja, kann man nur zwei Dateien zusammenführen. Also wenn Sie 10 Iterationen haben, müssen Sie extra Aufwand betreiben. Dennoch mag ich es.
MMDetection
Aufteilen des Datensatzes
Um den Datensatz in Trainings- und Testdaten aufzuteilen, verwendete ich das COCOSplit Tool.
git clone https://github.com/akarazniewicz/cocosplit.git
cd cocosplit
pip install -r requirements
Es gibt nicht viel zu tun:
$ python cocosplit.py -h
usage: cocosplit.py [-h] -s SPLIT [--having-annotations]
coco_annotations train test
Teilt die COCO-Annotationen in Trainings- und Testdaten auf.
positionale Argumente:
coco_annotations Pfad zur COCO-Annotationen-Datei.
train Wo die COCO-Trainings-Annotationen gespeichert werden
test Wo die COCO-Test-Annotationen gespeichert werden
optionale Argumente:
-h, --help Zeigt diese Hilfe an und beendet das Programm
-s SPLIT Prozentsatz der Aufteilung; eine Zahl in (0, 1)
--having-annotations Alle Bilder ohne Annotationen ignorieren. Nur diese mit mindestens einer Annotation behalten
--multi-class Aufteilen eines mehrklassigen Datensatzes, wobei die Klassenverteilung in Trainings- und Testdaten beibehalten wird
Um die COCO-Aufteilung durchzuführen:
python cocosplit.py --having-annotations \
--multi-class \
-s 0.8 \
source_coco_annotations.json \
train.json \
test.json
Denken Sie daran, die licenses-Eigenschaft am Anfang der Datensatz-JSON-Datei hinzuzufügen, irgendwo nach dem ersten “{”. Dieses Aufteilungstool benötigt sie wirklich.
"licenses": [],
Konfiguration
Ja, die Modellkonfigurationen sind kompliziert.
Aber mask-rcnn ist ziemlich schnell und hat eine vernünftige Erkennungsrate. Hier finden Sie die Details zur Konfiguration: https://mmdetection.readthedocs.io/en/latest/user_guides/train.html#train-with-customized-datasets
# Die neue Konfiguration erbt eine Basiskonfiguration, um die notwendige Änderung hervorzuheben
_base_ = '/home/someusername/mmdetection/configs/mask_rcnn/mask-rcnn_r50-caffe_fpn_ms-poly-1x_coco.py'
# Wir müssen auch die num_classes in der Kopfzeile ändern, um mit der Annotation des Datensatzes übereinzustimmen
model = dict(
roi_head=dict(
bbox_head=dict(num_classes=3),
mask_head=dict(num_classes=3)))
# Ändern Sie die datensatzbezogenen Einstellungen
data_root = '/home/someusername/'
metainfo = {
'classes': ('MyClass1', 'AnotherClass2', 'AndTheLastOne3'),
'palette': [
(220, 20, 60),
(20, 60, 220),
(60, 220, 20),
]
}
train_dataloader = dict(
batch_size=1,
dataset=dict(
data_root=data_root,
metainfo=metainfo,
ann_file='train.json',
data_prefix=dict(img='')))
val_dataloader = dict(
dataset=dict(
data_root=data_root,
metainfo=metainfo,
ann_file='test.json',
data_prefix=dict(img='')))
test_dataloader = val_dataloader
# Ändern Sie die metrikbezogenen Einstellungen
val_evaluator = dict(ann_file=data_root+'test.json')
test_evaluator = val_evaluator
# Wir können das vortrainierte Mask RCNN-Modell verwenden, um eine höhere Leistung zu erzielen
load_from = 'https://download.openmmlab.com/mmdetection/v2.0/mask_rcnn/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth'
# wenn Sie lange Filme mögen
# der Standard hier ist, wenn ich mich richtig erinnere, 12
train_cfg = dict(max_epochs=24)
Etwas zu beachten, wenn keine Masken benötigt werden: https://mmdetection.readthedocs.io/en/latest/user_guides/single_stage_as_rpn.html
Training
Nehmen wir an, Sie haben Ihre Modellkonfiguration in /home/someusername/myproject/models/configs/mask-rcnn_r50-caffe_fpn_ms-poly-1x_v1.0.py. Das Trainingskript ist ein Standardaufruf des mmdetection-Tools:
cd ~/mmdetection
python tools/train.py \
/home/someusername/myproject/models/configs/mask-rcnn_r50-caffe_fpn_ms-poly-1x_v1.0.py \
--work-dir /home/someusername/myproject/work-dirs/my-object-detector-v1.0-mask-rcnn_r50-caffe_fpn_ms-poly-1x
Inferenz
Einige Dokumentationen finden Sie hier: https://mmdetection.readthedocs.io/en/latest/user_guides/inference.html
from mmdet.apis import DetInferencer
inferencer = DetInferencer(
model='/home/someusername/myproject/models/configs/mask-rcnn_r50-caffe_fpn_ms-poly-1x_v1.0.py',
weights='/home/someusername/myproject/work-dirs/my-object-detector-v1.0-mask-rcnn_r50-caffe_fpn_ms-poly-1x/epoch_12.pth')
# führen Sie es für eine einzelne Datei aus:
# inferencer('demo/demo.jpg', out_dir='/home/someusername/myproject/test-output/1.0/', show=True)
# oder für den gesamten Ordner
inferencer('/home/someusername/myproject/test-images/', out_dir='/home/someusername/myproject/test-output/1.0/', no_save_pred=False)
Nützliche Links
Hoffentlich hilft Ihnen dies auf irgendeine Weise.
Weitere nützliche Lesematerialien finden Sie auf
- Label Studio Seite: https://labelstud.io/
- MMDetection Dokumentation: https://mmdetection.readthedocs.io/en/latest/get_started.html
- Bash Cheat Sheet
- Konkrete Reo Stahlkappen mit tensorflow erkennen
- Python Cheat Sheet
- Conda Cheat Sheet
- Flux Text zu Bild
- Ollama Cheat Sheet
- Docker Cheat Sheet
- Layered Lambdas mit AWS SAM und Python
- PDF in Python generieren - Bibliotheken und Beispiele"