Skip to content

Tutorials

Train YOLO to detect a custom object (online with free GPU)

Access community, courses and source codes
Logo

AI Vision Academy

Access the code of this tutorial, computer vision courses and an exclusive community on AI Vision Academy

  • Access to over 50+ source codes from Pysource.com/blog
  • Dedicated video courses about computer vision
  • Access to an exclusive community of professionals
  • Real-World AI Projects – Get hands-on experience building practical AI Computer Vision solutions with a structured path.
  • Monthly Coaching Calls – get support and any of your questions answered

Subscribe to our newsletter to learn more

In this tutorial I’m going to explain you one of the easiest way to train YOLO to detect a custom object even if you’re a beginner and have no experience with coding.

You will need just a simple laptop (windows, linux or mac), as the training is going to be done online, taking advantage of the free gpu offered by google colab.

We can train YOLO to detect a custom object, I choosed for example to detect a Koala, you can choose any animal/object you prefer.

Let’s start.

1. Prepare the Image dataset

An image dataset is a folder containing a lot of images (I suggest to get at least 100 of them) where there is the custom object you want to detect. For example I’m training YOLO to recognize a Koala, so I have downloaded around 350 images containing Koalas.

Having the iamges is not enough, but we also need to specify where the custom object is located on the specific image.

For this operation we will need an external software: LabelImg.
You can download it here for Windows and Linux: https://tzutalin.github.io/labelImg/
If you have the MAC, you can install it by following the instructions here: https://github.com/tzutalin/labelImg#macOS

1. Let’s set labelimg for our dataset:

  1. Once we run LabelImg let’s click on “Open Dir”.
  2. We choose the folder where the images are located
  3. Then we click on “Select folder”
  4. We then click on “Change save dir”.
  5. We select the folder where the images are located (same folder we selected on step 2).
  6. Then we click on “Select folder”.
  7. Finally make sure that we’re using the settings for YOLO.
    If pascalVOC is written, then let’s click and we will see YOLO.

2. Now we’re ready to label the images.

  1. Let’s click on “Create RectBox”
  2. Let’s select the area where our object is located (in my case I’m going to select the Koala)
  3. We add the label with the name of our object. In my case typed Koala and press Ok.
  4. We click on “Save”

We’re going to do this operation for all the images we have on the dataset.

At the end of this operation, we should see on the folder of the images, for each image a .txt file with the same name.

Inside the file will look like this:

15 0.392578 0.504395 0.566406 0.791992

3. Let’s now put all the images and txt file into a .zip archive called images.zip

Well done.
Your image dataset is now ready.

2. Train the Image dataset online

To train the image dataset we’re going to use the free server offered by google colab.

Google colab is a free service offered by google where you can run python scripts and use machine learning libraries taking advantage of their powerful hardware.
It’s for free with the only disadvantage the you can use it for 12 hours in a row, after that you’ll be disconnected and your files will be deleted.
you can restart it again but doing everything from scratch.

We can solve this problem by connecting google colab with google drive, so we won’t lose the files in case of disconnection.

Set up google drive:

  1. Go on google drive and log in. If you’ don’t have an account, create one and log in.
  2. Create a new folder called “yolov3”.
  3. Then upload the file “images.zip” you created before inside the yolov3 folder.

Set up google colab:

  1. Go on google colab and log in with the same account you used to log in on google drive.
  2. Upload this file “Train_YoloV3.ipynb”
    n.b. You can get this file by clicking on “Click here to download the Source code” at the beginning of the post.
  3. Then we need to enable the GPU. So click on “Edit”.
  4. Then we select “GPU” and click save.
  5. Now we’re ready to connect Colab with our drive.
    Run the cell where it’s written “from google.colam import drive” and then clicl on the link that appears.
  6. This links is to grant access to your google drive. Once you enter it asks you to allow the Google drive file Stream. Click on “Allow”. And then copy the code that appears.
  7. Paste the code on the notebook and press “Enter”.

Your colal is ready for the training.

Now you can start the training by simply clicking on “Runtime”, then “Run all”.

