【论文精读】Bag of Tricks for Image Classification with Convolutional Neural Networks

这篇文章比较早了,2018年的
摘要
最近在图像分类研究方面取得的大部分进展可以归功于训练程序的改进,如数据增强和优化方法的改变。然而,在文献中,大多数改进要么作为实现细节简要提到,要么只在源代码中可见。在本文中,我们将检验这些改进的集合,并通过消融研究来评估它们对最终模型准确性的影响。我们将展示,通过将这些改进结合在一起,我们能够显著地改进各种CNN模型。例如,我们在ImageNet上将ResNet-50的Top-1验证精度从75.3%提高到79.29%。我们还将证明,在目标检测和语义分割等其他应用领域,提高图像分类精度可以实现更好的迁移学习性能。
1.介绍
自2012年引入AlexNet [15]以来,深度卷积神经网络已经成为图像分类的主要方法。从那时起,各种新的架构被提出,包括VGG [24]、NiN [16]、Inception[1]、ResNet [9]、DenseNet [13]和NASNet [34]。同时,我们也看到了模型精度稳定地提高。例如,在ImageNet [23]上Top-1的验证精度已从62.5%(AlexNet)提高到82.7%(NASNet-A)。
然而,这些进步并不仅仅来自于改进的模型体系结构。训练流程的改进,包括损失函数的变化、数据预处理和优化方法也发挥了主要作用。在过去的几年中,已经提出了大量这样的改进,但受到的关注相对较少。在文献中,大多数只是作为实现细节简要提到,而其他的只能在源代码中找到。
在本文中,我们将检验一些训练过程和模型架构的改进,这些改进提高了模型的精度,但几乎没有改变计算的复杂度。
其中很多都是较小的“技巧”,比如修改特定卷积层的步幅或调整学习速率时间表。然而,总的来说,它们产生了很大的不同。我们将在多个网络架构和数据集上评估它们,并报告它们对最终模型精度的影响。
我们的实验表明有几种技巧可以显著提高精度,同时将它们结合在一起可以进一步提高模型的精度。在应用了所有技巧后,我们将ResNet-50与表1中的其他相关网络进行了比较。请注意,这些技巧将IMageNet上的ResNet-50的top-1的验证精度从75.3%提高到79.29%。它的性能也优于其他更新和改进的网络架构,如SE-ResNeXt-50。此外,我们还证明了我们的方法可以推广到其他网络(Inception V3 [1]和MobileNet [11])和数据集(Place365 [32])。我们进一步证明,用我们的技巧训练的模型在其他领域,如目标检测和语义分割,可以带来更好的迁移学习性能。
在这里插入图片描述

论文大纲
在这里插入图片描述

我们首先在第2节中建立了一个基线训练程序,然后在第三节中讨论了几个适用于新硬件的训练技巧。在第4节中,我们回顾了ResNet的三个小的模型架构调整,并提出了一个新的调整。然后在第5节中讨论了四个额外的训练程序的改进。最后,我们在第6节中研究这些更准确的模型是否可以帮助迁移学习。
我们的模型实现和训练脚本可以在GluonCV中公开获得。
2.训练程序
上图中的算法1中给出了用小批量随机梯度下降训练神经网络的模板。在每次迭代中,我们随机抽取b幅图像来计算梯度,然后更新网络参数。它在经过K轮后停止。算法1中的所有函数和超参数都可以用多种不同的方式来实现。在本节中,我们首先指定算法1的基线实现。
2.1.基线训练程序
我们遵循ResNet的一个广泛使用的实现[8]作为我们的基线。训练和验证之间的预处理管道是不同的。在培训过程中,我们会逐一执行以下步骤:

  • 1.随机采样图像,并解码为32位浮点原始像素值,像素值的范围在[0,255]。
  • 2.随机裁剪一个长宽比在[3/4,4/3]且面积在[8%,100%]中随机采样的矩形区域,然后将裁剪区域调整为224x224的正方形图像。
  • 3.以0.5的概率水平翻转。
  • 4.调整色调、饱和度和亮度,系数都来自[0.6,1.4]。
  • 5.加入一个从正态分布N(0,0.1)中采样的系数的PCA噪声。
  • 6.通过减去123.68、116.779、103.939,然后分别除以58.393、57.12、57.375来使RGB通道标准化。

