Vision Transformer(vit)的主干
图解:

代码:
class VisionTransformer(nn.Module):def __init__(self, img_size=224, patch_size=16, in_c=3, num_classes=1000,embed_dim=768, depth=12, num_heads=12, mlp_ratio=4.0, qkv_bias=True,qk_scale=None, representation_size=None, distilled=False, drop_ratio=0.,attn_drop_ratio=0., drop_path_ratio=0., embed_layer=PatchEmbed, norm_layer=None,act_layer=None):"""Args:img_size (int, tuple): input image size
#输入图像的大小,通常是 224 或其他标准尺寸patch_size (int, tuple): patch size
#每个块(patch)的大小,例如 16x16in_c (int): number of input channels
#输入图像的通道数,RGB 图像是 3num_classes (int): number of classes for classification head
#最终分类的类别数,默认 1000 类embed_dim (int): embedding dimension
#嵌入维度,即每个 patch 被映射到的向量的维度,默认是 768depth (int): depth of transformer
#Transformer 的深度,即堆叠的块(Block)数量。num_heads (int): number of attention heads
#注意力头的数量,默认设为 12mlp_ratio (int): ratio of mlp hidden dim to embedding dim
# MLP 隐藏层的维度与嵌入维度的比例。qkv_bias (bool): enable bias for qkv if True
#是否为 QKV(查询、键、值)矩阵添加偏置qk_scale (float): override default qk scale of head_dim ** -0.5 if set
#如果设定,将会覆盖默认的 qk 缩放因子representation_size (Optional[int]): enable and set representation layer (pre-logits) to this value if set
#如果设置了这个值,将会有一个表示层(pre-logits)distilled (bool): model includes a distillation token and head as in DeiT models
#vit中可以不管这个参数drop_ratio (float): dropout rate
# Dropout 的比例attn_drop_ratio (float): attention dropout rate
#注意力层的 Dropout 比例drop_path_ratio (float): stochastic depth rate
#droppath比例embed_layer (nn.Module): patch embedding layer
#用于嵌入图像的层,默认使用 PatchEmbednorm_layer: (nn.Module): normalization layer
#正则化层,通常是 LayerNorm"""super(VisionTransformer, self).__init__()self.num_classes = num_classesself.num_features = self.embed_dim = embed_dim # num_features for consistency with other models
# 与 embed_dim 保持一致,表示嵌入的维度。self.num_tokens = 2 if distilled else 1
#不管distilled所以distilled=1norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6)
#使用 LayerNorm作为默认的规范化层act_layer = act_layer or nn.GELU
#默认使用 GELU 作为激活函数self.patch_embed = embed_layer(img_size=img_size, patch_size=patch_size, in_c=in_c, embed_dim=embed_dim)
#Embedding层结构num_patches = self.patch_embed.num_patches
#patches的个数self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
#这是用于分类的分类标记(Class Token),它是一个可学习的参数,初始值为零self.dist_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) if distilled else None
#不管distilled所以self.dist_token=Noneself.pos_embed = nn.Parameter(torch.zeros(1, num_patches + self.num_tokens, embed_dim))
#位置编码(Position Embedding)self.pos_drop = nn.Dropout(p=drop_ratio)
#位置编码后的 Dropout 操作dpr = [x.item() for x in torch.linspace(0, drop_path_ratio, depth)] # stochastic depth decay rule
#用于控制每个 Block 的 DropPath 比例self.blocks = nn.Sequential(*[Block(dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,drop_ratio=drop_ratio, attn_drop_ratio=attn_drop_ratio, drop_path_ratio=dpr[i],norm_layer=norm_layer, act_layer=act_layer)for i in range(depth)])
#使用 Block 类构建了Transformer的主体部分,包括注意力和MLP层,并使用残差连接和 DropPath self.norm = norm_layer(embed_dim)
#最后的归一化层,用于 Transformer 输出的处理# Representation layerif representation_size and not distilled:
#设置了 representation_size则会增加一个表示层 pre_logits,not distilled=trueself.has_logits = Trueself.num_features = representation_sizeself.pre_logits = nn.Sequential(OrderedDict([("fc", nn.Linear(embed_dim, representation_size)),("act", nn.Tanh())]))
#pre_logits层结构一个全连接和tanh激活函数else:self.has_logits = Falseself.pre_logits = nn.Identity()# Classifier head(s)self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity()self.head_dist = Noneif distilled:self.head_dist = nn.Linear(self.embed_dim, self.num_classes) if num_classes > 0 else nn.Identity()
#distilled为none不用管# Weight initnn.init.trunc_normal_(self.pos_embed, std=0.02)if self.dist_token is not None:nn.init.trunc_normal_(self.dist_token, std=0.02)nn.init.trunc_normal_(self.cls_token, std=0.02)self.apply(_init_vit_weights)
#权重初始化def forward_features(self, x):# [B, C, H, W] -> [B, num_patches, embed_dim]x = self.patch_embed(x) # [B, 196, 768]
#将输入的图像 x 切分为多个 patch 并嵌入,通过Embedding层# [1, 1, 768] -> [B, 1, 768]cls_token = self.cls_token.expand(x.shape[0], -1, -1)if self.dist_token is None:x = torch.cat((cls_token, x), dim=1) # [B, 197, 768]else:x = torch.cat((cls_token, self.dist_token.expand(x.shape[0], -1, -1), x), dim=1)
#分类标记如果有将cls_token加入,因为dist_token为none,所以在维度1上拼接x = self.pos_drop(x + self.pos_embed)
#添加位置编码并应用 Dropoutx = self.blocks(x)
#通过 Transformer 的 Block 堆叠进行处理x = self.norm(x)
#进行归一化
#vit中self.dist_token is None所以模型只有分类标记 (class token)。if self.dist_token is None:return self.pre_logits(x[:, 0])
#x[:, 0]表示提取分类标记(class token) 的输出向量。这个向量是用于分类任务的主要特征表示。else:return x[:, 0], x[:, 1]def forward(self, x):x = self.forward_features(x)
#首先获取 Transformer 的特征输出if self.head_dist is not None:x, x_dist = self.head(x[0]), self.head_dist(x[1])if self.training and not torch.jit.is_scripting():# during inference, return the average of both classifier predictionsreturn x, x_distelse:return (x + x_dist) / 2else:
#self.head_dist为none只看head层就是最后的全连接层输出为num_classesx = self.head(x)return x
操作:

