引言:在本篇文章中,将探索和解析VGG-16模型,它的网格结构简洁,直观且统一,可以更方便地了解和学习卷积神经网络(CNN)的运行过程。本文不仅会详细阐述VGG-16的模型结构,而且还会介绍一些神经网络的通用基础概念,如神经网络层、神经元、激活函数和损失函数等。同时,还将简单介绍在模型训练过程中可能遇到的常见问题,如欠拟合、过拟合、梯度消失和损失无法收敛等。目的是分享和记录卷积神经网络的基本工作原理,以便为后续掌握和使用更复杂的神经网络奠定基础。
1.先看效果
可以看到我们用简单的几行代码,就可以使用VGG-16模型对图片进行识别预测,其中预测结果取了概率最高的前3条('ImageNet数据集对应的编号','预测结果','图片是该预测结果的概率')。
①:VGG-16:卷积神经网络的一种,2014年ImageNet图像分类竞赛亚军。
②:ImageNet数据集:ImageNet是一个大型视觉数据库,由150万+张标注图像,1000个类别组成。
Python
# tensorflow
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
# matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# 读取图片
from tensorflow.keras.preprocessing import image
import numpy as np
import os
# 获取测试数据
def get_files_in_directory(dir_path):
files = []
for root, dirs, filenames in os.walk(dir_path):
for filename in filenames:
files.append(os.path.join(root, filename))
return files
dir_path = './source' # 替换为你的识别图片目录的路径
files = get_files_in_directory(dir_path)
# 加载VGG16模型
model = VGG16(weights='imagenet') # 加载基于imagenet数据集训练模型生成的参数
for file in files:
# 读取图片
img = mpimg.imread(file)
# 用pyplot显示图片
imgplot = plt.imshow(img)
# 显示
plt.show()
# 模型加载图片
img = image.load_img(file, target_size=(224, 224)) # VGG16需要224x224的图片输入
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0) # 添加一维,变为四维,调整数据格式为符合模型输入数据的要求
x = preprocess_input(x) # 这会对输入执行必要的预处理,如去均值,归一化,等等
print('x_shape: ', x.shape) # 打印看下输入数据x维度
# 进行预测
predictions = model.predict(x)
# 打印预测结果
print('Predicted:', decode_predictions(predictions, top=3)[0]) # 取Top3
图片 | 目标结果 | 预测结果Top3 |
---|---|---|
东北虎 | 1. ('n02129604', 'tiger', 0.6801439)2.('n02123159', 'tiger_cat', 0.31981966)3. ('n02128925', 'jaguar', 2.3440358e-05) | |
小狗 | 1.('n02113023', 'Pembroke', 0.4605935)2.('n02112018', 'Pomeranian', 0.23562871)3.('n02085620', 'Chihuahua', 0.14339921) | |
非洲象 | 1.('n02504458', 'African_elephant', 0.9118622)2.('n01871265', 'tusker', 0.07037202)3.('n02504013', 'Indian_elephant', 0.017765094) |
2 为什么能够识别图片并做出判断
2.1 识别图片
在模型视角下识别的是图片像素信息。先看下上述代码中标红部分打印出输入图片的数据维度print('x_shape: ', x.shape),结果是x_shape: (1, 224, 224, 3)可以看出输入图片的数据是个四维数组,其中(224,224)是输入图片大小,即输入图片包含224*224个像素点,3指的就是组成像素点的RGB三原色,1是添加一个维度,调整数据格式为符合VGG16模型输入数据格式的要求。
①:VGG16模型输入数据格式:VGG16模型接受输入图片维度为四维,四个维度分别代表:
-
图片数据的批次大小(Batch Size): 用来告诉网络一次处理多少张图片。
-
图片的高度(Height): 图片的垂直维度。
-
图片的宽度(Width): 图片的水平维度。
-
颜色通道数(Color Channels): 对于彩色图片,颜色通道数通常为3(RGB三通道)。对于灰度图,则为1。
例如,如果要使用VGG16来处理500张224x224像素的彩色图片,那么输入数据的形状就应该是(500, 224, 224, 3)
2.2 图像数据预处理简介
数据预处理是图像模型训练和识别非常重要的一个过程,数据的质量,直接决定了模型的预测和泛化能力的好坏。而图像预处理方法不是固定的标准,需要根据实际的任务需要进行选择。常用的方法有图像缩放、图像归一化、去均值、数据增强、灰度处理等
比如:当模型复杂度远高于数据集量级时会出现过拟合现象,这种场景下在模型训练时,为了提高模型的精度和泛化能力,经常会使用数据增强方法(如随机旋转、翻转、缩放、剪切、色彩变换等)来扩充训练数据
2.2.1 VGG16模型采用的图像预处理方式
1.图像缩放;2.图像去均值化。
-
图像缩放:图像缩放很好理解,上述篇幅也介绍了VGG16的输入层期望224x224像素的RGB图像。因此,所有的输入图像都需要先调整至此尺寸。
-
图像去均值化:是指将输入数据的每个特征减去该特征的平均值,这样处理后,这个特征的新均值就为0。这样做可以消除特征之间的共线性,有利于梯度下降的收敛,使得优化器更容易找到最优解。去均值也可以减少模型对特定数据集的依赖,使模型具有更好的泛化能力。具体操作如下:
-
计算整个训练集中所有图像的RGB三通道的均值。
-
在训练模型时,将每张待训练图像的RGB值分别减去对应通道的均值。
-
2.3 计算并获取图片分类
下图描述的是一张图片输入到VGG16模型后格式变化过程,后文会详细介绍该过程。最终图片经过模型计算得到一个形状为(1, 1000)的数组,其中存储的数值就是待预测图片所属1000个种类中每个种类的概率。通过模型结构也可以看出来VGG16只支持1000种类型的图像分类,本质上也是受使用的ImageNet数据集图片种类以及模型结构设计的影响。
图1 VGG16体系结构
3 VGG16模型结构
3.1 CNN解决了什么问题
在CNN出现之前,图像处理面临着一些挑战。一方面,由于图像本身含有大量的信息,处理成本高且效率低。以一张灰度图为例,如果其大小为512 x 512,那么它的输入参数就超过了25w个,而对于颜色更加丰富的彩色图,如1024 x 1024 x 3的图片,数据量就超过了300w,对计算能力的需求极高。另一方面,图像数字化过程中很难保留原有特征,导致处理结果可能并不准确。
CNN恰好能够解决这些问题。CNN能够通过卷积核提取图像局部特征,并在此过程中可以缩减图像数据量级,降低了计算成本和复杂性,从而提高了计算效率。
3.2 VGG系列模型简介
下图是VGG系列模型结构图,VGG系列模型主要证明了两个理论:
-
神经网络的深度(即层数)对模型识别效果有着至关重要的影响。VGG模型相较于其它模型增加了模型结构的深度,使用重复的模块逐渐增大网络深度,从而取得了在图像识别领域更好的效果。
-
小尺寸的滤波器(如3x3)是有效的。VGG模型使用了多层3x3的小尺寸卷积核堆叠来代替大尺寸卷积核,提升了网络对图像细节的识别能力。
其中D列就是VGG16模型的神经网络层次结构。他由13个卷积层(cov3),5个最大池化层(maxpool)和3个全连接层(FC)组成。
图2 VGG系列模型结构
3.3 VGG16神经网络层次介绍
3.3.1 卷积层
卷积层是卷积神经网络的核心部分,它通过使用卷积核对图像进行特征提取。卷积核对图像的每个局部区域进行加权求和,并且通过训练学习到图像中有用的特征。卷积层的输出是一个特征图,它表示了图像中每个位置的特征。卷积核的特征:
-
卷积核大小:决定了覆盖的像素范围,明确了提取多大的相邻像素间的相关特征。
-
卷积核形状:绝大多数卷积核都是正方形的,如:1 × 1、3 × 3、5 × 5、7 × 7都是常见的卷积核形状,但是也可以使用其他形状,如矩形。
-
卷积核权值:卷积核中的每一个元素都有一个权重,卷积核的权重是通过训练数据学习得到的,每个元素的权重值影响了输出的结果。
-
卷积核数量:每个卷积核可以生成一个特征图,不同的卷积核可以提取图像的不同特性,每个卷积核的通道数和输入图像的颜色通道数相同,如:如果处理的是彩色图像,那么每个卷积核应该有三个通道,每个通道分别对应输入图像的一个通道最终该卷积核三个通道形成一张输出特征图。如果处理的是灰度图像,只有一个通道,那么卷积核也只有一个通道。一个卷积层可以包含多个卷积核,卷积核数量决定了输出图像的通道数,即最终卷积层输出的特征图数量。如果有些懵,可以参考图3、图4进行结合理解。
-
步长:卷积核步长是指卷积核在输入数据上滑动的步数。比如设置为1,那么卷积核每次向右或向下移动一个像素;设置为2,那么卷积核每次向右或向下移动两个像素。步长的设置影响输出数据的大小,步长越大,输出尺寸越小。
-
填充:当卷积核移动步长超过图像边界,需要考虑是否进行图像数据填充。填充的数值通常为0。一般有两种填充模式
如下图3、图4展示了卷积核进行卷积的过程。个人认为这两张图能够非常清晰描述卷积过程。
图3 卷积+全局平均池化过程(可忽略)
图4 卷积过程
在VGG16模型结构中,卷积核为3 × 3正方形,步长被设置为1,填充模式为"same"模式,所以可以看到图1 VGG16体系结构中图像经过卷积层卷积过后尺寸都没有发生变化,只有通道数发生了变化,变化为了该卷积层使用的卷积核的数量。如下展示了部分经过卷积层处理后输出的特征图。
原始图像 | block1_conv1 | block1_conv2 | ······ | block3_conv1 | block3_conv2 | block3_conv3 | ······ | block5_conv1 | block5_conv2 | block5_conv3 | ······ |
---|---|---|---|---|---|---|---|---|---|---|---|
3.3.2 池化层
池化层是卷积神经网络中的一个可选部分,它用于减少特征图的大小。池化层通过对特征图进行下采样来减少特征图的大小,并且通过训练学习到图像中有用的信息。池化层有池化窗口,池化窗口不需要有参数,计算的参数是经过卷积计算后输入特征图数据,常用的池化操作包括最大池化和平均池化。这两者没有绝对的优劣之分,取决于具体的应用场景和问题。
-
最大池化层(Max Pooling):最大池化是在池化窗口内取最大值作为该窗口的输出。这样做的好处是能够保留最突出的特征,并且在很大程度上保持了躁声的不变性。也就是说,即使输入有轻微偏移或旋转,最大值的位置可能变动不大,从而在输出上表现出稳定性。
-
平均池化层(Average Pooling):平均池化则是在池化窗口内取所有值的平均数作为该窗口的输出。与最大池化相反,平均池化可以平滑并减小突出值的影响,从而让模型更关注整体的特征,而不只是一部分最突出的特征。
VGG16池化层采用2 × 2池化窗口,步长为2,池化窗口数量与输入特征图数量一致,方式选用最大池化层。经过池化层降采样后输出特征图的数量不变,长、宽变为输入特征图像尺寸一半。如下展示了部分卷积层经过池化层处理后的降采样特征图。
原始图像 | ······ | block1_conv2 | block1_pool | ······ | block3_conv3 | block3_pool | ······ | block5_conv3 | block5_pool | ······ |
---|---|---|---|---|---|---|---|---|---|---|
3.3.3 全连接层
全连接层由输出层和输入层组成,输入层和输出层由神经元组成,输入层和输出层之间的连接有权重,如下图5展示了神经元结构,图6展示了全连接层的结构。全连接层将特征图中的每个像素连接到一个神经元上,并通过训练学习到图像中有用的信息。全连接的最后一层输出层的神经元数量决定了分类的类别数,输出层结果表示了输入图像的分类结果。
图5 神经元模型
其中f指的是激活函数,激活函数的主要作用是提供非线性特性,由于大多数真实世界的数据都是非线性的,非线性激活函数可以帮助神经网络更好地学习和理解这种复杂的、非线性的数据模式。如下表格展示了一些常用的激活函数
sigmoid | tanh | softmax | relu | elu | leaky_relu | |
---|---|---|---|---|---|---|
公式 | f(x) = 1 / (1 + e^-x) | f(x) = (e^x - e^-x) / (e^x + e^-x) | f(xi) = e^xi / Σe^xj | f(x) = max(0, x) | if x > 0, f(x) = xif x <= 0, f(x) = a*(e^x - 1) | f(x) = max(ax, x) |
图像 | ||||||
特点 | Sigmoid函数会将任意值转换到0和1之间。它在早期的神经网络中广泛应用,但现在已经很少使用,因为在梯度很大或很小的位置,Sigmoid函数的梯度接近于0,导致优化过程中的"梯度消失"问题 | Tanh函数是双曲正切函数,它将任意值转换到-1和1之间。与Sigmoid函数类似,Tanh函数在取值接近1和-1的位置梯度接近于0,可能产生"梯度消失"问题 | Softmax函数常用于多分类问题的输出层。它可以将输入转换为概率分布,使所有输出值的总和为1 | ReLu函数是目前最常用的激活函数。它在0处斜率突变,负数部分为0,正数部分为线性。这种形式可以加速神经网络的训练,因为它的梯度要么是0要么是1,没有Sigmoid函数"梯度消失"的问题 | 和ReLU类似,但是在输入值小于0时,输出值是一个负的指数函数,可以缓解梯度消失问题 | Leaky ReLU是ReLU函数的变种。它解决了ReLU函数在输入值小于0时,梯度为0的问题。当输入为负时,Leaky ReLU有一个小的正斜率 |
图6 全连接层
以VGG16模型为例子,最后一层最大池化层输出特征图是一个多通道的二维特征图,尺寸为(7,7,512),全连接层是一维向量,所以为了与全连接层进行连接,首先需要对这个二维特征图进行拉平操作,那么第一层全连接层的输入向量长度为7 × 7 × 512 = 25088,即包含25088个神经元,输出层向量长度为4096,即包含4096个神经元,最后一层全连接层的输出层向量长度为1000,即包含1000个神经元且模型能够做1000个类别的图像分类。
4 模型参数的确定
VGG16模型的参数是通过深度学习训练过程来确定的。这个过程主要包括以下步骤:
-
初始化:初始化模型的参数,包括卷积核的权重和偏值,全连接层神经元权重和偏值。通常采用小的随机数(例如:正态分布或均匀分布)进行初始化。
-
前向传播:然后,输入一张图像传入模型,通过一系列卷积层、激活函数和池化层进行运算,得到模型的输出。
-
计算损失:比较模型的输出和真实的标签,计算出损失函数的值。VGG16模型通常使用交叉熵损失函数。
-
反向传播:根据损失函数对模型的参数进行微分,计算出每个参数的梯度。这个过程我们通常称之为反向传播。
-
更新参数:使用一个优化算法(例如:随机梯度下降)更新模型的参数。优化算法会根据每个参数的梯度调整其值,以使损失函数的值减小。
其中1、2过程很好理解,主要聊一下3、4、5过程。
4.1 损失函数计算损失
首先介绍一下损失函数,损失函数在机器学习和深度学习模型中扮演着非常重要的角色,用来衡量模型预测结果与实际值之间的误差。损失函数是根据模型的预测结果和实际值计算得出的一个数值,这个数值越小,说明模型的预测结果与实际值越接近,也就是说模型的性能越好,在模型训练过程中,我们会不断地通过优化算法(例如:梯度下降算法)来更新模型的参数,使得损失函数的值达到最小。如下表格展示了两个常用的损失函数
均方误差损失 | 交叉熵损失 | |
---|---|---|
公式 | MSE:损失数值n:样本数量yᵢ:样本i的真实值ŷᵢ:样本i的预测值 | L:损失数值n:样本数量yᵢ:样本i的真实标签,正类为1,负类为0pᵢ:样本i预测为正类的概率 L:损失数值n:样本数量M:类别数量yᵢc:符号函数,如果样本i真实类别为c取1,否则取0pᵢc:样本i属于类别c的预测概率 |
图像 | 注:假设真实值为1 | 注:二分类场景,假设真实值为1 |
特点 | MSE 损失对于异常值非常敏感,因为异常值会被平方,从而放大了它们的影响。另一方面,MSE 损失易于计算梯度,且 MSE 在数学上具有非常好的性质。常用于回归任务的损失函数。 | 交叉熵损失常用于处理分类问题,特别是在处理多分类问题时效果较好。它优于 MSE 损失的一点是它不仅仅关心预测值与真实标签之间的差异,而且关心预测值本身的确定性。是常用于分类任务的损失函数。 |
4.2 反向传播算法更新参数
- 含义
在训练过程中,网络会根据输出结果和真实标签计算出损失函数的值,然后采用梯度下降等优化算法更新网络中的参数,以最小化损失函数。梯度下降算法主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。公式如下,其中α表示学习率:
在数学中,一个函数的梯度方向(函数的微分)就是该函数上升最快的方向,那么朝着梯度相反的方向就是该函数下降最快的方向。在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率;在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向**。**这个过程和下山的过程很类似。
图7 梯度下降算法大致原理
- 简单示例说明算法执行过程
假设我们目标函数如下,要求求出该函数最小值
现在要通过梯度下降法计算这个函数的最小值。我们通过观察就能发现最小值其实就是 (0,0)点。接下来,我们会从梯度下降算法开始一步步计算到这个最小值! 我们假设初始的起点为,初始学习率为α = 0.1:
获取函数梯度:
则:
进行多次迭代:
.
.
.
.
.
.
.
.
.
此时,可以发现,经过100次迭代计算,已经基本靠近函数的最小点。
VGG16使用的是多分类交叉熵损失函数,那么对于VGG16来说整个反向传播过程使用梯度下降算法,求该函数的最小值,并在这个过程中不断更新网络中的参数。
4.3 更新参数中可能遇到的问题
4.3.1 梯度消失&梯度爆炸
- 概念
梯度消失问题:当神经网络的层数很深时,神经网络在反向传播过程中,由于梯度经过每一层都会乘那一层的权重,如果这个权重小于1,那么梯度在传播的过程中就会不断衰减,这样就会导致梯度越来越小,最终接近于0,无法有效的更新网络的参数,这称为梯度消失。在使用Sigmoid和tanh作为激活函数的神经网络中,这种问题尤为严重,因为这两者的导数值在绝对值上都不超过1。
梯度爆炸问题:相反,如果权重大于1,那么梯度在反向传播的过程中就会不断增大,可能会导致梯度值变得十分巨大。这样不仅会引起训练的不稳定性,还可能会导致数值溢出。这种现象被称为梯度爆炸。梯度爆炸问题多见于循环神经网络(RNN)。
- 解决方法
对于梯度消失问题,可以尝试使用ReLU及其变体作为激活函数,或者使用批量归一化(Batch Normalization),引入残差连接(Residual Connection)等方法。
对于梯度爆炸问题,可以使用梯度剪裁(Gradient Clipping)等方法,限制梯度的最大值,避免梯度过大。
4.3.2 过拟合和欠拟合
- 基本含义
过拟合和欠拟合都是机器学习中经常遇到的问题。首先来看一下两者的产生原因。
过拟合:当模型过于复杂,或者训练数据量较小,模型可能会过度学习训练数据中的噪声,出现过拟合。模型出现过拟合问题时,它会在训练数据上表现得非常好,但在测试数据上效果却往往不佳。换句话说,过拟合就是模型"过度"地学习了训练数据。
欠拟合:当模型过于简单,无法学习到数据中的复杂结构时,可能会出现欠拟合。模型在训练数据上的表现就已经不足够好,它没能学习到数据的一般性质,导致模型对于新的数据预测能力也非常差。
- 解决方法
避免过拟合和欠拟合的方法主要有:解决模型欠拟合需要提供更多的训练数据;解决模型过拟合需要选择适当的模型复杂度,使用正则化方法等。
- 效果模拟
下面用一个简单的例子描述模型欠拟合和过拟合现象,我们在二次函数基础上增加一些噪声分别使用2个参数的一次函数、3个参数的二次函数和10个参数的高次函数去做拟合,创建一些测试数据,验证这些拟合模型的输出效果。结果如下图8所展示。最左边的图像是2个参数一次函数拟合的效果,可以看出因为模型过于简单,无法对样本数据做到很好的拟合,此现象就被称为欠拟合。中间图像使用3个参数的二次函数进行拟合,可以看到拟合效果还是不错的。最右边图像是高次函数拟合效果,因为模型过于复杂,完全适应了训练数据点,但是和我们起初设计的二次函数的目标差距很大,在新数据点的预测上会有很大的误差。
我们尝试增大训练数据集数量至1000,可以看到图9展示各个模型的拟合效果,一次函数欠拟合情况并没有任何改善,最右边过拟合有了很好的改善,也印证了上述过拟合优化手段。
Python
import numpy as np
import matplotlib.pyplot as plt
# 创建输入数据,相当于x,范围在-1到1之间的10个数的平方并加上一些随机噪声
np.random.seed(0)
x = np.linspace(-1, 1, 10)
y = np.power(x, 2) + np.random.normal(0, 0.1, size=x.shape)
# 创建测试数据,相当于x,范围在-1到1之间的100个数
x_test = np.linspace(-1, 1, 100)
# 欠拟合,选择2个参数的一次函数进行拟合
params1 = np.polyfit(x, y, 1)
y_fit1 = np.polyval(params1, x_test)
# 适度拟合,选择3个参数的二次函数进行拟合
params2 = np.polyfit(x, y, 2)
y_fit2 = np.polyval(params2, x_test)
# 过拟合,选择10个参数的九次函数进行拟合
params3 = np.polyfit(x, y, 9)
y_fit3 = np.polyval(params3, x_test)
# 绘制拟合曲线和原数据点
plt.figure(figsize=(18, 4))
plt.subplot(131)
plt.scatter(x, y, label='data')
plt.plot(x_test, y_fit1, 'r', label='under-fitting')
plt.legend()
plt.subplot(132)
plt.scatter(x, y, label='data')
plt.plot(x_test, y_fit2, 'r', label='proper-fitting')
plt.legend()
plt.subplot(133)
plt.scatter(x, y, label='data')
plt.plot(x_test, y_fit3, 'r', label='over-fitting')
plt.legend()
plt.show()
图8 一次函数、二次函数、高次函数模拟欠拟合和过拟合
图9 调大训练集数据一次函数、二次函数、高次函数拟合效果
4.3.3 损失不收敛
损失函数不收敛可能有许多原因,下面列举了一些常见的原因和可能的解决方法:
-
欠拟合和过拟合问题,采取上述对应的解决方法。
-
损失函数选择不当:如果选用的损失函数与实际问题不匹配,也可能导致模型训练不收敛。对于不同类型的任务(如:分类、回归等),应选择合适的损失函数。
-
梯度消失或梯度爆炸:深度神经网络在训练时,可能会遇到梯度消失或梯度爆炸的问题,从而导致损失无法收敛。使用ReLU等激活函数或者Batch Normalization等技术可以缓解这个问题。
-
学习率过高或过低:如果学习率设置得过高,优化算法可能会在最小值附近震荡并且无法收敛;如果学习率过低,训练过程将非常缓慢,可能在有限的迭代次数内无法收敛。解决方法是尝试不同的学习率,或者使用自适应学习率的优化方法(如:Adam)。
-
数据问题:如果数据存在大量的噪声,或者标签错误,可能会导致模型无法收敛。解决方法是对数据进行清洗,检查并减少错误标签。
-
初始化问题:如果模型参数的初始化不恰当,可能导致训练过程很难收敛。一般情况下,我们会使用小的随机数来初始化模型的参数。
5 扩展
-
大语言模型为什么可以根据不同的场景输出各种结果,而分类模型只能输出固定数据(transformers.run/back/transf...
-
大语言模型用的Transformer 模型结构,像GPT系列,是一种Transformer 模型结构下的一种自回归模型,模型在给定一段文本的情况下预测下一个词的概率分布,并根据概率选择下一个词。这种过程在一个长序列中持续迭代,形成一个逐字生成文本的过程。由于语言的多样性,模型能够根据不同的输入和随机性输出各种各样的结果。
-
分类模型则不同。分类任务是预测输入数据的离散标签,它是从预定义的分类列表中对输入进行分类,它的输出可能性由问题本身的设定。因此,对于一个给定的输入,分类模型的输出是固定的一组可能的类别标签,即使有新的输入,输出的类别也不会增加。
-
-
图像识别、分类更优的模型和发展方向,Visual Transformer(Vit)。是由Google团队在2020年提出的,它将Transformer结构应用于图像分类任务。ViT模型的核心思想是将图像数据转换为序列数据,以便使用基于自注意力机制的Transformer模型进行处理,在大规模数据集上表现出了更加优越的效果。
-
什么是影响神经网络发展的原因
-
算力
-
训练数据集量级
-
神经网络的设计
-
参考文章: