使用ViT进行图像分类

简介: 使用ViT进行图像分类

ViT模型的出现标志着Transformer架构在计算机视觉中的成功应用,以下是一个简要的实战与进阶解析:

 

实战:使用ViT进行图像分类

 

步骤概述:

 

1. 准备数据:

  - 首先,准备一个适当的图像分类数据集,如ImageNetCIFAR-10等。确保数据集包含标签,用于监督学习。

2. 加载和预处理数据:

  - 使用Python的图像处理库(如PIL)加载图像,并进行预处理,例如将图像缩放到模型所需的大小(通常为224x224或者384x384)。

 

3. 加载预训练的ViT模型:

  - PyTorchTensorFlow中,可以使用Hugging Face Transformers库或官方的模型库来加载预训练的ViT模型。常用的预训练模型包括ViT-B/32ViT-L/16等,选择适合任务和资源限制的模型。

 

4. 微调ViT模型:

  - 将加载的ViT模型进行微调以适应特定的图像分类任务。微调通常包括解冻最后几层,或者使用较小的学习率调整整个模型的权重。

 

5. 训练和评估模型:

  - 使用训练集训练ViT模型,并在验证集上进行评估。监控模型在训练集和验证集上的准确率、损失值等指标。

 

6. 模型调优和测试:

  - 根据验证集的表现调整超参数(如学习率、批量大小等),最终在测试集上评估模型的性能。

 

进阶:ViT模型的特点和优势

 

- 全局感知:ViT模型通过自注意力机制(self-attention)实现对整个图像的全局感知,而不是像传统卷积神经网络(CNN)一样依赖于局部滑动窗口。

 

- 可扩展性:ViT模型在处理不同大小的图像时具有较好的可扩展性,只需微调输入和输出的层即可适应不同的图像尺寸。

 

- 适应多任务学习:由于Transformer的结构和对比学习的特性,ViT模型可以轻松地扩展到多任务学习或零样本学习(zero-shot learning)等场景。

 

- 预训练和微调:ViT模型在大规模图像数据上进行预训练,然后通过微调适应特定任务,这种方法使得模型能够更快速地收敛和适应新数据。

 

代码示例

import tensorflow as tf
from tensorflow.keras import layers, models, initializers
import numpy as np
 
 
class PatchEmbedding(layers.Layer):
   def __init__(self, patch_size, num_patches, embed_dim):
       super(PatchEmbedding, self).__init__()
       self.num_patches = num_patches
       self.proj = layers.Dense(embed_dim)
       self.cls_token = self.add_weight("cls_token", shape=[1, 1, embed_dim], initializer=initializers.Zeros())
       self.pos_embed = self.add_weight("pos_embed", shape=[1, num_patches + 1, embed_dim], initializer=initializers.Zeros())
 
   def call(self, x):
       batch_size, height, width, channels = x.shape
       patch_size_h, patch_size_w = height // self.num_patches, width // self.num_patches
       x = tf.image.extract_patches(x, sizes=[1, patch_size_h, patch_size_w, 1], strides=[1, patch_size_h, patch_size_w, 1], rates=[1, 1, 1, 1], padding='VALID')
       x = tf.reshape(x, [batch_size, -1, patch_size_h * patch_size_w * channels])
       x = self.proj(x)
 
       cls_tokens = tf.broadcast_to(self.cls_token, [batch_size, 1, self.proj.units])
       x = tf.concat([cls_tokens, x], axis=1)
       x += self.pos_embed
       return x
 
 
class MultiHeadSelfAttention(layers.Layer):
   def __init__(self, embed_dim, num_heads):
       super(MultiHeadSelfAttention, self).__init__()
       self.embed_dim = embed_dim
       self.num_heads = num_heads
       self.proj_qkv = layers.Dense(3 * embed_dim)
       self.proj_out = layers.Dense(embed_dim)
 
   def call(self, x):
       batch_size, num_patches, embed_dim = x.shape
       qkv = self.proj_qkv(x)
       q, k, v = tf.split(qkv, 3, axis=-1)
       q = self.split_heads(q)
       k = self.split_heads(k)
       v = self.split_heads(v)
       attention_scores = tf.einsum('bhqd,bhkd->bhqk', q, k) / tf.math.sqrt(float(embed_dim))
       attention_weights = tf.nn.softmax(attention_scores, axis=-1)
       attention_output = tf.einsum('bhqk,bhvd->bhqd', attention_weights, v)
       attention_output = self.combine_heads(attention_output)
       return self.proj_out(attention_output)
 
   def split_heads(self, x):
       batch_size, num_patches, embed_dim = x.shape
       depth = embed_dim // self.num_heads
       x = tf.reshape(x, [batch_size, num_patches, self.num_heads, depth])
       return tf.transpose(x, perm=[0, 2, 1, 3])
 
   def combine_heads(self, x):
       batch_size, num_heads, num_patches, depth = x.shape
       x = tf.transpose(x, perm=[0, 2, 1, 3])
       return tf.reshape(x, [batch_size, num_patches, num_heads * depth])
 
 
class TransformerBlock(layers.Layer):
   def __init__(self, embed_dim, num_heads, mlp_dim, dropout_rate):
       super(TransformerBlock, self).__init__()
       self.mha = MultiHeadSelfAttention(embed_dim, num_heads)
       self.mlp = models.Sequential([
           layers.Dense(mlp_dim, activation=tf.nn.gelu),
           layers.Dense(embed_dim)
       ])
       self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)
       self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)
       self.dropout1 = layers.Dropout(dropout_rate)
       self.dropout2 = layers.Dropout(dropout_rate)
 
   def call(self, x, training):
       attn_output = self.mha(self.layernorm1(x))
       attn_output = self.dropout1(attn_output, training=training)
       out1 = x + attn_output
       mlp_output = self.mlp(self.layernorm2(out1))
       mlp_output = self.dropout2(mlp_output, training=training)
       return out1 + mlp_output
 
 
def create_vit_model(input_shape, patch_size, num_layers, num_patches, embed_dim, num_heads, mlp_dim, num_classes, dropout_rate):
   inputs = layers.Input(shape=input_shape)
    x = PatchEmbedding(patch_size, num_patches, embed_dim)(inputs)
 
   for _ in range(num_layers):
       x = TransformerBlock(embed_dim, num_heads, mlp_dim, dropout_rate)(x)
 
    x = layers.LayerNormalization(epsilon=1e-6)(x)
    x = x[:, 0]
    x = layers.Dense(num_classes)(x)
 
   model = models.Model(inputs=inputs, outputs=x)
   return model
 
 
# 超参数
input_shape = (224, 224, 3)
patch_size = 16
num_layers = 12
num_patches = (input_shape[0] // patch_size) * (input_shape[1] // patch_size)
embed_dim = 768
num_heads = 12
mlp_dim = 3072
num_classes = 10
dropout_rate = 0.1
 
vit_model = create_vit_model(input_shape, patch_size, num_layers, num_patches, embed_dim, num_heads, mlp_dim, num_classes, dropout_rate)
vit_model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
 
vit_model.summary()

 


 

 

结论

 

ViT作为一种新兴的计算机视觉模型,不仅仅在图像分类任务上表现出色,还为未来的多模态任务(如图像描述生成、视觉问答等)提供了新的思路和可能性。随着对Transformer架构的理解深入和计算资源的增加,ViT模型及其衍生变体有望在更广泛的视觉任务中发挥重要作用。

 

目录
相关文章
Vision Transformer 图像分类识别 基于 ViT(Vision Transformer)的图像十分类 实战 完整代码 毕业设计
Vision Transformer 图像分类识别 基于 ViT(Vision Transformer)的图像十分类 实战 完整代码 毕业设计
563 0
Vision Transformer 图像分类识别 基于 ViT(Vision Transformer)的图像十分类 实战 完整代码 毕业设计
|
存储 人工智能 测试技术
跨模态大升级!少量数据高效微调,LLM教会CLIP玩转复杂文本
LLM2CLIP是一种创新方法,旨在通过利用大型语言模型(LLM)的能力来改进CLIP多模态模型。该方法通过对比学习微调LLM,增强其文本判别性,并将其作为CLIP的强教师,从而显著提升CLIP处理长复杂文本和跨语言任务的能力。实验表明,LLM2CLIP在多个基准测试中优于现有模型,特别是在长文本检索任务上性能提升了16.5%。尽管如此,该方法在实际应用中的鲁棒性和资源需求仍需进一步验证。论文链接:https://arxiv.org/pdf/2411.04997。
588 70
|
机器学习/深度学习 自然语言处理 数据可视化
【自然语言处理(NLP)】基于GRU实现情感分类
【自然语言处理(NLP)】基于GRU实现情感分类,基于百度飞桨开发,参考于《机器学习实践》所作。
1008 1
【自然语言处理(NLP)】基于GRU实现情感分类
|
9月前
|
机器学习/深度学习 算法 测试技术
NSA稀疏注意力深度解析:DeepSeek如何将Transformer复杂度从O(N²)降至线性,实现9倍训练加速
本文将深入分析NSA的架构设计,通过详细的示例、可视化展示和数学推导,构建对其工作机制的全面理解,从高层策略到底层硬件实现均有涉及。
720 0
NSA稀疏注意力深度解析:DeepSeek如何将Transformer复杂度从O(N²)降至线性,实现9倍训练加速
|
2月前
|
人工智能 运维 数据可视化
老金靠Claude Code+OpenClaw从零写完中英多Agent学术论文,可我英语没过四级代码不会写
昨晚23点多,论文在Zenodo(学术论文发布平台)上提交成功了。 老金我盯着屏幕,有点不真实。 ​ ![Image](https://ucc.alicdn.com/pic/developer-ecology/p3shvhj26rigq_b5989ef70caa44bd828c5456218c15b4.png) ​ 不是因为论文有多牛。 而是这件事本来不应该发生在我身上。 英语没
|
并行计算 Python
Python错误笔记(一):CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up env
这篇文章讨论了CUDA初始化时出现的未知错误及其解决方案,包括重启系统和安装nvidia-modprobe。
2067 0
|
机器学习/深度学习 计算机视觉
深度学习原理篇 第七章:Deformable DETR
简要介绍Deformable DETR的原理和代码实现。
3273 1
|
数据可视化 计算机视觉
【计算机视觉】DINOv2的四种模型代码示范(含源代码)
DINOv2利用最大模型ViT-g的知识蒸馏,而不是从头开始训练,从而提高了性能。这个过程包括将知识从更大、更复杂的模型(教师)转移到更小的模型(学生)。学生模型被训练来模仿教师的输出,从而继承其优越的能力。这个过程提高了小型模型的性能,使它们更有效率。
5188 0
|
机器学习/深度学习 算法 数据挖掘
【检测|RCNN系列3】原理+源码彻底搞懂Faster RCNN(文末下载论文)
【检测|RCNN系列3】原理+源码彻底搞懂Faster RCNN(文末下载论文)
4038 0