Сегментирането на изображението е важна област в компютърното зрение, прилага се в различни области на живота. PixelLib е библиотека, създадена, за да позволи лесно прилагане на сегментирането към проблеми от реалния живот. Поддържа сегментиране на екземпляри на обекти с модел Coco. Сегментирането с модел coco е ограничено, тъй като не можете да извършвате сегментиране извън 80-те класа, налични в coco. Вече е възможно да обучите модела за сегментиране на вашите персонализирани обекти с библиотеката PixelLib само със 7 реда код.

Инсталирайте PixelLib и неговите зависимости:

Инсталирайте Tensorflow с: (PixelLib поддържа tensorflow 2.0 и по-нова версия)

  • pip3 инсталиране на tensorflow

Инсталирайте imgaug с:

  • pip3 install imgaug

Инсталирайте PixelLib с

  • pip3 инсталирайте pixellib

Ако е инсталиран, надстройте до най-новата версия, като използвате:

  • pip3 инсталирайте pixellib — надграждане

Стъпките, необходими за обучение на потребителски модел.

СТЪПКА 1:

Подгответе своя набор от данни:

Нашата цел е да създадем модел, който може да извършва сегментиране на екземпляри и откриване на обекти върху пеперуди и катерици.

Съберете изображения за обектите, които искате да откриете, и анотирайте своя набор от данни за персонализирано обучение. Labelme е инструментът, използван за извършване на анотация на полигони на обекти. Създайте главна директория или папка и в нея създайте обучителна и тестова папка. Отделете изображенията, необходими за обучение (минимум 300) и тествайте. Поставете изображенията, които искате да използвате за обучение, в папката на влака и поставете изображенията, които искате да използвате за тестване, в тестовата папка. Ще анотирате и двете изображения в папката за влак и тест. Изтеглете Nature’s dataset, използван като примерен набор от данни в тази статия, разархивирайте го, за да извлечете папката на изображенията. Този набор от данни ще ви служи като ръководство, за да знаете как да организирате вашите изображения. Уверете се, че форматът на директорията на вашия набор от данни не е различен от него. Nature е набор от данни с два класа пеперудаи катерица. Има 300 изображения за всеки клас за обучение и 100 изображения за всеки клас за тестване, т.е. 600 изображения за обучение и 200 изображения за валидиране. Nature е набор от данни с 800 изображения.

Прочетете тази статия, за да научите как да използвате labelme за анотиране на обекти.



Nature >>train>>>>>>>>>>>> image1.jpg
                           image1.json
                           image2.jpg
                           image2.json
      
       >>test>>>>>>>>>>>>  img1.jpg
                           img1.json
                           img2.jpg
                           img2.json   

Пример за директория с папки след анотация.

Забележка:PixelLib поддържа анотация с Labelme. Ако използвате друг инструмент за пояснения, той няма да е съвместим с библиотеката.

СТЪПКА 2:

Визуализирайте набор от данни

Визуализирайте примерно изображение преди обучение, за да потвърдите, че маските и ограничителните полета са добре генерирани.

import pixellib
from pixellib.custom_train import instance_custom_training
vis_img = instance_custom_training()

Импортирахме pixellib, от pixellibниеимпортирахме класа instance_custom_training и създадохме екземпляр на класа.

