昇思25天学习打卡营第8天 |昇思MindSpore Vision Transformer(ViT)学习总结

一、前言

今天探索一个新的深度学习模型——Vision Transformer(ViT)。Transformer 在自然语言处理领域那可是大名鼎鼎,如今跨界到计算机视觉领域,照样大放异彩!

二、操作流程总结

  1. 环境准备与数据读取
    • 安装 Python 和 MindSpore 等必要环境。
    • 下载并解压 ImageNet 数据集的子集。
    • 示例代码:
from download import download
dataset_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/vit_imagenet_dataset.zip"
path = "./"
path = download(dataset_url, path, kind="zip", replace=True)

import os
import mindspore as ms
from mindspore.dataset import ImageFolderDataset
import mindspore.dataset.vision as transforms

data_path = './dataset/'
mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
std = [0.229 * 255, 0.224 * 255, 0.225 * 255]

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),
    transforms.Normalize(mean=mean, std=std),
    transforms.HWC2CHW()
]

dataset_train = dataset_train.map(operations=trans_train, input_columns=["image"])
dataset_train = dataset_train.batch(batch_size=16, drop_remainder=True)
- 这段代码主要进行了数据集的下载、读取、预处理和批处理操作。其中,`ImageFolderDataset` 用于读取数据集,`map` 函数用于对数据进行各种转换操作,`batch` 函数用于将数据分组为批次。
  1. 模型解析
    • 理解 Transformer 的基本原理,包括 Encoder 和 Decoder 结构,重点是其中的多头注意力机制。
    • 剖析 Self-Attention 机制,包括如何将输入向量映射为 Q、K、V 以及计算注意力权重和最终输出。
    • 构建 Transformer Encoder 部分,包括 Feed Forward、Residual Connection 等结构。
    • 解析 ViT 模型的输入处理,如将图像划分为 patch 并转换为一维向量,以及添加 class_embedding 和 pos_embedding。
    • 构建完整的 ViT 模型。
    • 示例代码:
class Attention(nn.Cell):
    def __init__(self,
                 dim: int,
                 num_heads: int = 8,
                 keep_prob: float = 1.0,
                 attention_keep_prob: float = 1.0):
        super(Attention, self).__init__()

        self.num_heads = num_heads
        head_dim = dim // num_heads
        self.scale = ms.Tensor(head_dim ** -0.5)

        self.qkv = nn.Dense(dim, dim * 3)
        self.attn_drop = nn.Dropout(p=1.0 - attention_keep_prob)
        self.out = nn.Dense(dim, dim)
        self.out_drop = nn.Dropout(p=1.0 - keep_prob)
        self.attn_matmul_v = ops.BatchMatMul()
        self.q_matmul_k = ops.BatchMatMul(transpose_b=True)
        self.softmax = nn.Softmax(axis=-1)

    def construct(self, x):
        """Attention construct."""
        b, n, c = x.shape
        qkv = self.qkv(x)
        qkv = ops.reshape(qkv, (b, n, 3, self.num_heads, c // self.num_heads))
        qkv = ops.transpose(qkv, (2, 0, 3, 1, 4))
        q, k, v = ops.unstack(qkv, axis=0)
        attn = self.q_matmul_k(q, k)
        attn = ops.mul(attn, self.scale)
        attn = self.softmax(attn)
        attn = self.attn_drop(attn)
        out = self.attn_matmul_v(attn, v)
        out = ops.transpose(out, (0, 2, 1, 3))
        out = ops.reshape(out, (b, n, c))
        out = self.out(out)
        out = self.out_drop(out)

        return out
- 在 `Attention` 类中,`dim` 表示输入的维度,`num_heads` 决定了多头注意力的头数,`keep_prob` 和 `attention_keep_prob` 用于控制 dropout 的概率。`construct` 方法实现了多头注意力的计算过程。
  1. 模型训练与推理
    • 设定损失函数、优化器、回调函数等进行模型训练。
    • 进行模型验证,评估准确率等指标。
    • 对图像进行推理,展示预测结果。
    • 示例代码:
class CrossEntropySmooth(LossBase):
    """CrossEntropy."""

    def __init__(self, sparse=True, reduction='mean', smooth_factor=0., num_classes=1000):
        super(CrossEntropySmooth, self).__init__()
        self.onehot = ops.OneHot()
        self.sparse = sparse
        self.on_value = ms.Tensor(1.0 - smooth_factor, ms.float32)
        self.off_value = ms.Tensor(1.0 * smooth_factor / (num_classes - 1), ms.float32)
        self.ce = nn.SoftmaxCrossEntropyWithLogits(reduction=reduction)

    def construct(self, logit, label):
        if self.sparse:
            label = self.onehot(label, ops.shape(logit)[1], self.on_value, self.off_value)
        loss = self.ce(logit, label)
        return loss
- 在 `CrossEntropySmooth` 类中,`sparse` 表示标签是否为稀疏格式,`reduction` 决定了损失的归约方式,`smooth_factor` 用于平滑标签,`num_classes` 表示类别数量。`construct` 方法计算了平滑交叉熵损失。

三、个人思考与阐述

ViT 模型巧妙地把 Transformer 的架构应用到图像领域,打破了传统卷积神经网络的常规。

就像把图像切成小块(patch),然后通过复杂但有效的注意力机制去分析它们之间的关系,这简直是天才的想法!多头注意力机制就像是一群聪明的小精灵,从不同角度深入挖掘图像的特征,让模型能够捕捉到更丰富、更全面的信息。

在代码实现中,各种参数的设置和函数的设计都非常精妙。比如 Attention 类中的头数和维度设置,影响着模型对特征的关注和提取能力;CrossEntropySmooth 类中的平滑因子和类别数量等参数,对损失的计算和模型的优化方向有着重要的引导作用。

不过,ViT 也不是毫无挑战。它的训练需要大量的计算资源和时间,这就像是一场艰苦的马拉松。但正是这些挑战,推动着我们不断探索更高效的训练方法和更优秀的模型架构。

总的来说,学习 ViT 就像是开启了一扇通往新世界的大门,让我们看到了深度学习在计算机视觉领域的无限可能!期待未来能有更多令人惊喜的创新和突破!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值