金字塔视觉变换器 V2 (PVTv2)
概述
PVTv2模型由Wenhai Wang、Enze Xie、Xiang Li、Deng-Ping Fan、Kaitao Song、Ding Liang、Tong Lu、Ping Luo和Ling Shao在PVT v2: Improved Baselines with Pyramid Vision Transformer中提出。作为PVT的改进版本,它摒弃了位置嵌入,转而依赖于通过零填充和重叠的补丁嵌入编码的位置信息。这种不依赖位置嵌入的方式简化了架构,并使得在任何分辨率下运行推理时无需进行插值。
PVTv2编码器结构已成功部署,在Segformer中实现了语义分割的最先进分数,在GLPN中实现了单目深度的最先进分数,以及在Panoptic Segformer中实现了全景分割的最先进分数。
PVTv2属于一类称为分层变换器的模型,这些模型对变换器层进行调整以生成多尺度特征图。与视觉变换器(ViT)的列式结构不同,后者会丢失细粒度细节,而多尺度特征图已知可以保留这些细节并有助于密集预测任务的性能。在PVTv2的情况下,这是通过在每个编码器层中使用重叠核的2D卷积生成图像补丁标记来实现的。
分层变换器的多尺度特性使得它们可以轻松替换传统的主力计算机视觉骨干模型,如ResNet,在更大的架构中。Segformer和Panoptic Segformer都证明了使用PVTv2作为骨干的配置在性能上始终优于使用类似大小的ResNet骨干的配置。
PVTv2 的另一个强大特性是自注意力层的复杂度降低,称为空间缩减注意力(SRA),它使用 2D 卷积层将隐藏状态投影到较小的分辨率,然后再用查询进行处理,从而将自注意力的 $O(n^2)$ 复杂度改进为 $O(n^2/R)$,其中 $R$ 是空间缩减比率(sr_ratio
,即 2D 卷积中的核大小和步幅)。
SRA在PVT中引入,并且是PVTv2中默认使用的注意力复杂度降低方法。然而,PVTv2还引入了使用与图像大小相关的线性复杂度的自注意力机制的选项,他们称之为“线性SRA”。该方法使用平均池化将隐藏状态减少到固定大小,该大小与其原始分辨率无关(尽管这本质上比常规SRA更具损失性)。可以通过在PVTv2Config中将linear_attention
设置为True
来启用此选项。
论文摘要:
Transformer 最近在计算机视觉领域展示了令人鼓舞的进展。在这项工作中,我们通过改进原始的金字塔视觉 Transformer (PVT v1) 提出了新的基线,增加了三个设计,包括 (1) 线性复杂度注意力层,(2) 重叠的补丁嵌入,以及 (3) 卷积前馈网络。通过这些修改,PVT v2 将 PVT v1 的计算复杂度降低到线性,并在分类、检测和分割等基本视觉任务上取得了显著改进。值得注意的是,所提出的 PVT v2 实现了与 Swin Transformer 等近期工作相当或更好的性能。我们希望这项工作能够促进计算机视觉领域中最先进的 Transformer 研究。代码可在 https://github.com/whai362/PVT 获取。
该模型由FoamoftheSea贡献。原始代码可以在这里找到。
使用提示
PVTv2 是一种分层变压器模型,在图像分类和多个其他任务中展示了强大的性能,被用作Segformer中的语义分割、GLPN中的单目深度估计以及Panoptic Segformer中的全景分割的骨干网络,始终显示出比类似的ResNet配置更高的性能。
像PVTv2这样的分层变换器通过在编码器中融入卷积神经网络(CNN)的设计元素,在图像数据上实现了比纯变换器架构更优越的数据和参数效率。这创造了一种两全其美的架构,将CNN的有用归纳偏差(如平移等变性和局部性)注入网络,同时仍然享受由变换器的自注意力机制提供的动态数据响应和全局关系建模的好处。
PVTv2 使用重叠的补丁嵌入来创建多尺度特征图,这些特征图通过零填充和深度卷积注入位置信息。
为了减少注意力层的复杂性,PVTv2 使用步幅2D卷积(SRA)或固定大小的平均池化(线性SRA)对隐藏状态进行空间缩减。尽管线性SRA本质上更具损失性,但它提供了令人印象深刻的性能,并且相对于图像大小具有线性复杂性。要在自注意力层中使用线性SRA,请在
PvtV2Config
中设置linear_attention=True
。PvtV2Model 是分层变压器编码器(在文献中也常被称为Mix Transformer或MiT)。PvtV2ForImageClassification 在其顶部添加了一个简单的分类器头以执行图像分类。
PvtV2Backbone
可以与 AutoBackbone 系统一起用于更大的架构中,如Deformable DETR。所有模型大小的ImageNet预训练权重可以在hub上找到。
开始使用PVTv2的最佳方式是使用
AutoModelForImageClassification
加载您选择大小的预训练检查点:
import requests
import torch
from transformers import AutoModelForImageClassification, AutoImageProcessor
from PIL import Image
model = AutoModelForImageClassification.from_pretrained("OpenGVLab/pvt_v2_b0")
image_processor = AutoImageProcessor.from_pretrained("OpenGVLab/pvt_v2_b0")
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
processed = image_processor(image)
outputs = model(torch.tensor(processed["pixel_values"]))
要将PVTv2用作更复杂架构(如DeformableDETR)的主干网络,您可以使用AutoBackbone(由于您正在替换预训练模型中的主干网络,因此该模型需要进行微调):
import requests
import torch
from transformers import AutoConfig, AutoModelForObjectDetection, AutoImageProcessor
from PIL import Image
model = AutoModelForObjectDetection.from_config(
config=AutoConfig.from_pretrained(
"SenseTime/deformable-detr",
backbone_config=AutoConfig.from_pretrained("OpenGVLab/pvt_v2_b5"),
use_timm_backbone=False
),
)
image_processor = AutoImageProcessor.from_pretrained("SenseTime/deformable-detr")
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
processed = image_processor(image)
outputs = model(torch.tensor(processed["pixel_values"]))
PVTv2 在 ImageNet-1K 上的性能按模型大小(B0-B5)显示:
方法 | 大小 | Acc@1 | 参数数量 (M) |
---|---|---|---|
PVT-V2-B0 | 224 | 70.5 | 3.7 |
PVT-V2-B1 | 224 | 78.7 | 14.0 |
PVT-V2-B2-Linear | 224 | 82.1 | 22.6 |
PVT-V2-B2 | 224 | 82.0 | 25.4 |
PVT-V2-B3 | 224 | 83.1 | 45.2 |
PVT-V2-B4 | 224 | 83.6 | 62.6 |
PVT-V2-B5 | 224 | 83.8 | 82.0 |
PvtV2Config
类 transformers.PvtV2Config
< source >( image_size: typing.Union[int, typing.Tuple[int, int]] = 224 num_channels: int = 3 num_encoder_blocks: int = 4 depths: typing.List[int] = [2, 2, 2, 2] sr_ratios: typing.List[int] = [8, 4, 2, 1] hidden_sizes: typing.List[int] = [32, 64, 160, 256] patch_sizes: typing.List[int] = [7, 3, 3, 3] strides: typing.List[int] = [4, 2, 2, 2] num_attention_heads: typing.List[int] = [1, 2, 5, 8] mlp_ratios: typing.List[int] = [8, 8, 4, 4] hidden_act: typing.Union[str, typing.Callable] = 'gelu' hidden_dropout_prob: float = 0.0 attention_probs_dropout_prob: float = 0.0 initializer_range: float = 0.02 drop_path_rate: float = 0.0 layer_norm_eps: float = 1e-06 qkv_bias: bool = True linear_attention: bool = False out_features = None out_indices = None **kwargs )
参数
- image_size (
Union[int, Tuple[int, int]]
, optional, defaults to 224) — 输入图像的大小。传递整数值用于正方形图像,或传递(高度,宽度)的元组。 - num_channels (
int
, optional, 默认为 3) — 输入通道的数量。 - num_encoder_blocks (
[int]
, 可选, 默认为 4) — 编码器块的数量(即 Mix Transformer 编码器中的阶段数)。 - depths (
List[int]
, optional, 默认为[2, 2, 2, 2]
) — 每个编码器块中的层数。 - sr_ratios (
List[int]
, 可选, 默认为[8, 4, 2, 1]
) — 每个编码器块中的空间缩减比率。 - hidden_sizes (
List[int]
, 可选, 默认为[32, 64, 160, 256]
) — 每个编码器块的维度。 - patch_sizes (
List[int]
, optional, defaults to[7, 3, 3, 3]
) — 每个编码器块之前的重叠补丁嵌入的补丁大小。 - strides (
List[int]
, 可选, 默认为[4, 2, 2, 2]
) — 在每个编码器块之前用于重叠补丁嵌入的步幅。 - num_attention_heads (
List[int]
, optional, 默认为[1, 2, 5, 8]
) — Transformer编码器每个块中每个注意力层的注意力头数。 - mlp_ratios (
List[int]
, 可选, 默认为[8, 8, 4, 4]
) — 编码器块中Mix FFNs的隐藏层大小与输入层大小的比率。 - hidden_act (
str
或Callable
, 可选, 默认为"gelu"
) — 编码器和池化器中的非线性激活函数(函数或字符串)。如果是字符串,支持"gelu"
、"relu"
、"selu"
和"gelu_new"
。 - hidden_dropout_prob (
float
, optional, 默认为 0.0) — 嵌入层、编码器和池化器中所有全连接层的 dropout 概率。 - attention_probs_dropout_prob (
float
, optional, defaults to 0.0) — 注意力概率的丢弃比例。 - initializer_range (
float
, 可选, 默认值为 0.02) — 用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。 - drop_path_rate (
float
, optional, 默认为 0.0) — 用于Transformer编码器块中的随机深度的丢弃概率。 - layer_norm_eps (
float
, optional, defaults to 1e-06) — 层归一化层使用的epsilon值。 - qkv_bias (
bool
, optional, defaults toTrue
) — 是否应向查询、键和值添加可学习的偏置。 - linear_attention (
bool
, 可选, 默认为False
) — 使用线性注意力复杂度。如果设置为True,sr_ratio
将被忽略,并且在注意力层中使用平均池化进行降维,而不是使用步幅卷积。 - out_features (
List[str]
, 可选) — 如果用作骨干网络,输出特征的列表。可以是"stem"
、"stage1"
、"stage2"
等。 (取决于模型有多少个阶段)。如果未设置且out_indices
已设置,将默认为相应的阶段。如果未设置且out_indices
也未设置,将默认为最后一个阶段。 - out_indices (
List[int]
, 可选) — 如果用作骨干网络,输出特征的索引列表。可以是0、1、2等(取决于模型有多少个阶段)。如果未设置且out_features
已设置,将默认为相应的阶段。 如果未设置且out_features
也未设置,将默认为最后一个阶段。
这是用于存储PvtV2Model配置的配置类。它用于根据指定的参数实例化一个Pvt V2模型,定义模型架构。使用默认值实例化配置将产生类似于Pvt V2 B0 OpenGVLab/pvt_v2_b0架构的配置。
配置对象继承自PretrainedConfig,可用于控制模型输出。阅读PretrainedConfig的文档以获取更多信息。
示例:
>>> from transformers import PvtV2Model, PvtV2Config
>>> # Initializing a pvt_v2_b0 style configuration
>>> configuration = PvtV2Config()
>>> # Initializing a model from the OpenGVLab/pvt_v2_b0 style configuration
>>> model = PvtV2Model(configuration)
>>> # Accessing the model configuration
>>> configuration = model.config
PvtForImageClassification
类 transformers.PvtV2ForImageClassification
< source >( 配置: PvtV2Config )
参数
- config (~PvtV2Config) — 包含模型所有参数的模型配置类。 使用配置文件初始化不会加载与模型相关的权重,只会加载配置。查看 from_pretrained() 方法以加载模型权重。
Pvt-v2 模型转换器,顶部带有图像分类头(在 [CLS] 标记的最终隐藏状态之上的线性层),例如用于 ImageNet。
该模型是一个PyTorch torch.nn.Module 子类。将其作为常规的PyTorch模块使用,并参考PyTorch文档以获取与一般使用和行为相关的所有信息。
前进
< source >( pixel_values: typing.Optional[torch.Tensor] labels: typing.Optional[torch.Tensor] = None output_attentions: typing.Optional[bool] = None output_hidden_states: typing.Optional[bool] = None return_dict: typing.Optional[bool] = None ) → transformers.modeling_outputs.ImageClassifierOutput 或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
of shape(batch_size, num_channels, height, width)
) — 像素值。像素值可以使用AutoImageProcessor获取。详情请参见 PvtImageProcessor.call(). - output_attentions (
bool
, 可选) — 是否返回所有注意力层的注意力张量。有关更多详细信息,请参见返回张量下的attentions
。 - output_hidden_states (
bool
, 可选) — 是否返回所有层的隐藏状态。有关更多详细信息,请参见返回张量下的hidden_states
。 - return_dict (
bool
, 可选) — 是否返回一个ModelOutput而不是一个普通的元组。 - labels (
torch.LongTensor
形状为(batch_size,)
, 可选) — 用于计算图像分类/回归损失的标签。索引应在[0, ..., config.num_labels - 1]
范围内。如果config.num_labels == 1
,则计算回归损失(均方损失),如果config.num_labels > 1
,则计算分类损失(交叉熵)。
返回
transformers.modeling_outputs.ImageClassifierOutput 或 tuple(torch.FloatTensor)
一个 transformers.modeling_outputs.ImageClassifierOutput 或一个由
torch.FloatTensor
组成的元组(如果传递了 return_dict=False
或当 config.return_dict=False
时),包含各种
元素,具体取决于配置(PvtV2Config)和输入。
-
loss (
torch.FloatTensor
形状为(1,)
,可选,当提供labels
时返回) — 分类(或回归,如果 config.num_labels==1)损失。 -
logits (
torch.FloatTensor
形状为(batch_size, config.num_labels)
) — 分类(或回归,如果 config.num_labels==1)得分(在 SoftMax 之前)。 -
hidden_states (
tuple(torch.FloatTensor)
,可选,当传递output_hidden_states=True
或当config.output_hidden_states=True
时返回) — 由torch.FloatTensor
组成的元组(一个用于嵌入层的输出,如果模型有嵌入层,+ 一个用于每个阶段的输出)形状为(batch_size, sequence_length, hidden_size)
。模型在每个阶段输出的隐藏状态 (也称为特征图)。 -
attentions (
tuple(torch.FloatTensor)
,可选,当传递output_attentions=True
或当config.output_attentions=True
时返回) — 由torch.FloatTensor
组成的元组(每个层一个)形状为(batch_size, num_heads, patch_size, sequence_length)
。注意力 softmax 后的注意力权重,用于计算自注意力头中的加权平均值。
PvtV2ForImageClassification 的前向方法,重写了 __call__
特殊方法。
尽管前向传递的配方需要在此函数内定义,但之后应该调用Module
实例而不是这个,因为前者负责运行预处理和后处理步骤,而后者会默默地忽略它们。
示例:
>>> from transformers import AutoImageProcessor, PvtV2ForImageClassification
>>> import torch
>>> from datasets import load_dataset
>>> dataset = load_dataset("huggingface/cats-image", trust_remote_code=True)
>>> image = dataset["test"]["image"][0]
>>> image_processor = AutoImageProcessor.from_pretrained("OpenGVLab/pvt_v2_b0")
>>> model = PvtV2ForImageClassification.from_pretrained("OpenGVLab/pvt_v2_b0")
>>> inputs = image_processor(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])
LABEL_281
PvtModel
类 transformers.PvtV2Model
< source >( 配置: PvtV2Config )
参数
- config (~PvtV2Config) — 包含模型所有参数的模型配置类。 使用配置文件初始化不会加载与模型相关的权重,只会加载配置。查看 from_pretrained() 方法以加载模型权重。
裸的Pvt-v2编码器输出原始隐藏状态,没有任何特定的头部。 该模型是PyTorch torch.nn.Module的子类。将其用作常规的PyTorch模块,并参考PyTorch文档以获取与一般使用和行为相关的所有事项。
前进
< source >( pixel_values: FloatTensor output_attentions: typing.Optional[bool] = None output_hidden_states: typing.Optional[bool] = None return_dict: typing.Optional[bool] = None ) → transformers.modeling_outputs.BaseModelOutput 或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
of shape(batch_size, num_channels, height, width)
) — 像素值。像素值可以使用AutoImageProcessor获取。详情请参见 PvtImageProcessor.call(). - output_attentions (
bool
, 可选) — 是否返回所有注意力层的注意力张量。有关更多详细信息,请参见返回张量中的attentions
。 - output_hidden_states (
bool
, 可选) — 是否返回所有层的隐藏状态。有关更多详细信息,请参见返回张量下的hidden_states
。 - return_dict (
bool
, 可选) — 是否返回一个 ModelOutput 而不是一个普通的元组。
返回
transformers.modeling_outputs.BaseModelOutput 或 tuple(torch.FloatTensor)
一个 transformers.modeling_outputs.BaseModelOutput 或一个由
torch.FloatTensor
组成的元组(如果传递了 return_dict=False
或当 config.return_dict=False
时),包含各种
元素,具体取决于配置(PvtV2Config)和输入。
-
last_hidden_state (
torch.FloatTensor
形状为(batch_size, sequence_length, hidden_size)
) — 模型最后一层输出的隐藏状态序列。 -
hidden_states (
tuple(torch.FloatTensor)
, 可选, 当传递了output_hidden_states=True
或当config.output_hidden_states=True
时返回) — 由torch.FloatTensor
组成的元组(一个用于嵌入层的输出,如果模型有嵌入层,+ 一个用于每一层的输出)形状为(batch_size, sequence_length, hidden_size)
。模型在每一层输出的隐藏状态加上可选的初始嵌入输出。
-
attentions (
tuple(torch.FloatTensor)
, 可选, 当传递了output_attentions=True
或当config.output_attentions=True
时返回) — 由torch.FloatTensor
组成的元组(每一层一个)形状为(batch_size, num_heads, sequence_length, sequence_length)
。注意力 softmax 后的注意力权重,用于计算自注意力头中的加权平均值。
PvtV2Model 的前向方法,重写了 __call__
特殊方法。
尽管前向传递的配方需要在此函数内定义,但之后应该调用Module
实例而不是这个,因为前者负责运行预处理和后处理步骤,而后者会默默地忽略它们。
示例:
>>> from transformers import AutoImageProcessor, PvtV2Model
>>> import torch
>>> from datasets import load_dataset
>>> dataset = load_dataset("huggingface/cats-image", trust_remote_code=True)
>>> image = dataset["test"]["image"][0]
>>> image_processor = AutoImageProcessor.from_pretrained("OpenGVLab/pvt_v2_b0")
>>> model = PvtV2Model.from_pretrained("OpenGVLab/pvt_v2_b0")
>>> inputs = image_processor(image, return_tensors="pt")
>>> with torch.no_grad():
... outputs = model(**inputs)
>>> last_hidden_states = outputs.last_hidden_state
>>> list(last_hidden_states.shape)
[1, 256, 7, 7]