File size: 10,377 Bytes
d2c33e3 7d74eea d2c33e3 1822d71 d2c33e3 1822d71 d2c33e3 f87581f d2c33e3 f87581f d2c33e3 1822d71 d2c33e3 1822d71 d2c33e3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | ---
license: apache-2.0
library_name: pytorch
pipeline_tag: image-segmentation
tags:
- affordance-segmentation
- instance-segmentation
- object-detection
- robotics
- manipulation
- rt-detr
- real-time
metrics:
- name: Weighted F-measure (beta^2=1)
type: f-measure
value: 0.8685
---
# AffKernel: IIT-AFF affordance segmentation (R50vd, stride-2 + deep supervision)
Single-pass, NMS-free affordance segmentation. AffKernel couples RT-DETR object
queries with a CondInst-style per-query dynamic-convolution kernel that decodes
per-object affordance masks from one shared high-resolution affordance map. A
detector tells a robot *what* an object is; AffKernel also tells it *where* to
act on it, at a latency a control loop can afford.
- **Code:** https://github.com/anh0001/affkernel
- **Reproduction guide:** https://github.com/anh0001/affkernel/blob/main/docs/reproduction.md
- **Architecture:** RT-DETR-R50vd + affordance branch with stride-2 readout and deep supervision
- **Training data:** IIT-AFF (Nguyen et al., IROS 2017), 6,184 train images
- **Weights:** last-epoch (epoch 72) EMA parameters, fp32, 174 MB
## Results
Evaluated on the IIT-AFF test split (2,651 images) with the Margolin weighted
F-measure.
| Metric | Value |
|---|---:|
| `F_beta^w` (beta^2 = 1), this checkpoint | **0.8685** |
| `F_beta^w` (beta^2 = 0.3), this checkpoint | 0.8582 |
| `F_beta^w` (beta^2 = 1), mean of 3 seeds | 0.8675 Β± 0.0009 |
| Mask quality on detected instances | 0.8933 |
| Latency, 640x640, fp32, RTX 6000 Ada | 16.3 ms median |
| Throughput | 61.5 img/s |
Against published baselines on the same benchmark: Mask R-CNN 0.844 at 45 ms,
deterministic Swin-T 0.883 at 42 ms, Bayesian Swin-T deep ensemble 0.906 at
roughly 1015 ms. AffKernel beats the Mask R-CNN baseline at about a third of its
latency and trails the deterministic Swin-T by 1.55 points at 39% of its
latency, with fully deterministic single-pass inference.
**On seed selection.** This is seed 42, which is both the primary anchor seed
used throughout the paper and the highest scoring of the three seeds trained
(seed 7: 0.8668, seed 123: 0.8673). IIT-AFF provides no validation split, so
the epoch was fixed a priori (last epoch, EMA weights) rather than selected on
the test set.
**On the beta convention.** Two conventions circulate in this literature. The
AffordanceNet lineage reports `beta^2 = 0.3`; recent transformer baselines
report `beta^2 = 1`. Both are given above so that comparisons can be made at a
matched convention. Do not compare a `beta^2 = 1` number against a
`beta^2 = 0.3` number.
## Usage
```bash
git clone https://github.com/anh0001/affkernel.git
cd affkernel
pip install -r requirements.txt
pip install huggingface_hub
hf download anhrisn/affkernel-iit-aff \
affkernel_iit_r50vd_stride2_deepsup_seed42.pth --local-dir weights/
python tools/infer.py \
-c configs/rtdetr/rtdetr_r50vd_6x_iit_v3_stride2_deepsup.yml \
-r weights/affkernel_iit_r50vd_stride2_deepsup_seed42.pth \
--input path/to/image.jpg \
--output outputs/
```
`--input` takes a single image or a directory. `--output` is a **directory**;
results are written as `<stem>_aff.png`. Add `--device cpu` to run without a
GPU. Verified working on GPU and CPU, for both single-image and folder input.
Reproduce the reported metric (requires the IIT-AFF dataset; see
[`docs/datasets.md`](https://github.com/anh0001/affkernel/blob/main/docs/datasets.md)):
```bash
python tools/decompose_fbw_gap.py \
-c configs/rtdetr/rtdetr_r50vd_6x_iit_v3_stride2_deepsup.yml \
-r weights/affkernel_iit_r50vd_stride2_deepsup_seed42.pth --beta2 1.0
```
### Checkpoint format
A single file containing the EMA weights only:
```python
{"ema": {"module": <OrderedDict of 760 tensors>, "updates": 111312}}
```
The evaluation path uses the EMA parameters, so the raw (non-EMA) weights and
the optimizer state from training are not included. Do not repack this into a
bare `{"model": ...}` dict: under an EMA-enabled config the solver would then
evaluate a freshly initialised EMA module and score near zero.
The first run downloads ImageNet-pretrained ResNet-50vd backbone weights from
the RT-DETR release artefacts, so it needs network access. For an offline
deployment, set `PResNet.pretrained: False` in the config.
## Deployment
All rows below use **these same weights** β fp16, CUDA graphs, BatchNorm folding
and the TensorRT backbone are runtime configurations, not separate checkpoints.
**RTX 6000 Ada**, 640x640, batch 1, end to end (preprocess, forward, mask decode,
device-to-host copy):
| Inference path | End to end | FPS | Peak GPU | `F_beta^w` (0.3 / 1) |
|---|---:|---:|---:|---:|
| fp32, as released | 35.7 ms | 28.0 | 0.43 GiB | 0.8582 / 0.8685 |
| fp16 + CUDA graph + BN fold | **16.0 ms** | **62.7** | 0.29 GiB | 0.8577 / 0.8680 |
**Jetson AGX Orin** Developer Kit (64 GB), JetPack 6.2, MAXN:
| Inference path | End to end | FPS | Peak GPU | `F_beta^w` (0.3 / 1) |
|---|---:|---:|---:|---:|
| fp32, as released | 199.5 ms | 5.0 | 1.29 GiB | 0.8598 / 0.8680 |
| `--half --cudagraph` | 53.2 ms | 18.8 | 0.21 GiB | 0.8596 / 0.8678 |
| `--trt-backbone` | **43.4 ms** | **23.1** | 0.23 GiB | 0.8591 / 0.8673 |
The fastest path costs **0.0007** `F_beta^w` at beta^2=1 β below the Β±0.0009
seed-to-seed spread of the training run itself. Dropping the input to 512x512 is
*not* worth it by comparison: it costs 0.007, ten times more, to save less time.
### `backbone_fp16.plan` β prebuilt TensorRT engine
This repository also ships an fp16 TensorRT engine for the **backbone only**. The
dynamic-kernel affordance head cannot be exported to ONNX, but the backbone is
plain convolutions, exports cleanly, and is the largest single term of the forward
pass: 17.7 ms β 5.3 ms. The encoder, decoder and affordance head stay in PyTorch,
CUDA-graphed against the engine's output buffers.
| | |
|---|---|
| Built on | Jetson AGX Orin (64 GB), JetPack 6.2 (L4T R36.4.7) |
| TensorRT / CUDA | 10.3.0 / 12.6 |
| Input | `images` β `(1, 3, 640, 640)`, fp16, fixed |
| Outputs | `feat0..feat3` β fp16 |
| Size | 46.4 MiB |
> **Engine files are not portable.** A `.plan` is compiled for one specific GPU,
> TensorRT version and input shape. On any other device, JetPack/TensorRT version
> or input size it will fail to deserialize β or load and behave incorrectly. It
> is published here as a convenience for setups identical to the table above.
> **If yours differs in any respect, build your own** β one command, a few
> minutes. That is the supported path.
```bash
# use the prebuilt engine (identical setups only)
hf download anhrisn/affkernel-iit-aff backbone_fp16.plan --local-dir weights/
# or build your own (recommended)
python tools/build_trt_backbone.py \
-c configs/rtdetr/rtdetr_r50vd_6x_iit_v3_stride2_deepsup.yml \
-r weights/affkernel_iit_r50vd_stride2_deepsup_seed42.pth \
--out weights/backbone_fp16.plan
python tools/infer.py \
-c configs/rtdetr/rtdetr_r50vd_6x_iit_v3_stride2_deepsup.yml \
-r weights/affkernel_iit_r50vd_stride2_deepsup_seed42.pth \
--input path/to/image.jpg --output outputs/ \
--trt-backbone weights/backbone_fp16.plan --gpu-preprocess
```
Keep the checkpoint either way β the engine replaces the backbone at inference
only, and training is unaffected.
## Files
| File | What it is |
|---|---|
| `affkernel_iit_r50vd_stride2_deepsup_seed42.pth` | The model. fp32 EMA weights, 174 MB. |
| `backbone_fp16.plan` | Optional deployment artifact. TensorRT fp16 backbone engine for AGX Orin / JetPack 6.2 / TensorRT 10.3 @ 640x640. Not portable; not usable on its own. |
## Classes
**Objects (10):** bowl, tvm, pan, hammer, knife, cup, drill, racket, spatula, bottle
**Affordances (9):** contain, cut, display, engine, grasp, hit, pound, support, w-grasp
## Intended use and limitations
Intended for research on affordance perception and perception-guided grasping.
- Trained on a closed vocabulary of 10 object and 9 affordance classes; it will
not generalise to unseen categories.
- IIT-AFF is a tabletop dataset. Performance under other viewpoints, lighting
or clutter regimes is untested.
- The residual error is dominated by **missed detections**, not by mask quality.
On instances the detector does fire on, mask quality (0.893) already exceeds
the deterministic Swin-T baseline's overall score.
- The headline latency is fp32 on an RTX 6000 Ada. fp16, CUDA graphs and a
TensorRT backbone are now characterised on both a workstation and a Jetson AGX
Orin β see [Deployment](#deployment) β and cost at most 0.0007 `F_beta^w`.
- Not validated for safety-critical deployment. A predicted grasp region is a
perception cue, not a guarantee of a safe grasp.
## License and attribution
These weights are released under Apache-2.0, matching the licence of the
RT-DETR components and the ImageNet-pretrained backbone they were initialised
from. The AffKernel repository's own source contributions are MIT licensed; see
[`THIRD_PARTY_LICENSES.md`](https://github.com/anh0001/affkernel/blob/main/THIRD_PARTY_LICENSES.md).
The **IIT-AFF dataset is not redistributed** here or in the code repository. It
states no licence; its authors request citation of the original paper. Obtain
it from https://sites.google.com/site/iitaffdataset/.
## Citation
```bibtex
@article{risnumawan2026affkernel,
title = {AffKernel: Single-Pass Affordance Segmentation with Per-Query
Dynamic Convolution for Real-Time Robotic Manipulation},
author = {Risnumawan, Anhar},
journal = {IEEE Access},
year = {2026},
note = {Under review}
}
@inproceedings{nguyen2017object,
title = {Object-Based Affordances Detection with Convolutional Neural
Networks and Dense Conditional Random Fields},
author = {Nguyen, Anh and Kanoulas, Dimitrios and Caldwell, Darwin G. and
Tsagarakis, Nikos G.},
booktitle = {IEEE/RSJ International Conference on Intelligent Robots and
Systems (IROS)},
year = {2017}
}
@inproceedings{lv2024detrs,
title = {DETRs Beat YOLOs on Real-time Object Detection},
author = {Lv, Wenyu and Zhao, Yian and Xu, Shangliang and Wei, Jinman and
Wang, Guanzhong and Cui, Cheng and Du, Yuning and Dang, Qingqing
and Liu, Yi},
booktitle = {CVPR},
year = {2024}
}
```
|