Custom Object Detection using Darknet | Towards Data Science

In this article you will get your hands dirty using Darknet and training the model for mask detection.
This article can be referred to train any custom object detector
Citations: The video output feed is available on YouTube by Bloomberg Quicktake, images downloaded for training are available as open source on Kaggle. The images are the screenshots of my personal computer. Huge thanks to my colleague Shauryasikt Jena
Instead of training your own model from scratch, you can build on existing models and fine-tune them for your own purpose without requiring as much computing power. I was using Google Colab for training and CPU (local machine) for testing.
Darknet is an open source neural network framework. It is a fast and highly accurate (accuracy for custom trained model depends on training data, epochs, batch size and some other factors) framework for real time object detection (also can be used for images). The most important reason it is fast because it is written in C and CUDA.
To get an idea how fast C is —
For more comparison stats please visit this page —
benchmarksgame-team.pages.debian.net
InstallationCollecting ImagesLabeling the imagesGetting and setting up DarknetTraining our darknet
Installation
Collecting Images
Labeling the images
Getting and setting up Darknet
Training our darknet
So let’s get started its pretty easy and simple. Just go through the article and follow the steps. Thanks :)
We are going to train our model on Google colab so there is no extra library you are going to require to install
But if you are testing the model on your local machine, here are the libraries you need —
opencv==4.2.0tensorflow==1.13.2numpy==1.18.1pandas==1.0.2keras==2.3.1matplotlib==3.2.0PIL==7.0.0ffmpeg==4.2.2
Please install these libraries on your local system using conda or pip available on anaconda cloud or Pypi respectively.
Note: ffmpeg is used to save the output video file hence, the specific version is required.
conda install ffmpeg
You can get the images from this link by clicking the download —
www.kaggle.com
Note: This link contains a zip file in which the images and their labels/annotations are already present but ensure that the they are correct(with respect to the coordinates of masked/non masked). Just to be sure I labelled it manually so that I do not need to train the model again.
The downloaded file would have only around 700 images which is not enough to get a good accuracy. You can get them from these links too..
www.kaggle.com
You can get masked and non masked images from here —
www.kaggle.com
So now you have collected 1300+ images (If possible you can add more images, it would surely increase the accuracy), here comes a little tedious step but an important one.
After collecting so many images which is around 1300 or more you have to manually label them. Yes, this is a very tedious task but it’s very important to correctly label the images or else it would reflect on the model and the accuracy would not be so satisfying!
To label the images, you can use a very well known tool Labelimg.
You can clone this link on your system —
github.com
Note: After cloning I would recommend to see installation steps as you have to write two or three lines on your command prompt
For installation guidance you can watch any labelimg installation video. Don’t worry the installation is easy but the labeling part is uh... you know what I mean.
Go to file and open the folder in which you have the images
Go to file and open the folder in which you have the images
2. Click on the create\nRectBox and start labeling masked images
3. Drag on the area around the mask and type masked
4. We also need non masked hence the same procedure click on the create/nRectBox and drag on non masked face and label it not_masked
5. After labeling every face save and move to next image
Honestly you will require 2 to 3 hours to do this depending on your speed. So good luck ;)
Getting the darknet
You can directly clone this GitHub Repository on google colab for training —
github.com
Note: Along with this repository there is another repository which is forked version of pjreddie. I used pjreddie because at my first attempt it worked fine for me.
Setting up Darknet
You need a file called as darknet53.conv.74 , you can download it from here and put it in darknetIn cfg folder, create a file named as yolov3_custom_train.cfg using notepad, copy everything from yolov3.cfg in the new file. copy these 22 lines instead of those in the file
You need a file called as darknet53.conv.74 , you can download it from here and put it in darknet
In cfg folder, create a file named as yolov3_custom_train.cfg using notepad, copy everything from yolov3.cfg in the new file. copy these 22 lines instead of those in the file
[net]#Testing#batch=1#subdivisions=1#Trainingbatch=24subdivisions=8width=416height=416channels=3momentum=0.9decay=0.0005angle=0saturation = 1.5exposure = 1.5hue=.1learning_rate=0.001burn_in=1000max_batches = 6000policy=stepssteps=5400scales=.1,.1
In the file search for [yolo] using ctrl + f and make these changes everywhere (There will be three [yolo] blocks).
Note: The changes will be in the each [yolo] and the [convolutional] block just above [yolo] and that’s it for .cfg, don’t forget to save it!
[convolutional]size=1stride=1pad=1filters=21activation=linear[yolo]mask = 6,7,8anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326classes=2num=9jitter=.3ignore_thresh = .7truth_thresh = 1random=1
Let’s understand briefly what we just did..
We changed the classes=2 as we have two classes masked and not_masked and in [convolutional], filters=21
Formulae for number of filters is —
filters = (number of classes + 5)*3
3. Create a new file in data folder named as yolo.names using notepad and just copy these lines..
maskednot_masked
..and done, save it. (We are gonna need this file for testing)
4. Create another two files train.txt and val.txt and divide your images in training 95% Validation-5%.
darknet    ├── cfg    |       ├── data    |   ├── images    |          ├── some_image.jpg    |          ├── other_image.jpg    |          ├── ...    |   ├── labels    |          ├── Some_image.txt    |          ├── other_image.txt    |          ├── ...    |   ├── train.txt     |   ├── val.txt    |    ├── ...    .    .    ├── darknet53.conv.74    ...
Now here comes the tricky part.. the images you have downloaded should be put in images folder in darknet and the annotations/labels in labels folder. In train.txt and val.txt you have to give the path to every image like this..
Tip: You can write a simple python code to do this which takes only takes 2 mins, no need to write the entire thing manually
5. Create a file ‘yolo.data’ using notepad and paste this in the file..
classes= 2train  = data/train.txtvalid  = data/val.txtnames = data/yolo.namesbackup = backup
The most awaited part is finally here. From here you don’t need to do anything just run some codes and wait for the training to be completed.
Now just upload your darknet folder on google drive and we are almost there.
Tip: If in any case google colab disconnects you automatically because your GPU runtime has exceeded, you can save checkpoints of your generated weight files so that you can continue from that epoch and also test which weight file gives the best results. You can go to detector.c file in examples folder and make these changes so that you get weight files after every 100 epochs and after 1000 epochs you will get the weights after every 1000 epochs
Create a folder ‘backup’ outside your darknet folder in My Drive
void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear){ ....   ....  ....  if(i%1000==0 || (i < 1000 && i%100 == 0)){#ifdef GPU    if(ngpus != 1) sync_nets(nets, ngpus, 0);#endif       char buff[256];       sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i);       save_weights(net, buff);    }
Now that we are almost there, just make sure you have everything you need to train the model because you don’t wanna do everything again.
Okay.. now let’s train the model (yeah.. finally)
The easiest step is here, but first make sure the paths you are giving are correct. Run these codes cell by cell and done. Change the colab runtime to GPU
Note: The commands below will work only for linux, hence we are using Google Colab
google.colab import drivedrive.mount('/content/drive')#If you have a zipped darknet!unzip "/content/drive/My Drive/darknet.zip"%cd /content/darknet!make!chmod +x ./darknet!rm /content/darknet/backup -r!ln -s /content/drive/'My Drive'/backup /content/darknet!sudo apt install dos2unix!dos2unix ./data/train.txt!dos2unix ./data/val.txt!dos2unix ./data/yolo.data!dos2unix ./data/yolo.names!dos2unix ./cfg/yolov3_custom_train.cfg#To start the training%cd /content/darknet!./darknet detector train data/yolo.data cfg/yolov3_custom_train.cfg darknet53.conv.74
Note: When you are starting the training from a checkpoint let’s say after 2000 epochs, just change the training command to this..
!./darknet detector train data/yolo.data cfg/yolov3_custom_train.cfg yolov3_custom_train_2000.weights
That’s it!! Thank you for going through the entire article
towardsdatascience.com
For more information about darknet visit this link —