The command above is going to run all the cells.
The code will automatically install the darknet (framework used to run and train YOLO), it will make the configuration and it will run the training.

If you see an output similar to the one below, then well done, your model is training.

Leav it as long as it goes. Usually it takes a minimum of 3 hours to the entire 12 hours you have the access to the gpu.

We will see now how to use the model you’ve created.

3. Test the model we created

Each 100 iterations, our custom object detector is going to be updated and saved on our Google drive, inside the folder “yolov3”.

The file that we need is “yolov3_training_last.weights”.
You might find that other files are also saved on your drive, “yolov3_training__1000.weights”, “yolov3_training_2000.weights” and so on because the darknet makes a backup of the model each 1000 iterations.

I created a python project to test your model with Opencv.
The project is on the folder yolo_custom_detection, which contains 2 files (yolo_object_detection.py and yolov3_testing.cfg).
n.b. You can get this file by clicking on “Click here to download the Source code” at the beginning of the post.

You need to download the file yolov3_training_last.weights from Google Drive and place in on the same folder with yolo_object_detection.py and yolov3_testing.cfg.

On the file “yolo_object_detection.py” on line 11 change “koala” with the name of your object.
And on line 14 you have to put the path of a folder containing the images where there is your object, so you can test it.

# Load Yolo
net = cv2.dnn.readNet("yolov3_training_last.weights", "yolov3_testing.cfg")

# Name custom object
classes = ["Koala"]

# Images path
images_path = glob.glob(r"D:\Pysource\Youtube\2020\105) Train Yolo google cloud\dataset\*.jpg")

And finally, here is the result.
It works!

4. Train YOLO for multiple class

This tutorial has been optimized and works only for a single custom class.

If you need a custom object detection for multiple classes I recommend you to evaluate the purchase of my Object Detection course.
You will also find a lesson dedicated lesson to train a custom object detector with YOLO and a notebook file that automatically configures itself for the training of multiple classes.


