Back to all projects

Nordic AI Cup 2026

Four days, three AI challenges and one graded attempt at each. I led our SDU team on the real-time drone detection challenge.

Role
Team Elysa's Secret · lead on Drone Flyby
Year
2026
Stack
Python, YOLO11, PyTorch, FastAPI, Docker, Kaggle, Cloudflare Tunnel
Status
Shipped

Problem

The Nordic AI Cup gives each team four days and three unrelated problems: answering questions about a recorded medical consultation, keeping a simulated colony alive, and spotting objects from a drone. Nothing is submitted as a file. Each solution is a web service the team hosts itself, the grader calls it live, and every challenge has exactly one graded attempt. This edition drew over 430 participants: 112 teams submitted and 82 reached the final evaluation.

My part was Drone Flyby. A drone films a synthetic landscape in 4K, and the service has to find sixteen kinds of object in each frame (tanks, hangars, launchers, planes…) while choosing where to point a 960×540 camera, with a third of a second per frame. The organisers gave us 25 labelled frames, one example of each class.

Solution

  • Training data from almost nothing. I cut the 25 labelled objects out of their frames and pasted them onto real aerial photos to build a training set, then trained YOLO11 detectors on Kaggle and rented GPUs. The first model scored 0.79 locally and 0.01 on validation: it had memorised the one city it was trained on.
  • Better detectors stopped paying. Four attempts at a stronger single model all failed. What worked was serving several models that fail on different classes, each at its own resolution, and matching the grader’s box convention, which alone was worth +0.157. Adding a model never lost; replacing one never won.
  • Distrusting my own numbers. A container that looked healthy was serving stale code, one rented host cut the score to 0.19 through a congested network, and single runs varied by ±0.005 at best. From then on every setting ran about three times, and I checked what was actually loaded and how many frames were answered.
  • A service built for the deadline. FastAPI in Docker, five detector passes per frame, a tracker that refits the ground motion during the flight, and a camera that alternates quadrant views with whole-frame views, all inside a third of a second.
  • Only settings that should generalise. Per-class box sizes, thresholds and extra passes looked good offline but lost on the real grader, so they were dropped.

Result

The team’s graded score in each of the three challenges:

ChallengeGraded score
Medical Appointment0.822
Survival Simulator1405.3
Drone Flyby0.263

How the Drone Flyby validation score moved (COCO mAP@0.5, macro over 16 classes):

DayChangeValidation
17 SepObjects pasted onto 25 frames of one city0.011–0.035
17 SepReal aerial backgrounds, real cut-outs, blended pasting0.1445
18 SepTwo models that fail on different classes0.2365
18 SepEach model at its own resolution0.3048
19 SepThe grader’s box convention0.4618
19 SepThree models, box growth, a 4th pass at 2560 px0.5270 (mean of 4)
20 SepWhole-frame views in the camera sweep, 5 passes0.5841 (mean of 7)
20 SepGraded evaluation, unseen flight0.2630

All 249 evaluation frames were answered without errors, yet less than half of the validation score carried over. The likely cause is visible in the repository: about 60% of the training backgrounds were cut from the validation flight itself, so the detectors had learned its terrain. That is the lesson I take from it: a validation score you tune against is not a score you have earned. The repository documents exactly what was graded for each challenge, including what we tried and rejected.