Classification Evaluation

December 22, 2025 · View on GitHub

We evaluate the pre-trained backbones on a binary classification task using a two-layer linear classifier, providing a simple yet effective benchmark for assessing the feature quality of the pre-trained backbone.

Content Summary

  • How the classification dataset is structured and formatted
  • How to launch the training, enable experiment tracking
  • SSL Baseline Models Comparison: DeepAndes, MAE, MoCo-v2, SATMAE, and Scratch

This linear probe evaluation can be modified very flexibly. The key is to load the pre-trained backbone and append a classifier. An example script is provided linear_prob_simple_args.py

Installation (Conda)

Linear classification can use the same conda environment as pre-training; refer to the dinov2_8bands installation. When using the linear_prob_simple_args.py module, install the required libraries:

conda activate dinov2_env

pip install matplotlib pandas timm

These libraries are needed for data analysis and for easier loading of other baseline backbones.

Dataset Format

Each image is saved as a .npy file with 8 spectral bands/channels, having a shape of (256, 256, 8) and a data type of np.uint8. The structure follows the standard used by torchvision:

/path/to/train_dataset_dir/
    ├── 0/  # Negative samples
    │   └── *.npy
    └── 1/  # Positive samples
        └── *.npy

/path/to/val_dataset_dir/
    ├── 0/  # Negative samples
    │   └── *.npy
    └── 1/  # Positive samples
        └── *.npy

Training CLI

After pre-training (see SSL README), checkpoints are saved at: /path/to/output_dir/eval/. We provided our pre-trained ViT-L/14 backbone on Google Drive.

Adjust Path and Key

import sys

# Replace '/path/to/dinov2_ssl_8bands' with your actual path
sys.path.append('/path/to/dinov2_ssl_8bands')

if use_wandb:
    wandb.login(key="api_key_here") # Replace with your wandb api_key

To fine-tune a model (e.g., deepandes) using binary classification dataset, run:

python ./classification_eval/linear_prob_simple_args.py \
    --use_wandb \
    --wandb_project <wandb_project_name> \
    --wandb_trial <wandb_run_name> \
    --train_dataset_str /path/to/train_dataset_dir \
    --val_dataset_str /path/to/val_dataset_dir \
    --output_dir /path/to/output_dir \
    --epochs 10 \
    --cuda 0 \
    --model_name deepandes \
    --pretrained_weights /path/to/teacher_checkpoint.pth

Replace each placeholder (like <wandb_project_name>) as appropriate.

Torch hub Error (dinotxt)

If the error ModuleNotFoundError: No module named 'dinov2.hub.dinotxt' occurs while loading module, simply comment out the following line in the hubconf.py file:

# from dinov2.hub.dinotxt import dinov2_vitl14_reg4_dinotxt_tet1280d20h24l

An example hubconf.py is provided. This is the config mis-match since we used the simple torch hub loading and adjust the pre-trained wieght.

Other Baseline Models Comparison

The --model_name flag supports the following backbone options:

  • deepandes — our ViT-L model from DINOv2
  • mae — Masked Autoencoder
  • mocov2 — Momentum Contrast v2
  • satmae — A Satellite MAE baseline
  • scratch — randomly initialized ViT-L (no pre-training)

To fine-tune MAE backbone:
python ./classification_eval/linear_prob_simple_args.py \
    --use_wandb \
    --wandb_project <wandb_project_name> \
    --wandb_trial <wandb_run_name> \
    --train_dataset_str /path/to/train_dataset_dir \
    --val_dataset_str /path/to/val_dataset_dir \
    --output_dir /path/to/output_dir \
    --epochs 10 \
    --cuda 0 \
    --model_name mae

To fine-tune MoCo-V2 backbone:
python ./classification_eval/linear_prob_simple_args.py \
    --use_wandb \
    --wandb_project <wandb_project_name> \
    --wandb_trial <wandb_run_name> \
    --train_dataset_str /path/to/train_dataset_dir \
    --val_dataset_str /path/to/val_dataset_dir \
    --output_dir /path/to/output_dir \
    --epochs 10 \
    --cuda 0 \
    --model_name mocov2 \
    --pretrained_weights /path/to/moco_v2_200ep_pretrain.pth.tar

the moco pre-trained weight can be downloaded from offical github download here.


To fine-tune SatMAE backbone:
python ./classification_eval/linear_prob_simple_args.py \
    --use_wandb \
    --wandb_project <wandb_project_name> \
    --wandb_trial <wandb_run_name> \
    --train_dataset_str /path/to/train_dataset_dir \
    --val_dataset_str /path/to/val_dataset_dir \
    --output_dir /path/to/output_dir \
    --epochs 10 \
    --cuda 0 \
    --model_name satmae

To fine-tune ViT-L/14 backbone with no pretrained weights (Scratch):
python ./classification_eval/linear_prob_simple_args.py \
    --use_wandb \
    --wandb_project <wandb_project_name> \
    --wandb_trial <wandb_run_name> \
    --train_dataset_str /path/to/train_dataset_dir \
    --val_dataset_str /path/to/val_dataset_dir \
    --output_dir /path/to/output_dir \
    --epochs 10 \
    --cuda 0 \
    --model_name scratch

Notes: Public SSL backbones for comparison are adapted to 8 bands (by adjusting patch embedding) using the timm API, which also supports the DINO series and other SOTA PyTorch-based ViT models. An example of this adjustment is moco_loader.py


Citing Our Work

If you find this repository useful, please consider giving a star ⭐ and citation 🦖 Thank you:)

@article{guo2025deepandes,
  title={DeepAndes: A Self-Supervised Vision Foundation Model for Multi-Spectral Remote Sensing Imagery of the Andes},
  author={Guo, Junlin and Zimmer-Dauphinee, James R and Nieusma, Jordan M and Lu, Siqi and Liu, Quan and Deng, Ruining and Cui, Can and Yue, Jialin and Lin, Yizhe and Yao, Tianyuan and others},
  journal={arXiv preprint arXiv:2504.20303},
  year={2025}
}

Contact

For questions or contributions, open an issue or pull request. We are looking forward to your feedback!

Contact: Junlin Guo (junlinguo1@gmail.com), Yuankai Huo (PI)(yuankai.huo@vanderbilt.edu), Steven Wernke (PI)(s.wernke@Vanderbilt.Edu), and Parker VanValkenburgh (parker_vanvalkenburgh@brown.edu)