SuObjectDetection is an object detection project for learning and experimentation. It is designed for teaching and research validation:
- The data pipeline uses almost no data augmentation — images are resized to a uniform size by simple
reshape(stretching) only. Accuracy and robustness are therefore limited, and the project is not suitable for production use. - However, the project is simple and small in code size (the entire model core is only about one hundred lines), making it easy to read line by line and ideal for beginners who want to understand the full pipeline of object detection.
- The project includes deliberate modifications to the loss computation — in particular a negative-IoU scheme that addresses the vanishing-gradient problem of standard IoU loss when the predicted box and the target box do not intersect (see below) — which offers some reference value for scientific research.
Place the dataset under data/:
data/
├── images/ # image files (jpg), any number
│ ├── 000001.jpg
│ ├── 000002.jpg
│ └── ...
└── labels/ # label files (txt), any number
├── 000001.txt
├── 000002.txt
└── ...
Files in images/ and labels/ must match one-to-one by filename (ignoring the extension) (e.g. 000001.jpg ↔ 000001.txt).
Each line of a label file describes one object, with fields separated by spaces:
<class_id> <x> <y> <h> <w>
class_idis the class index;x, y, h, ware percentages (normalized to 0~1) computed against the image size: the center coordinates and the height/width of the bounding box.
The model output is a feature map of shape (B, 5 + num_classes, H', W'). Starting from channel 0, the channels are:
| Channel | Meaning |
|---|---|
| 0 | Exist: whether an object exists in this grid cell |
| 1 | X: center x of the predicted box |
| 2 | Y: center y of the predicted box |
| 3 | H: box height |
| 4 | W: box width |
| 5 ~ 5+N-1 | probabilities of the N classes |
Coordinate conventions:
x, y, h, ware all values in 0~1;x, yare relative coordinates within the responsible grid cell, not percentages over the whole image;h, ware ratios relative to the whole image.
The total loss consists of three terms:
- Existence loss: cross-entropy loss on the
Existchannel, computed over all grid cells. - Class loss: cross-entropy loss on the class-probability channels, with class balancing applied to mitigate the imbalance of per-class object counts.
- Box IoU loss (
ciou_loss): see below.
Note: the class loss and the IoU loss are computed only in grid cells that contain an object; all other cells are masked out and contribute nothing to these two terms.
Standard IoU loss suffers from a well-known issue: when the predicted box and the target box do not intersect at all, IoU is constantly 0, the gradient vanishes, and the loss can no longer guide the box toward the target.
This project modifies the loss accordingly: besides the normal intersection-over-union iou, when the two boxes do not overlap, a negative IoU iou_neg is computed from the "gap rectangle" between them, which makes the loss grow rapidly and restores useful gradients:
loss_iou = -2 * (iou + iou_neg) / (Box1 + Box2)
- Left: when the boxes intersect,
iouis the intersection area divided by the union area, andiou_neg = 0; - Right: when they do not intersect, the intersection is empty and the gap rectangle between the boxes contributes
-iou_neg(a negative term), which significantly increases the overall loss.
This loss is named ciou_loss; its value is the (negative-direction) IoU: the better the overlap, the smaller the loss; the more the boxes miss each other, the faster the loss grows.
The model is named VRes (Virtual ResNet), a lightweight convolutional network for object detection with a small parameter count. Core code: model.py.
The network is built from a Head, down_sample cascaded parallel-downsampling stages, an End head and output activations, reusing the following basic modules:
| Module | Composition | Purpose |
|---|---|---|
| CBR | Conv2d(3×3) + BatchNorm + LeakyReLU | basic convolution unit |
| DownSample | Conv2d(3×3, stride 2) + BatchNorm + LeakyReLU | learnable downsampling |
| Attention | Q/K/V linear projections + Softmax spatial self-attention (with residual) | global spatial dependency, used only in the last two stages |
| PR | DownSample / MaxPool / AvgPool in parallel → concat → CBR | Parallel Reduction hybrid downsampling that preserves multi-scale information |
Forward pass:
- Head:
Conv2d(3×3) + BN + LeakyReLU, lifting the 3-channel input tomid_scalechannels; - Cascaded downsampling stages (
down_samplein total): each stage runs a residual branch (several CBRs, Attention inserted in deeper levels, followed by DownSample) in parallel with a PR branch; outputs are concatenated along the channel dimension, and the channel count grows by a factor of 1.5 per stage; - End: two
Conv2d(3×3)layers (with BN + LeakyReLU in between) map the features to5 + num_classeschannels; - Output activations: the first 5 channels (Exist/X/Y/H/W) go through Sigmoid to 0~1, and the class channels go through Softmax to produce a probability distribution.
- ✅ Suitable for: learning the fundamentals of object detection, reading a compact implementation, reproducing or improving loss designs for research exploration;
- ❌ Not suitable for: production deployment (no data augmentation, no NMS tuning, no multi-scale training or other engineering measures).



