Detection and Metric Learning from Pseudo-Labels for Unsupervised Maritime Vessel Re-Identification

This repository contains the weights of the model trained for vessel re-identification on the VesselReID Dataset, presented at AVSS 2026:

This model has been pushed to the Hub using the PytorchModelHubMixin integration:

Usage

Install the required dependencies:

pip install torch torchvision timm huggingface_hub

Download the model from Hugging Face and run this self-contained inference script on a random image:

import torch
import torch.nn as nn
import torch.nn.functional as F
import timm

from huggingface_hub import PyTorchModelHubMixin

MODEL_ID = "sangioai/vessel-reid-vit-base-dinov3"

class VesselReIDModel(
    nn.Module,
    PyTorchModelHubMixin,
    library_name="vessel-reid",
    tags=[
        "vessel-reid",
        "image-retrieval",
        "image-embeddings",
        "computer-vision",
        "pytorch",
        "timm",
        "dinov3",
    ],
):
    """
    Vessel Re-Identification model.

    Backbone:
        ViT-B/16 DINOv3

    Projection head:
        2-layer MLP

    Output:
        L2-normalized 256-dimensional embedding.
    """

    def __init__(
        self,
        model_name: str = "vit_base_patch16_dinov3.lvd1689m",
        proj_dim: int = 256,
        pretrained: bool = False,
    ):
        super().__init__()

        self.model_name = model_name
        self.proj_dim = proj_dim
        self.encoder = timm.create_model(model_name, pretrained=pretrained, num_classes=0)
        embedding_dim = self.encoder.num_features
        self.projector = nn.Sequential(
            nn.Linear(embedding_dim, embedding_dim),
            nn.ReLU(inplace=True),
            nn.Linear(embedding_dim, proj_dim),
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Args:
            x:
                Tensor of shape (B, 3, H, W).

        Returns:
            L2-normalized embeddings of shape (B, proj_dim).
        """
        features = self.encoder(x)
        if isinstance(features, (tuple, list)):
            features = features[0]
        embeddings = self.projector(features)
        return F.normalize(embeddings, dim=1)

    @torch.no_grad()
    def encode_image(self, x: torch.Tensor) -> torch.Tensor:
        """
        Convenience method for extracting normalized image embeddings.
        """
        self.eval()
        return self.forward(x)



if __name__ == "__main__":
    ## Example usage of VesselReIDModel
    DEVICE = ("cuda" if torch.cuda.is_available() else "cpu")
    
    # Download model from Hugging Face
    model = VesselReIDModel.from_pretrained(MODEL_ID)
    model = model.to(DEVICE)
    model.eval()
    
    # Random image smoke test
    image = torch.randn(1, 3, 224, 224, device=DEVICE)
    with torch.no_grad():
        embedding = model(image)
    print("Embedding shape:", embedding.shape)
    print("Embedding norm:", embedding.norm(dim=1))

Expected output:

Embedding shape: torch.Size([1, 256])
Embedding norm: tensor([1.])

The model returns a 256-dimensional L2-normalized embedding. These embeddings can be compared using cosine similarity for vessel re-identification and image retrieval.

Dataset

This model is trained on the VesselReID Dataset with about 30,587 images over 1,248 unique vessels (624 for training, 624 for testing).

Evaluation

Evaluation code will be published.

Comparison of representative vessel re-identification methods on the VesselReID benchmark dataset:

Methods R1*โ†‘ R5*โ†‘ R10*โ†‘ mAP*โ†‘
BNN 63.8 85.3 90.9 50.7
PAGS 66.2 85.7 90.9 53.9
MCL 63.9 82.1 82.1 45.3
Trans-ReID 68.2 86.3 91.1 58.7
PFD-Net 66.1 84.9 90.2 49.2
AP-Net 62.6 83.3 89.6 50.1
Tran-Aligned 64.3 82.8 89.4 51.8
MCFormer 72.8 88.9 93.1 63.4
ResNet50 (Ours) 58.1 81.9 87.5 36.5
ConvNeXt DINOv2 (Ours) 77.7 93.9 65.3 65.3
ViT DINOv3 (Ours) 83.4 95.5 97.6 68.1

* Best result is in bold and second-best result is underlined.

Further information about the metrics and the cited models can be found in the paper.

License

This model uses the pretrained DINOv3 ViT-B/16 backbone timm/vit_base_patch16_dinov3.lvd1689m, which originates from Meta's DINOv3 project. The backbone was pretrained on the LVD-1689M dataset.

The pretrained DINOv3 weights are distributed under the DINOv3 License. This model incorporates these pretrained weights, and their applicable licensing and redistribution terms therefore apply.

For the complete license terms, please refer to the DINOv3 License and the official DINOv3 repository.

This model is not an independently initialized network; its backbone is initialized from the pretrained DINOv3 checkpoint. Users redistributing or using this model should review and comply with the applicable DINOv3 License terms.รน

Citation

@inproceedings{sangiorgi2026detection,
  author    = {Marco Sangiorgi},
  title     = {Detection and Metric Learning from Pseudo-Labels for Unsupervised Maritime Vessel Re-Identification},
  booktitle = {2026 IEEE International Conference on Advanced Video and Signal-Based Systems (AVSS)},
  year      = {2026},
  publisher = {IEEE},
  address   = {Lecce, Italy}
}
Downloads last month
26
Safetensors
Model size
86.4M params
Tensor type
F32
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for sangioai/vessel-reid-vit-base-dinov3

Finetuned
(4)
this model