当前位置:   article > 正文

昇思MindSpore 应用学习-Vision Transformer图像分类

昇思MindSpore 应用学习-Vision Transformer图像分类

昇思MindSpore 应用学习-Vision Transformer图像分类(AI 代码解析)

Vision Transformer图像分类

Vision Transformer(ViT)简介

近些年,随着基于自注意(Self-Attention)结构的模型的发展,特别是Transformer模型的提出,极大地促进了自然语言处理模型的发展。由于Transformer的计算效率和可扩展性,它已经能够训练具有超过100B参数的空前规模的模型。
ViT则是自然语言处理和计算机视觉两个领域的融合结晶。在不依赖卷积操作的情况下,依然可以在图像分类任务上达到很好的效果。

模型结构

ViT模型的主体结构是基于Transformer模型的Encoder部分(部分结构顺序有调整,如:Normalization的位置与标准Transformer不同),其结构图[1]如下:

模型特点

ViT模型主要应用于图像分类领域。因此,其模型结构相较于传统的Transformer有以下几个特点:

  1. 数据集的原图像被划分为多个patch(图像块)后,将二维patch(不考虑channel)转换为一维向量,再加上类别向量与位置向量作为模型输入。
  2. 模型主体的Block结构是基于Transformer的Encoder结构,但是调整了Normalization的位置,其中,最主要的结构依然是Multi-head Attention结构。
  3. 模型在Blocks堆叠后接全连接层,接受类别向量的输出作为输入并用于分类。通常情况下,我们将最后的全连接层称为Head,Transformer Encoder部分为backbone。

下面将通过代码实例来详细解释基于ViT实现ImageNet分类任务。
注意,本教程在CPU上运行时间过长,不建议使用CPU运行。

环境准备与数据读取

开始实验之前,请确保本地已经安装了Python环境并安装了MindSpore。
首先我们需要下载本案例的数据集,可通过http://image-net.org下载完整的ImageNet数据集,本案例应用的数据集是从ImageNet中筛选出来的子集。
运行第一段代码时会自动下载并解压,请确保你的数据集路径如以下结构。

.dataset/
    ├── ILSVRC2012_devkit_t12.tar.gz
    ├── train/
    ├── infer/
    └── val/
  • 1
  • 2
  • 3
  • 4
  • 5
from download import download  # 导入download模块中的download函数

# 定义数据集的URL
dataset_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/vit_imagenet_dataset.zip"

# 定义下载的保存路径
path = "./"  # 当前目录

# 调用download函数下载数据集
path = download(dataset_url, path, kind="zip", replace=True)  # 下载数据集并指定为zip文件,若已存在则替换
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. from download import download:
    • 这一行代码从download模块中导入了download函数。这个函数通常用于从指定的URL下载文件。
  2. dataset_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/vit_imagenet_dataset.zip":
    • 这里定义了一个字符串dataset_url,它包含了要下载的数据集的链接。这个链接指向一个zip文件,包含了ImageNet数据集的一部分。
  3. path = "./":
    • 这行代码定义了一个变量path,其值为当前目录"./"。这意味着下载的文件将保存在当前执行代码的目录中。
  4. path = download(dataset_url, path, kind="zip", replace=True):
    • 这一行调用了download函数:
      • dataset_url: 指定要下载的文件的URL。
      • path: 指定下载后文件的保存路径。
      • kind="zip": 指定下载文件的类型为zip格式。
      • replace=True: 如果文件已存在,则会被替换。
  • download(url, path, kind, replace):
    • url: 要下载文件的链接。
    • path: 文件下载后保存的路径。
    • kind: 指定下载文件的类型,通常为"zip"、"tar"等,适用于不同格式的压缩包。
    • replace: 布尔值,决定是否覆盖已存在的同名文件。设置为True时,若目标路径已有同名文件,则将其替换。
import os  # 导入os模块,用于处理文件和目录路径

import mindspore as ms  # 导入MindSpore库
from mindspore.dataset import ImageFolderDataset  # 从MindSpore中导入ImageFolderDataset类,用于加载图像文件夹数据集
import mindspore.dataset.vision as transforms  # 导入MindSpore的图像处理变换模块

# 定义数据集路径
data_path = './dataset/'  # 存放数据集的路径

# 定义图像的均值和标准差,用于归一化
mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]  # RGB通道的均值
std = [0.229 * 255, 0.224 * 255, 0.225 * 255]    # RGB通道的标准差

# 创建训练数据集
dataset_train = ImageFolderDataset(os.path.join(data_path, "train"), shuffle=True)  # 从指定路径加载训练集,并随机打乱数据