vis_img.load_dataset("Nature”)

Заредихме набора от данни с помощта на функцията load_dataset. PixelLib изисква многоъгълните анотации да бъдат във формат coco. Когато извикате функцията load_dataset, отделните json файлове във влаковата и тестовата папка ще бъдат преобразувани в един train.json и test.json съответно. Файловете обучение и тест json ще бъдат разположени в главната директория като папка за обучение и тест. Новата папка сега ще изглежда така:

Nature >>>>>>>>train>>>>>>>>>>>>>>> image1.jpg
               train.json           image1.json
                                    image2.jpg
                                    image2.json
       >>>>>>>>>>>test>>>>>>>>>>>>>>> img1.jpg
                  test.json           img1.json
                                      img2.jpg
                                      img2.json

Във функцията load_dataset анотациите се извличат отфайловете на jsons. Маските се генерират от многоъгълните точки на анотациите, а ограничителните полета се генерират от маските. Най-малката кутия, която капсулира всички пиксели на маска, се използва като ограничаваща кутия.

vis_img.visualize_sample()

Когато извикате тази функция, тя показва примерно изображение с маска и ограничителна рамка.

Страхотен! наборът от данни е подходящ за обучение, функцията load_dataset успешно генерира маска и ограничителна рамка за всеки обект в изображението. Генерират се произволни цветове за маските в HSV пространството и след това се преобразуват в RGB.

ПОСЛЕДНА СТЪПКА:

Обучете персонализиран модел с помощта на вашия набор от данни

Това е кодът за извършване на обучение. Само в седем реда код обучавате своя набор от данни.

train_maskrcnn.modelConfig(network_backbone = "resnet101", num_classes= 2, batch_size = 4)                       

Нарекохме функцията modelConfig, т.е.конфигурация на модела. Необходими са следните параметри:

  • network_backbone:Това е мрежата CNN, използвана като инструмент за извличане на функции за mask-rcnn. Използваният екстрактор на функции е resnet101.
  • num_classes:Задаваме броя на класовете на категориите обекти в набора от данни. В този случай имаме два класа (пеперуда и катерица) в природния набор от данни.
  • batch_size:Това е размерът на партидата за обучение на модела. Настроено е на 4.
train_maskrcnn.load_pretrained_model("mask_rcnn_coco.h5")
train_maskrcnn.load_dataset(“Nature”)

Ще използваме техниката на трансферно обучение за обучение на модела. Моделът Coco е обучен на 8O категории обекти, той е научил много функции, които ще помогнат при обучението на модела. Извикахме функцията функция load_pretrained_model, за да заредиммодела mask-rcnn coco. Ние заредихменабора от данни с помощта нафункцията load_dataset.

Изтеглете коко модел от тук.

train_maskrcnn.train_model(num_epochs = 300, augmentation=True,path_trained_models = “mask_rcnn_models”)

Накрая извикахме функцията на влака за тренировъчен модел mask r-cnn. Извикахме функцията train_model. Функцията прие следните параметри:

  • num_epochs: Броят на епохите, необходими за обучение на модела. Настроено е на 300.
  • увеличаване: Увеличаването на данните се прилага към набора от данни. Това е така, защото искаме моделът да научи различни представяния на обектите.
  • path_trained_models:Това е пътят за запазване на обучените модели по време на обучение. Моделите с най-ниски загуби при валидиране се запазват.
Using resnet101 as network backbone For Mask R-CNN model
Train 600 images 
Validate 200 images 
Applying augmentation on dataset 
Checkpoint Path: mask_rcnn_models
Selecting layers to train
Epoch 1/200
100/100 - 164s - loss: 2.2184 - rpn_class_loss: 0.0174 - rpn_bbox_loss: 0.8019 - mrcnn_class_loss: 0.1655 - mrcnn_bbox_loss: 0.7274 - mrcnn_mask_loss: 0.5062 - val_loss: 2.5806 - val_rpn_class_loss: 0.0221 - val_rpn_bbox_loss: 1.4358 - val_mrcnn_class_loss: 0.1574 - val_mrcnn_bbox_loss: 0.6080 - val_mrcnn_mask_loss: 0.3572

Epoch 2/200
100/100 - 150s - loss: 1.4641 - rpn_class_loss: 0.0126 - rpn_bbox_loss: 0.5438 - mrcnn_class_loss: 0.1510 - mrcnn_bbox_loss: 0.4177 - mrcnn_mask_loss: 0.3390 - val_loss: 1.2217 - val_rpn_class_loss: 0.0115 - val_rpn_bbox_loss: 0.4896 - val_mrcnn_class_loss: 0.1542 - val_mrcnn_bbox_loss: 0.3111 - val_mrcnn_mask_loss: 0.2554

Epoch 3/200
100/100 - 145s - loss: 1.0980 - rpn_class_loss: 0.0118 - rpn_bbox_loss: 0.4122 - mrcnn_class_loss: 0.1271 - mrcnn_bbox_loss: 0.2860 - mrcnn_mask_loss: 0.2609 - val_loss: 1.0708 - val_rpn_class_loss: 0.0149 - val_rpn_bbox_loss: 0.3645 - val_mrcnn_class_loss: 0.1360 - val_mrcnn_bbox_loss: 0.3059 - val_mrcnn_mask_loss: 0.2493

Това е дневникът на обучението. Той показва гръбнака на мрежата, използван за обучение mask-rcnn, който е resnet101, броя на изображенията, използвани за обучение, и броя на изображенията, използвани за валидиране. В директорията path_to_trained models' моделите се записват въз основа на намаляване на загубата при валидиране и типичното име на модела ще се появи така: mask_rcnn_model_25–0.55678, езапаметена с номера на епохата и съответната загуба на валидиране.

Гръбнаци на мрежата:

Има две мрежови опори за обучение на mask-rcnn

  • Resnet101
  • Resnet50

Google Colab:Google Colab предоставя един 12GB NVIDIA Tesla K80 GPU, който може да се използва до 12 часа непрекъснато.

Използване на Resnet101: Training Mask-RCNN консумира много памет. В google colab, използвайки resnet101 като гръбнак на мрежата, ще можете да обучавате с размер на партида от 4. Мрежовият гръбнак по подразбиране е resnet101. Resnet101 се използва като гръбнак по подразбиране, тъй като изглежда достига по-ниска загуба при валидиране по време на обучение по-бързо от resnet50. Освен това работи по-добре за набор от данни с множество класове и много повече изображения.

Използване на Resnet50: Предимството на resnet50 е, че консумира по-малко памет. По този начин можете да използвате batch_size от 6 или 8 в google colab в зависимост от това как colab произволно разпределя GPU.

Модифицираният код, поддържащ resnet50ще бъде така.

Пълен код

Основните разлики от оригиналния код са, че във функцията за конфигуриране на модела зададохме network_backbone да бъде resnet50и променихме размера на пакета на 6.

Единствената разлика в дневника на обучението е следната:

Using resnet50 as network backbone For Mask R-CNN model

Това показва, че използваме resnet50 за обучение.

Забележка:Дадените batch_sizes са мостри, използвани за google colab. Ако използвате по-малко мощен GPU, намалете размера на партидата. Например, за компютър с 4G RAM графичен процесор, трябва да използвате партиден размер 1 както за resnet50, така и за resnet101. Използвах партида с размер 1, за да обуча моя модел на графичния процесор на моя компютър, обучен за по-малко от 100 епохи и това доведе до загуба при валидиране от 0,263. Това е благоприятно, защото моят набор от данни не е голям. Компютър с по-мощен GPU трябва да може да използва партида с размер 2. Ако имате голям набор от данни с повече класове и много повече изображения, можете да използвате google colab, където имате безплатен достъп до GPU. Най-важното е да опитате да използвате по-мощен графичен процесор и да тренирате за повече епохи, за да създадете персонализиран модел, който ще работи ефективно в множество класове.

Постигнете по-добри резултати, като тренирате с много повече изображения. 300 изображения за всеки клас се препоръчват като минимално изискване за обучение.

Оценка на модел

Когато приключим с обучението, трябва да оценим модели с най-ниски загуби при валидиране. Оценката на модела се използва за достъп до производителността на обучения модел върху тестовия набор от данни. Изтеглете обучения модел от тук.

изход

mask_rcnn_models/Nature_model_resnet101.h5 evaluation using iou_threshold 0.5 is 0.890000

mAP (средна средна точност) на модела е 0,89.

Можете да оцените няколко модела наведнъж, това, от което се нуждаете, е да преминете в директорията на папката на моделите.

Изходен дневник

mask_rcnn_models\Nature_model_resnet101.h5 evaluation using iou_threshold 0.5 is 0.890000
mask_rcnn_models\mask_rcnn_model_055.h5 evaluation using iou_threshold 0.5 is 0.867500
mask_rcnn_models\mask_rcnn_model_058.h5 evaluation using iou_threshold 0.5 is 0.8507500

Оценка с Resnet50

Забележка: Сменете network_backbone на resnet50, ако оценявате модел resnet50.

Извод с персонализиран модел

Ние обучихме и оценихме модела. Следващата стъпка е да видите представянето на модела върху неизвестни изображения.

Ще тестваме модела в класовете, на които сме го обучавали.

Пример1.jpg

import pixellib
from pixellib.instance import custom_segmentation 
segment_image =custom_segmentation()
segment_image.inferConfig(num_classes= 2, class_names= ["BG", "butterfly", "squirrel"])

Импортирахме класаcustom_segmentation, класът за извършване на изводи и създадохме екземпляр на класа. Извикахме функцията на конфигурацията на модела и въведохме допълнителен параметър class_names.

class_names= ["BG", "butterfly", "squirrel"])

