Skip to content

Object detection training

Training an Object Detection Model

When you're ready to train a model, the process generally boils down to three main steps:

  1. Download the data for training, validation, and testing.
  2. Transform that data into the format the model needs.
  3. Initiate the training.

The instructions below show you how to train either RF-DETR(recommended) or the YOLOv26 model.

You will need the mbari-aidata package installed for this.

Tip

Grab your project's YAML file from the project page. If you haven't yet, install the aidata tool - see the installation instructions if you need help.


Setting Up

Download

Download the training data (object detection only). This excludes the held-out test set (testset) and optionally mixes in a percentage of unverified/negative background crops later during transform:

aidata download dataset \
  --config https://docs.mbari.org/internal/ai/projects/config/config_uav.yml \
  --base-path $PWD/TrainNegatives07152026 \
  --voc \
  --labels "Batray","Bird","Boat","Cement_Ship","Egregia","Fish","Jelly","Kayak","Kelp","Mola","Mooring_Buoy","Otter","Person","Pinniped","Secci_Disc","Shark","Surfboard","Velella_velella","Velella_velella_raft","Whale" \
  --verified \
  --token $TATOR_TOKEN \
  --disable-ssl-verify \
  --exclude-versions testset --single-class object

Download the testing data (object detection only), pulling only from the testset version:

aidata download dataset \
  --config https://docs.mbari.org/internal/ai/projects/config/config_uav.yml \
  --base-path $PWD/Test07152026 \
  --voc \
  --labels "Batray","Bird","Boat","Cement_Ship","Egregia","Fish","Jelly","Kayak","Kelp","Mola","Mooring_Buoy","Otter","Person","Pinniped","Secci_Disc","Shark","Surfboard","Velella_velella","Velella_velella_raft","Whale" \
  --verified \
  --token $TATOR_TOKEN \
  --disable-ssl-verify \
  --version testset

For more details, see the aidata download documentation.

Transform (train set)

Transform sizing depends on which model you're targeting:

YOLO models (all sizes) — use 640x640 images:

aidata transform voc --base-path $PWD/TrainNegatives07152026 --resize 640 --crop-size 640 --crop-overlap 0.5 --min-visibility 0.0 --min-dim 20 --negative-percent 0.2

RF-DETR Medium — use 576x576 crops. For other RF-DETR sizes, see the RF-DETR GitHub repo:

aidata transform voc --base-path $PWD/TrainNegatives07152026 --resize 576 --crop-size 576 --crop-overlap 0.5 --min-visibility 0.0 --min-dim 20

You can include background/negative crops with --negative-percent. A lower recommended value for RF-DETR:

aidata transform voc --base-path $PWD/TrainNegatives07152026 --resize 576 --crop-size 576 --crop-overlap 0.5 --min-visibility 0.0 --min-dim 20 --negative-percent 0.05

Convert to YOLO format:

aidata transform voc-to-yolo --base-path $PWD/TrainNegatives07152026/transformed

Split into train/validate/test sets. Since the held-out test set is downloaded separately above, the split here typically skips the test partition (--split 0.9,0.1,0.0):

aidata transform split -i $PWD/TrainNegatives07152026/transformed -o $PWD/TrainNegatives07152026split --split 0.9,0.1,0.0

For more details, see the transform command docs.

Compress the test data

Compress the held-out test set for easy upload into Google Drive (used later in Colab):

tar -czf images.tar.gz -C $PWD/Test07152026/testset images
tar -czf labels.tar.gz -C $PWD/Test07152026/testset labels

Train in AWS SageMaker with deepsea-ai 🚀

Training with deepsea-ai on AWS SageMaker has been moved to its own doc — see Training with deepsea-ai.


Training an RF-DETR Model in Google Colab Environment

Create a data.yaml file:

train: /content/datasets/train/images
val: /content/datasets/valid/images
test: /content/datasets/test/images

nc: 1
names: ['object']

Upload the data.yaml file, and the images.tar.gz/labels.tar.gz files (produced in the Compress the test data step, or from the train split) to Google Drive. Google Drive for Desktop makes this easy.

