LeViT
概述
LeViT 模型由 Ben Graham、Alaaeldin El-Nouby、Hugo Touvron、Pierre Stock、Armand Joulin、Hervé Jégou 和 Matthijs Douze 在 LeViT: Introducing Convolutions to Vision Transformers 中提出。LeViT 通过一些架构上的差异,如 Transformer 中分辨率递减的激活图和引入注意力偏差来整合位置信息,在性能和效率上改进了 视觉 Transformer (ViT)。
论文的摘要如下:
我们设计了一个图像分类架构系列,它在高速环境下优化了准确性和效率之间的权衡。我们的工作利用了基于注意力的架构的最新发现,这些架构在高度并行处理硬件上具有竞争力。我们重新审视了卷积神经网络文献中的大量原则,并将它们应用于 Transformer,特别是具有递减分辨率的激活图。我们还引入了注意力偏差,这是一种在视觉 Transformer 中整合位置信息的新方法。因此,我们提出了 LeVIT:一种用于快速推理图像分类的混合神经网络。我们考虑了不同硬件平台上效率的不同衡量标准,以最大程度地反映各种应用场景。我们广泛的实验经验验证了我们的技术选择,并表明它们适用于大多数架构。总体而言,LeViT 在速度/准确性权衡方面明显优于现有的卷积网络和视觉 Transformer。例如,在 80% ImageNet top-1 准确率下,LeViT 比 EfficientNet 在 CPU 上快 5 倍。
LeViT 架构。取自 原始论文。该模型由 anugunj 贡献。原始代码可以在这里找到 here.
使用技巧
- 与 ViT 相比,LeViT 模型使用了一个额外的蒸馏头,可以有效地从教师(在 LeViT 论文中,是一个类似 ResNet 的模型)学习。蒸馏头通过类似 ResNet 模型的监督在反向传播下学习。他们还从卷积神经网络中汲取灵感,使用具有递减分辨率的激活图来提高效率。
- 有两种方法可以微调蒸馏模型,要么 (1) 以传统方式,只在最终隐藏状态之上放置一个预测头,而不使用蒸馏头,要么 (2) 在最终隐藏状态之上放置一个预测头和一个蒸馏头。在这种情况下,预测头使用预测头与真实标签之间的交叉熵进行训练,而蒸馏预测头使用硬蒸馏(蒸馏头预测与教师预测标签之间的交叉熵)进行训练。在推理时,将两个头的平均预测作为最终预测。(2) 也称为“使用蒸馏进行微调”,因为依赖于已经对下游数据集进行过微调的教师。在模型方面,(1) 对应于 LevitForImageClassification,(2) 对应于 LevitForImageClassificationWithTeacher.
- 所有发布的检查点都在 ImageNet-1k(也称为 ILSVRC 2012,包含 130 万张图像和 1000 个类别)上进行了预训练和微调。仅此而已。没有使用外部数据。这与原始 ViT 模型形成对比,原始 ViT 模型在预训练时使用了 JFT-300M 数据集/ImageNet-21k 等外部数据。
- LeViT 的作者发布了 5 个训练好的 LeViT 模型,你可以直接将它们插入到 LevitModel 或 LevitForImageClassification 中。为了模拟在更大数据集上进行训练(仅使用 ImageNet-1k 进行预训练),使用了数据增强、优化和正则化等技术。5 种可用的变体是(所有变体都在 224x224 尺寸的图像上进行训练):facebook/levit-128S、facebook/levit-128、facebook/levit-192、facebook/levit-256 和 facebook/levit-384。请注意,应使用 LevitImageProcessor 来准备模型的图像。
- LevitForImageClassificationWithTeacher 目前仅支持推理,不支持训练或微调。
- 你可以查看有关推理以及在自定义数据上进行微调的演示笔记本 here(你可以直接用 ViTFeatureExtractor 替换 LevitImageProcessor,用 ViTForImageClassification 替换 LevitForImageClassification 或 LevitForImageClassificationWithTeacher)。
资源
以下是官方 Hugging Face 和社区(🌎 表示)资源列表,可帮助你开始使用 LeViT。
- LevitForImageClassification 由此 示例脚本 和 笔记本 支持。
- 另请参阅:图像分类任务指南
如果你想提交要在此处包含的资源,请随时打开一个 Pull Request,我们会进行审查!理想情况下,该资源应该演示新的内容,而不是重复现有的资源。
LevitConfig
class transformers.LevitConfig
< 源代码 >( image_size = 224 num_channels = 3 kernel_size = 3 stride = 2 padding = 1 patch_size = 16 hidden_sizes = [128, 256, 384] num_attention_heads = [4, 8, 12] depths = [4, 4, 4] key_dim = [16, 16, 16] drop_path_rate = 0 mlp_ratio = [2, 2, 2] attention_ratio = [2, 2, 2] initializer_range = 0.02 **kwargs )
参数
- image_size (
int
, 可选, 默认值 224) — 输入图像的大小。 - num_channels (
int
, 可选, 默认值 3) — 输入图像的通道数。 - kernel_size (
int
, 可选, 默认值 3) — 补丁嵌入的初始卷积层的内核大小。 - stride (
int
, 可选, 默认值 2) — 补丁嵌入的初始卷积层的步长大小。 - padding (
int
, 可选, 默认值 1) — 补丁嵌入的初始卷积层的填充大小。 - patch_size (
int
, 可选, 默认值 16) — 嵌入的补丁大小。 - hidden_sizes (
List[int]
, 可选, 默认值[128, 256, 384]
) — 每个编码器块的维度。 - num_attention_heads (
List[int]
, 可选, 默认值[4, 8, 12]
) — Transformer 编码器每个块中每个注意力层的注意力头数量。 - depths (
List[int]
, 可选, 默认值[4, 4, 4]
) — 每个编码器块的层数。 - mlp_ratios (
List[int]
, 可选, 默认值为[2, 2, 2]
) — 编码器块中 Mix FFNs 的隐藏层大小与输入层大小的比率。 - attention_ratios (
List[int]
, 可选, 默认值为[2, 2, 2]
) — 注意力层的输出维度大小与输入维度大小的比率。 - initializer_range (
float
, 可选, 默认值为 0.02) — 用于初始化所有权重矩阵的截断正态初始化的标准差。
这是用于存储 LevitModel 配置的配置类。 它用于根据指定的参数实例化 LeViT 模型,定义模型架构。 使用默认值实例化配置将产生与 LeViT facebook/levit-128S 架构类似的配置。
配置对象继承自 PretrainedConfig,可用于控制模型输出。 阅读 PretrainedConfig 的文档以获取更多信息。
示例
>>> from transformers import LevitConfig, LevitModel
>>> # Initializing a LeViT levit-128S style configuration
>>> configuration = LevitConfig()
>>> # Initializing a model (with random weights) from the levit-128S style configuration
>>> model = LevitModel(configuration)
>>> # Accessing the model configuration
>>> configuration = model.config
LevitFeatureExtractor
预处理图像或一批图像。
LevitImageProcessor
class transformers.LevitImageProcessor
< 源代码 >( do_resize: bool = True size: Dict = None resample: Resampling = <Resampling.BICUBIC: 3> do_center_crop: bool = True crop_size: Dict = None do_rescale: bool = True rescale_factor: Union = 0.00392156862745098 do_normalize: bool = True image_mean: Union = [0.485, 0.456, 0.406] 参数 bool
, 可选, 默认为 True
) — 是否将输入的最短边调整为 int(256/224 *size
)。可以通过 preprocess
方法中的 do_resize
参数覆盖。 Dict[str, int]
, 可选, 默认为 {"shortest_edge" -- 224}
): 调整大小后输出图像的大小。如果 size 是一个包含键“width”和“height”的字典,则图像将被调整为 (size["height"], size["width"])
。如果 size 是一个包含键“shortest_edge”的字典,则最短边值 c
将被重新调整为 int(c * (256/224))
。图像的较小边将与该值匹配,即如果 height > width,则图像将被重新调整为 (size["shortest_egde"] * height / width, size["shortest_egde"])
。可以通过 preprocess
方法中的 size
参数覆盖。 PILImageResampling
, 可选, 默认为 Resampling.BICUBIC
) — 如果调整图像大小,则要使用的重采样过滤器。可以通过 preprocess
方法中的 resample
参数覆盖。 bool
, 可选, 默认为 True
) — 是否将输入裁剪到 (crop_size["height"], crop_size["width"])
的中心。可以通过 preprocess
方法中的 do_center_crop
参数覆盖。 Dict
, 可选, 默认为 {"height" -- 224, "width": 224}
): center_crop
后所需图像大小。可以通过 preprocess
方法中的 crop_size
参数覆盖。 bool
, 可选, 默认为 True
) — 控制是否按指定的 scale rescale_factor
重新调整图像大小。可以通过 preprocess
方法中的 do_rescale
参数覆盖。 int
或 float
, 可选, 默认为 1/255
) — 如果重新调整图像大小,则要使用的缩放因子。可以通过 preprocess
方法中的 rescale_factor
参数覆盖。 bool
, 可选, 默认为 True
) — 控制是否对图像进行归一化。可以通过 preprocess
方法中的 do_normalize
参数覆盖。 List[int]
, 可选, 默认为 [0.485, 0.456, 0.406]
) — 如果对图像进行归一化,则要使用的均值。这是一个浮点数或与图像通道数相同的浮点数列表。可以通过 preprocess
方法中的 image_mean
参数覆盖。 List[int]
, 可选, 默认为 [0.229, 0.224, 0.225]
) — 如果对图像进行归一化,则要使用的标准差。这是一个浮点数或与图像通道数相同的浮点数列表。可以通过 preprocess
方法中的 image_std
参数覆盖。
构建 LeViT 图像处理器。
LevitModel
class transformers.LevitModel
< 源代码 >( config )
参数
- config (LevitConfig) — 模型配置类,包含模型的所有参数。使用配置文件初始化不会加载与模型相关的权重,只加载配置。查看 from_pretrained() 方法以加载模型权重。
不带任何特定头的 LeViT 模型,输出原始特征。此模型是 PyTorch torch.nn.Module 子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档了解所有与一般使用和行为相关的事项。
forward
< 源代码 > ( pixel_values: FloatTensor = None output_hidden_states: Optional = None return_dict: Optional = None ) → transformers.modeling_outputs.BaseModelOutputWithPoolingAndNoAttention
或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 像素值。可以使用 AutoImageProcessor 获取像素值。有关详细信息,请参阅 LevitImageProcessor.call()。 - output_hidden_states (
bool
, 可选) — 是否返回所有层的隐藏状态。有关更多详细信息,请参阅返回张量中的hidden_states
。 - return_dict (
bool
, 可选) — 是否返回一个 ModelOutput 而不是一个普通元组。
返回
transformers.modeling_outputs.BaseModelOutputWithPoolingAndNoAttention
或 tuple(torch.FloatTensor)
一个 transformers.modeling_outputs.BaseModelOutputWithPoolingAndNoAttention
或一个 torch.FloatTensor
元组(如果传递了 return_dict=False
或当 config.return_dict=False
时),包括取决于配置(LevitConfig)和输入的各种元素。
-
last_hidden_state (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 模型最后一层的输出处的隐藏状态序列。 -
pooler_output (
torch.FloatTensor
形状为(batch_size, hidden_size)
) — 在对空间维度进行池化操作后,最后一层的隐藏状态。 -
hidden_states (
tuple(torch.FloatTensor)
, 可选,当传递output_hidden_states=True
或当config.output_hidden_states=True
时返回) —torch.FloatTensor
元组(一个用于嵌入的输出,如果模型具有嵌入层,+ 一个用于每一层的输出)形状为(batch_size, num_channels, height, width)
。模型在每一层输出处的隐藏状态以及可选的初始嵌入输出。
该 LevitModel 正向方法,重写了 __call__
特殊方法。
虽然正向传递的配方需要在此函数中定义,但之后应该调用 Module
实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者则默默地忽略它们。
示例
>>> from transformers import AutoImageProcessor, LevitModel
>>> 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("facebook/levit-128S")
>>> model = LevitModel.from_pretrained("facebook/levit-128S")
>>> 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, 16, 384]
LevitForImageClassification
class transformers.LevitForImageClassification
< 源代码 >( config )
参数
- config (LevitConfig) — 模型配置类,包含模型的所有参数。使用配置文件初始化不会加载与模型关联的权重,只会加载配置。查看 from_pretrained() 方法来加载模型权重。
Levit 模型,顶部有一个图像分类头(在池化特征上方的线性层),例如用于 ImageNet。
此模型是一个 PyTorch torch.nn.Module 子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档了解有关一般用法和行为的所有事宜。
forward
< 源代码 > ( pixel_values: FloatTensor = None labels: 可选 = None output_hidden_states: 可选 = None return_dict: 可选 = None ) → transformers.modeling_outputs.ImageClassifierOutputWithNoAttention 或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 像素值。像素值可以使用 AutoImageProcessor 获取。有关详细信息,请参阅 LevitImageProcessor.call()。 - 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.ImageClassifierOutputWithNoAttention 或 tuple(torch.FloatTensor)
一个 transformers.modeling_outputs.ImageClassifierOutputWithNoAttention 或一个 torch.FloatTensor
元组(如果传递 return_dict=False
或者 config.return_dict=False
),包含根据配置 (LevitConfig) 和输入的不同元素。
- 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, num_channels, height, width)
。模型在每个阶段输出处的隐藏状态(也称为特征图)。
The LevitForImageClassification 正向方法,覆盖了 __call__
特殊方法。
虽然正向传递的配方需要在此函数中定义,但之后应该调用 Module
实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者则默默地忽略它们。
示例
>>> from transformers import AutoImageProcessor, LevitForImageClassification
>>> 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("facebook/levit-128S")
>>> model = LevitForImageClassification.from_pretrained("facebook/levit-128S")
>>> 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])
tabby, tabby cat
LevitForImageClassificationWithTeacher
class transformers.LevitForImageClassificationWithTeacher
< 源代码 >( config )
参数
- config (LevitConfig) — 模型配置类,包含模型的所有参数。使用配置文件初始化不会加载与模型相关的权重,只加载配置。查看 from_pretrained() 方法以加载模型权重。
具有图像分类头的 LeViT 模型转换器(在最终隐藏状态之上有一个线性层,在蒸馏令牌的最终隐藏状态之上有一个线性层)例如 ImageNet。 .. warning:: 此模型仅支持推理。目前还不支持使用蒸馏(即使用教师)进行微调。
此模型是一个 PyTorch torch.nn.Module 子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档了解有关一般用法和行为的所有事宜。
forward
< 源代码 > ( pixel_values: FloatTensor = None output_hidden_states: Optional = None return_dict: Optional = None ) → transformers.models.levit.modeling_levit.LevitForImageClassificationWithTeacherOutput
或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 像素值。可以使用 AutoImageProcessor 获取像素值。查看 LevitImageProcessor.call() 获取详细信息。 - output_hidden_states (
bool
,可选) — 是否返回所有层的隐藏状态。查看返回张量中的hidden_states
获取更多详细信息。 - return_dict (
bool
,可选) — 是否返回一个 ModelOutput 而不是一个普通元组。
返回
transformers.models.levit.modeling_levit.LevitForImageClassificationWithTeacherOutput
或 tuple(torch.FloatTensor)
一个 transformers.models.levit.modeling_levit.LevitForImageClassificationWithTeacherOutput
或一个 torch.FloatTensor
元组(如果传递 return_dict=False
或者 config.return_dict=False
),包含根据配置 (LevitConfig) 和输入的不同元素。
- logits (
torch.FloatTensor
形状为(batch_size, config.num_labels)
) — 预测分数,为cls_logits
和distillation_logits
的平均值。 - cls_logits (
torch.FloatTensor
形状为(batch_size, config.num_labels)
) — 分类头的预测分数(即分类令牌的最终隐藏状态之上的线性层)。 - distillation_logits (
torch.FloatTensor
形状为(batch_size, config.num_labels)
) — 蒸馏头的预测分数(即蒸馏令牌的最终隐藏状态之上的线性层)。 - hidden_states (
tuple(torch.FloatTensor)
, 可选,在传递output_hidden_states=True
或config.output_hidden_states=True
时返回) —torch.FloatTensor
元组(一个用于嵌入输出,一个用于每一层的输出),形状为(batch_size, sequence_length, hidden_size)
。模型在每一层输出的隐藏状态,以及初始嵌入输出。
LevitForImageClassificationWithTeacher 前向方法覆盖了__call__
特殊方法。
虽然正向传递的配方需要在此函数中定义,但之后应该调用 Module
实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者则默默地忽略它们。
示例
>>> from transformers import AutoImageProcessor, LevitForImageClassificationWithTeacher
>>> 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("facebook/levit-128S")
>>> model = LevitForImageClassificationWithTeacher.from_pretrained("facebook/levit-128S")
>>> 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])
tabby, tabby cat