This is a second-year DSBA coursework at HSE University, completed under the guidance of the HSE Robotics Lab. It studies synthetic-to-real domain adaptation in image classification - how models trained on source data perform on real target images-using the VisDA-2017 benchmark and modern adaptation methods. The repository provides a modular training framework to compare adaptation setups in one pipeline, with shared utilities and method-specific scripts. Full methods, analysis, and results are in the report at tex/coursework.pdf, while the trained weights are available on the Yandex disk.
The core problem is domain shift: models often perform well on clean training data but degrade significantly when evaluated on real-world data with different statistics, texture patterns, and visual conditions.
This project addresses that challenge by:
- training image classification models on source-domain data
- evaluating them on real target-domain data
- comparing different adaptation strategies
- measuring the effectiveness of feature alignment and adversarial learning
- providing a reproducible experimental pipeline
The final experiments show that domain adaptation can substantially reduce the performance gap between synthetic and real data, with the best configuration achieving strong target-domain accuracy.
The repository is structured as a framework rather than a single monolithic script.
The main idea is simple:
train.pyis the execution entry pointmethods/contains experiment-specific training scriptsutils/contains reusable code used by experiments
Individual experiments are implemented as focused training scripts, while shared functionality such as dataset loading, transforms, losses, training loops, and metrics live in the utility layer.
In practice, each method follows the same contract:
- create or load the model
- prepare the dataset and transforms
- run the common training pipeline
- log metrics and save checkpoints
The utils package contains the general-purpose components of the framework. It is responsible for the common machine learning infrastructure:
- dataset loading and preprocessing
- transformations and augmentations
- loss functions and adaptation objectives
- metrics and evaluation
- training and validation loops
- model creation and initialization
- checkpointing and experiment tracking
- utility logic for adversarial or alignment-based training
This layer is shared across experiments and is intentionally kept independent from the specific method logic.
The methods package contains the actual experiment definitions.
The method scripts are designed to be plug-in components that use the shared training infrastructure instead of re-implementing it.
from methods import TrainArgs, register
from utils.dataset import build_data_loaders
from utils.models import build_model
from utils.trainer import train
@register("example_method")
def example_method(args: TrainArgs):
train_loader, val_loader = build_data_loaders(
data_dir=args["data"],
batch_size=args["batch_size"],
workers=args["workers"],
)
model = build_model("resnet50", pretrained=True, num_classes=12)
optimizer = ...
criterion = ...
train(
model=model,
train_loader=train_loader,
val_loader=val_loader,
optimizer=optimizer,
criterion=criterion,
args=args,
)Copy the example environment file:
cp .env.example .envThen update the variables in .env:
METHOD=vitb16_dann
RUN_NAME=vitb16_dann
EPOCHS=20
START_EPOCH=0
BATCH_SIZE=128
LEARNING_RATE=1e-4
WORKERS=4
SEED=42
CHECKPOINT_INTERVAL=5
DEVICE=cuda:0
IMAGENET_WEIGHTS=true
DANN_LAMBDA=1.0
MMD_LAMBDA=1.0
CORAL_LAMBDA=1.0Create the required folders if needed:
mkdir -p data checkpoints logspython train.py \
--trainer "$METHOD" \
--name "$RUN_NAME" \
--data ./data \
--env .env \
--logs ./logs \
--epochs "$EPOCHS" \
--start_epoch "$START_EPOCH" \
--batch_size "$BATCH_SIZE" \
--learning_rate "$LEARNING_RATE" \
--workers "$WORKERS" \
--seed "$SEED" \
--checkpoint_path ./checkpoints \
--checkpoint_interval "$CHECKPOINT_INTERVAL" \
--device "$DEVICE" \
--verboseNOTE: Arguments passed to the script overwrite environment variables passed by the file!
The project also includes Docker support for running experiments in a consistent environment and for exposing TensorBoard logs.
The key experimental findings are summarized below:
| Method | ResNet-50 | ViT-B/16 |
|---|---|---|
| Source-only baseline | 43.5% | 58.5% |
| MMD alignment | 58.3% | 70.8% |
| CORAL alignment | 44.4% | 64.4% |
| DANN adversarial training | 62.7% | 74.8% |
These results show that the synthetic-to-real domain gap is significant for both architectures, but it is substantially reduced with domain adaptation. The best result is achieved with ViT-B/16 combined with adversarial training, reaching approximately 74.8% validation Top-1 accuracy on the target domain.
The report also highlights that:
- ViT-B/16 consistently outperforms ResNet-50 under the same task conditions.
- Adversarial alignment provides the strongest improvement among the tested methods.
- MMD is also effective, while CORAL yields a smaller gain.
- All models still show some overfitting, indicating that further regularization and tuning are possible.
This project is licensed under the MIT License. See the LICENSE file for details.