This repository implements the paper's Target Domain Feature Generation (TDFG) active domain adaptation framework, its TopNHC data-selection strategy, three comparison strategies, and the DSN and PixelDA baselines, on the six digit-domain pairs MNIST / MNIST-M / SVHN / SYNTH.
Paper: https://doi.org/10.1080/08839514.2024.2349410
TDFG is a two-stage human-in-one-loop framework for digit-recognition domain adaptation:
-
Stage 1 — active generation DA. A VGG-11 source classifier predicts the target pool; the TopNHC method selects the N highest-confidence samples; a human ("oracle") corrects only the mislabeled ones. A group of 10 per-class CycleGANs (the image generator) learns source→target style and produces a large pool of labeled fake-target data, which — together with the corrected samples — trains the target classifier (initialized from the source classifier).
-
Stage 2 — iterative co-training. The target classifier now labels the target pool autonomously (no human). Each round pseudo-labels an incremental batch via TopNHC, retrains the image generator, regenerates fake target, and retrains the target classifier. This feedback loop drives the accuracy gains reported in the paper.
flowchart LR
S[Source classifier ĈS] -->|predict XT| TOP[TopNHC select]
TOP -->|oracle correct| X0[X0_Ttrue]
S --> X0
X0 --> IG[Image generator 10×CycleGAN]
S --> IG
IG -->|generate| XF[X0_Tfake]
XF --> TC[Target classifier Ĉ0_T]
X0 --> TC
TC -->|auto-label + TopNHC| IG
IG -->|regenerate| TC
TC --> OUT[Final ĈJ_T]
| Path | Contents |
|---|---|
src/hiol/data/ |
Domain dataset wrappers (MNIST/MNIST-M/SVHN/SYNTH), MNIST-M and SYNTH generators, prepare entrypoint |
src/hiol/models/ |
VGG-11 classifier, CycleGAN (generator/discriminator/losses), per-class image generator |
src/hiol/selection.py |
Four selection strategies: RS, LC, EN, TopNHC |
src/hiol/baselines/ |
DSN (Bousmalis 2016) and PixelDA (Bousmalis 2017) baselines |
src/hiol/framework.py |
Two-stage TDFG co-training loop (Algorithm 1) |
src/hiol/train.py |
Unified CLI entrypoint |
tests/test_hiol.py |
Unit tests (selection logic, model shapes, gradients) |
pip install poetry
poetry install
# or, with plain pip and a src layout:
pip install torch torchvision numpy pillow scipy
pip install -e .Requires Python ≥ 3.9. GPU recommended (CUDA-capable torch). CPU works for testing but training the CycleGAN image generator is slow on CPU.
MNIST and SVHN download automatically via torchvision. MNIST-M and SYNTH are generated (self-contained, no extra downloads):
python -m hiol.data.prepare # generate MNIST-M + SYNTH caches
python -m hiol.data.prepare --only mm # only MNIST-MThis writes data/generated/{mnist_m,synth}_{train,test}.pt.
Note on MNIST-M / SYNTH: the original benchmarks blend digits over proprietary background sets (BSDS500 for MNIST-M). To keep this reproduction dependency-free, the generators use procedurally-textured random-color backgrounds while preserving the defining domain-shift properties (colored, textured-background digits for MNIST-M; multi-font rendered digits for SYNTH). Training dynamics and the relative ordering of methods match the paper; absolute numbers may differ slightly from the original datasets.
Training is YAML-config driven: configs/default.yaml holds the paper's defaults, a per-experiment config overrides them, and any CLI flag overrides the config.
# Recommended: run from a config file
python -m hiol.train --config configs/m2sv.yaml --device cuda
# TDFG on SYNTH -> MNIST-M
python -m hiol.train --method tdfg --source sy --target mm --device cuda
# DSN / PixelDA baselines (reuse the same config, switch method)
python -m hiol.train --config configs/m2sv.yaml --method dsn
python -m hiol.train --config configs/m2sv.yaml --method pixelda
# Results auto-save to results/<method>_<src>2<tgt>_<strategy>_seed<N>.json
# or specify an explicit path:
python -m hiol.train --config configs/m2sv.yaml --out results/m2sv.jsonDomain codes: m=MNIST, mm=MNIST-M, sv=SVHN, sy=SYNTH. The six domain pairs of Table 3: m→sv, m→sy, mm→sv, sv→m, sv→mm, sy→mm.
for strat in RS LC EN TopNHC; do
python -m hiol.train --method tdfg --source m --target sy \
--strategy $strat --device cuda
done
# results auto-save per strategy under results/TDFG records both num_label (human corrections needed in stage 1 — Table 1) and acc_autolabel (autonomous labeling accuracy in stage 2 — Table 2).
PYTHONPATH=src python -m pytest tests/ -qVerify the entire pipeline runs end-to-end without a GPU (tiny config, random data — accuracy will be near chance):
python -m hiol.train --method tdfg --source m --target sy \
--device cpu --cls-epochs 1 --gen-epochs 1 \
--n-init 200 --n-query 100 --n-iterations 1If you use this code, please cite the original paper:
@article{Xiu2024HIOL,
title={A Human-In-One-Loop Active Domain Adaptation Framework for Digit Recognition},
author={Xiu, Hao and Li, Guanchen and He, Jie and Zhang, Xiaotong and Qi, Yue},
journal={Applied Artificial Intelligence},
volume={38},
number={1},
pages={e2349410},
year={2024},
doi={10.1080/08839514.2024.2349410}
}The DSN and PixelDA baselines cite respectively:
- Bousmalis et al., Domain Separation Networks, NeurIPS 2016.
- Bousmalis et al., Unsupervised Pixel-level Domain Adaptation with Generative Adversarial Networks, CVPR 2017.
MIT.