تدريب كاشف الأهداف الذكاء الاصطناعي باستخدام Label Studio و MMDetection
يتطلب التصنيف والتدريب بعض التصاق الأجزاء
عندما قمت تدريب مكتشف كائنات الذكاء الاصطناعي في وقت ما - كان LabelImg أداة مفيدة للغاية، لكن تصدير البيانات من Label Studio إلى تنسيق COCO لم يكن مقبولاً من قبل إطار عمل MMDetection..
كان من الضروري استخدام بعض الأدوات والبرمجة لجعل كل شيء يعمل.
القائمة هنا تشمل الأجزاء المفقودة وبعض النصوص البرمجية بعضها وجدته على الإنترنت، والآخر كتبتُه أنا.
الخطوات الأساسية
تحضير، تدريب واستخدام الذكاء الاصطناعي يتضمن
- الحصول على البيانات الأصلية (الصور للكشف عن الكائنات والتصنيف)
- تحديد الصور وإعداد مجموعة البيانات
- تطوير نموذج جديد أو العثور على نموذج مناسب موجود
- تدريب النموذج، أحيانًا مع تعديل معلمات التدريب
- استخدام النموذج للتنبؤ بالعلامات للصور الجديدة (الاستنتاج)
هنا أقدم الخطوات الدقيقة لكيفية تحديد البيانات باستخدام Label Studio (الخطوة 2) وتدريبها مع mmdetection و torchvision (الخطوة 4)، ومساهمة الاستنتاج (الخطوة 5)
Label Studio
لديه بعض الجذور المفتوحة المصدر من برنامج LabelImg ولكن الآن تم تطويره وصيانته بطريقة مركزية للغاية. ولديه نسخة مؤسسية بالطبع.
ولكنه متوفر للنشر الذاتي، وهو أمر جميل للغاية.
التكوين والتشغيل
يمكن تثبيت وتشغيل Label Studio بعدة طرق، مثل حزمة pip على سبيل المثال، أو مجموعة حاويات docker compose. هنا أستخدم حاوية docker واحدة.
تحضير المجلد الأصلي
mkdir ~/ls-data
sudo chown -R 1001:1001 ~/ls-data10
تكوين التخزين المحلي
mkdir ~/ai-local-store
mkdir ~/ai-local-labels
# إعداد بعض الأذونات الإضافية
في ~/ai-local-store تُحتفظ بملفات الصور، ~/ai-local-labels - التسميات المتزامنة.
تشغيل حاوية docker
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 - بسبب إعادة توجيه واجهة LS الويب. DATA_UPLOAD_MAX_NUMBER_FILES … قيود Django على عدد الملفات المُحملة إلى 100، وكان له تأثير سيء للغاية على Label Studio، لذا كان من الضروري توفير هذا الحد الجديد. جميع الإعدادات الأخرى موثقة جيدًا في وثائق Label Studio.
استيراد التكوين. في إعدادات المشروع في التخزين السحابي، أضف تخزينًا محليًا من نوع Source Storage مماثل ل:
لا تنسَ تحديد “اعتبر كل كائن في المجموعة كملف مصادر” إذا كنت تخطط لتوحيد الصور (أعتقد أنك تفعل ذلك)، وليس الملفات json. إذا كانت لديك بعض التسميات مسبقًا لهذه الصور في ملف json منفصل - فكل ما عليك هو تكوين هذا التخزين السحابي. عدم النقر على “التوحيد”. ثم استيراد الملف json.
قم بتكوين نفس الشيء للتخزين السحابي المستهدف و ai-local-labels - إذا كنت ترغب في توحيد الملفات.
استيراد البيانات المُسماة مسبقًا إلى Label Studio
أحب تنسيق JSON لـ COCO، وPascal VOC أيضًا. لكنها ليست متوافقة مباشرة مع Label Studio، لذا من الضروري تحويلها أولاً إلى التنسيق الخاص بـ LS.
لكن قبل ذلك، من المحتمل أن تحتاج إلى فلترة مجموعة البيانات. قد تحتاج فقط إلى بعض العلامات هناك، وليس جميعها. أحب نسخة filter.py من 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 .
تحويل من COCO وتحديد المجلد الصحيح
label-studio-converter import coco -i your-input-file.json -o output.json
استيراد ملف output.json بالنقر على زر الاستيراد في Label Studio.
التسمية
يتم إجراء الكثير من العمل الإبداعي للغاية هنا.
التصدير
بعد النقر على زر التصدير في Label Studio واختيار تنسيق COCO للتصدير - تحقق من داخل هذا الملف وانظر إلى أسماء الصور. سيبدو مثل هذا إذا استيردت التسميات مسبقًا دون استبدال مسار الصورة الأساسية
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "\/data\/local-files\/?d=\/iteration1001\/123.jpg"
},
أو سيبدو مثل هذا إذا تم تزامن التخزين السحابي الخارجي.
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "http:\/\/localhost:8080\/data\/local-files\/?d=iteration1001\/123.jpg"
},
هذه ليست جميلة. نريد شيئًا مثل
"images": [
{
"width": 800,
"height": 600,
"id": 0,
"file_name": "iteration1001/123.jpg"
},
لإصلاح أسماء الملفات، استخدمت نصوصًا رائعة. إنها تعيد كتابة ملف result.json، إذن إذا كنت بحاجة إلى نسخة احتياطية مسبقًا - اهتم بذلك بنفسك:
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
نسخ احتياطي لبيانات Label Studio وقاعدة البيانات
توقف بعناية عن حاوية Label Studio docker ثم قم بتشغيل شيء مثل
cp ~/ls-data ~/all-my-backups
cp ~/ai-local-store ~/all-my-backups
cp ~/ai-local-labels ~/all-my-backups
الدمج
أحيانًا يكون من الضروري دمج عدة مجموعات بيانات في واحدة، خاصة إذا كنت تقوم بإجراء عدة دورات تكرارية.
استخدمت أداة COCO-merger . بعد التثبيت والتشغيل مع معلمة -h:
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
نعم، يمكن دمجه فقط بين ملفين. إذن إذا كان لديك 10 دورات تكرارية - ستحتاج إلى مجهود إضافي. لكنني أحب ذلك.
MMDetection
تقسيم مجموعة البيانات
لتقسيم مجموعة البيانات إلى تدريب واختبار، استخدمت أداة COCOSplit.
git clone https://github.com/akarazniewicz/cocosplit.git
cd cocosplit
pip install -r requirements
ليس هناك الكثير من العمل فيه:
$ python cocosplit.py -h
usage: cocosplit.py [-h] -s SPLIT [--having-annotations]
coco_annotations train test
Splits COCO annotations file into training and test sets.
positional arguments:
coco_annotations Path to COCO annotations file.
train Where to store COCO training annotations
test Where to store COCO test annotations
optional arguments:
-h, --help show this help message and exit
-s SPLIT A percentage of a split; a number in (0, 1)
--having-annotations Ignore all images without annotations. Keep only these
with at least one annotation
--multi-class Split a multi-class dataset while preserving class
distributions in train and test sets
لتشغيل تقسيم COCO:
python cocosplit.py --having-annotations \
--multi-class \
-s 0.8 \
source_coco_annotations.json \
train.json \
test.json
تذكر فقط إضافة خاصية الترخيص في بداية ملف json للمجموعة، في مكان ما بعد أول “{”. هذا أداة تقسيم تريدها حقًا.
"licenses": [],
التكوين
نعم، تكوين النماذج مثير للقلق.
لكن mask-rcnn سريع نسبيًا ولديه معدل كشف معقول. انظر هنا للمزيد من تفاصيل التكوين: https://mmdetection.readthedocs.io/en/latest/user_guides/train.html#train-with-customized-datasets
# التكوين الجديد يرث تكوينًا قاعدة لتسليط الضوء على التعديلات الضرورية
_base_ = '/home/someusername/mmdetection/configs/mask_rcnn/mask-rcnn_r50-caffe_fpn_ms-poly-1x_coco.py'
# نحتاج أيضًا إلى تغيير عدد الفئات في الرأس لتتناسب مع تسمية مجموعة البيانات
model = dict(
roi_head=dict(
bbox_head=dict(num_classes=3),
mask_head=dict(num_classes=3)))
# تعديل إعدادات مجموعة البيانات
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
# تعديل إعدادات المترابط
val_evaluator = dict(ann_file=data_root+'test.json')
test_evaluator = val_evaluator
# يمكننا استخدام نموذج Mask RCNN المدرب مسبقًا للحصول على أداء أعلى
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'
# إذا كنت تحب الأفلام الطويلة
# الافتراض القياسي هنا، إذا أتذكر بشكل صحيح، هو 12
train_cfg = dict(max_epochs=24)
شيء يجب النظر فيه إذا لم تكن تحتاج إلى الأقنعة: https://mmdetection.readthedocs.io/en/latest/user_guides/single_stage_as_rpn.html
التدريب
لنفترض أن لديك تكوين النموذج في /home/someusername/myproject/models/configs/mask-rcnn_r50-caffe_fpn_ms-poly-1x_v1.0.py . النص البرمجي للتدريب هو مكالمة معيّنة لـ mmdetection:
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
الاستنتاج
بعض الوثائق هنا: 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')
# قم بتشغيله لملف واحد:
# inferencer('demo/demo.jpg', out_dir='/home/someusername/myproject/test-output/1.0/', show=True)
# أو لجميع المجلد
inferencer('/home/someusername/myproject/test-images/', out_dir='/home/someusername/myproject/test-output/1.0/', no_save_pred=False)
روابط مفيدة
أتمنى أن يساعدك هذا بطريقة أو بأخرى.
اقرأ أيضًا:
- موقع Label Studio: https://labelstud.io/
- وثائق MMDetection: https://mmdetection.readthedocs.io/en/latest/get_started.html
- ورقة مساعدة برمجة Bash
- كشف علامات معدنية في الخرسانة باستخدام tensorflow
- ورقة مساعدة لـ Python
- ورقة مساعدة لـ Conda
- تحويل النص إلى صورة باستخدام Flux
- ورقة مساعدة لـ Ollama
- ورقة مساعدة لـ Docker
- الدوال المركبة مع AWS SAM و Python
- إنشاء ملف PDF في Python - المكتبات والأمثلة"