Overview

An end-to-end deep-learning pipeline for drone- and camera-based target identification. The system unifies heterogeneous public image datasets, trains a multi-output CNN that predicts both a fine-grained object class and a coarse valid/invalid label, and embeds the trained classifier behind a YOLO segmentation front-end for real-time video.

The work emphasizes practical concerns: dataset unification, label consistency, and computational efficiency, so the classifier can be dropped into a streaming application running on drone footage or fixed surveillance cameras.

Pipeline

Three modular stages, each independently upgradable.

Dataset

Source datasets use inconsistent directory layouts, label columns, and category names. The builder normalizes all of this into one corpus suitable for stratified training.

Each fine label (e.g. person_pedestrian, civilian_vehicle, tank_av) is mapped onto one of three coarse buckets. Labels are derived per source via folder names, CSV columns, or filename regex, then aliased onto a canonical taxonomy. The 70 / 15 / 15 train/val/test split is stratified on both fine and coarse labels, with class-balanced sampling and per-label caps to prevent background and other dominant categories from swamping training. Quality checks verify on-disk presence, skip corrupted files, and ensure every split contains a minimum number of valid examples. Hash-based de-duplication catches the same image appearing across multiple sources.

Model architecture

A compact multi-output ConvNet shared between two classification heads.

The backbone is a stack of Conv → BatchNorm → ReLU → MaxPool blocks with growing channel depth (32 → 64 → 128) and shrinking spatial resolution. Global average pooling collapses the final feature map into a fixed-length vector that feeds both heads:

Both heads are optimized jointly with categorical cross-entropy and configurable per-head weights. Dropout and L2 weight regularization mitigate overfitting; Adam / AdamW with a plateau-triggered LR schedule, and optional mixed-precision training, round out the optimizer setup.

Training

Implemented in TensorFlow with tf.data pipelines built directly from metadata.csv. Each row loads its image via out_relpath, decodes to RGB, resizes to a fixed input resolution, and normalizes pixel values. Augmentations (horizontal flip, mild rotation, brightness/contrast jitter) are applied conservatively so small targets and label semantics survive.

Sample weights down-weight over-represented classes (notably invalid_background) and up-weight under-represented valid categories. An optional flag controls whether invalid examples contribute to the fine-head loss: when disabled, invalids train only the coarse head, freeing the fine head to focus on examples with meaningful fine labels. Two recipes were used: end-to-end joint training from scratch, and a two-stage warm-up where the coarse head trains alone before the fine head joins.

Training and validation loss/accuracy curves for the multi-output drone CNN across 50 epochs at 128×128 input resolution.
Training and validation curves at 128×128 input resolution. Loss and accuracy converge cleanly with no major overfitting, with the LR scheduler kicking in on plateau.

Results

Held-out test set: 27,362 samples across 11 fine classes. Naïve single-class baselines reach 23.5% (fine) and 34.5% (coarse), so both heads must learn real structure to be useful.

Fine confusion matrix

Test set confusion matrix for the 11-class fine head. Strong diagonal dominance: most off-diagonal mass clusters on visually similar pairs (soldier / civilian, random_animal / bird, rock_debris / invalid_background).

Fine-head confusion matrix across 11 classes: civilian_vehicle, tank_av, aerial_landscape, cloud_blanksky, tree_shrub, flying_target, bird, random_animal, civilian, soldier, rock_debris.
Held-out test set, 27,362 samples. Diagonal dominance confirms the 87.1% headline accuracy; the brightest off-diagonals match the qualitative error patterns documented in the writeup.

Per-class precision

The fine head is strongest on visually distinct categories (vehicles, landscape) and weakest where classes share appearance (soldier / civilian, random animal / bird, rock debris / background).

Fine head: test precision per class
Class Precision
civilian_vehicle 0.9538
tank_av 0.9426
aerial_landscape 0.9306
cloud_blanksky 0.9174
tree_shrub 0.8885
flying_target 0.8629
bird 0.8123
random_animal 0.8027
civilian 0.7882
soldier 0.7730
rock_debris 0.7547
Coarse head: test precision per class
Class Precision
invalid_nontarget 0.9277
valid 0.9165
invalid_background 0.8941

Error analysis

Confusion matrices and qualitative review highlight three recurring failure modes.

Input resolution trade-off

Bumping inputs from 64×64 to 128×128 significantly improved both fine and coarse accuracy; 256×256 added very little. For offline classification, 128×128 is the sweet spot. For the live video pipeline, lower-resolution crops actually helped: they kept the YOLO + CNN loop closer to real time and improved detection of small, distant targets thanks to the larger effective receptive field.

Real-time utilization

The deployment program runs against video files (with webcam and live drone feed as future targets). YOLO produces per-frame instance masks; each mask is cropped from the source frame, resized to the CNN's input size, and normalized identically to training. Only the coarse head is consulted in the live overlay: the operational question is "valid target?", and the three-way decision is fast and easy to render:

Optional frame skipping keeps throughput up. Decoupling detection from classification means a newer YOLO model can drop in without touching the CNN, and adding new fine classes only requires retraining the classifier.

Live overlay demo: YOLO segmentation drives per-frame crops; the coarse head colors each detection valid (green) or invalid_nontarget (red), and ignores invalid_background. Lower-resolution CNN input crops (32×32 in this run) keep the loop close to real time without sacrificing detection of small distant targets. Prefer the longer demo? Download the extended cut (≈7 MB).

Limitations & future work