In a Colab notebook, install RF-DETR and dependencies:

%pip install "rfdetr[train,loggers]==1.7.1" -q
%pip install supervision roboflow -q

Set up HOME:

import os
HOME = os.getcwd()
print(HOME)

Mount Google Drive:

# Allow access to personal google drive and add new folders

# Connect Google Drive
from google.colab import drive
drive.mount("/content/drive", force_remount=True) # This will prompt for authorization.

# This will create the uavs files if they don't exist.
folders = ["uavs/"]
for folder in folders:
    path = "/content/drive/MyDrive/" + folder
    if not os.path.exists(path):  # Create the folder if it does not exist
        os.mkdir(path)

Move in the compressed files and unpack them:

!mkdir {HOME}/datasets
%cd {HOME}/datasets
from google.colab import userdata
uavs_folder = "/content/drive/MyDrive/uavs/"

!mkdir -p /content/datasets/savedir/
!cp -r "/content/drive/MyDrive/uavs/images.tar.gz" "/content/datasets/savedir/"
!cp -r "/content/drive/MyDrive/uavs/labels.tar.gz" "/content/datasets/savedir/"

!tar xf /content/datasets/savedir/images.tar.gz --directory /content/datasets/savedir/
!tar xf /content/datasets/savedir/labels.tar.gz --directory /content/datasets/savedir/

Move the data to the directory structure RF-DETR expects (note: RF-DETR uses valid/, not val/):

## create directories
!mkdir /content/datasets/train/
!mkdir /content/datasets/train/images/
!mkdir /content/datasets/train/labels/
!mkdir /content/datasets/test/
!mkdir /content/datasets/test/images/
!mkdir /content/datasets/test/labels/
!mkdir /content/datasets/valid/
!mkdir /content/datasets/valid/images/
!mkdir /content/datasets/valid/labels/

#get the data.yaml file
!cp "/content/drive/MyDrive/uavs/data.yaml" "/content/datasets/data.yaml"
!ls /content/datasets/

#move the data to the expected directories
!cp -r "/content/datasets/savedir/images/train/." "/content/datasets/train/images/"
!cp -r "/content/datasets/savedir/labels/train/." "/content/datasets/train/labels/"

!cp -r "/content/datasets/savedir/images/test/." "/content/datasets/test/images/"
!cp -r "/content/datasets/savedir/labels/test/." "/content/datasets/test/labels/"

!cp -r "/content/datasets/savedir/images/val/." "/content/datasets/valid/images/"
!cp -r "/content/datasets/savedir/labels/val/." "/content/datasets/valid/labels/"

!ls /content/datasets/

Train a new RF-DETR Nano model:

from rfdetr import RFDETRNano

model = RFDETRNano()

model.train(
    dataset_dir="/content/datasets/",
    epochs=20,
    batch_size=16,
    grad_accum_steps=1,
    output_dir="/content/outputs"
)

Copy outputs to Drive:

!cp -r "/content/outputs" "/content/drive/MyDrive/uavs/"

If Colab restarts, restore from Drive first:

!cp -r /content/drive/MyDrive/uavs/outputs /content/outputs

Resuming training from a checkpoint:

from rfdetr import RFDETRNano

model = RFDETRNano()
model.train(
    dataset_dir="/content/datasets/",
    epochs=50,           # total epochs — not "50 more", but the new total
    batch_size=16,
    grad_accum_steps=1,
    output_dir="/content/outputs",
    resume="/content/outputs/checkpoint_best_total.pth"   # <-- resume here
)

Exporting the model to ONNX format:

model = RFDETRNano(pretrain_weights="/content/outputs/checkpoint_best_total.pth")
model.export(
    format="onnx",
    output_dir="/content/drive/MyDrive/uavs/onnx_export"
)

Training a YOLO26 Model in Google Colab Environment

Create the data.yaml file:

train: /content/datasets/train/images
val: /content/datasets/val/images
test: /content/datasets/test/images

nc: 1
names: ['object']