# 定义数据增强与预处理的操作
trans_train = [
    transforms.RandomCropDecodeResize(size=224, scale=(0.08, 1.0), ratio=(0.75, 1.333)),  # 随机裁剪并调整大小
    transforms.RandomHorizontalFlip(prob=0.5),  # 以50%概率进行随机水平翻转
    transforms.Normalize(mean=mean, std=std),  # 对图像进行归一化处理
    transforms.HWC2CHW()  # 将图像从HWC格式转换为CHW格式
]

# 将变换应用于数据集
dataset_train = dataset_train.map(operations=trans_train, input_columns=["image"])  # 对图像列应用预处理操作

# 将数据集分批处理
dataset_train = dataset_train.batch(batch_size=16, drop_remainder=True)  # 将数据集按批次进行处理,每批次16张图像,若不足16张则丢弃
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  1. import os:
    • 导入os模块,以便于处理文件路径和目录操作。
  2. import mindspore as ms:
    • 导入MindSpore库,主要用于深度学习相关任务的计算和模型构建。
  3. from mindspore.dataset import ImageFolderDataset:
    • 从MindSpore的dataset模块中导入ImageFolderDataset类,这个类用于加载存储在文件夹中的图像数据集。
  4. import mindspore.dataset.vision as transforms:
    • 导入MindSpore的视觉处理模块,提供了多种图像预处理和增强的操作。
  5. data_path = './dataset/':
    • 定义数据集的基本路径,假设数据集位于当前目录的dataset文件夹中。
  6. mean** 和 **std:
    • 定义图像在训练过程中使用的均值和标准差,用于归一化处理,有助于改善模型的训练效果。
  7. dataset_train = ImageFolderDataset(os.path.join(data_path, "train"), shuffle=True):
    • 创建一个训练数据集对象,从data_path下的train目录加载图像数据,并在每个epoch结束时随机打乱数据顺序。
  8. trans_train:
    • 定义一个包含多个图像预处理操作的列表:
      • RandomCropDecodeResize: 随机裁剪并调整图像大小到224x224。
      • RandomHorizontalFlip: 随机水平翻转图像,概率为0.5。
      • Normalize: 使用指定的均值和标准差对图像进行归一化处理。
      • HWC2CHW: 将图像格式从高度-宽度-通道(HWC)转换为通道-高度-宽度(CHW)。
  9. dataset_train.map(operations=trans_train, input_columns=["image"]):
    • 将定义的转换操作应用到数据集的“image”列上,对每张图像进行预处理。
  10. dataset_train.batch(batch_size=16, drop_remainder=True):
    • 将数据集分成批次进行训练,每个批次包含16张图像,drop_remainder=True表示如果最后一批数据不足16张,则丢弃该批次。
  • ImageFolderDataset:
    • 用于从指定目录加载图像数据集,接收目录路径和是否打乱数据的参数。
  • transforms.RandomCropDecodeResize:
    • 随机裁剪和调整图像尺寸的变换,允许指定目标尺寸、缩放范围和宽高比范围。
  • transforms.RandomHorizontalFlip:
    • 随机水平翻转图像,接受翻转的概率参数。
  • transforms.Normalize:
    • 对图像进行归一化处理,接受均值和标准差。
  • transforms.HWC2CHW:
    • 转换图像的存储格式,从高度-宽度-通道(HWC)转换为通道-高度-宽度(CHW)。
  • dataset.map():
    • 将指定的操作应用于数据集的指定列。
  • dataset.batch():
    • 将数据集分批处理,指定每个批次的大小以及处理不足一个批次的方式。

模型解析

下面将通过代码来细致剖析ViT模型的内部结构。

Transformer基本原理

Transformer模型源于2017年的一篇文章[2]。在这篇文章中提出的基于Attention机制的编码器-解码器型结构在自然语言处理领域获得了巨大的成功。模型结构如下图所示:

其主要结构为多个Encoder和Decoder模块所组成,其中Encoder和Decoder的详细结构如下图[2]所示:

Encoder与Decoder由许多结构组成,如:多头注意力(Multi-Head Attention)层,Feed Forward层,Normaliztion层,甚至残差连接(Residual Connection,图中的“Add”)。不过,其中最重要的结构是多头注意力(Multi-Head Attention)结构,该结构基于自注意力(Self-Attention)机制,是多个Self-Attention的并行组成。
所以,理解了Self-Attention就抓住了Transformer的核心。

Attention模块

以下是Self-Attention的解释,其核心内容是为输入向量的每个单词学习一个权重。通过给定一个任务相关的查询向量Query向量,计算Query和各个Key的相似性或者相关性得到注意力分布,即得到每个Key对应Value的权重系数,然后对Value进行加权求和得到最终的Attention数值。
在Self-Attention中:

  1. 最初的输入向量首先会经过Embedding层映射成Q(Query),K(Key),V(Value)三个向量,由于是并行操作,所以代码中是映射成为dim x 3的向量然后进行分割,换言之,如果你的输入向量为一个向量序列(
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/863905
推荐阅读
相关标签