--- library_name: vessel-reid tags: - computer-vision - image-embeddings - image-retrieval - model_hub_mixin - pytorch - pytorch_model_hub_mixin - timm - vessel-reid - vessel - dinov3 - identification base_model: - timm/vit_base_patch16_dinov3.lvd1689m license: other license_name: dinov3-license license_link: https://ai.meta.com/resources/models-and-libraries/dinov3-license --- # 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](https://github.com/vsislab/VesselReID), presented at [AVSS 2026](https://www.avss2026.org/): - Backbone: ViT-B/16 DINOv3 - Code: [TO-DO] - Paper: [Detection and Metric Learning from Pseudo-Labels for Unsupervised Maritime Vessel Re-Identification](https://cnrsc-my.sharepoint.com/:b:/g/personal/cosimo_distante_cnr_it/IQA9ASnL2ykMSYyj0rbKjIPvARy8eIHqRC_VEq0htfgLWmg?e=7QtdNm) (AVSS'26 oral) This model has been pushed to the Hub using the [PytorchModelHubMixin](https://huggingface.co/docs/huggingface_hub/package_reference/mixins#huggingface_hub.PyTorchModelHubMixin) integration: ## Usage Install the required dependencies: ```bash pip install torch torchvision timm huggingface_hub ``` Download the model from Hugging Face and run this self-contained inference script on a random image: ```python 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](https://github.com/vsislab/VesselReID) 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. * **Upstream model**: [timm/vit_base_patch16_dinov3.lvd1689m](https://huggingface.co/timm/vit_base_patch16_dinov3.lvd1689m) * **Original model**: Meta DINOv3 ViT-B/16 * **Pretraining dataset**: LVD-1689M * **Upstream license**: [DINOv3 License](https://ai.meta.com/resources/models-and-libraries/dinov3-license/) 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 ```bibtex @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} } ```