Upload the data.yaml file, and the image/label tar files to Google Drive. Google Drive for Desktop makes this easy.

Install YOLO26 via Ultralytics:

%pip install ultralytics supervision roboflow -q
import ultralytics
ultralytics.checks()

Set up HOME:

import os
HOME = os.getcwd()
print(HOME)

Mount Google Drive:

# Allow access to personal google drive and add new folders

# Connect Google Drive
from google.colab import drive
drive.mount("/content/drive", force_remount=True) # This will prompt for authorization.

# This will create the uavs files if they don't exist.
folders = ["uavs-yolo26/"]
for folder in folders:
    path = "/content/drive/MyDrive/" + folder
    if not os.path.exists(path):  # Create the folder if it does not exist
        os.mkdir(path)

Move in the compressed files and unpack them:

!mkdir {HOME}/datasets
%cd {HOME}/datasets
from google.colab import userdata
uavs_folder = "/content/drive/MyDrive/uavs-yolo26/"

!mkdir -p /content/datasets/savedir/
!cp -r "/content/drive/MyDrive/uavs-yolo26/images.tar.gz" "/content/datasets/savedir/"
!cp -r "/content/drive/MyDrive/uavs-yolo26/labels.tar.gz" "/content/datasets/savedir/"

!tar xf /content/datasets/savedir/images.tar.gz --directory /content/datasets/savedir/
!tar xf /content/datasets/savedir/labels.tar.gz --directory /content/datasets/savedir/

Move the data to the directory structure YOLO26 expects:

## make the directories that yolo26 expects
!mkdir /content/datasets/train/
!mkdir /content/datasets/train/images/
!mkdir /content/datasets/train/labels/
!mkdir /content/datasets/test/
!mkdir /content/datasets/test/images/
!mkdir /content/datasets/test/labels/
!mkdir /content/datasets/val/
!mkdir /content/datasets/val/images/
!mkdir /content/datasets/val/labels/

#get the data.yaml file
!cp "/content/drive/MyDrive/uavs-yolo26/data.yaml" "/content/datasets/data.yaml"
!ls /content/datasets/

#move the data to the expected directories
!cp -r "/content/datasets/savedir/images/train/" "/content/datasets/train/images/"
!cp -r "/content/datasets/savedir/labels/train/" "/content/datasets/train/labels/"

!cp -r "/content/datasets/savedir/images/test/" "/content/datasets/test/images/"
!cp -r "/content/datasets/savedir/labels/test/" "/content/datasets/test/labels/"

!cp -r "/content/datasets/savedir/images/val/" "/content/datasets/val/images/"
!cp -r "/content/datasets/savedir/labels/val/" "/content/datasets/val/labels/"

!ls /content/datasets/

Train a YOLO26 Medium model for 150 epochs:

!yolo task=detect mode=train model=yolo26m.pt data=/content/datasets/data.yaml \
  batch=128 epochs=150 patience=30 imgsz=640 \
  mixup=0.3 scale=0.9 plots=True

Save outputs to Drive:

!cp "/content/datasets/runs/detect/train/weights/best.pt" "/content/drive/MyDrive/uavs-yolo26/best.pt"
!cp "/content/datasets/runs/detect/train/weights/last.pt" "/content/drive/MyDrive/uavs-yolo26/last.pt"
!cp -r "/content/datasets/runs/detect/train/" "/content/drive/MyDrive/uavs-yolo26/train/"

You can train the model again for more epochs by loading the last checkpoint. Copy the last checkpoint from Drive:

!cp /content/drive/MyDrive/uavs-yolo26/last.pt /content/last.pt

Train for another 150 epochs starting from the last checkpoint:

!yolo task=detect mode=train model=/content/last.pt data=/content/datasets/data.yaml \
  batch=128 epochs=150 patience=30 imgsz=640 \
  mixup=0.3 scale=0.9 plots=True

Export the model to ONNX format:

from ultralytics import YOLO

model = YOLO("/content/drive/MyDrive/uavs-yolo26/best.pt")
model.export(format="onnx")

🗓️ Updated: 2026-08-10