تدريب كاشف الأهداف الذكاء الاصطناعي باستخدام Label Studio و MMDetection

يتطلب التصنيف والتدريب بعض التصاق الأجزاء

Page content

عندما قمت تدريب مكتشف كائنات الذكاء الاصطناعي في وقت ما - كان LabelImg أداة مفيدة للغاية، لكن تصدير البيانات من Label Studio إلى تنسيق COCO لم يكن مقبولاً من قبل إطار عمل MMDetection..

كان من الضروري استخدام بعض الأدوات والبرمجة لجعل كل شيء يعمل.

topimage

القائمة هنا تشمل الأجزاء المفقودة وبعض النصوص البرمجية بعضها وجدته على الإنترنت، والآخر كتبتُه أنا.

الخطوات الأساسية

تحضير، تدريب واستخدام الذكاء الاصطناعي يتضمن

  1. الحصول على البيانات الأصلية (الصور للكشف عن الكائنات والتصنيف)
  2. تحديد الصور وإعداد مجموعة البيانات
  3. تطوير نموذج جديد أو العثور على نموذج مناسب موجود
  4. تدريب النموذج، أحيانًا مع تعديل معلمات التدريب
  5. استخدام النموذج للتنبؤ بالعلامات للصور الجديدة (الاستنتاج)

هنا أقدم الخطوات الدقيقة لكيفية تحديد البيانات باستخدام 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 مماثل ل:

topimage

لا تنسَ تحديد “اعتبر كل كائن في المجموعة كملف مصادر” إذا كنت تخطط لتوحيد الصور (أعتقد أنك تفعل ذلك)، وليس الملفات 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

topimage

تقسيم مجموعة البيانات

لتقسيم مجموعة البيانات إلى تدريب واختبار، استخدمت أداة 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)

روابط مفيدة

أتمنى أن يساعدك هذا بطريقة أو بأخرى.

اقرأ أيضًا: