《Transformer如何进行图像分类:从新手到入门》

引言

如果你对人工智能(AI)或深度学习(Deep Learning)感兴趣,可能听说过“Transformer”这个词。它最初在自然语言处理(NLP)领域大放异彩,比如在翻译、聊天机器人和文本生成中表现出色。但你知道吗?Transformer不仅能处理文字,还能用来分类图像!这听起来是不是有点神奇?别担心,这篇博客将带你从零开始,了解Transformer的基本概念、它如何被应用到图像分类,以及通过一个简单的例子让你直观理解它的运作原理。无论你是AI新手还是好奇的技术爱好者,这篇文章都会尽量用通俗的语言为你解锁Transformer的奥秘。

第一部分:Transformer是什么?

Transformer是一种深度学习模型,最早由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它的核心思想是“注意力机制”(Attention Mechanism),这是一种让模型学会“关注”输入中重要部分的能力。传统的模型,比如卷积神经网络(CNN)和循环神经网络(RNN),在处理图像或序列数据时有局限性,而Transformer通过注意力机制突破了这些限制。

1.1 为什么叫“Transformer”?

“Transformer”这个名字听起来很酷,但它其实反映了模型的功能:它能将输入数据“转换”(Transform)成更有意义的表示形式。比如,把一句话翻译成另一种语言,或者把一张图片“翻译”成一个分类标签(比如“猫”或“狗”)。它的核心在于通过计算输入数据之间的关系,生成更有用的输出。

1.2 Transformer的基本结构

Transformer由两个主要部分组成:编码器(Encoder)和解码器(Decoder)。不过,在图像分类任务中,我们通常只用到编码器部分。让我们简单看看它的组成:

  • 输入嵌入(Input Embedding):把输入数据(比如单词或图像块)转换成数字向量。
  • 注意力机制(Attention):让模型关注输入中最重要的部分。
  • 前馈神经网络(Feed-Forward Network):对数据进一步处理。
  • 层归一化和残差连接(Layer Normalization & Residual Connection):帮助模型稳定训练,避免“梯度消失”等问题。

这些组件堆叠在一起,形成多层结构,每一层都让模型对数据的理解更深一层。

1.3 注意力机制:Transformer的“超能力”

注意力机制是Transformer的核心。想象你在读一本书,当你看到“猫”这个词时,你会自动想到整句话的上下文,比如“猫在睡觉”还是“猫在跑”。注意力机制让模型也能做到这一点:它会计算输入中每个部分对其他部分的“重要性”,然后根据这些关系调整输出。

具体来说,Transformer使用的是“自注意力”(Self-Attention)。它会为输入的每个部分(比如图像的一个小块)生成三个向量:

  • 查询(Query):我想知道什么?
  • 键(Key):我有哪些信息?
  • 值(Value):这些信息有多重要?

通过计算查询和键之间的相似度,模型决定每个值的权重,然后把它们加权组合起来。这种方式让Transformer能捕捉全局关系,而不是像CNN那样只关注局部区域。

第二部分:从NLP到图像分类:Vision Transformer (ViT)

Transformer最初是为NLP设计的,那它是怎么“跨界”到图像分类的呢?这要归功于2020年提出的Vision Transformer(简称ViT)。让我们看看它是如何工作的。

2.1 图像怎么变成Transformer的输入?

图像和文字完全不同,对吧?图像是一堆像素,而文字是一串单词。要让Transformer处理图像,第一步就是把图像“翻译”成它能理解的形式。ViT的做法是:

  1. 切分图像:把一张图片(比如224x224像素)切成固定大小的小块(比如16x16像素),就像把一张大拼图拆成小碎片。
  2. 展平并嵌入:把每个小块展平成一个向量(就像把拼图碎片摊平),然后通过一个线性层把它们变成嵌入向量(Embedding)。
  3. 加上位置信息:因为Transformer不像CNN有固定的空间感知能力,我们需要手动告诉它每个小块在图像中的位置。这通过“位置编码”(Positional Encoding)实现。

经过这些步骤,一张图像就变成了一个序列(Sequence),就像NLP中的一句话,只不过这里的“单词”是图像块。

2.2 Transformer处理图像的过程

一旦图像被转换成序列,Transformer的编码器就开始工作:

  • 自注意力:计算每个图像块和其他图像块之间的关系。比如,在一张猫的图片中,耳朵和眼睛的图像块可能会被关联起来。
  • 多层堆叠:通过多层编码器,模型逐渐提取更高层次的特征。
    分类头:在最后一层,添加一个简单的分类层(比如全连接层),输出图像的类别(比如“猫”或“狗”)。

2.3 ViT的优势和挑战

