资讯动态

YOLOS:用 ViT 一序列走到底的端到端目标检测模型(Transformers 实现全解析)

发布时间:2026/9/9 14:20:23 来源:尧图企业网站定制
YOLOS用 ViT 一序列走到底的端到端目标检测模型Transformers 实现全解析【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformersYOLOSYou Only Look at One Sequence是本文档对应的核心模型它把 Vision TransformerViT当作主干以最小改动、去掉区域先验的方式完成目标检测任务并达到与传统专用检测框架相近的能力。在 Transformers 仓库中YOLOS 拥有从配置、图像处理器到完整推理/微调接口的一整套实现本文将以仓库文档docs/source/en/model_doc/yolos.md为主体骨架结合源码与测试帮助你掌握用Pipeline/AutoModel快速做目标检测、解读输出结果、理解底层 ViT 变体架构与各类超参的真实含义。YOLOS 概览一次把目标检测看成序列问题YOLOS原论文于 2021-06-01 发表于 Hugging Face 论文页2022-05-02 被贡献进本仓库的核心思想非常直接复用 ViT 结构做目标检测仅做极小改动且不使用任何区域先验region priors。也就是说它不像传统检测框架那样依赖 2D 空间结构先验、anchor 或 proposal而是把整幅图像切成 patch 序列后交给 Transformer 编码器自主学习哪里可能有目标。在这个仓库中YOLOS 的实现位于src/transformers/models/yolos/目录包括configuration_yolos.pyYolosConfig配置类modeling_yolos.pyYolosModel/YolosForObjectDetection等 PyTorch 模型实现image_processing_yolos.py 与 image_processing_pil_yolos.py基于 Torchvision 后端与 PIL 后端的图像处理器convert_yolos_to_pytorch.py原始 checkpoint 转换脚本modular_yolos.py图像处理器与模型的模块化定义源YolosImageProcessor继承自DetrImageProcessor生成类注释见文件头部。模型的贡献者是 nielsr文档推荐的可复现 checkpoint 位于hustvl/yolos-base模型推理示例、配置 docstring 均以其为默认 checkpointmodeling_yolos.py中的端到端示例还使用了hustvl/yolos-tiny。从源码看YOLOS 注意力同时开启了对sdpa、flash_attn、flex_attn的支持见modeling_yolos.py中_supports_sdpa True、_supports_flash_attn True、_supports_flex_attn True这也对应原文档顶部的 FlashAttention / SDPA 徽标。快速上手跑通一次目标检测推理原文档给出了两种完全等价的推理入口Pipeline与AutoModel。二者底层共用同一个模型与图像预处理链路下面分别展开。方式一用 object-detection PipelinePipeline方式最省事只需一行构造加一行调用from transformers import pipeline detector pipeline( taskobject-detection, modelhustvl/yolos-base, device0 # 指定使用第 0 号 GPU ) detector(https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png)要点说明taskobject-detection会由仓库的 pipeline 注册表自动找到适用于检测任务的模型类与后处理逻辑model直接指定 checkpoint 名hustvl/yolos-base首次运行会下载权重与preprocessor_config.jsondevice0将模型放置到 GPU若没有 GPU省略该参数即可在 CPU 上运行。方式二用 AutoModel 手动控制完整链路手动方式能让你看到每一步发生了什么图像下载 → 预处理成张量 → 前向传播 → 解码出目标框与类别。import requests import torch from PIL import Image from transformers import AutoImageProcessor, AutoModelForObjectDetection processor AutoImageProcessor.from_pretrained(hustvl/yolos-base) model AutoModelForObjectDetection.from_pretrained( hustvl/yolos-base, attn_implementationsdpa, # 使用 PyTorch SDPA 注意力 device_mapauto, # 自动分配设备 ) url https://huggingface.co/datasets/Narsil/image_dummy/raw/main/parrots.png image Image.open(requests.get(url, streamTrue).raw).convert(RGB) inputs processor(imagesimage, return_tensorspt).to(model.device) with torch.no_grad(): outputs model(**inputs) logits outputs.logits.softmax(-1) # 对每个 query 的类别打分归一化 scores, labels logits[..., :-1].max(-1) # 取有目标类别的最高分与对应类别 boxes outputs.pred_boxes # 归一化中心格式 (cx, cy, w, h) threshold 0.3 keep scores[0] threshold filtered_scores scores[0][keep] filtered_labels labels[0][keep] filtered_boxes boxes[0][keep] # 把归一化框还原成像素坐标 width, height image.size pixel_boxes filtered_boxes * torch.tensor([width, height, width, height], deviceboxes.device) for score, label, box in zip(filtered_scores, filtered_labels, pixel_boxes): x0, y0, x1, y1 box.tolist() print(fLabel {model.config.id2label[label.item()]}: {score:.2f} at [{x0:.0f}, {y0:.0f}, {x1:.0f}, {y1:.0f}])这段代码里有几个必须理解的细节为什么logits[..., :-1].max(-1)YOLOS 每个检测 query 会输出num_classes 1个 logit多出来的 1 个是无目标no-object类。去掉它再取 max得到的就是每个 query 在当前图像上预测的目标类别与置信度为什么 pred_boxes 要乘[width, height, width, height]模型输出的框是归一化相对坐标格式为(center_x, center_y, width, height)值域[0, 1]见YolosObjectDetectionOutput的字段说明。乘以图像宽高后才变成可直接用于可视化的像素坐标with torch.no_grad()用于推理时节省显存attn_implementationsdpa与device_mapauto均为可选优化参数。下面给出一个更省事的替代方案——直接调用image_processor.post_process_object_detection它会替你把 softmax、阈值过滤、坐标还原全部做完。该示例来自YolosForObjectDetection.forward的 docstring源码在 modeling_yolos.pyfrom transformers import AutoImageProcessor, AutoModelForObjectDetection import torch from PIL import Image 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(hustvl/yolos-tiny) model AutoModelForObjectDetection.from_pretrained(hustvl/yolos-tiny) inputs image_processor(imagesimage, return_tensorspt) outputs model(**inputs) # 转成 Pascal VOC 格式 (xmin, ymin, xmax, ymax) target_sizes torch.tensor([image.size[::-1]]) # (height, width) results image_processor.post_process_object_detection(outputs, threshold0.9, target_sizestarget_sizes)[0] for score, label, box in zip(results[scores], results[labels], results[boxes]): box [round(i, 2) for i in box.tolist()] print(fDetected {model.config.id2label[label.item()]} with confidence f{round(score.item(), 3)} at location {box})参考输出来自源码 docstringDetected remote with confidence 0.991 at location [46.48, 72.78, 178.98, 119.3] Detected remote with confidence 0.908 at location [336.48, 79.27, 368.23, 192.36] Detected cat with confidence 0.934 at location [337.18, 18.06, 638.14, 373.09] Detected cat with confidence 0.979 at location [10.93, 53.74, 313.41, 470.67] Detected remote with confidence 0.974 at location [41.63, 72.23, 178.09, 119.99]注意target_sizes的语义是(height, width)这与PIL.Image.size(width, height)正好相反因此示例中用了image.size[::-1]。YolosImageProcessor图像与标注的唯一入口原文档的 Notes 明确指出UseYolosImageProcessorfor preparing images (and optional targets) for the model. Contrary to DETR, YOLOS doesnt require apixel_mask.仓库中的实现把这句话落到了类上图像处理由YolosImageProcessorTorchvision 后端image_processing_yolos.py负责另有YolosImageProcessorPilPIL 后端image_processing_pil_yolos.py提供preprocess、pad、post_process_object_detection等 Pillow 生态方法。两个类都由模块化源 modular_yolos.py 自动生成后者直接继承DetrImageProcessor/DetrImageProcessorPil。默认预处理流水线从YolosImageProcessor的类属性image_processing_yolos.py可以看到默认配置属性默认值含义resampleBILINEAR缩放插值方式image_mean/image_stdImageNet 默认均值/方差归一化使用的统计量formatCOCO_DETECTION标注数据格式do_resize/do_rescale/do_normalize/do_pad均为True依次执行缩放、除以 255、归一化、paddingsize{shortest_edge: 800, longest_edge: 1333}保持宽高比地将短边与长边限制在给定值内default_to_squareFalse不做正方形强制缩放model_input_names[pixel_values, pixel_mask]声明模型可接收的输入名其中size有三种写法在resize的 docstring 中有完整说明{height: int, width: int}精确缩放到该尺寸不保留宽高比{shortest_edge: int, longest_edge: int}保持宽高比短边 ≤shortest_edge、长边 ≤longest_edge默认走这一支这也是检测任务常见的 resize 策略{max_height: int, max_width: int}保持宽高比高度 ≤max_height且宽度 ≤max_width。训练标注与 padding 的联动训练fine-tuning时你需要把 COCO 格式标注喂给图像处理器让标注与图像一起经受缩放、填充。关键行为支持的标注格式为coco_detection与coco_panopticimage_processing_pil_yolos.py中的SUPPORTED_ANNOTATION_FORMATSdo_convert_annotations默认True会把边界框坐标转换为 YOLOS 期望的(center_x, center_y, width, height)且值域在[0, 1]的格式见YolosImageProcessorKwargs的字段说明padimage_processing_pil_yolos.py在批内尺寸不一致时对图像做常数填充并同步更新标注框同时生成pixel_mask1 表示有效像素、0 表示填充区但模型前向并不消费 pixel_mask——这与文档YOLOS doesnt require a pixel_mask一致填充与 mask 主要服务于训练数据组织的需要。post_process_object_detection 的输出契约推理解码由post_process_object_detection(outputs, threshold0.5, target_sizesNone)image_processing_pil_yolos.py承担其内部逻辑清晰对应我们在 AutoModel 示例里手写的那几步对outputs.logits做 softmax去掉最后一列no-object后按类别取 max得到每个 query 的scores与labels用center_to_corners_format把(cx, cy, w, h)转成(x0, y0, x1, y1)若给定target_sizesshape(batch_size, 2)或(height, width)元组列表把相对坐标乘回像素坐标若缺省则不还原按threshold过滤后返回每张图像一个字典{scores: ..., labels: ..., boxes: ...}。方法仅支持 PyTorch源码中有requires(backends(torch,))与运行时的requires_backends(self, [torch])双重校验传入的outputs需要是YolosObjectDetectionOutput或其等价物。模型输出结构解读YolosObjectDetectionOutputYolosForObjectDetection.forward返回YolosObjectDetectionOutput定义于 modeling_yolos.py字段如下字段形状 / 说明loss标量损失仅在传入labels时返回由类别负对数似然交叉熵与边界框损失L1 与 generalized IoU 的线性组合构成loss_dict分项损失字典便于日志记录logits(batch_size, num_queries, num_classes 1)每个 query 的分类 logit含 no-objectpred_boxes(batch_size, num_queries, 4)归一化框(cx, cy, w, h)值域[0, 1]相对各自图像尺寸不含 padding 影响auxiliary_outputs仅当config.auxiliary_lossTrue且传入 labels 时返回是各中间层检测头输出的{logits, pred_boxes}列表last_hidden_state/hidden_states/attentionsViT 编码器的输出隐状态、每层隐状态与注意力矩阵按需返回从源码看懂 YOLOS 架构ViT 的检测化改造YOLOS 的网络结构本质是一个逐层给编码器加料的 ViT改动集中在以下四处可在 modeling_yolos.py 中逐一核对1. 三类 tokenCLS Patch Detection TokensYolosEmbeddings第 76-115 行把输入序列构造成[CLS token] [patch 序列] [detection tokens]三段的拼接self.cls_token nn.Parameter(torch.zeros(1, 1, config.hidden_size)) self.detection_tokens nn.Parameter(torch.zeros(1, config.num_detection_tokens, config.hidden_size)) ... embeddings torch.cat((cls_tokens, embeddings, detection_tokens), dim1)其中cls_token延续自 ViT 的分类习惯detection_tokens是可学习的检测锚默认 100 个即num_detection_tokens它们像待填空的检测槽位一样与 patch 一起参与所有编码器层的信息交换。位置编码长度为num_patches num_detection_tokens 1。2. 双份可插拔位置编码因为 YOLOS 要支持在任意输入分辨率下工作而预训练位置编码绑定了固定的 patch 网格作者引入了两层位置编码插值InterpolateInitialPositionEmbeddings第 118-144 行在输入侧把 patch 位置编码 reshape 成 2D 网格用nn.functional.interpolate(..., modebicubic)插值到当前输入对应的新网格再拼回 CLS 与 detection token 的位置编码InterpolateMidPositionEmbeddings第 147-177 行对应use_mid_position_embeddingsTrue的中层位置编码。YolosEncoder会为前num_hidden_layers - 1层各准备一份可学习的mid_position_embeddings形状(layers-1, 1, seq_length, hidden_size)并在每一层 Transformer 之后注入插值后的位置信息for i, layer_module in enumerate(self.layer): hidden_states layer_module(hidden_states) if self.config.use_mid_position_embeddings: if i (self.config.num_hidden_layers - 1): hidden_states hidden_states interpolated_mid_position_embeddings[i]这说明该配置项的本质是让 2D 空间信息不止出现一次而是持续地在各层刷新位置先验缓解 ViT 缺乏空间先验带来的检测定位困难。3. Pre-LN 的编码器层YolosLayer第 364-395 行遵循 timm 风格 Block先layernorm_before→ 自注意力残差 ①→layernorm_after→ MLP残差 ②。即注意力与 MLP 之前都做 LayerNorm这与 DETR 代码家族的Pre-LN写法一致。注意力本身与 ViT 同源源码注释标明Copied from ...modeling_vit.ViTAttention with ViT-Yolos并通过ALL_ATTENTION_FUNCTIONS分发到 eager / SDPA / FlashAttention / FlexAttention 实现。4. 检测头从 detection tokens 中读出目标YolosForObjectDetection第 544-652 行在YolosModel之上挂了两只 3 层 MLP 头YolosMLPPredictionHead复用自 DETR 的实现含 ReLU 隐层self.vit YolosModel(config, add_pooling_layerFalse) # 纯编码器不带池化 self.class_labels_classifier YolosMLPPredictionHead( input_dimconfig.hidden_size, hidden_dimconfig.hidden_size, output_dimconfig.num_labels 1, num_layers3, ) self.bbox_predictor YolosMLPPredictionHead( input_dimconfig.hidden_size, hidden_dimconfig.hidden_size, output_dim4, num_layers3, )前向时模型丢弃 CLS 与 patch 位置只取最后一层编码器输出的最后num_detection_tokens个 token即 detection tokens 位置的隐状态送入检测头sequence_output outputs.last_hidden_state sequence_output sequence_output[:, -self.config.num_detection_tokens :, :] logits self.class_labels_classifier(sequence_output) pred_boxes self.bbox_predictor(sequence_output).sigmoid() # sigmoid 保证归一化pred_boxes末尾的.sigmoid()使输出恒在[0, 1]对应输出结构中的归一化 (cx, cy, w, h)。若开启auxiliary_lossTrue且提供labels模型还会取各中间层隐状态额外计算一组中间检测结果_set_aux_loss把各层输出打包成[{logits, pred_boxes}, ...]配合训练时使用的二分图匹配损失见src/transformers/loss/loss_for_object_detection.py共同监督。注基础版YolosModel会额外返回pooler_output对第一个 token 也就是 CLS 做Linear Tanh见YolosPooler。而YolosForObjectDetection构造时传入add_pooling_layerFalse因此检测链路中不需要该池化层。用代码配置 YOLOSYolosConfig 全参数说明默认配置文档化代码位于 configuration_yolos.pymodel_type yolos。除继承自PreTrainedConfig的通用字段如num_labels、id2label外关键字段如下ViT 主干参数与 ViT 对齐参数默认值说明hidden_size768隐层维度num_hidden_layers12编码器层数num_attention_heads12注意力头数intermediate_size3072MLP 中间层维度hidden_actgeluMLP 激活函数hidden_dropout_prob0.0全连接 dropoutattention_probs_dropout_prob0.0注意力 dropoutinitializer_range0.02参数初始化范围layer_norm_eps1e-12LayerNorm epsilonimage_size(512, 864)训练用默认输入分辨率patch 网格据此计算patch_size16patch 边长num_channels3输入通道数RGBqkv_biasTrueQ/K/V 投影是否带 biasYOLOS 专属参数参数默认值说明num_detection_tokens100检测 token 数量即最大可输出目标数解码时每图最多给 100 个框候选use_mid_position_embeddingsTrue是否使用各中间层的位置编码注入auxiliary_lossFalse是否开启中间层辅助检测头损失class_cost1二分图匹配中类别匹配代价bbox_cost5二分图匹配中 L1 框代价权重giou_cost2二分图匹配中 GIoU 代价权重bbox_loss_coefficient5总损失中 L1 框损失的系数giou_loss_coefficient2总损失中 GIoU 损失的系数eos_coefficient0.1no-object 类别损失的缩放系数程序化创建与读取配置与所有PreTrainedConfig一样你可以脱离 Hub 从零创建并检查configuration_yolos.pyfrom transformers import YolosConfig, YolosModel # 初始化一个 hustvl/yolos-base 风格的配置 configuration YolosConfig() # 用随机权重初始化模型仅用于实验/训练不做推理 model YolosModel(configuration) # 回读配置 configuration model.config配置字段的实际消费点包括num_detection_tokens决定YolosEmbeddings与YolosEncoder中 detection token 及位置编码的序列长度auxiliary_loss/ 各*_cost/*_coefficient决定训练损失函数与标签分配二分图匹配行为use_mid_position_embeddings控制YolosEncoder是否创建mid_position_embeddings参数。训练与微调注意事项labels 格式若传入labelslist[Dict]长度为 batch_size每个字典至少要含class_labelstorch.LongTensor长度等于该图目标数与boxestorch.FloatTensor形状(num_boxes, 4)两个键供损失函数计算二分图匹配损失此时返回的YolosObjectDetectionOutput会带上loss与loss_dict。动态分辨率得益于初始与中层两套位置编码插值微调时可以直接用image_processor处理任意长宽比图像短边/长边被限制在 800/1333 以内无需把图像缩放到固定方形。梯度检查点YolosPreTrainedModel声明supports_gradient_checkpointing True长序列训练下可考虑开启以节省显存。对自定义数据集进行推理与微调的 Notebook 指引见原文档 Resources 部分NielsRogge 的 Transformers-Tutorials 仓库中专门整理了一组 YOLOS notebook可在本地参考其做法搭建 COCO 风格数据集训练流程。如何在仓库里进一步验证与扩展模型行为测试test_modeling_yolos.py 覆盖了前向输出形状、与参考 checkpoint 的数值对齐、辅助损失、梯度检查点等图像处理测试test_image_processing_yolos.py 验证 resize/pad/标注同步、后处理坐标换算等如果你要研究它与 DETR 的关系匹配代价、损失函数高度同源可对照查看 detr.md 模型文档 与src/transformers/loss/loss_for_object_detection.py想从 ViT 的角度理解主干结构可阅读 vit.md 模型文档。总结一句话YOLOS 证明了目标检测并不必须依赖卷积式或区域式的 2D 先验——一个看得懂序列的 ViT配上一组可学习 detection tokens 与逐层位置编码刷新就能以端到端的方式完成检测。在 Transformers 仓库中这套设计已经被封装为开箱即用的Pipeline/AutoModel/AutoImageProcessor全链路从上面的推理代码到配置调整都可以直接在本地落地验证。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价