class_names:Това е списък, съдържащ имената на класовете, с които моделът е обучен. „BG“ се отнася за фона на изображението. Това е първият клас и трябва да бъде наличен по имената на класовете.

Забележка:Ако имате няколко класа и сте объркани как да подредите имената на класовете според техните идентификатори на класове, във вашия test.json в папката на набора от данни, проверете списък с категории.

{
"images": [
{
"height": 205,
"width": 246,
"id": 1,
"file_name": "C:\\Users\\olafe\\Documents\\Ayoola\\PIXELLIB\\Final\\Nature\\test\\butterfly (1).png"
},
],
"categories": [
{
"supercategory": "butterfly",
"id": 1,
"name": "butterfly"
},
{
"supercategory": "squirrel",
"id": 2,
"name": "squirrel"
}
],

Можете да видите от примера на директорията на test.json по-горе, че след списъка с изображения в test.json е списъкът с категории на обекти. Tимената на класовете са там със съответните им идентификатори на класове. Пеперудата има идентификатор на клас 1, а катерица има идентификатор на клас 2. Не забравяйте, че първият идентификатор „0“ се запазва в резерв за фон.

segment_image.load_model("mask_rcnn_model/Nature_model_resnet101.h5)
segment_image.segmentImage("sample1.jpg", show_bboxes=True, output_image_name="sample_out.jpg")

Персонализираният модел се зарежда и извикахме функцията за сегментиране на изображението.

Когато параметърът show_bboxesе зададен на True, ще можем да извършим сегментиране на екземпляр с откриване на обект.

test_maskrcnn.segmentImage(“sample1.jpg”,show_bboxes = False, output_image_name=”sample_out.jpg”)

Когато show_bboxes е зададено на False, получаваме само маски за сегментиране.

Пример2.jpg

test_maskrcnn.segmentImage(“sample2.jpg”,show_bboxes = True, output_image_name=”sample_out.jpg”)

ЕХА! Ние успешно обучихме персонализиран модел за извършване на сегментиране на екземпляри и откриване на обекти върху пеперуди и катерици.

Сегментиране на видео с персонализиран модел.

sample_video1

Искаме да извършим сегментиране на пеперудите в това видео.

test_video.process_video("video.mp4", show_bboxes = True,  output_video_name="video_out.mp4", frames_per_second=15)

Функцията process_video се извиква, за да извърши сегментиране на обекти във видео.

Необходими са следните параметри:-

  • video_path: Това е пътят до видео файла, който искаме да сегментираме.
  • frames_per_second: Това е параметърът, използван за задаване на броя кадри в секунда за запазения видео файл. В този случай е зададено на 15, т.е. записаният видео файл ще има 15 кадъра в секунда.
  • output_video_name: Tтова е името на запазениясегментиран видеоклип. Изходният видеоклип ще бъде записан в текущата ви работна директория.

Изход_видео

Пример за друго сегментирано видео с нашия персонализиран модел.

Можете да извършите сегментиране на камера на живо с вашия персонализиран модел, като използвате този код:

Ще замените функцията process_video с функцията process_camera.Във функцията заменихме пътя на файла на видеоклипа за заснемане, т.е. обработваме поток от кадри, заснети от камерата, вместо видео файл. Добавихме допълнителни параметри с цел показване на кадрите на камерата:

  • show_frames: Този параметър управлява показването на сегментирани рамки на камерата.
  • frame_name: Tтова е името, дадено на рамката на показаната камера.

Посетете бележника на Google Colab, настроен за обучение на персонализиран набор от данни.



„Посетете официалното хранилище на Github на Pixellib“

„Посетете официалната документация на Pixellib“

Свържете се с мен чрез:

Имейл: [email protected]

Linkedin: Ayoola Olafenwa

Twitter: @AyoolaOlafenwa

Facebook: Ayoola Olafenwa