相比传统的CNN,ViT有几个优点:

  • 全局视野:它能一次性看到整张图像的关系,而不像CNN只关注局部。
  • 灵活性:同一个模型可以轻松处理不同大小的输入。

但它也有挑战:

  • 计算量大:自注意力机制需要大量计算,尤其当图像块很多时。
  • 数据需求高:ViT需要大量标注数据才能训练得好。

第三部分:一个简单的例子:用ViT分类猫和狗

为了让新手更容易理解,我们通过一个具体的例子来说明Transformer如何进行图像分类。假设我们要训练一个模型,区分CIFAR-10数据集中的“猫”和“狗”图片(CIFAR-10是PyTorch内置的一个小型图像数据集,包含10类32x32像素的图像)。下面我们逐步拆解过程,并新增代码实现。

3.1 数据准备

CIFAR-10中的每张图片是32x32像素,RGB格式。我们将它切成4x4的小块(为了简化示例),总共有64个块(32 ÷ 4 = 8,8x8 = 64)。每个小块有48个数值(4x4x3,因为RGB有3个通道)。

3.2 嵌入过程

  • 把每个小块展平成一个48维向量。
  • 通过一个线性层,把48维映射到一个固定维度(比如32维),得到嵌入向量。
  • 加上位置编码,告诉模型每个块的位置。

现在,这张图片变成了一个64x32的矩阵,就像一个有64个“单词”的序列。

3.3 自注意力计算

假设猫咪的耳朵在第10个块,眼睛在第20个块。Transformer会:

  1. 为每个块生成查询、键和值向量。
  2. 计算第10个块的查询和第20个块的键之间的相似度,发现它们关系密切。
  3. 根据相似度加权组合值向量,生成一个新的表示。

经过多层自注意力,模型学会关联猫的特征。

3.4 分类输出

在最后一层,ViT取一个特殊的“分类标记”(CLS Token),通过全连接层输出10个类别的概率(CIFAR-10有10类),比如“猫”的概率是0.8,“狗”是0.1。

3.5 代码实现

下面我们提供两种代码实现方式,帮助你直观感受ViT的运作。代码基于PyTorch,使用CIFAR-10数据集。

实现方式1:从头实现一个简化的ViT

这个实现简化了ViT的核心组件,适合理解原理。

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader# 超参数
patch_size = 4  # 切分图像为4x4的小块
embed_dim = 32  # 每个小块的嵌入维度
num_heads = 4   # 注意力头的数量
num_classes = 10  # CIFAR-10有10个类别
num_patches = (32 // patch_size) ** 2  # 64个小块 (32x32图像)# 数据加载
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=64, shuffle=True)# 简化的ViT模型
class SimpleViT(nn.Module):def __init__(self):super(SimpleViT, self).__init__()# 将图像块映射到嵌入空间self.patch_to_embedding = nn.Linear(patch_size * patch_size * 3, embed_dim)# 位置编码self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, embed_dim))# CLS Tokenself.cls_token = nn.Parameter(torch.randn(1, 1, embed_dim))# Transformer编码器self.transformer = nn.TransformerEncoder(nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads), num_layers=2)# 分类头self.fc = nn.Linear(embed_dim, num_classes)def forward(self, x):b, c, h, w = x.shape  # [batch_size, 3, 32, 32]# 切分成小块并展平x = x.view(b, c, h // patch_size, patch_size, w // patch_size, patch_size)x = x.permute(0, 2, 4, 1, 3, 5).contiguous()  # [b, 8, 8, 3, 4, 4]x = x.view(b, num_patches, -1)  # [b, 64, 48]# 映射到嵌入空间x = self.patch_to_embedding(x)  # [b, 64, 32]# 添加CLS Tokencls_tokens = self.cls_token.expand(b, -1, -1)  # [b, 1, 32]x = torch.cat((cls_tokens, x), dim=1)  # [b, 65, 32]# 加上位置编码x = x + self.pos_embedding# 通过Transformerx = self.transformer(x)  # [b, 65, 32]# 取CLS Token的输出进行分类x = self.fc(x[:, 0])  # [b, 10]return x# 训练模型
model = SimpleViT()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)for epoch in range(5):  # 训练5个epochfor images, labels in trainloader:optimizer.zero_grad()outputs = model(images)loss = criterion(outputs, labels)loss.backward()optimizer.step()print(f'Epoch {epoch+1}, Loss: {loss.item()}')

代码解释:

  • 数据加载:从CIFAR-10加载32x32的图像,归一化处理。
  • 图像切分:将32x32图像切成64个4x4的小块,展平后映射到32维嵌入。
  • CLS Token:添加一个特殊标记,用于最终分类。
  • Transformer:使用PyTorch内置的Transformer编码器,包含2层,每层有4个注意力头。
  • 训练:简单训练5个epoch,优化分类损失。
