ViT 模型讲解
文章目录
- 一、模型的诞生背景
- 1.1 背景
- 1.2 ViT 的提出(2020年)
- 二、模型架构
- 2.1 patch
- 2.2 模型结构
- 2.2.1 数据 shape 变化
- 2.2.2 代码示例
- 2.2.3 模型结构图
- 2.3 关于空间信息
- 三、实验
- 3.1 主要实验
- 3.2 消融实验
- 四、先验问题
- 4.1 归纳偏置
- 4.2 先验or大数据???
- 五、补充
- 5.1 二维的位置编码
- 5.2 挖坑
Vision Transformer(ViT)是一个开创性的计算机视觉模型,它首次成功地将Transformer架构引入到视觉领域,打破了长期以来以卷积神经网络(CNN)为主导的局面。
一、模型的诞生背景
1.1 背景
-
Transformer 在 NLP 的成功
Transformer 架构由 Vaswani 等人在 2017 年提出(论文《Attention is All You Need》),它在 NLP 中(比如 BERT、GPT)表现非常出色。 -
CV 领域的主流仍是 CNN
视觉领域长期由 CNN 主导(如 ResNet、EfficientNet 等),这些模型通过局部卷积提取空间信息。 -
挑战:Transformer 在图像上的应用
图像不像文本那样是离散的序列,Transformer 需要序列化输入,因此直接用 Transformer 处理图像并不直观。
1.2 ViT 的提出(2020年)
论文:“An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale”
作者:Google Research
意义:首次证明了,在足够的数据和算力支持下,Transformer 可以在图像分类任务中超过最好的 CNN。
二、模型架构
2.1 patch
假设输入是一批图像,维度为:
(B, H, W, C)
- B = batch size
- H = 高(比如 224)
- W = 宽(比如 224)
- C = 通道数(比如 RGB → 3)
我们想让 Transformer 接收这个图像,但问题:Transformer 要求输入是序列: 每个 token 有一个 embedding,形状应该是:
(B, N, D)
- N = 序列长度(token 数)
- D = 每个 token 的 embedding 维度
那我们能不能把图像 reshape 成这种形状呢?
尝试直接 reshape:把每个像素当作一个 token?
(B, H, W, C) → reshape → (B, H*W, C)
比如说:
B = 32
H = W = 224
C = 3→ (32, 224*224, 3) = (32, 50176, 3)
问题:序列长度 N = 50,176,太长了!
- Transformer 的注意力是 O(N²),即
O(50176²) ≈ 2.5 billion
,显存、计算量巨大! - 实际上,BERT 这样的 NLP 模型一般处理的序列长度才 512 左右。
这就是 ViT 的关键创新:
把图像划分为 Patch,每个 Patch 当成一个 token。
我们将图像划分为大小为 P x P
的 patch,比如 16 x 16
。
-
则每个 patch 的像素数为:
P*P*C = 16*16*3 = 768
-
每张图像总共包含 patch 数:
N = (H / P) * (W / P) = (224 / 16)^2 = 14 * 14 = 196
-
所以 reshape 后的数据维度是:
(B, 14, 14, 16, 16, 3) -> (B, 14*14, 16*16*3)
2.2 模型结构
设定一个典型 ViT 的输入参数如下:
- 图像大小:
224 x 224 x 3
(高×宽×通道)- Patch 大小:
16 x 16
- 输出维度(embedding dim):
768
- Patch 数量:
(224 / 16)^2 = 14 x 14 = 196
- Transformer 层数:
12
- Head 数:
12
- MLP Head 输出类别数:
1000
(如 ImageNet)
2.2.1 数据 shape 变化
数据 shape 流程(标准 ViT)
Input Image: (3, 224, 224)↓
1. Split into Patches (16x16) → 每个 patch 展平成向量:得到 (196, 3*16*16) = (196, 768)↓
2. Linear Projection of Patches → Embedding:每个 patch 向量映射为 (196, 768)↓
3. 加入 CLS token:+ 1 个 token,shape 变为 (197, 768)↓
4. 加入 Position Embedding:shape 仍是 (197, 768)↓
5. 输入 Transformer Encoder(L 层):每层输出:仍是 (197, 768)Attention → FFN → Add & Norm↓
6. 取 CLS token 表示:(1, 768)↓
7. 分类头(MLP Head):Linear(768 → 1000)得到 (1, 1000)↓
8. softmax 输出:1000 类别概率
架构图(图示)
┌─────────────────────┐Image │ Input Image │(3, 224, 224) │ (3 x 224 x 224) │└────────┬────────────┘↓┌────────────────────────┐│ Split into Patches ││ 16x16 patches ││ 196 patches total │└────────┬───────────────┘↓┌─────────────────────────────┐│ Flatten + Linear Projection ││ Each patch → (1 x 768) ││ → (196 x 768) │└────────┬────────────────────┘↓┌──────────────────────────┐│ Add CLS Token (1 x 768) ││ → (197 x 768) │└────────┬─────────────────┘↓┌───────────────────────────────┐│ Add Positional Embedding ││ → (197 x 768) │└────────┬──────────────────────┘↓┌────────────────────────────┐│ L x Transformer Encoder ││ (Self-Attn + FFN) ││ Output: (197 x 768) │└────────┬───────────────────┘↓┌──────────────────────────────┐│ Take [CLS] token (1 x 768) │└────────┬─────────────────────┘↓┌─────────────────────────────┐│ MLP Head → Class logits ││ Linear: 768 → 1000 │└────────┬────────────────────┘↓Output: (1 x 1000)
2.2.2 代码示例
PyTorch 实现的示例
# 假设输入图像 batch 为 (B, 3, 224, 224)
B = 32
patch_size = 16
embed_dim = 768
num_patches = (224 // patch_size) ** 2 # 14 * 14 = 196# 1. Patch embedding
x = torch.randn(B, 3, 224, 224)
patches = x.unfold(2, patch_size, patch_size).unfold(3, patch_size, patch_size)
patches = patches.contiguous().view(B, 3, -1, patch_size, patch_size)
patches = patches.permute(0, 2, 1, 3, 4).contiguous().view(B, num_patches, -1) # (B, 196, 768)# 2. Linear projection + Add cls + pos embedding → (B, 197, 768)
# 3. Transformer blocks → 输出 shape 不变 (B, 197, 768)
# 4. MLP Head → (B, 1000)
2.2.3 模型结构图
2.3 关于空间信息
ViT 把每个 patch flatten 后再当作 token 输入,是否会丢失空间信息?模型还能理解图像的空间结构吗?
我们来逐步拆解这个问题。
原图 → (B, 224, 224, 3)
patch → 划成 (B, 14, 14, 16, 16, 3)
flatten → (B, 196, 768) ← 每个 patch 被完全拉平
也就是说:
- 每个
16x16
patch 被视为一个 768 维向量,送进 Transformer。 - 在 patch 内部,像素之间的 2D 空间关系已经丢失了(被 flatten)。
这其实是一个 trade-off:局部 vs 全局
CNN 是局部建模:
- 用卷积核滑动 → 保留局部空间结构
- 多层堆叠 → 扩展感受野
ViT 是全局建模:
- 每个 patch 被视作一个整体 token,不知道 patch 内部的位置信息
- 但可以通过 self-attention 在patch 之间建模全局关系
ViT 是如何弥补空间结构缺失的?
-
位置编码(Positional Embedding)
虽然 patch 本身是被 flatten 的,但 ViT 给每个 patch 加了一个位置向量:
patch_embeddings + positional_embeddings
- 这些 positional embeddings 是可学习参数,形状为
(num_patches, embed_dim)
,比如(196, 768)
- 它告诉模型:第几个 patch 是图像的哪一部分(左上、右下、中间…)
- 这些 positional embeddings 是可学习参数,形状为
-
Self-Attention 建模 patch 间的关系
虽然每个 patch 内部的空间结构被 flatten 掉了,但 ViT 有全局的 self-attention:
- 每个 patch 可以“看到”所有其他 patch
- 自注意力机制可以自动学习到:哪些 patch 是连续的、有相似内容的、有上下文关系的
patch之间有位置编码,那patch内部的空间信息就真的没了吗?
基本上……是的,ViT 在标准设计中:
完全忽略了 patch 内部像素的空间结构(除了间接靠大量数据让模型学到某些模式)
这就是为什么后续很多改进型 ViT 试图引入更精细的空间建模,比如:
-
CNN + ViT 结合
比如CvT
,ConViT
:在 embedding 之前加一层卷积提取局部特征。 -
局部注意力 / 层次结构
比如Swin Transformer
:只在局部窗口内做注意力,保留 patch 内空间结构。 -
使用 Patch Token Hierarchy
把图像分层次进行划分,像 CNN 的 downsampling 一样逐层抽象。 -
位置编码增强
有些 ViT 用坐标编码(x, y)拼进去,或者使用相对位置编码(像 NLP 中那样)。
问题 | 是否存在 | 弥补方式 |
---|---|---|
Patch 内部 flatten 导致空间信息丢失 | 存在 | 无法恢复(在标准 ViT 中) |
Patch 之间的空间结构 | 被建模 | 位置编码 + attention |
模型理解图像结构的能力 | 部分靠 attention 建模 | 更依赖大规模预训练数据 |
三、实验
3.1 主要实验
实验 | 变量 | 设置 | 结果/结论 |
---|---|---|---|
ViT vs ResNet | 模型结构 | ViT-B/16 vs ResNet152x4 | 在 ImageNet-21k 上 ViT > ResNet,参数更少,性能更高 |
不同预训练数据 | 数据规模 | ImageNet (1M) vs IN-21k (14M) vs JFT-300M (300M) | ViT 在大数据集上才训练得好,小数据集会过拟合 |
小样本迁移能力 | Fine-tune 到小数据集 | CIFAR, Flowers, VTAB | ViT 表现良好,迁移性强 |
与其他模型迁移对比 | 方法对比 | ResNet vs ViT | ViT 表现更好,但需要预训练支持 |
3.2 消融实验
- Patch Size 影响
- Patch size: 8x8、16x16、32x32
- 越小越好(序列变长,表达力强)
- 但计算量 ↑,内存占用 ↑
- 16x16 是最佳平衡
结论:小 patch 能提升性能,但要付出代价。
- 位置编码
- 加 vs 不加
- 绝对位置 vs 相对位置
- 插值位置编码支持不同分辨率
结论:必须加位置编码,且可插值适配不同输入大小。
- MLP Head 设计
- Linear head vs 多层 MLP
- 结果几乎一样
结论:简单的 linear classifier 足以。
- LayerNorm 放置位置
- Pre-LN(LN 在 Attention 前) vs Post-LN
- Pre-LN 更稳定,训练更好收敛
结论:Pre-LN 更适合 ViT。
- Class Token 的作用
- 类似 BERT 的 [CLS]
- 每层 attention 都能访问,用于最终分类
结论:必须有,模型依赖它来提取全局特征。
- 是否需要强数据增强 / 自监督
- 加了 CutMix、RandAug 等 → 效果提升小
- ViT 不如 CNN 那么依赖数据增强
结论:数据增强对 ViT 不敏感,但对 CNN 很关键。
- 是否使用卷积替代 patch embedding
- 用卷积提 patch embedding 没有显著提升
结论:线性投影就可以,无需 CNN 特征提取头。
关键有效设计
组件 | 作用 | 是否关键 |
---|---|---|
Patch embedding | 降低序列长度 | 1 |
Positional Encoding | 建模空间顺序 | 1 |
Class Token | 输出图像全局表征 | 1 |
Self-Attention | 全局建模 | 1 |
Pre-LN 架构 | 稳定训练 | 1 |
大规模数据预训练 | 避免过拟合 | 111 |
可有可无的点
组件 | 作用 | 结论 |
---|---|---|
强数据增强 | 抗扰动、泛化 | 提升小,可有可无 |
MLP Head | 增加判别能力 | 线性 head 足够 |
卷积前置层 | 提取局部特征 | 变化不大 |
四、先验问题
4.1 归纳偏置
“先验(prior)”在深度学习里,其实就是“归纳偏置(inductive bias)”的一个通俗说法。
归纳偏置(Inductive Bias):指的是一个学习算法在数据不足时,如何做出合理泛化的偏好或假设。
简化理解:
当我看不到所有数据的时候,我默认事情是这样的 —— 这就是我的归纳偏置。
举几个通俗例子:
模型 | 归纳偏置 / 先验 |
---|---|
CNN | 局部连接、权重共享、平移不变性(空间先验) |
RNN/LSTM | 时间顺序相关性 |
GNN | 图结构邻居影响中心点 |
Transformer | 无特别强的归纳偏置(完全数据驱动) |
先验 = 归纳偏置 = 模型对现实世界的一种结构性假设
4.2 先验or大数据???
ViT 完全基于 Transformer,没有 CNN 的结构先验:
- 不知道局部区域重要;
- 不知道平移后的图还是同一个图;
- 所以 ViT 必须通过大量数据自己“悟出这些结构”;
- 而 CNN 天生就有这些“归纳偏置”植入其中。
ViT 证明了一件事:在足够大、足够多样的数据下,模型可以学出先验,从而超越“手工嵌入先验”的模型。
在 ViT 的实验中:
数据集 | 模型表现 |
---|---|
ImageNet-1k | ViT 差于 CNN |
ImageNet-21k | ViT ≈ CNN |
JFT-300M | ViT > CNN(显著) |
这清楚地说明了:
- 在小数据(ImageNet-1k)下,CNN 的归纳偏置(如局部性、平移不变)提供了巨大优势;
- 在大数据(JFT-300M)下,ViT 能通过学习自动获得这些归纳偏置(甚至更多),从而反超 CNN;
- 也就是说:数据能“弥补”先验的缺失,甚至最终超越它。
所以,ViT 是一个“用海量数据和大模型学到归纳偏置”的典范。
但这并不是说“先验没用了”!
ViT 不是在否定先验的价值,而是在提出一个新的平衡:
归纳偏置(先验)和数据之间,是可以相互替代的,但各有代价。
| 有强归纳偏置(CNN) | 少数据、高效训练、泛化强,但灵活性差 |
| 无归纳偏置(ViT) | 灵活、能力上限高,但数据、算力需求大 |
所以:
- CNN 很适合“小数据集、低资源”的任务;
- ViT 更适合“数据丰富、资源充足”的大规模学习;
- ViT 的出现是因为 Google 拥有海量数据和TPU,大部分人是玩不起纯 ViT 的。
ViT 后续的发展说明了:先验和数据,是可以结合的
很多 ViT 变体其实都在 “加回先验”:
- Swin Transformer:加入了局部窗口(locality),有点像滑动卷积核;
- CvT、LeViT:在前几层用卷积替代patch embedding;
- DeiT + distillation:用CNN当teacher,把先验“蒸馏”给ViT;
- Token2Token ViT:加了局部token聚合结构;
- ConvNeXt:是个有Transformer设计灵感的CNN,重新思考CNN架构;
这些模型的核心目标:
找到“结构先验”和“灵活模型”之间最优的折中点。
五、补充
5.1 二维的位置编码
论文中虽然使用的是一维的位置编码(形状是 ( N \times D )),但其内部其实是用 二维网格的位置(行、列)来生成的。这种方式可以分两种做法:
方法一:直接学习一个二维位置编码表
- 假设有一个 ( h \times w ) 的patch grid,例如 ( 14 \times 14 );
- 可以学习一个形状为 ( h \times w \times D ) 的可训练tensor;
- 然后 reshape 为 ( N \times D )(即 ( 196 \times 768 ));
- 加到 patch embedding 上。
方法二:分离式编码(Horizontal + Vertical)
这是某些 ViT 变种(比如 Axial Attention、Swin Transformer、BEiT 等)采用的方式。
- 学两个 embedding:行方向的位置编码
h × D/2
和列方向的位置编码w × D/2
; - 对于每个位置 (i,j),位置编码是两个向量之和或拼接:
PE i , j = RowPE i ∣ ∣ ColPE j \text{PE}_{i,j} = \text{RowPE}_i || \text{ColPE}_j PEi,j=RowPEi∣∣ColPEj - 再 reshape 成一维序列。
这种方式的好处是更结构化、可扩展、可插值(这在fine-tuning时很有用)。
5.2 挖坑
众所周知,ViT挖了很多坑。
众所周知,CV界是出了名的卷。坑多,填坑的也多。
略微总结:
坑号 | 挖坑主题 | 被谁填了? |
---|---|---|
1 | 去CNN化 | Swin、PVT、CvT、LeViT、ConvNeXt |
2 | 位置编码不泛化 | 相对PE、Swin移动窗口、Focal、Twins |
3 | 局部性完全缺失 | T2T、DeiT distill、RegionViT、MobileViT |
4 | 训练资源极高 | DeiT、MAE、DINO、BEiT、自监督系列 |
5 | 没有多尺度层次 | PVT、Swin、SegFormer、Pix2Seq |
6 | 归纳偏置之争 | 整个 community 都在参与 |
7 | 图像语言统一建模范式 | CLIP、BLIP、GPT-4V、Flamingo |
相关文章:
ViT 模型讲解
文章目录 一、模型的诞生背景1.1 背景1.2 ViT 的提出(2020年) 二、模型架构2.1 patch2.2 模型结构2.2.1 数据 shape 变化2.2.2 代码示例2.2.3 模型结构图 2.3 关于空间信息 三、实验3.1 主要实验3.2 消融实验 四、先验问题4.1 归纳偏置4.2 先验or大数据&…...
【技术文章的标准结构与内容指南】
技术文章的标准结构与内容指南 技术文章是传递专业知识、分享实践经验的重要媒介。一篇高质量的技术文章不仅能够帮助读者解决问题,还能促进技术交流与创新。以下是技术文章通常包含的核心内容与结构指南。 1. 标题 一个好的技术文章标题应当: 简洁明…...
Mysql概述
一、数据库相关概念 1.数据库(Data Base ,简称DB)是长期存储在计算机中有组织、可管理、可共享的数据集合。 2.数据库管理系统(Database Management System,简称为 DBMS)是管理数据库的系统软件 3.MySQL数据库全称为MySQL数据库管理系统 3.SQL语言(S…...
系统设计模块之安全架构设计(身份认证与授权(OAuth2.0、JWT、RBAC/ABAC))
一、OAuth 2.0:开放授权框架 OAuth 2.0 是一种标准化的授权协议,允许第三方应用在用户授权下访问其资源,而无需直接暴露用户密码。其核心目标是 分离身份验证与授权,提升安全性与灵活性。 1. 核心概念与流程 角色划分ÿ…...
如何管理“灰色时间”导致的成本漏洞
明确时间记录机制、优化流程透明度、应用自动化工具、强化绩效考核机制、提高员工时间意识 来有效管理。其中,明确时间记录机制 是最关键的一步。通过统一的时间记录平台,例如Toggl Track、Clockify或企业级工时系统,不仅可以实时掌握员工工作…...
程序化广告行业(84/89):4A广告代理公司与行业资质解读
程序化广告行业(84/89):4A广告代理公司与行业资质解读 大家好!在探索程序化广告行业的道路上,每一次知识的分享都是我们共同进步的阶梯。一直以来,我都希望能和大家携手前行,深入了解这个充满机…...
MTK Android12-13 -Intent Filter Verification Service 停止运行
MTK Android12-13 -Intent Filter Verification Service 停止运行 问题修复 文章目录 参考资料解决方案-修改文件源码分析源码 StatementService配置加载config_appsNotReportingCrashesActivityManagerService -retrieveSettings 加载配置AppErrors-loadAppsNotReportingCrash…...
Sentinel源码—1.使用演示和简介二
大纲 1.Sentinel流量治理框架简介 2.Sentinel源码编译及Demo演示 3.Dashboard功能介绍 4.流控规则使用演示 5.熔断规则使用演示 6.热点规则使用演示 7.授权规则使用演示 8.系统规则使用演示 9.集群流控使用演示 5.熔断规则使用演示 (1)案例说明熔断和降级 (2)Sentin…...
基于Geotools的PostGIS原始操作之CQL过滤及按属性名称生成面属性时间-以湖北省地级市行政区划为例
目录 前言 背景与意义 技术方法概述 一、CQL查询实现 1、CQL查询原理 2、Geotools中的CQL实现 二、SLD编程式样式生成 1、获取唯一的分类值 2、生成不同颜色分类 3、集成生成SLD的Style文件 三、总结 前言 随着地理信息系统(GIS)技术的快速发展…...
Linux内核中struct net_protocol的early_demux字段解析
背景问题 在内核版本4.19.0-25的头文件中,struct net_protocol结构体的定义未显式包含early_demux字段。然而,在内核版本4.19的源代码中可以看到tcp_protocol实例化时却对该字段进行了赋值: static struct net_protocol tcp_protocol = {.early_demux = tcp_v4_earl…...
TLS协议四次握手原理详解,密钥套件采用DH密钥交换算法
目录 1.TLS协议握手概述 2.TLS协议握手具体步骤 2.1.TLS第一次握手 2.2.TLS第二次握手 2.3.TLS第三次握手 2.4.TLS第四次握手 3.DH密钥交换算法 1.TLS协议握手概述 第一步客户端会发起一个消息,携带了TLS的版本号,客户端随机数,密码套…...
React 更新state中的对象
更新 state 中的对象 state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新一个对象时,你需要创建一个新的对象(或者将其拷贝一份)…...
祁连山国家公园shp格式数据
地理位置:祁连山国家公园位于中国西北部,横跨甘肃省与青海省交界处,主体处于青藏高原东北边缘。总面积约5.02万平方公里,是中国首批设立的10个国家公园之一。 设立背景 试点启动:2017年,祁连山国家公园体制…...
电梯设备与电源滤波器:现代建筑中的安全守护者与电力净化师
在现代都市的钢铁森林中,电梯作为垂直交通的动脉,承载着无数人的日常出行。与此同时,在电气系统的隐秘角落,电源滤波器则默默扮演着“电力净化师”的角色,保障着各类电子设备的稳定运行。电梯设备与电源滤波器…...
Qt样式表(窗口、按钮之类,有图片和代码详细注释)
Qt样式表 1、前言2、QWdiget窗口添加背景图片2.1使用Frame解决 3、主题1(黑色背景发光边框冷色调)3.1 QWidget3.2 QPushButton3.3QLineEdit3.4 QTextEdit 4、主题二(极简冰川蓝)4.1QWidget4.2 QLineEdit4.3QTextEdit4.4QPushButto…...
在Ubuntu下进行单片机开发是否需要关闭Secure Boot
1. Secure Boot的作用 功能:Secure Boot是UEFI的安全功能,旨在阻止未经验证的驱动或操作系统启动,防止恶意软件篡改引导过程。 影响范围:它主要限制的是操作系统启动阶段加载的内核级驱动(如显卡驱动、虚拟化模块&…...
【Python爬虫】简单案例介绍4
本文继续接着我的上一篇博客【Python爬虫】简单案例介绍3-CSDN博客 目录 3.4 完整代码 3.4 完整代码 此小节给出上述案例的完整代码, # encodingutf-8 import re, json, requests, xlwt, csv import pandas as pd from lxml import etree from bs4 import Beauti…...
农民剧团的春天与改变之路
杨天义,男,1966年9月生,中共党员,江西省吉安市吉水县水南农民剧团团长。 杨天义从废品收购起家,凭借自身的努力和奋斗,自筹资金100余万元建设了水南镇的第一座影剧院,组建了江西省吉安市吉水县…...
网页防篡改与盗链防护:实时监控与自动化修复实践
摘要:针对网页内容篡改与盗链问题,本文基于群联AI云防护系统,详解如何通过哈希校验、实时监控与CDN联动实现秒级修复,并提供Python与AWS S3集成代码。 一、网页安全的核心需求 防篡改:保障页面内容完整性,…...
【密码学——基础理论与应用】李子臣编著 第五章 序列密码 课后习题
免责声明 这里都是自己搓或者手写的。 里面不少题目感觉有问题或者我的理解有偏颇,请大佬批评指正! 不带思考抄作业的请自动退出,我的并非全对,仅仅提供思维! 题目 逐题解析 5.1 我们先要知道三阶LFSR函数的表达式…...
【uni-app】页面跳转传参
一、EventChannel 的核心作用 替代全局事件总线 相比传统的 uni.$emit 和 uni.$on,EventChannel 无需手动移除监听(如 uni.$off),避免内存泄漏风险。解决 URL 传参限制 当需要传递大量数据时,URL 拼接参数可能超出长度…...
【MySQL】表的增删改查
前言 前面我们对表结构做了介绍,本期我们对表的内容操作机增删改查进行介绍! 目录 前言 一、insert 插入 1.1 单行数据 全列插入 1.2 多行数据 指定列插入 1.3 插入否则更新 1.4 插入否则替换 二、select 查询 2.1 select 列 2.1.1 全列查询…...
AQchat
在当前项目里,Handler 类主要用于处理不同类型的命令或者消息,下面按照不同功能模块为你详细介绍各 Handler 的作用。 命令处理 Handler(位于 com.howcode.aqchat.handler.impl 包) SyncRoomMembersCmdHandler:处理同…...
Profibus DP转ModbusTCP网关通讯案例解析
Profibus DP转ModbusTCP网关通讯案例解析 Profibus DP和Modbus TCP都是工业自动化领域中常见的通信协议,各自在不同的应用场景中发挥着重要作用。然而,由于不同设备、系统之间的兼容性需求,常常需要进行这两种协议的转换。本文将介绍一个典型…...
将你的 Rust + WebAssembly 项目发布到 npm
一、准备工作:登录 npm 在发布之前,你需要: 拥有一个 npm 账号 没有的话可前往 https://www.npmjs.com/signup 免费注册。 登录本地 npm 账户 使用 wasm-pack 自带的登录命令: wasm-pack login它会提示你输入 npm token…...
RGBD惯性SLAM
介绍 本篇介绍一种基于视觉光流法的RGBD惯性SLAM算法,该算法的前身是DEMO算法。 相对于原始版本: 更新了相对较老的IplImage 相关接口 加入了GTSAM后端;滑动窗口后端;3D-3Dbatch优化;点到面batch后端。分别对应不同的…...
linuxbash原理
3417 1647 0 04:17 ? 00:00:21 /usr/libexec/gnome-terminal-server yangang 3425 3417 0 04:17 pts/0 00:00:00 bash yangang 4524 3417 0 04:26 pts/1 00:00:00 bash 控制台创建是通过/usr/libexec/gnome-terminal-server 进行创建 rea…...
ctfshow做题笔记—栈溢出—pwn75~pwn79
目录 前言 一、pwn75(栈空间不够怎么办?) 二、pwn76 三、pwn77(Ez ROP or Mid ROP ?) 四、pwn79(你需要注意某些函数,这是解题的关键!) 前言 嘿嘿,隔了一段时间没有做pwn题了(主播脱单了)࿰…...
C++ 标准库中的 <algorithm> 头文件算法总结
C 常用 <algorithm> 算法概览 C 标准库中的 <algorithm> 头文件提供了大量有用的算法,主要用于操作容器(如 vector, list, array 等)。这些算法通常通过迭代器来操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…...
leecode Hot100之回溯算法【C++速查】
文章目录 [46. 全排列](https://leetcode.cn/problems/permutations/)[78. 子集](https://leetcode.cn/problems/subsets/)[17. 电话号码的字母组合](https://leetcode.cn/problems/letter-combinations-of-a-phone-number/)[39. 组合总和](https://leetcode.cn/problems/combi…...
前端 main.js能做哪些事?
前端 main.js 的从入门到进阶 摘要 在前端开发中,main.js 文件是项目启动的关键入口,它承担着初始化应用、引入依赖、配置全局设置等重要职责。本文将全面介绍 main.js 的基础知识,包括其基本结构和作用,并深入探讨如何进行进阶开…...
JAVA Web_定义Servlet2_学生登录验证Servlet
题目 页面StudentLogin.html中有一HTML的表单代码如下: <form action"studentLogin" method"post">学生姓名:<input type"text" name"stuName" value""><br>登录密码:…...
【信息系统项目管理师】高分论文:论信息系统项目的范围管理(电网公司保供电可视化系统)
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划范围管理2、收集需求3、定义范围4、创建工作分解结构(WBS)5、确认范围6、控制范围论文 2017年5月,我作为项目经理参加XX省电网公司保供电可视化系统应用项目的建设,该项目是2017年XX省电网信息化…...
如何高效查询订单销售情况与售罄率:从SQL到架构优化的全流程设计
在电商平台、SaaS多租户系统中,订单数据作为核心数据之一,承载了关键的运营指标,如销售额、商品售罄率、订单转化等。随着数据量的持续增长,如何在大数据量条件下快速、稳定地获取统计信息,成为系统设计的重点之一。 本文将从查询目标分析入手,结合数据库设计优化与典型…...
RTT添加一个RTC时钟驱动,以DS1307为例
添加一个外部时钟芯片 这里多了一个选项 复制drv_rtc.c,重命名为drv_rtc_ds1307.c 添加到工程中 /*** @file drv_rtc_ds1307.c* @brief * @author jiache (wanghuan3037@fiberhome.com)* @version 1.0* @date 2025-01-08* * @copyright Copyright (c) 2025 58* */ #...
Leetcode 独一无二的出现次数
可以通过哈希集来判断是否独一无二,如果set中已经包含了count,那么set.add(count)会返回false class Solution {public boolean uniqueOccurrences(int[] arr) {Map<Integer, Integer> map new HashMap<>();for(int i 0; i < arr.leng…...
ubuntu上,e1000e,i1210有线网卡驱动安装
1,下载附属资源,解压对应的压缩包 tar zxf e1000e-<x.x.x>.tar.gz 2,进入压缩包src目录下 cd e1000e-<x.x.x>/src/ 3,安装 sudo make install 4,重启 reboot e1000e Intel官网下载地址 https://www.i…...
Xmind 2025 中文思维导图
Xmind 2025 中文思维导图 一、介绍 Xmind ,是一款出色的思维导图和头脑风暴软件,拥有美观的智能配色方案,便于你轻松理清思路捕捉创意。丰富的导图模板及多种创意整合工具,可助力导图迸发更多活力。还拥有强大演说模式ÿ…...
搭载DeepSeek|暴雨AI教育一体机加速AI教育普及
近日,在全国智算大会上,暴雨公司展示了新一代 AI 教育一体机,通过全栈国产化技术与 DeepSeek 模型的深度适配,打造低成本、高性能的人工智能教育解决方案,助力 AI 教育普及与教育数字化转型。 暴雨AI教育一体机&#…...
【字节跳动AI论文】Seaweed-7B:视频生成基础模型的高成本效益培训
摘要:本技术报告介绍了一种经济有效的视频生成基础模型训练策略。 我们提出了一种中等规模的研究模型,大约有70亿个参数(7B),称为Seaweed-7B,使用665,000个H100 GPU小时从头开始训练。 尽管使用适度的计算资…...
java 线程池:IO密集型的任务(CPU核数 * 2 + 1),为什么这么设置,计算密集型任务( CPU核数+1 ),为什么这么设置
文章目录 1. IO密集型任务:`CPU核数 2 + 1`为什么这样设置?示例场景:2. CPU密集型任务:`CPU核数 + 1`为什么这样设置?示例场景:3. 两者的核心差异4. 实际应用中的注意事项5. 总结在Java线程池的配置中, IO密集型和 CPU密集型任务的线程数设置逻辑存在显著差异,核心原…...
RabbitMQ消息的可靠性
生产者的可靠 首先,我们一起分析一下消息丢失的可能性有哪些。 消息从发送者发送消息,到消费者处理消息,需要经过的流程是这样的: 消息从生产者到消费者的每一步都可能导致消息丢失: ● 发送消息时丢失:…...
涵盖通算、智算、超算、量算!“四算合一”算力网络投入使用,效率提升20%
近日,由中国移动承建的全国首个“四算合一”算力网络调度平台日前正式投入使用。这座“数字三峡”的诞生,标志着我国算力基建完成从“单兵作战”到“军团协同”的跃迁。 什么是“四算合一”? “四算合一”是指将通用算力、智能算力、超级算…...
【Redis】数据结构和内部编码
先来复习一下之前学过的几个基本的全局命令: keys:用来查看匹配规则的keyexists:用来判定执行key是否存在del:删除指定的keyexpire:给key设置过期时间ttl:查询key的过期时间type:查询key对应的…...
考研数据结构之二叉树(一)(包含真题及解析)
考研数据结构之二叉树(一) 下期预告:后续文章将深入探讨二叉树的遍历算法与高频考点(如平衡二叉树、线索二叉树)。 二叉树是数据结构中的核心内容之一,也是考研高频考点。本文将从定义和存储结构两方面展开…...
linux多线(进)程编程——番外1:内存映射与mmap
前言 在修真世界之外,无数异世界,其中某个叫地球的异世界中,一群人对共享内存的第二种使用方式做出了讲解。 内核空间与用户空间 内存空间的划分 Linux操作系统下一个进程的虚拟地址空间被分为用户空间与内核空间 Linux 内核空间在内存管…...
旧版 VMware 虚拟机迁移至 KVM 平台-案例2
项目背景 需将一台旧版 VMware 虚拟机(VMDK 格式)迁移至 KVM 虚拟化平台,具体要求如下: 格式转换:将 VMDK 转换为 QCOW2 格式。磁盘扩容:将原 40GB 磁盘扩展至 60GB。密码重置:修改 aiden 用户…...
六、adb通过Wifi连接
背景 收集是荣耀X40,数据线原装全新的,USB连上之后,老是断,电脑一直叮咚叮咚的响个不停,试试WIFI 连接是否稳定,需要手机和电脑用相同的WIFI. 连接 1.通过 USB 连接手机和电脑(打开USB调试等这些都略过) adb device…...
Kafka使用方式与底层原理解析
一、Kafka简介 Apache Kafka是一个分布式流处理平台,由LinkedIn开发并开源,现已成为实时数据管道和流应用的核心组件。它具备高吞吐量、低延迟、高可扩展性等特点,广泛应用于日志收集、消息系统、流处理等领域。 1.1 Kafka核心概念 Topic&…...
【Python内置函数的深度解析与应用】id
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现1. 基础身份验证2. 不可变对象优化3. 对象生命周期追踪 运行结果验证 三、性能对比测试方法论量化数据…...