# ViTMSN

## 概述

ViTMSN 模型由 Mahmoud Assran、Mathilde Caron、Ishan Misra、Piotr Bojanowski、Florian Bordes、Pascal Vincent、Armand Joulin、Michael Rabbat 和 Nicolas Ballas 在 [Masked Siamese Networks for Label-Efficient Learning](https://huggingface.co/papers/2204.07141) 中提出。该论文介绍了一种联合嵌入架构，用于将掩码补丁的原型与未掩码补丁的原型进行匹配。在此设置下，该方法在少样本和极端少样本场景中均展现出优异的性能。

该论文的摘要如下：

*我们提出了掩码孪生网络（Masked Siamese Networks，MSN），这是一种用于学习图像表示的自监督学习框架。我们的方法将包含随机掩码块的图像视图的表示与原始未掩码图像的表示进行匹配。当应用于 Vision Transformer 时，这种自监督预训练策略具有极高的可扩展性，因为网络仅处理未掩码的块。因此，MSN 提升了联合嵌入架构的可扩展性，同时生成了具有高语义层次的表示，在少样本图像分类任务中表现出具有竞争力的性能。例如，在 ImageNet-1K 上，仅使用 5,000 张标注图像，我们的基础 MSN 模型即可达到 72.4% 的 top-1 准确率；而使用 ImageNet-1K 1% 的标签时，我们达到了 75.7% 的 top-1 准确率，在该基准上刷新了自监督学习的最佳纪录。*

 MSN 架构。摘自原始论文。

该模型由 [sayakpaul](https://huggingface.co/sayakpaul) 贡献。原始代码可在[此处](https://github.com/facebookresearch/msn)找到。

## 使用技巧

- MSN （掩码孪生网络）是一种用于视觉 Transformer（ViT）自监督预训练的方法。预训练
目标是将分配给图像未掩码视图的原型与同一图像掩码视图的原型进行匹配。
- 作者仅发布了骨干网络的预训练权重（ImageNet-1k 预训练）。因此，要在您自己的图像分类数据集上使用它，
使用从 [ViTMSNModel](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNModel) 初始化的 [ViTMSNForImageClassification](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNForImageClassification) 类。有关微调的详细教程，请参见[此笔记本](https://github.com/huggingface/notebooks/blob/main/examples/image_classification.ipynb)。
- MSN 在少样本和极端少样本场景中尤为有用。值得注意的是，它仅使用 ImageNet-1K 的 1% 数据就达到了 75.7% 的 top-1 准确率
微调时的标签。

### 使用缩放点积注意力（SDPA）

PyTorch 在 `torch.nn.functional` 中包含了原生的缩放点积注意力（SDPA）算子。该函数涵盖了多种实现方式，可根据输入和所用硬件进行应用。有关更多信息，请参阅[官方文档](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html)或[GPU 推理](https://huggingface.co/docs/transformers/main/en/perf_infer_gpu_one#pytorch-scaled-dot-product-attention)页面。

当存在可用实现时，`torch>=2.1.1` 默认使用 SDPA，但您也可以在 `from_pretrained()` 中设置 `attn_implementation="sdpa"` 以显式请求使用 SDPA。

```python
from transformers import ViTMSNForImageClassification

model = ViTMSNForImageClassification.from_pretrained("facebook/vit-msn-base", attn_implementation="sdpa", device_map="auto")
...
```

为了获得最佳加速效果，我们建议以半精度（例如 `torch.float16` 或 `torch.bfloat16`）加载模型。

在本地基准测试（A100-40GB、PyTorch 2.3.0、操作系统 Ubuntu 22.04）中，使用 `float32` 和 `facebook/vit-msn-base` 模型，我们在推理过程中观察到以下加速效果。

|   批处理大小 |   平均推理时间（毫秒），eager 模式 |   平均推理时间（毫秒），sdpa 模型 |   加速，Sdpa / Eager (x) |
|--------------|-------------------------------------------|-------------------------------------------|------------------------------|
|            1 |                                         7 |                                         6 |                      1.17 |
|            2 |                                         8 |                                         6 |                      1.33 |
|            4 |                                         8 |                                         6 |                      1.33 |
|            8 |                                         8 |                                         6 |                      1.33 |

## 资源

一份来自 Hugging Face 官方和社区（以 🌎 标识）的资源列表，帮助你快速上手 ViT MSN。

- [ViTMSNForImageClassification](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNForImageClassification) 受此 [notebook](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/image_classification.ipynb) 支持。
- 另请参阅：[图像分类任务指南](../tasks/image_classification)

如果您有兴趣提交资源以收录在此处，请随时发起 Pull Request，我们将对其进行审核！理想情况下，该资源应展示一些新内容，而不是重复现有资源。

## ViTMSNConfig[[transformers.ViTMSNConfig]]

#### transformers.ViTMSNConfig[[transformers.ViTMSNConfig]]

```python
transformers.ViTMSNConfig(transformers_version: str | None = None, architectures: list[str] | None = None, output_hidden_states: bool | None = False, return_dict: bool | None = True, dtype: str | torch.dtype | None = None, chunk_size_feed_forward: int = 0, is_encoder_decoder: bool = False, id2label: dict[int, str] | dict[str, str] | None = None, label2id: dict[str, int] | dict[str, str] | None = None, problem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = None, hidden_size: int = 768, num_hidden_layers: int = 12, num_attention_heads: int = 12, intermediate_size: int = 3072, hidden_act: str = 'gelu', hidden_dropout_prob: float | int = 0.0, attention_probs_dropout_prob: float | int = 0.0, initializer_range: float = 0.02, layer_norm_eps: float = 1e-06, image_size: int | list[int] | tuple[int, int] = 224, patch_size: int | list[int] | tuple[int, int] = 16, num_channels: int = 3, qkv_bias: bool = True)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/vit_msn/configuration_vit_msn.py#L24)

**参数：**

hidden_size (`int`，*可选*，默认为 `768`)：隐藏表示的维度。

num_hidden_layers (`int`，*可选*，默认为 `12`)：Transformer 解码器中的隐藏层数。

num_attention_heads (`int`，*可选*，默认为 `12`)：Transformer 解码器中每个注意力层的注意力头数量。

intermediate_size (`int`，*可选*，默认值为 `3072`)：MLP 表示的维度。

hidden_act (`str`，*可选*，默认为 `gelu`)：解码器中的非线性激活函数（函数或字符串）。例如，`"gelu"`、`"relu"`、`"silu"` 等。

hidden_dropout_prob (`Union[float, int]`，*可选*，默认值为 `0.0`)：嵌入层、编码器和池化器中所有全连接层的 dropout 概率。

attention_probs_dropout_prob (`Union[float, int]`，*可选*，默认值为 `0.0`)：注意力概率的 dropout 比率。

initializer_range (`float`，*可选*，默认值为 `0.02`)：用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。

layer_norm_eps (`float`, *可选*, 默认为 `1e-06`) : 层归一化层使用的 epsilon。

image_size (`Union[int, list[int], tuple[int, int]]`，*可选*，默认为 `224`)：每张图片的尺寸（分辨率）。

patch_size (`Union[int, list[int], tuple[int, int]]`，*可选*，默认为 `16`)：每个 patch 的大小（分辨率）。

num_channels (`int`，*可选*，默认为 `3`)：输入通道数。

qkv_bias (`bool`，*可选*，默认为 `True`)：是否向查询、键和值添加偏置。

这是用于存储 ViTMSNModel 配置的类。它根据指定的参数实例化 Vit Msn 模型，并定义模型架构。使用默认值实例化配置将生成与 [facebook/vit_msn_base](https://huggingface.co/facebook/vit_msn_base) 类似的配置。

配置对象继承自 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig)，可用于控制模型输出。有关更多信息，请参阅 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig) 的文档。

示例：

```python
>>> from transformers import ViTMSNModel, ViTMSNConfig

>>> # Initializing a ViT MSN vit-msn-base style configuration
>>> configuration = ViTConfig()

>>> # Initializing a model from the vit-msn-base style configuration
>>> model = ViTMSNModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config
```

## ViTMSNModel[[transformers.ViTMSNModel]]

#### transformers.ViTMSNModel[[transformers.ViTMSNModel]]

```python
transformers.ViTMSNModel(config: ViTMSNConfig, use_mask_token: bool = False)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/vit_msn/modeling_vit_msn.py#L317)

**参数：**

config ([ViTMSNConfig](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNConfig))：模型配置类，包含模型的所有参数。使用配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

use_mask_token (`bool`，*可选*，默认为 `False`)：是否使用掩码标记进行掩码图像建模。

未添加任何特定头部的裸 Vit Msn 模型，直接输出原始隐藏状态。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

#### forward[[transformers.ViTMSNModel.forward]]

```python
forward(pixel_values: typing.Optional[torch.Tensor] = None, bool_masked_pos: typing.Optional[torch.BoolTensor] = None, interpolate_pos_encoding: bool | None = None, attention_mask: typing.Optional[torch.Tensor] = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/vit_msn/modeling_vit_msn.py#L331)

**参数：**

pixel_values (`torch.Tensor`，形状为 `(batch_size, num_channels, image_size, image_size)`，*可选*) : 与输入图像对应的张量。可以使用 [ViTImageProcessor](/docs/transformers/main/zh/model_doc/vit#transformers.ViTImageProcessor) 获取像素值。有关详细信息，请参阅 [ViTImageProcessor.__call__()](/docs/transformers/main/zh/model_doc/molmo2#transformers.Molmo2ImageProcessor.__call__)（`processor_class` 使用 [ViTImageProcessor](/docs/transformers/main/zh/model_doc/vit#transformers.ViTImageProcessor) 处理图像）。

bool_masked_pos (`torch.BoolTensor`，形状为 `(batch_size, num_patches)`，*可选*)：布尔掩码位置。指示哪些 patch 被掩码（1），哪些未被掩码（0）。

interpolate_pos_encoding (`bool`, *可选*) : 是否对预训练的位置编码进行插值。

attention_mask (`torch.Tensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于避免对填充（padding）标记索引执行注意力机制的掩码。掩码值取自 `[0, 1]`： - 1 表示**未掩码**的标记， - 0 表示**已掩码**的标记。 [什么是注意力掩码？](../glossary#attention-mask)

**返回：** [BaseModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.BaseModelOutput) 或 `tuple(torch.Tensor)`

一个 [BaseModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.BaseModelOutput) 或 `torch.Tensor` 元组（如果传入了 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[ViTMSNConfig](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNConfig)）和输入。

[ViTMSNModel](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNModel) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

- **last_hidden_state**（形状为 `(batch_size, sequence_length, hidden_size)` 的 `torch.Tensor`）-- 模型最后一层输出的隐藏状态序列。
- **hidden_states** (`tuple(torch.Tensor)`，*可选*，在传入 `output_hidden_states=True` 或 `config.output_hidden_states=True` 时返回) -- 一个 `torch.Tensor` 元组（如果模型具有嵌入层，则包含嵌入层的输出，以及每一层的输出），形状为 `(batch_size, sequence_length, hidden_size)`。

  模型在每一层输出处的隐藏状态，以及可选的初始嵌入输出。
- **attentions** (`tuple(torch.Tensor)`，*可选*，当传入 `output_attentions=True` 或 `config.output_attentions=True` 时返回) -- 一个 `torch.Tensor` 元组（每层一个），形状为 `(batch_size, num_heads, sequence_length, sequence_length)`。

  经过注意力 softmax 后的注意力权重，用于在自注意力头中计算加权平均值。

示例：

```python
>>> from transformers import AutoImageProcessor, ViTMSNModel
>>> import torch
>>> from PIL import Image
>>> from huggingface_hub.utils import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-msn-small")
>>> model = ViTMSNModel.from_pretrained("facebook/vit-msn-small")
>>> inputs = image_processor(images=image, return_tensors="pt")
>>> with torch.no_grad():
...     outputs = model(**inputs)
>>> last_hidden_states = outputs.last_hidden_state
```

## ViTMSNForImageClassification[[transformers.ViTMSNForImageClassification]]

#### transformers.ViTMSNForImageClassification[[transformers.ViTMSNForImageClassification]]

```python
transformers.ViTMSNForImageClassification(config: ViTMSNConfig)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/vit_msn/modeling_vit_msn.py#L387)

**参数：**

config ([ViTMSNConfig](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNConfig))：模型配置类，包含模型的所有参数。使用配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

带有图像分类头的 Vit Msn 模型，例如用于 ImageNet。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

#### forward[[transformers.ViTMSNForImageClassification.forward]]

```python
forward(pixel_values: typing.Optional[torch.Tensor] = None, labels: typing.Optional[torch.Tensor] = None, interpolate_pos_encoding: bool | None = None, attention_mask: typing.Optional[torch.Tensor] = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/vit_msn/modeling_vit_msn.py#L395)

**参数：**

pixel_values (`torch.Tensor`，形状为 `(batch_size, num_channels, image_size, image_size)`，*可选*) : 与输入图像对应的张量。可以使用 [ViTImageProcessor](/docs/transformers/main/zh/model_doc/vit#transformers.ViTImageProcessor) 获取像素值。有关详细信息，请参阅 [ViTImageProcessor.__call__()](/docs/transformers/main/zh/model_doc/molmo2#transformers.Molmo2ImageProcessor.__call__)（`processor_class` 使用 [ViTImageProcessor](/docs/transformers/main/zh/model_doc/vit#transformers.ViTImageProcessor) 处理图像）。

labels (`torch.LongTensor`，形状为 `(batch_size,)`，*可选*)：用于计算图像分类/回归损失的标签。

interpolate_pos_encoding (`bool`, *可选*) : 是否对预训练的位置编码进行插值。

attention_mask (`torch.Tensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于避免对填充（padding）标记索引执行注意力机制的掩码。掩码值取自 `[0, 1]`： - 1 表示**未掩码**的标记， - 0 表示**已掩码**的标记。 [什么是注意力掩码？](../glossary#attention-mask)

**返回：** [ImageClassifierOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.ImageClassifierOutput) 或 `tuple(torch.Tensor)`

一个 [ImageClassifierOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.ImageClassifierOutput) 或 `torch.Tensor` 元组（如果传入了 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[ViTMSNConfig](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNConfig)）和输入。

[ViTMSNForImageClassification](/docs/transformers/main/zh/model_doc/vit_msn#transformers.ViTMSNForImageClassification) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

- **loss** (`torch.Tensor`，形状为 `(1,)`，*可选*，当提供 `labels` 时返回) -- 分类损失（如果 config.num_labels==1，则为回归损失）。
- **logits**（形状为 `(batch_size, config.num_labels)` 的 `torch.Tensor`）-- 分类（或当 config.num_labels==1 时为回归）得分（SoftMax 之前）。
- **hidden_states** (`tuple(torch.Tensor)`，*可选*，在传入 `output_hidden_states=True` 或 `config.output_hidden_states=True` 时返回) -- 一个 `torch.Tensor` 元组（如果模型具有嵌入层，则包含嵌入层输出的一个张量，以及每个阶段输出的一个张量），形状为 `(batch_size, sequence_length, hidden_size)`。模型在每个阶段输出处的隐藏状态（也称为特征图）。
- **attentions** (`tuple(torch.Tensor)`，*可选*，当传入 `output_attentions=True` 或 `config.output_attentions=True` 时返回) -- 一个 `torch.Tensor` 元组（每层一个），形状为 `(batch_size, num_heads, patch_size, sequence_length)`。

  经过注意力 softmax 后的注意力权重，用于在自注意力头中计算加权平均值。

示例：

```python
>>> from transformers import AutoImageProcessor, ViTMSNForImageClassification
>>> import torch
>>> from PIL import Image
>>> from huggingface_hub.utils import httpx
>>> from io import BytesIO

>>> torch.manual_seed(2)
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read())).convert("RGB")

>>> image_processor = AutoImageProcessor.from_pretrained("facebook/vit-msn-small")
>>> model = ViTMSNForImageClassification.from_pretrained("facebook/vit-msn-small")

>>> inputs = image_processor(images=image, return_tensors="pt")
>>> with torch.no_grad():
...     logits = model(**inputs).logits
>>> # model predicts one of the 1000 ImageNet classes
>>> predicted_label = logits.argmax(-1).item()
>>> print(model.config.id2label[predicted_label])
tusker
```