在验证过程中,我们将每幅图像的短边调整为256像素,同时保持其长宽比。接下来,我们在中心裁剪出224x224的区域,并和训练过程一样将RGB通道规范化。我们在验证期间不执行任何随机增强。
利用Xavier算法[6]初始化卷积层和全连接层的权值。特别地,我们将参数设置为从[−a,a]中均匀抽取的随机值,其中 a = s q r t ( 6 / d i n + d o u t ) a=sqrt(6/d_{in}+d_{out}) a=sqrt(6/din+dout)。这里的 d i n d{in} din d o u t d{out} dout分别是输入和输出通道的大小。所有的偏差都被初始化为0。对于批处理归一化层,γ向量初始化为1,β向量初始化为0
内斯特洛夫加速梯度(NAG)下降[20]用于训练。每个模型在8个Nvidia V100 GPU上进行120次的训练,总批量大小为256。学习率初始化为0.1,然后在第30个、第60个和第90个阶段除以10。

2.2.实验结果
我们评估了三个CNN:ResNet-50[9], Inception v3[1]和MobileNet [11]。对于Inception-v3,我们将输入图像的大小调整为299x299。我们使用ISLVRC2012 [23]数据集,该数据集有130万张图像用于训练和1000个类。验证准确度见表2。可以看出,我们的ResNet-50结果略优于参考结果,而我们的基线Inception-v3和MobileNet由于训练流程的不同准确性略低。
在这里插入图片描述
3.高效的训练
硬件,特别是gpu,近年来发展迅速。因此,许多与性能相关的权衡的最佳选择都发生了变化。例如,现在在训练过程中使用较低的数值精度和更大的批处理规模更有效。在本节中,我们将回顾能够在不牺牲模型精度的情况下实现低精度和大批量训练的各种技术。有些技术甚至可以提高准确性和训练速度。
3.1.大批量培训
小批量SGD将多个样本分组到一个小批中,以提高并行性和降低通信成本。然而,使用大的批处理可能会减缓训练进度。对于凸问题,收敛速度随着批处理大小的增加而减小。对神经网络[25]也有类似的实验结果证明。换句话说,对于相同数量的epoch,与小批量训练相比,大批量训练的模型验证精度降低。[7,14]提出了多个启发式方法来解决这个问题。在下面的段落中,我们将研究四种启发式方法,以帮助扩大单机训练的批量规模。
**线性缩放学习率。**在小批量SGD中,梯度下降是一个随机过程,因为在每个批中样例都是随机选择的。增加批大小不会改变随机梯度的期望,而会减小其方差。换句话说,大批量减少了梯度中的噪声,所以我们可以提高学习率,沿梯度方向取得更大的步长。Goyal等人[7]提出这种按照批大小线性增加学习率对于ResNet-50的训练有效。特别的,如果我们遵循He等人[9]选择0.1作为批量256的初始学习率,那么当改变到更大的批量b时,我们将把初始学习率提高到0.1×b/256。
学习率预热在训练开始时,所有的参数通常都是随机的值,因此远离最终的解决方案。使用过大的学习速率可能会导致数值不稳定。在预热启发式中,我们在开始时使用一个小的学习速率,然后在训练过程稳定[9]时切换到初始学习速率。Goyal等人[7]提出了一种渐进的预热策略,将学习率从0线性提高到初始学习率。换句话说,假设我们将使用前m批(例如5个epoch)来预热,初始学习速率为 η η η,然后在第 i i i批, 1 ≤ i ≤ m 1≤i≤m 1im,我们将学习率设置为 i η / m iη/m iη/m