113 comments

  1. Hi Sergio,

    Your post looks great and easy to follow however I am having problem finding the “brain” behind it all. Where is the link –> “Click here to download the Source code” at the beginning of the post.” It may be hiding at plain site but I am reading your post for the 3rd time and still can’t find it.

    thx

    1. If it was able to reach 106 iterations you should find them. Please refresh the page of your google drive.

      I’m saying this because, if there was an error, the code would stop at 100 iterations saying that weights could not be saved, but as I went further to 106 iterations, the weights should be there.

      1. Dear Sergio,
        I’ve encountered the same issue, I even tried to remove the yolov3 folder so the mkdir line runs withouts errors(Also changed the location to load images.zip) but in both cases, I did not find the weights in my yolov3 folder. Could they be hidden? I ran the code for approximately 2102 iterations.

        1. I was getting error after 100 iterations saying it could not locate the yolov3 folder. And the reason was that apparently, the code cannot read the space between “My Drive”, and reads it as “MyDrive” no matter what.

          Solution:
          In the step where we define the backup folder, change the path to /content/darknet instead of /mydrive/yolov3

          This will store your weight files in the darknet folder which can be accessed from the left pane.
          The only care you need to take is to download the weight file immediately as they are created since if your session gets interrupted or you exceed 12 hrs, the darknet directory gets deleted.
          So download and store locally before that happens

          cheers

  2. if I have two objects, how this code looks?

    !echo “Koala” > data/obj.names
    !echo -e ‘classes= 1\ntrain = data/train.txt\nvalid = data/test.txt\nnames = data/obj.names\nbackup = /mydrive/yolov3’ > data/obj.data
    !mkdir data/obj

        1. Hey Rafael,
          Im currently working on a 2 object detectation system, an saw your comment.
          did you try it and work ?
          and if yes, can you tell me how did you do it ?
          Thank you in advance !!

  3. The training function outputs the following results and then stops running. What is the problem?
    100 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    101 conv 128 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 128 0.177 BF
    102 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    103 conv 128 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 128 0.177 BF
    104 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    105 conv 18 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 18 0.025 BF
    106 yolo
    [yolo] params: iou loss: mse (2), iou_norm: 0.75, cls_norm: 1.00, scale_x_y: 1.00
    Total BFLOPS 65.304
    avg_outputs = 516723
    Allocate additional workspace_size = 52.43 MB
    Loading weights from darknet53.conv.74…
    seen 64, trained: 0 K-images (0 Kilo-batches_64)
    Done! Loaded 75 layers from weights-file
    Learning Rate: 0.001, Momentum: 0.9, Decay: 0.0005
    Resizing, random_coef = 1.40

    608 x 608

      1. In my case, I was not including the class.txt file generated by labelImg.
        My other mistake was that my .txt files generated from the images read the class as “15”, I changed them to “0” and now it is running.
        Did you try something similar?

      2. I found my mistake. I put all my files in the “images” folder, and then compressed the “images” folder. Another error now occurs at runtime: class=15 in the TXT file, but the class range is 0 to 0.

        1. I updated the Train_YoloV3.ipynb file to solve the problem regarding the class index “lass=15 in the TXT file, but the class range is 0 to 0”.

          please download again the notbook file and it shoudl work fine.

    1. Hi Steve,
      I didn’t put my images to download. I used them as to show everyone as to train a custom object, so that anyone can train his own images.

  4. The training process stopped at step 6 with:
    CUDA status Error: file: ./src/dark_cuda.c : () : line: 39 : build time: Apr 6 2020 – 12:24:18
    CUDA Error: no CUDA-capable device is detected
    CUDA Error: no CUDA-capable device is detected: Success
    darknet: ./src/utils.c:325: error: Assertion `0′ failed.

      1. Yes it will work fine with different image file formats. I trained the network on .bmp image files and tested on JPG, PNG and BMP formats and the results are coming. Just make sure to use glob right when dealing with multiple image formats.

  5. When I started training in google colab I am getting this error.
    Error: You set incorrect value batch=1 for Training! You should set batch=64 subdivision=64
    Kindly acknowledge how to resolve this error.

    1. I have same trouble

      Allocate additional workspace_size = 52.43 MB
      Loading weights from darknet53.conv.74…
      seen 64, trained: 0 K-images (0 Kilo-batches_64)
      Done! Loaded 75 layers from weights-file
      Learning Rate: 0.001, Momentum: 0.9, Decay: 0.0005
      Resizing, random_coef = 1.40

      608 x 608
      Create 6 permanent cpu-threads

      any solution?

  6. Hi Sergio,

    Your post is awesome, I was able to follow most of it, however I am having difficulty running the last portion since I have no idea of how to test the model. One more question the path for the images can be local or does it have to be on the google drive? thanks in advance.

  7. I can train the model for multiple pictures for example i took the pictures of my friends and label different names but after i done training it cannot give correct result mean if i put class a it will show the pictures of label b with display the name of a. whats the problem can explain please

  8. Always show this error:
    yolo] params: iou loss: mse (2), iou_norm: 0.75, cls_norm: 1.00, scale_x_y: 1.00
    95 route 91 -> 26 x 26 x 256
    96 conv 128 1 x 1/ 1 26 x 26 x 256 -> 26 x 26 x 128 0.044 BF
    97 upsample 2x 26 x 26 x 128 -> 52 x 52 x 128
    98 route 97 36 -> 52 x 52 x 384
    99 conv 128 1 x 1/ 1 52 x 52 x 384 -> 52 x 52 x 128 0.266 BF
    100 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    101 conv 128 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 128 0.177 BF
    102 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    103 conv 128 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 128 0.177 BF
    104 conv 256 3 x 3/ 1 52 x 52 x 128 -> 52 x 52 x 256 1.595 BF
    105 conv 18 1 x 1/ 1 52 x 52 x 256 -> 52 x 52 x 18 0.025 BF
    106 yolo
    [yolo] params: iou loss: mse (2), iou_norm: 0.75, cls_norm: 1.00, scale_x_y: 1.00
    Total BFLOPS 65.304
    avg_outputs = 516723
    Allocate additional workspace_size = 52.43 MB
    Loading weights from darknet53.conv.74…
    seen 64, trained: 0 K-images (0 Kilo-batches_64)
    Done! Loaded 75 layers from weights-file
    Learning Rate: 0.001, Momentum: 0.9, Decay: 0.0005
    Resizing, random_coef = 1.40
    608 x 608
    Create 6 permanent cpu-threads
    my txt looks like this:
    0 0.510563 0.516892 0.936620 0.966216

    1. I have the same issue. I’ve found that ‘import glob
      images_list = glob.glob(“data/obj/*.jpg”)
      print(images_list)’ returns [] as if there are no images

      1. I got it. The problem was that my files were *.JPG (all capital) where the training.txt was searching for *.jpg (lower case). I’m “learning” now

  9. Thank you for the explanation,
    I created an own dataset of plastic waste to detect in rivers, but when I am running the Google Colab file, the Darknet cannot be cloned. I get the message:
    fatal: destination path ‘darknet’ already exists and is not an empty directory.

    When extracting the images, I get this question for every image in the database:
    replace data/obj/plastic_bottle/classes.txt? [y]es, [n]o, [A]ll, [N]one, [r]ename:

    This is not possible to do for every image, every time I try to train the model.
    I hope you can help me with these two problems.

    Thanks you in regards.

  10. Hi Sergio,
    I just downloaded the zip file but it does not contain the Train_YoloV3.ipynb file in it instead it has the testing python file
    need help.

  11. Hello! Your tutorial was simply amazing and very helpful. My question here is how can I extend the detection to multiple instances of my custom class in one picture, as it currently ignores the other objects? I trained the weights with varying images gotten from google open images dataset. I would really appreciate the help.

    1. Did you solve it ? Have the same problem. It only detects if i set image with one instance of object. For example if I show the image with multiple koalas in one image it doesnt return anything. But if i split it in multiple images with one koala per image it works fine.

  12. Traceback (most recent call last):
    File “yolo_object_detection.py”, line 8, in
    net = cv2.dnn.readNet(“yolov3_training_last(1).weights”, “yolov3_testing.cfg”)
    cv2.error: OpenCV(4.2.0) /io/opencv/modules/dnn/src/darknet/darknet_importer.cpp:214: error: (-212:Parsing error) Failed to parse NetParameter file: yolov3_training_last(1).weights in function ‘readNetFromDarknet’

  13. It worked great when labels were marked in the labelimg software, but now I have a new data set that I want to label automatically but the values I get in the txt file are not the same. I understand the first no. is the class no. but what is the meaning of the other numbers?

  14. Hello, Sergio, great article, it worked great. I have one question. The size of yolov3_training_last.weights file is about 235 Mb, is it ok? Do I need to use a GPU to use the detection on webcam o only with CPU is enought?
    About the precision, i executed the training for 3.30 hours, but I observe that the precision Image detection accuracy is not as accurate. Is it normal? Thanks for all your help and work.

    1. Hi Sergio,
      The size of yolov3_training_last.weights will be always the same, no matter what you’re training YOLO for, what changes is the values of the file. So Yes, the size of the file is fine.

      If you use CPU you will get around 2 FPS, while with GPU you will get 20 or more FPS, it depends on the GPU that you have.

      It’s normale that it’s not accurate after only 3.30 hours. I suggest you to wait till the end of the training (in this case 12 hours) because it’s the maximum allowed by google colab.

  15. i couldn’t run code in google collab im getting an error “Could not load the JavaScript files needed to display output.
    This is probably because your Google Account login access has expired or because third-party cookies are not allowed by your browser.

    Please reload this page.” i got this error for first line of code itself..pls help

  16. Great tutorial Sergio, I was wondering how to show the confidence score along with the class label while displaying the test results. Like right now we are only displaying the label name “Koala” along with the bounding box. How do I say the text like “Koala, 0.96” or something like that. Please help, it’s important.

  17. Hi, I did all the step you mention, and it all worked well, but I can’t save the annotation in LabelImg, its just not working for me. I’m using Windows 10.

  18. Hi Sergio,
    Saving weights to /mydrive/yolov3/yolov3_training_last.weights
    Couldn’t open file: /mydrive/yolov3/yolov3_training_last.weights
    I am getting this error again and again.
    what to do now.

  19. Hi Sergio,
    I am getting this error while training, please help me
    608 x 608
    Create 6 permanent cpu-threads
    Can’t open label file. (This can be normal only if you use MSCOCO): data/obj/ppt2 (38).txt
    Can’t open label file. (This can be normal only if you use MSCOCO): data/obj/ppt2 (76).txt
    Can’t open label file. (This can be normal only if you use MSCOCO): data/obj/ppt2 (83).txt
    Can’t open label file. (This can be normal only if you use MSCOCO): data/obj/ppt2 (81).txt

    Thank you

  20. Hi Sergio,
    Thanks for the tutorial. It’s great!
    however i need some clarification.. while i’m training my model using my own dataset i’m getting Can’t open label file. (This can be normal only if you use MSCOCO): . i have done every step you mention. please help me to correct that.

    1. Hi Athira,
      this is most likely due to missing labels. So it could be either when lableing the images on labelImg, you used the pascalVOC format instead of YOLO, or the labels might be in the wrong directory.
      So make sure you carefully follow the first steps of the tutorial.

  21. For everybody that ask to Sergio for help to code a multiclass example, GET THE COURSE! This is a such a good tutorial and he is a good explainer too that it is pretty easy to make the changes needed but, even if you could make those changes, you should support the educator. Good luck to everybody, Sergio, keep up the good work.

  22. Can I use “yolov3_training_1000.weights” changing the name to “yolov3.weights”?
    Because when I run:
    $ python3 convert.py model_data/yolov3.cfg model_data/yolov3.weights model_data/yolo.h5

    an error occurred:
    File “convert.py”, line 143, in _main
    buffer=weights_file.read(weights_size * 9999999))
    TypeError: buffer is too small for requested array

    I think this error is probably caused by a mismatch between “.cfg” file and “.weights” file.

  23. Wait, correct me if I’m wrong, but are you using the same dataset of images for both training and testing? Because I don’t see you splitting them into the training set and testing set anywhere in your video. Thanks!

  24. To those who encountered issue, take note on these two steps:
    1. When compressing the image and txt files, do not create a new folder then zipped! ; Select all files and zip.
    2. In line 25 in the colab; change the default image file type in the script.

  25. Hi Sergio!
    Thanks for the great and easy tutorial! 🙂
    However when trying to run the last python file I’m getting this error:
    cv2.error: C:\ci\opencv_1512688052760\work\modules\dnn\src\darknet\darknet_io.cpp:503: error: (-212) Unknown layer type: shortcut in function cv::dnn::darknet::ReadDarknetFromCfgFile
    I tried searching for any help in google and I couldn’t find any. Could you please help me with this?
    I changed cv2.dnn.readNet(weights, cfg) to cv2.dnn.readNetFromDarknet(cfg, weights) as I was getting this error: AttributeError: module ‘cv2.dnn’ has no attribute ‘readNet’.
    Thank you!!

  26. Hello Sergio!
    At first thank you for that great post.
    I have a problem downloading the notebook “Train_YoloV3.ipynb”. First i see the download link, but after subscribing the newsletter as required, it dissapears after I confirm my email.
    Could you please help me with that issue?
    Kind regards

  27. This is an amazing tutorial!
    When I run the code I get no output at all. I don’t get an error or anything.
    No window or anything.

    can you also help define what all of line 14 should be?
    I have changes the location of where the pictures are (I am on a linux system), but the last part of line 14 is confusing to me. What is that part of line supposed to be?
    images_path = glob.glob(r”D:\Pysource\Youtube205) Train Yolo google cloud\dataset\*.jpg”)

  28. Congratulations, your course is fantastic. I need to do for multiple classes, and I know if I pay your course I will have access. But I’m Braziliam, Real (Braziliam money) is worthless. Don’t get me wrong, but how much just for the multiple classes code? Is it possible? Thanks.

Join the discussion