实现方式2:使用预训练ViT模型(Hugging Face)

这个实现利用Hugging Face的预训练ViT模型,适合快速上手。

import torch
from transformers import ViTFeatureExtractor, ViTForImageClassification
from torchvision import datasets, transforms
from torch.utils.data import DataLoader# 数据加载
transform = transforms.Compose([transforms.Resize((224, 224)),  # ViT需要224x224输入transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=16, shuffle=True)# 加载预训练ViT模型和特征提取器
feature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224')
model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224')
model.classifier = torch.nn.Linear(model.classifier.in_features, 10)  # 修改分类头为10类# 训练设置
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)# 训练模型
model.train()
for epoch in range(3):  # 训练3个epochfor images, labels in trainloader:inputs = feature_extractor(images=[img.permute(1, 2, 0).numpy() for img in images], return_tensors="pt")inputs = {k: v for k, v in inputs.items()}  # 转换为模型输入格式optimizer.zero_grad()outputs = model(**inputs).logits  # 获取分类输出loss = criterion(outputs, labels)loss.backward()optimizer.step()print(f'Epoch {epoch+1}, Loss: {loss.item()}')

代码解释:

  • 数据预处理:将CIFAR-10图像调整到224x224(ViT预训练模型的要求)。
  • 预训练模型:加载Google的vit-base-patch16-224,替换分类头为10类。
  • 特征提取器:自动处理图像输入,切分并嵌入。
  • 训练:微调模型,适应CIFAR-10任务。

注意:运行第二种方式需要安装transformers库(pip install transformers)。

第四部分:新手常见问题解答

4.1 Transformer和CNN有什么不同?

CNN像一个放大镜,逐步扫描图像的局部特征;而Transformer像一个全景相机,一次性捕捉全局关系。两者各有千秋,ViT证明了Transformer也能在图像任务中大放异彩。

4.2 我需要多强的编程基础才能用Transformer?

好消息是,你不需要从头写Transformer!开源工具(如PyTorch和Hugging Face)提供了预训练模型。你只需要学会加载模型、准备数据和微调,就能上手。

4.3 ViT适合所有图像任务吗?

不完全是。ViT在大数据集(如ImageNet)上表现很好,但在小数据集或需要精细局部特征的任务上,CNN可能更合适。

第五部分

Transformer通过注意力机制和全局视野,为图像分类带来了新思路。Vision Transformer(ViT)展示了它如何将图像切分成块,像处理句子一样处理图片,最终实现分类。对于新手来说,理解它的关键在于:

  1. 图像如何变成序列。
  2. 自注意力如何捕捉关系。
  3. 分类如何通过简单输出实现。

通过上面的代码示例,你可以看到:

  • 从头实现ViT帮助理解原理。
  • 使用预训练模型能快速应用到实际任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33190.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FANUC机器人几种常用的通讯网络及接口

FANUC机器人几种常用的通讯网络及接口 Devicenet 网络通讯接口,接口为5针线 (规定用的机架为 81-84) PROFIBUS 网络通讯接口,针脚为2针(规定用的机架为 67) Intemet 网络通讯接口(常用的网线接口&#xf…

分布式锁技术全景解析:从传统锁机制到MySQL、Redis/Redisson与ZooKeeper实现

文章目录 一、分布式锁介绍1.1 为什么需要分布式锁1.2 什么是分布式锁?1.3 分布式锁特点 二. 传统锁回顾2.1商品超卖演示2.2 JVM锁演示2.3 JVM锁失效的三种情况2.3.1 多例模式2.3.2 事务2.3.3 分布式集群 三. 基于mysql实现分布式锁3.1 一条SQL3.2 悲观锁3.3 乐观锁…

【GPT入门】第18课 langchain介绍与API初步体验

【GPT入门】langchain第一课 langchain介绍与API初步体验 1. langchain介绍定义特点1. 模块化与灵活性2. 链式调用机制3. 数据连接能力4. 记忆管理功能5. 提示工程支持6. 可扩展性 2.langchain核心组件架构图3. 最简单的helloworld入门 1. langchain介绍 LangChain 是一个用于…

神经网络分类任务

import torch %matplotlib inline from pathlib import Path import requestsimport torchvision mnist_dataset torchvision.datasets.MNIST(root./data, downloadTrue) 下载mnist数据集 但不知道数据集里面是什么打印 import torchvision import torchvision.transforms …

ROS实践(三)机器人描述文件xacro(urdf扩展)

目录 一、定义 二、xacro 文件常见组成部分 1. 命名空间声明 2. 定义宏 3. 调用宏 4. 定义参数 5. 条件语句 6. 转换 xacro 文件为 urdf 7. gazebo标签 三、代码示例 1. gazebo标签使用(仿真参数配置) 2. 引用仿真配置并定义机器人模型&#x…

Vision Mamba论文精读笔记

这篇博客主要针对Vision Mamba 论文进行精读,包含全文翻译以及部分内容注解。 读者最好有SSM以及Mamba的前期基础,便于理解。 论文链接:[2401.09417] Vision Mamba: Efficient Visual Representation Learning with Bidirectional State Spa…

大模型架构记录4-文档切分 (chunks构建)

chunks: 块 trunks : 树干 “RAG”通常指 检索增强生成(Retrieval-Augmented Generation) 主要框架:用户提query,找到和它相关的,先把问题转换为向量,和向量数据库的数据做比较,检…

个性化音乐推荐系统

python、pycharm、Django、Mysql都已经安装好了! 目录 2025/3/13 2025/3/13 一.打开CMD,安装Mysql驱动 pip install mysqlclient 二.项目初始化: 1.创建Django项目: django-admin startproject project1 cd project1 2.创…

面试高频#LeetCode#Hot100-字母异位词分组

题号链接 49. 字母异位词分组 - 力扣(LeetCode) 1首先定义map集合一个String对应一个String[]集合,遍历字符串数组 2对其先进行拆分,拆分为字符数组,再进行排序,再转为字符串 3如果key值没有就创建一个字符…

笔试刷题专题(一)

文章目录 最小花费爬楼梯(动态规划)题解代码 数组中两个字符串的最小距离(贪心(dp))题解代码 点击消除题解代码 最小花费爬楼梯(动态规划) 题目链接 题解 1. 状态表示&#xff1…

hcia华为路由器静态路由实验配置

目录 一、网络拓扑分析 二、华为路由器配置(分设备) 1. R1 配置 2. R2 配置 3. R3 配置 三、验证测试 拓扑图 一、网络拓扑分析 IP 地址规划: R1:E0/0/0(12.1.1.1/24)、E0/0/1(192.168.1.…

贪心算法和遗传算法优劣对比——c#

项目背景:某钢管厂的钢筋原材料为 55米,工作需要需切割 40 米(1段)、11 米(15 段)等 4 种规格 ,现用贪心算法和遗传算法两种算法进行计算: 第一局:{ 40, 1 }, { 11, 15…

PowerBi,一个简单的动态度量值以及图表联动的案例

假设我们有一张[销量表],数据如下: 我们想做下面的效果: 左边的饼图显示每个门店的销量以及百分比,右边是一个堆积条形图,显示每种商品的销量,并且有一个切片器能切换显示销售渠道 做法如下: 1.报表里放入一个饼图&a…

夜莺监控 v8.0 新版通知规则 | 对接企微告警

对新版本通知规则还不太了解的用户可以阅读文章:《夜莺监控巨大革新:抽象出通知规则,增强告警通知的灵活性》。下面我们将以企微通知为例,介绍如何使用新版通知规则来对接企微通知。 上图是通知规则对接企微通知的示意逻辑图。 在…

HCIA-11.以太网链路聚合与交换机堆叠、集群

链路聚合背景 拓扑组网时为了高可用,需要网络的冗余备份。但增加冗余容易后会出现环路,所以我们部署了STP协议来破除环路。 但是,根据实际业务的需要,为网络不停的增加冗余是现实需要的一部分。 那么,为了让网络冗余…

LeetCode 解题思路 15(Hot 100)

解题思路: 引入哑节点: 简化头节点删除操作,统一处理所有边界条件。快慢指针法: 快指针先移动 n 步,确保快慢指针距离为 n,之后同步移动快慢指针。当快指针到达末尾时,慢指针指向倒数第 n 个节…

大数据学习(65)- Hue详解

🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…

设计模式之美

UML建模 统一建模语言(UML)是用来设计软件的可视化建模语言。它的语言特点是简单 统一 图形化 能表达软件设计中的动态与静态信息。 UML的分类 动态结构图: 类图 对象图 组件图 部署图 动态行为图: 状态图 活动图 时序图 协作…

【大模型学习】第十八章 强化学习介绍

目录 引言 一、 强化学习的理论基础与发展脉络 1.1 基本概念与核心要素 1.2 历史演进与里程碑 二、 强化学习的数学框架与核心算法 2.1 马尔可夫决策过程与贝尔曼方程 2.2 基于价值的算法 2.3 基于策略的算法 2.4 混合算法:Actor-Critic架构 2.5 应用举例 …

Chatbox通过百炼调用DeepSeek

解决方案链接:评测|零门槛,即刻拥有DeepSeek-R1满血版 方案概览 本方案以 DeepSeek-R1 满血版为例进行演示,通过百炼模型服务进行 DeepSeek 开源模型调用,可以根据实际需求选择其他参数规模的 DeepSeek 模型。百炼平台…