γ γ γ ResNet网络由多个残差块组成,每个块由多个卷积层组成。给定输入x,假设 b l o c k ( x ) block(x) block(x)是块的最后一层的输出,那么这个残差块就输出 x + b l o c k ( x ) x+block(x) x+block(x)。请注意,块的最后一层可以是批归一化(BN)层。BN层首先对其输入进行标准化,用 x ˉ \bar{x} xˉ表示,然后执行尺度变换。γ和β都是可学习的参数,其元素分别被初始化为1s和0s。在零γ初始化启发式中,我们把位于残差块末端的所有BN层γ 初始化为0。因此,所有的残差块只是返回它们的输入,模拟的网络有更少的层数,并且更容易在初始阶段进行训练。

没有偏差衰减权重衰减通常应用于所有可学习的参数,包括权重和偏差。这相当于对所有参数应用l2正则化,使它们的值趋向0。然而,正如Jia等人[14]所指出的,建议只对权重应用正则化,以避免过拟合。无偏置衰减启发式遵循了这一建议,它只将权重衰减应用于卷积层和全连接层中的权重。其他参数,包括BN层中的偏差、γ和β,都不正则化。请注意,LARS [4]提供了分层的自适应学习速率,并且据报道对于非常大的批大小(超过16K)是有效的。而在本文中,我们将自己限制在单机训练的方法上,在这种情况下,不超过2K的批大小通常会有良好的系统效率。

3.2.低精密度训练
神经网络通常采用32位浮点数(FP32)精度进行训练。也就是说,所有的数字都以FP32的格式存储,算术运算的输入和输出也都是FP32的数字。然而,新的硬件可能增强了针对较低精度的数据类型的算术逻辑单元。例如,前面提到的Nvidia V100在FP32中提供14个TFLOPS,但在FP16中提供超过100个TFLOPS。如表3所示,在V100上,从FP32切换到FP16后,整体训练速度加快了2~3倍。
在这里插入图片描述
尽管性能良好,但是精度降低导致了一个更窄的范围,使得结果更有可能溢出,然后干扰训练进度。[19]等人提出在FP16中存储所有的参数和激活量,并使用FP16来计算梯度。同时,所有参数在FP32中都有一个副本,用于参数更新。此外,将一个标量乘以损失,以更好地将梯度的范围对齐到FP16中,也是一个实际的解决方案。

3.3.实验结果
ResNet-50的评价结果如表3所示。与批大小为256和FP32的基线相比,使用更大的1024批大小和FP16将ResNet-50的训练时间从每个epoch13.3分钟减少到每个epoch4.4分钟。此外,通过给大批量训练叠加所有的启发式,在1024批大小和FP16条案件下训练的模型相比基线模型在top-1准确率上甚至有轻微的0.5%的提高。
所有启发式方法的消融研究见表4。仅通过线性缩放学习率将批处理大小从256增加到1024,将导致top-1精度降低0.9%,而叠加其余三个启发式方法弥补了差距。在训练结束时从FP32切换到FP16并不影响准确性。
在这里插入图片描述
4.模型调整
模型调整是对网络架构的一个小调整,例如改变特定卷积层的步长。这样的调整通常几乎不会改变计算的复杂度,但可能会对模型的精度产生不可忽视的影响。在本节中,我们将使用ResNet作为一个示例来研究模型调整的影响。
4.1.ResNet体系结构
我们将简要介绍ResNet的体系结构,特别是它与模型调整相关的模块。详细信息请参考He等人[9]。ResNet网络由一个输入干、四个后续阶段和一个最终的输出层组成,如图1所示。输入干有一个输出通道为64,步长为2的7×7的卷积,然后是一个3×3的最大池化层,步长也为2。输入干将输入宽度和高度减少4倍,并将其通道大小增加到64。
在这里插入图片描述
从阶段2开始,每个阶段都从一个降采样块开始,然后是几个残差块。在下采样块中,有pathA和pathB。pathA有3个卷积,其内核大小分别为1×1、3×3和1×1。第一个卷积的步长为2,使输入的宽度和高度减半,最后一个卷积的输出通道比前两个大4倍,称为瓶颈结构。pathB使用步幅为2的1×1卷积,将输入形状转换为pathA的输出形状,因此我们可以对两条路径的输出进行求和,得到下采样块的输出。残差块类似于降采样块,只是只使用步幅为1的卷积。
人们可以在每个阶段改变剩余块的数量来获得不同的ResNet模型,如ResNet-50和ResNet-152,其中的数字表示网络中的卷积层数。
4.2.ResNet调整
接下来,我们将重新讨论两个流行的ResNet调整,我们分别称它们为ResNet-B和ResNet-C。然后提出一种新的调整ResNet-D的模型。
ResNet-B这个调整首先出现在ResNet [8]的Torch实现中,然后被多项工作[7,12,27]采用。它改变了ResNet的降采样块。我们观察到,路径A中的卷积忽略了四分之三的输入特征图,因为它使用的内核大小为1×1,步长为2。ResNet-B切换路径A中前两个卷积的步长,如图2a所示,因此不忽略任何信息。因为第二次卷积的核大小为3×3,所以路径a的输出形状保持不变。
在这里插入图片描述
ResNet-C这个调整最初是在Inception-v2[26]中提出的,它也可以在其他实现中找,如SENet [12],PSPNet [31],DeepLabV3 [1],和ShuffleNetV2[21]。观察到卷积的计算代价与该卷积的核的宽度或高度的关系是二次的。7×7卷积比3×3卷积的计算代价贵5.4倍。因此,这个调整用三个3×3卷积替换输入端的7×7卷积,如图2b所示,第一个和第二个卷积的输出通道为32,步长为2,而最后一个卷积有64个输出通道。
ResNet-D受ResNet-B的启发,我们注意到降采样块pathB中的1×1卷积也忽略了3/4的输入特征图,我们想对其进行修改,这样就不会忽略任何信息。根据经验,我们发现在卷积前添加一个2×2的平均池化层,其步幅为1,在实践中效果良好,对计算成本的影响很小。这个调整如图2c所示。
4.3.实验结果
我们用第3节中描述的三个调整和设置来评估ResNet-50,批大小为1024,精度为FP16。结果如表5所示。
在这里插入图片描述
结果表明,ResNet-B在下采样块的路径A中接收到更多的信息,与ResNet- 50相比,验证精度提高了约0.5%。用3个3×3卷积替换7×7卷积,又提高了0.2%。在pathB的下采样块中引入更多的信息再次提高了0.3%。总的来说,ResNet-50-D使ResNet-50提高了1%
另一方面,这四种模型的模型尺寸相同。ResNet-D的计算成本最大,但与ResNet-50相比,它在浮点运算方面的差异在15%以内。在实践中,我们观察到ResNet-50-D的训练吞吐量仅比ResNet-50慢3%。
5.训练改进
在本节中,我们将描述旨在进一步提高模型精度的四种训练改进。
5.1.余弦学习率衰减
学习率的调整是训练的关键。在第3.1节中描述的学习速率预热之后,我们通常会稳步降低初始学习率的值。广泛使用的策略是以指数级衰减学习率。He等人[9]每30个epoch下降0.1,我们称之为“阶梯衰减”。Szegedy等人,[26]每两个时期下降0.94。
与此相反,洛什奇洛夫等人提出了一种余弦退火策略。一个简化的版本是通过遵循余弦函数,将学习速率从初始值降低到0。假设批次总数为T(忽略预热阶段),则在批次t时,学习率 η t η_t ηt的计算为:
在这里插入图片描述
其中,η为初始学习率。我们称这种调度为“余弦”衰减。
阶梯衰减和余弦衰减的比较如图3a所示。可以看出,余弦衰减在开始时缓慢地降低了学习速率,然后在中间几乎呈线性减小,在结束时再次减慢。与阶跃衰减相比,余弦衰减从一开始就开始衰减学习,但直到阶跃衰减使学习率降低了10倍其仍然很大,这可能会提高训练进度。
在这里插入图片描述
5.2.标签平滑
图像分类网络的最后一层通常是全连通层,隐藏层大小等于标签数,用K表示,输出预测置信分数。给定一幅图像,用 z i z_i zi表示第i类的预测分数。这些分数可以通过softmax算子进行归一化,以获得预测的概率。用q表示softmax操作q=softmax(z)的输出,第i类 q i q_i qi的概率可以通过以下方法计算:
在这里插入图片描述
很容易看到 q i > 0 q_i>0 qi>0 q i q_i qi求和为1,所以q是一个概率分布。
另一方面,假设这幅图像的真值为y,如果i = y,我们可以使得其概率为 p i = 1 p_i = 1 pi=1,否则为0。在训练过程中,我们最小化负交叉熵损失使得更新模型参数,使这两个概率分布彼此相似。
在这里插入图片描述
特别地,关于p是如何构造的,我们知道 l ( p , q ) = − l o g p y = − z y + l o g ( ∑ i = 1 K exp ⁡ ( z i ) ) l(p,q)=-logp_y=-z_y+log(\sum^{K}_{i=1}\exp(z_i)) l(p,q)=logpy=zy+log(i=1Kexp(zi))。最优解是 z y ∗ = i n f z^*_y=inf zy=inf,同时保持其他的足够小。换句话说,它鼓励输出分数显著不同,这可能会导致过拟合。
标签平滑的概念最初被提出来训练Inception-v2[26]。它改变真实概率的构造
在这里插入图片描述
其中,ε是一个很小的常数。现在最优解变成了
在这里插入图片描述
其中,α可以是一个任意的实数。这鼓励了来自全连接层的有限输出,并可以更好地推广。
当ε = 0时,gap l o g ( ( K − 1 ) ( 1 − ε ) / ε ) log((K−1)(1−ε)/ε) log((K1)(1ε)/ε)将为∞,并且随着ε的增加,gap减小。特别是当 ε = ( K − 1 ) / K ε =(K−1)/K ε=(K1)/K时,所有最优 z i ∗ z^*_i zi都是相同的(为α)。图4a显示了当我们改变ε时,gap如何变化,给定了K = 1000的ImageNet数据集。
在这里插入图片描述
我们通过实验比较了两个ResNet-50-D模型的输出值,它们分别使用了标签平滑和没有使用标签平滑,并计算了最大预测值与其余预测值的平均值之间的差距。在ε = 0.1和K = 1000条件下,理论差距约为9.1。图4b展示了两个模型在ImageNet验证集上的gap分布。很明显,采用标签平滑后,分布中心在理论值且具有较少的极值。
5.3知识蒸馏
在知识蒸馏[10]中,我们使用一个教师模型来帮助训练当前的模型称为学生模型。教师模型通常是一种预先训练好的、精度较高的模型,因此通过模仿,学生模型能够在保持模型复杂性不变的同时提高自身的准确性。其中一个例子是使用ResNet-152作为教师模型来帮助培训ResNet-50。
在训练过程中,我们添加了一个蒸馏损失来惩罚来自教师模型和学生模型的softmax输出之间的差异。给定一个输入,假设p为真实概率分布,学生模型和教师模型的最后一个全连接层的输出分别为z和r。
记得之前我们使用负的交叉熵损失 l ( p , s o f t m a x ( z ) ) l(p,softmax(z)) l(p,softmax(z))来评估p和z之间的不同,这里我们使用相同的损失函数作为蒸馏损失。因此,损失变为了:
在这里插入图片描述
其中,T为温度超参数,使softmax输出更平滑,从而从教师模型的预测中提取出标签分布的知识。
5.4.混合训练
在第2.1节中,我们描述了在训练前如何增强图像。这里我们考虑另一种增强方法,称为混合[29]。在混合过程中,每次我们随机抽取两个例子 ( x i , y i ) (x_i,y_i) xi,yi ( x j , y j ) (x_j,y_j) xj,yj。然后我们通过这两个例子的加权线性插值形成一个新的样例:
在这里插入图片描述
其中,λ∈[0,1]是从Beta(α,α)分布中抽取的一个随机数。在混合训练中,我们只使用新的样例( x ^ \hat x x^ y ^ \hat y y^)。
5.5.实验结果
现在我们评估这四种训练改进。我们按照Szegedy等人[26]的做法将用于标签平滑的ε 设置为0.1。对于模型蒸馏,我们使用T = 20,特定一个预训练的使用了余弦衰减和标签平滑的ResNet-152-D模型作为教师模型。在混合训练中,我们选择α = 0.2的Beta分布,并将epoch的数量从120增加到200,因为混合训练需要更长的训练epoch来更好地收敛。在将混合训练与蒸馏相结合时,我们也对教师模型进行了混合训练。
我们证明了这些改进不仅局限于ResNet架构或ImageNet数据集。首先,我们在ImageNet数据集上微调了ResNet-50-D、Inception-v3和MobileNet。逐个应用这些训练细化的验证精度如表6所示。通过叠加余弦衰减、标签平滑和混合训练,我们稳步改进了ResNet、Inception-v3和MobileNet模型。蒸馏在ResNet上效果很好,但在Inception-v3和MobileNet上效果不佳。我们的解释是,教师模型不是来自于同一学生模型的统一家族,因此在预测中存在不同的分布,并给模型带来了负面影响。
在这里插入图片描述
为了证明我们的技巧可以转移到其他数据集,我们在MIT Places365数据集上在改进与否两种情况下训练了ResNet-50-D模型。结果见表7。我们看到这些改进在验证和测试集上一致地提高了TOP-5准确性。
在这里插入图片描述
6.迁移学习
迁移学习是训练图像分类模型的一个主要的下游用例。在本节中,我们将研究到目前为止所讨论的这些改进是否可以有利于迁移学习。特别地,我们选择了两个重要的计算机视觉任务,目标检测和语义分割,并通过不同的基础模型来评估它们的性能。
6.1.目标检测
目标检测的目标是定位图像中对象的边界框。我们使用PASCAL VOC [3]来评估性能。与Ren等人的[22]类似,我们分别使用VOC 2007训练验证集和VOC 2012训练验证集的联合集进行培训,并使用VOC 2007测试集进行评价。我们在这个数据集上训练了Faster-RCNN[22],并对Detectron[5]进行了改进,如线性预热和较长的训练计划。在前面的讨论中,Faster-RCNN中的VGG-19基础模型被各种预训练模型所取代。我们保持其他设置相同,所以增益仅来自基础模型。
mAP结果见表8。我们可以观察到,具有较高验证精度的基础模型会以一致的方式提高Faster-RNN的mAP。特别是,在ImageNet上,准确率为79.29%的最佳基础模型可以在VOC上得到81.33%的最佳mAP,比标准模型高了4%
在这里插入图片描述
6.2.语义分割
语义分割从输入的图像中预测每个像素的类别。我们使用全卷积网络(FCN)[17]来完成这个任务,并在ADE20K [33]数据集上训练模型。照着PSPNet [31]和Zhang等人[30],我们用前几节中讨论的各种预训练模型替换基础网络,并在第3阶段和第4阶段应用扩张网络策略[2,28]。在基础网络之上建立了一个完全卷积解码器来进行最终的预测。
表9报告了像素精度(pixAcc)和平均交并比(mIoU)。与我们在目标检测上的结果相反,余弦学习率调度有效地提高了FCN性能的准确性,而其他的改进提供了次优的结果。对这一现象的一种可能的解释是,语义分割在像素级进行预测。虽然经过标签平滑、蒸馏和混合训练的模型有利于soften标签,但模糊的像素级信息可能会导致模糊,并最终降低整体像素级的精度。
在这里插入图片描述
7.结论
在本文中,我们调查了十几种训练深度卷积神经网络以提高模型精度的技巧。这些技巧对模型体系结构数据预处理损失函数学习率计划进行了微小的修改。我们在ResNet-50、Inception-v3和MobileNet上的实验结果表明,这些技巧始终一致地提高了模型的准确性。更令人兴奋的是,将它们堆叠在一起可以获得显著的更高的准确性。此外,这些提高性能后的预训练模型在迁移学习中显示了很强的优势,同时提高了目标检测和语义分割的效果。我们相信这些提升可以拓展到广阔的依赖于分类基础模型的其他领域。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kafka实验部署