代码:
# [B, C, H, W] -> [B, num_patches, embed_dim]
x = self.patch_embed(x) # [B, 196, 768]
#将输入的图像 x 切分为多个 patch 并嵌入,通过Embedding层
操作:

代码:
# [1, 1, 768] -> [B, 1, 768]
cls_token = self.cls_token.expand(x.shape[0], -1, -1)
if self.dist_token is None:
x = torch.cat((cls_token, x), dim=1) # [B, 197, 768]
else:
x = torch.cat((cls_token, self.dist_token.expand(x.shape[0], -1, -1), x), dim=1)
#分类标记如果有将cls_token加入,因为dist_token为none,所以在维度1上拼接
操作:

代码:
x = self.pos_drop(x + self.pos_embed)
#添加位置编码并应用 Dropout
操作:

代码:
x = self.blocks(x)
#通过 Transformer 的 Block 堆叠进行处理
x = self.norm(x)
#进行归一化
操作:

代码:
#vit中self.dist_token is None所以模型只有分类标记 (class token)。
if self.dist_token is None:
return self.pre_logits(x[:, 0])
#x[:, 0]表示提取分类标记(class token) 的输出向量。这个向量是用于分类任务的主要特征表示。
else:
return x[:, 0], x[:, 1]
操作:

代码:
#self.head_dist为none只看head层就是最后的全连接层输出为num_classes
x = self.head(x)
分类标记 (Class Token):
是一种特殊的 输入 token,在 Transformer 模型中被用来聚合全局特征。
它在模型中起到了类似于 CNN 中全局池化 (Global Pooling) 的作用,负责从所有 patch 的信息中提取一个全局表示。
这个 token 的输出向量被用作分类任务的特征输入,之后会被送入分类头 (classifier head) 进行最终的类别预测。
embedding层:
Vision Transformer(vit)的Embedding层结构-CSDN博客
Multi-Head Self-Attention:
Vision Transformer(vit)的Multi-Head Self-Attention(多头注意力机制)结构-CSDN博客
MLP模块:
Vision Transformer(vit)的MLP模块-CSDN博客
Encoder block:
Vision Transformer(vit)的Encoder层结构-CSDN博客
详解:Vision Transformer详解-CSDN博客
相关文章:
Vision Transformer(vit)的主干
图解: 代码: class VisionTransformer(nn.Module):def __init__(self, img_size224, patch_size16, in_c3, num_classes1000,embed_dim768, depth12, num_heads12, mlp_ratio4.0, qkv_biasTrue,qk_scaleNone, representation_sizeNone, distilledFalse,…...
手撸了一个文件传输工具
在日常的开发与运维中,文件传输工具是不可或缺的利器。无论是跨服务器传递配置文件,还是快速从一台机器下载日志文件,一个高效、可靠且简单的文件传输工具能够显著提高工作效率。今天,我想分享我自己手撸一个文件传输工具的全过程…...
Java程序调kubernetes(k8s1.30.7)core API简单示例,并解决403权限验证问题,即何进行进行权限授权以及验证
简单记录问题 一、问题描述 希望通过Java程序使用Kubernetes提供的工具包实现对Kubernetes集群core API的调用,但是在高版本上遇见权限验证问题4xx。 <dependency><groupId>io.kubernetes</groupId><artifactId>client-java</artifact…...
java八股-Redis Stream和RocketMQ实现的解决方案
文章目录 Redis Stream方案:ShortLinkStatsSaveProducer.javaShortLinkStatsSaveConsumer.java RocketMQ方案ShortLinkStatsSaveProducer.javaShortLinkStatsSaveConsumer.java Redis Stream方案: ShortLinkStatsSaveProducer.java package com.nageoff…...
第29天 MCU入门
目录 MCU介绍 MCU的组成与作用 电子产品项目开发流程 硬件开发流程 常用元器件初步了解 硬件原理图与PCB板 常见电源符号和名称 电阻 电阻的分类 贴片电阻的封装说明: 色环电阻的计算 贴片电阻阻值计算 上拉电阻与下拉电阻 电容 电容的读数 二极管 LED 灯电路 钳位作…...
【Python网络爬虫笔记】6- 网络爬虫中的Requests库
一、概述 Requests 是一个用 Python 语言编写的、简洁且功能强大的 HTTP 库。它允许开发者方便地发送各种 HTTP 请求,如 GET、POST、PUT、DELETE 等,并且可以轻松地处理请求的响应。这个库在 Python 生态系统中被广泛使用,无论是简单的网页数…...
Linux网络_网络协议_网络传输_网络字节序
一.协议 1.概念 协议(Protocol) 是一组规则和约定,用于定义计算机网络中不同设备之间如何进行通信和数据交换。协议规定了数据的格式、传输方式、传输顺序等详细规则,确保不同设备和系统能够有效地互联互通。 在网络通信中&#…...
浅谈网络 | 应用层之流媒体与P2P协议
目录 流媒体名词系列视频的本质视频压缩编码过程如何在直播中看到帅哥美女?RTMP 协议 P2PP2P 文件下载种子文件 (.torrent)去中心化网络(DHT)哈希值与 DHT 网络DHT 网络是如何查找 流媒体 直播系统组成与协议 近几年直播比较火,…...
css vue vxe-text-ellipsis table 实现多行文本超出隐藏省略
分享 vxe-text-ellipsis table grid 多行文本溢出省略的用法 正常情况下如果需要使用文本超出隐藏,通过 css 就可以完成 overflow: hidden; text-overflow: ellipsis; white-space: nowrap;但是如果需要实现多行文本溢出,就很难实现里,谷歌…...
基于hexo框架的博客搭建流程
这篇博文讲一讲hexo博客的搭建及文章管理,也算是我对于暑假的一个交代 !!!注意:下面的操作是基于你已经安装了node.js和git的前提下进行的,并且拥有github账号 创建一个blog目录 在磁盘任意位置创建一个…...
数据结构-简单排序
一.前提 二.冒泡排序 三.插入排序 #include<iostream> using namespace std; typedef int ElemengType; void Bubble_Sort(ElemengType A[], int N) {for (int p N - 1; p > 0; p--) {int flag 0;for (int i 0; i < p; i) {if (A[i] > A[i 1]) {swap(A[i], …...
三十一:HTTP多种重定向跳转方式的差异
在现代网站开发中,HTTP 重定向是一种常见的技术,用于将用户的请求从一个 URL 跳转到另一个 URL。重定向机制广泛应用于网站迁移、SEO 优化、以及内容管理系统中。不同的 HTTP 状态码代表不同的重定向方式,每种方式的行为和适用场景各有不同。…...
利用Python爬虫精准获取淘宝商品详情的深度解析
在数字化时代,数据的价值日益凸显,尤其是在电子商务领域。淘宝作为中国最大的电商平台之一,拥有海量的商品数据,对于研究市场趋势、分析消费者行为等具有重要意义。本文将详细介绍如何使用Python编写爬虫程序,精准获取…...
架构师的英文:Architect
中文版 软件架构师 的英文是 “Software Architect”。 Software: 软件Architect: 架构师,通常指的是设计和规划某种系统或结构的人。 Software Architect 通常负责软件系统的整体设计、技术选型、架构规划,确保系统的可扩展性、可维护性和高效性等。…...
数据结构 ——— 计数排序算法的实现
目录 计数排序算法的思想 计数排序算法的实现 计数排序算法的思想 遍历数组,找出数组中的最大值 max 和 最小值 min 最大值 max 减去最小值 min 再加 1 得出数组元素的范围 range 利用 range 的大小 malloc 一个 count 数组用来计数 再对 count 数组进行初始化…...
k8s搭建Istio环境,案例pod一直处在Init:CrashLoopBackOff
1 部署calico网络环境,网上去找k8s版本对应的calico的配置文件,k8s2.8.0我用的3.28 2 安装istio环境 curl -L https://istio.io/downloadIstio | sh - # 省略istioctl生效的步骤 source <(istioctl completion zsh) istioctl install --set profile…...
Jenkins升级到最新版本后无法启动
1. 场景还原 最近在web界面将jenkins升级到最新版本后,后台无法启动jenkins服务,服务状态如下: 运行jenkins命令提示invalid Java version jenkins --version jenkins: invalid Java version: java version "1.8.0_202" Java(TM)…...
用户界面创建一个新的运动类型
● 现在我们需要根据我们之前规划的架构步骤来实现在用户界面创建一个运动类型 ● 首先我们在要获取用户在表单中输入的数据 //从表单中获取数据const type inputType.value;const distance inputDistance.value;const duration inputDuration.value;● 然后针对与不同的运动…...
ubuntu防火墙入门(一)——设置服务、关闭端口
本机想通过git clone gitgithub.com:skumra/robotic-grasping.git下载代码,firewall-config中需要为当前区域的防火墙开启SSH服务吗 是的,如果你想通过 git clone gitgithub.com:skumra/robotic-grasping.git 使用 SSH 协议从 GitHub 下载代码࿰…...
分治算法——二分查找(c++)(详解)
大家好,今天进入一个实用算法:分治算法。 1.分治算法介绍 分治算法,大概就是将一个大问题拆解成若干个小问题,将小问题一一解决,大问题也就迎刃而解。它包含了多种算法,比如递归、递推等。这里就讲解一下其…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