一、前期准备 二、kafka实验 在zookeeper后继续进行操作 2.1 为ndoe1、node2、node3作出部署 2.1.1 解压kafka压缩包(node1举例) 2.1.2 操作 将解压后的kafka移动到kafka,进入到kafka下的config中,复制文件 2.1.2.1 编辑server.pr…

C语言语法进阶

条件运算符 条件运算符是 C 语言中唯一的一种三目运算符。三目运算符代表有三个操作数;双目 运算符代表有两个操作数,如逻辑与运算符就是双目运算符;单目运算符代表有一个操作数, 如逻辑非运算符就是单目运算符。运算符也称操作符…

Elasticsearch:(二)2.安装kibana

1.环境安装介绍: 安装java环境安装Elasticsearch安装kibana安装Elasticsearch-head插件 本节文章主要讲解kibana的安装。 2.下载 下载Elasticsearch对应的版本,参考官方自身产品兼容版本:支持一览表 | Elastic 下载地址:Kibana 7.17.20 | Elastic Kibana 7.17.20 | Ela…

Linux之C编程入门

目录 第1关:第一个C程序 任务描述 相关知识 编译C程序 编程要求 答案及其步骤: 第2关:Linux编译C程序 任务描述 相关知识 gcc编译器使用方法 编程要求 答案及其步骤: 第3关:Linux之静态库编写 任务描述 相关知识 生成…

el-menu 有一级二级三级菜单

效果如下 菜单代码如下 <el-menu:default-active"menuDefaultActive"class"el-menu-box":text-color"menuTextColor":active-text-color"menuActiveTextColor":unique-opened"true"><!-- 一级菜单 --><tem…

常见排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序)

一.排序的概念 1.排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作 2.稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排…

STM32 HAL库 利用CH376进行USB文件读写

STM32 其实可以进行读取USB文件,但仅限于F4以上芯片才可以进行SUB文件读写,但在项目开发中,往往用不到此芯片,那么只能通过外挂的USB芯片进行USB文件读写,本文则是采用STM32F103的SPI与CH376进行通信,通过CH376操作指令进行操作。 1、CH376介绍 CH376芯片 是沁恒的一款文…

paho-mqtt 库揭秘

文章目录 **paho-mqtt 库揭秘**第一部分&#xff1a;背景介绍第二部分&#xff1a;paho-mqtt 是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第七部…

如何批量给Word文件增加前缀序号?“汇帮批量重命名”帮助你批量给word文件增加前缀序号。

批量给Word文件增加前缀序号的过程&#xff0c;对于经常处理大量文档的人来说&#xff0c;是一项既繁琐又必要的任务。首先&#xff0c;我们需要明确为什么要给Word文件增加前缀序号。在很多情况下&#xff0c;当我们需要按照一定的顺序对多个文档进行管理和归档时&#xff0c;…

海绵结构:Hash as RO

参考文献&#xff1a; [BDPA07] Bertoni G, Daemen J, Peeters M, et al. Sponge functions[C]//ECRYPT hash workshop. 2007, 2007(9).[GPP11] Guo J, Peyrin T, Poschmann A. The PHOTON family of lightweight hash functions[C]//Advances in Cryptology–CRYPTO 2011: 31…

MBD_入门篇_19_Simulink数学运算模块

19.Simulink数学运算模块 19.1 概述 数学运算模块&#xff0c;包含了一些数学运算&#xff0c;比如最常用的加减乘除等。 19.2 Add加法模块 设置加法模块的形状&#xff0c;默认是方形的&#xff0c;推荐使用方形的。 运算符设置。 设置符号为-&#xff0c;可以理解为本来是0,…

CSS 设置空格原样显示 white-space:pre-wrap;

CSS 设置空格原样显示 问题描述 html 渲染内容时&#xff0c;对于 空格、回车、Tab 键的 默认处理方式是 &#xff1a; 无论存在多少个连续的空格&#xff0c;都只会保留一个。 结论 由于以上的特性&#xff0c;导致了我们无法直接渲染出原格式的文本。pre 标签 了解一下 &…

今日刷三题(day4):简写单词+dd爱框框+除2!

题目一&#xff1a;简写单词 题目描述&#xff1a; 比如 “College English Test”可以简写成“CET”&#xff0c;“Computer Science”可以简写为“CS”&#xff0c;“I am Bob”简写为“IAB” 输入输出描述&#xff1a; 输入&#xff1a;一个复合单词 输出&#xff1a;输…

20240330-1-词嵌入模型w2v+tf-idf

Word2Vector 1.什么是词嵌入模型&#xff1f; 把词映射为实数域向量的技术也叫词嵌⼊ 2.介绍一下Word2Vec 谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际是一种浅层的神经网络模型&#xff0c;它有两种网络结构&#xff0c;分别是连续词袋&#xff…

C++ stl容器stack,queue,priority_queue的底层模拟实现

目录 前言&#xff1a; 文档借鉴&#xff1a;Reference - C Reference 1.deque a.deque的结构特点&#xff1a; b.deque的迭代器结构&#xff1a; c.面试题&#xff1a; 2.stack 3.queue 4.仿函数 5.priority_queue 总结&#xff1a; 前言&#xff1a; 本篇一共简单…

Hive 中常用的函数以及数据类型

数据类型 1.基本数据类型: 数据类型大小范围示例TINYINT1byte-128 ~ 127100YSMALLINT2byte-32768 ~ 32767100SINT4byte-2^32~ 2^32-1100BIGINT8byte-2^64~ 2^64-1100LFLOAT4byte单精度浮点数5.21DOUBLE8byte双精度浮点数5.21DECIMAL-高精度浮点数DECIMAL(9,8)BOOLEAN-布尔型tr…

VF02 XBLNR增强将不可编辑状态改为可编辑状态

VF02 XBLNR增强将不可编辑状态改为可编辑状态 一、业务界面展示 二、在程序SAPMV60A的INCLUDE程序MV60AF0F_FELDAUSWAHL_SONDERREG增强 *$*$-Start: ZEN_POINT_TEST1---------------------------------------------------------------------$*$* ENHANCEMENT 1 ZFI_TEST01.…

C语言 | 自定义类型:联合和枚举

目录&#xff1a; ----前言 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联合体对比 1.4 联合体大小的计算 1.5 联合的使用 1.6联合体的练习 2. 枚举 2.1 枚举类型的声明 2.2 枚举类型的优点 2.3 枚举类型的使用 --前言&#xff1a; c语言中内…

代码随想录刷题随记24-回溯

代码随想录刷题随记24-回溯 491. 非递减子序列 leetcode链接 与之前的集合问题不同&#xff0c;而本题求自增子序列&#xff0c;是不能对原数组进行排序的&#xff0c;排完序的数组都是自增子序列了。所以不能通过排序的问题去重 class Solution {List<List<Integer…

超越GPT-4V,苹果多模态大模型上新,神经形态计算加速MLLM(二)

上文介绍基于MINOnets神经网络架构加速多模态大模型的策略&#xff0c;本文将以Spinnaker2多核神经网络芯片EGRU架构为起点&#xff0c;覆盖存内计算架构&#xff0c;介绍新型计算架构在加速大模型推理的作用。SpiNNaker 2是一个设计用于大规模异步处理的多核神经形态芯片&…