ShuffleNet:一种为移动设备设计的极致高效的卷积神经网络
摘要
https://arxiv.org/pdf/1707.01083
我们介绍了一种名为ShuffleNet的计算效率极高的卷积神经网络(CNN)架构,该架构专为计算能力非常有限的移动设备(例如10-150 MFLOPs)而设计。新架构利用两种新操作:逐点分组卷积和通道混洗,以大大降低计算成本,同时保持准确性。在ImageNet分类和MS COCO目标检测上的实验表明,ShuffleNet的性能优于其他结构,例如,在40 MFLOPs的计算预算下,在ImageNet分类任务上的top-1错误率比最近的MobileNet [12]低7.8%(绝对值)。在基于ARM的移动设备上,ShuffleNet在保持相当准确性的同时,实现了比AlexNet快约 13 13 13倍的实际加速。
1. 引言
构建更深、更大的卷积神经网络(CNN)是解决主要视觉识别任务的主要趋势[21, 9, 33, 5, 28, 24]。最准确的CNN通常有数百层和数千个通道[9,34,32,40],因此需要数十亿FLOPs的计算量。本报告研究了相反的情况:在数十或数百MFLOPs的非常有限的计算预算下追求最佳准确性,重点关注无人机、机器人和智能手机等常见的移动平台。注意,许多现有工作[16,22, 43, 42, 38, 27]集中在修剪、压缩或低比特表示“基本”网络架构上。本文旨在探索一种专为所需计算范围设计的高效基本架构。
我们注意到,Xception [3]和ResNeXt [40]等最先进的基本架构在极小的网络中效率较低,因为 1 × 1 1 \times 1 1×1卷积的成本很高。我们建议使用逐点分组卷积来降低 1 × 1 1 \times 1 1×1卷积的计算复杂度。为了克服分组卷积带来的副作用,我们提出了一种新颖的通道混洗操作,以促进信息在特征通道之间流动。基于这两种技术,我们构建了一个高效的架构,称为ShuffleNet。与[30, 9, 40]等流行结构相比,在给定计算复杂度预算的情况下,我们的ShuffleNet允许更多的特征图通道,这有助于编码更多信息,对极小网络的性能尤其关键。
我们在具有挑战性的ImageNet分类[4, 29]和MS COCO目标检测[23]任务上评估了我们的模型。一系列受控实验表明,我们的设计原则有效,并且性能优于其他结构。与最先进的架构MobileNet [12]相比,ShuffleNet在40 MFLOPs水平上的ImageNet top-1错误率低7.8%(绝对值),性能显著提高。
我们还评估了在真实硬件(即现成的基于ARM的计算核心)上的加速情况。ShuffleNet模型在保持相当准确性的同时,实现了比AlexNet [21]快约 13 \mathbf{13} 13倍的实际加速(理论加速为 18 18 18倍)。
2. 相关工作
高效模型设计 近年来,深度神经网络在计算机视觉任务中取得了成功[21, 36, 28],其中模型设计起着重要作用。在嵌入式设备上运行高质量深度神经网络的需求不断增加,这推动了高效模型设计的研究[8]。例如,GoogLeNet [33]与简单堆叠卷积层相比,以更低的复杂度增加了网络的深度。SqueezeNet [14]显著减少了参数和计算量,同时保持了准确性。ResNet [9,10]利用高效的瓶颈结构取得了令人印象深刻的性能。SENet [13]引入了一个以轻微计算成本提升性能的架构单元。与我们同时,最近的一项工作[46]采用强化学习和模型搜索来探索高效的模型设计。提出的移动NASNet模型与我们的ShuffleNet模型性能相当(在564 MFLOPs下ImageNet分类错误率为 26.0 % 26.0 \% 26.0%,对比ShuffleNet在524 MFLOPs下为 26.3 % 26.3 \% 26.3%)。但[46]没有报告在极小模型(例如,复杂度小于150 MFLOPs)上的结果,也没有评估在移动设备上的实际推理时间。
分组卷积 分组卷积的概念最初在AlexNet [21]中引入,用于在两个GPU上分布模型,在ResNeXt [40]中已充分证明了其有效性。Xception [3]中提出的深度可分离卷积推广了Inception系列[34, 32]中可分离卷积的思想。最近,MobileNet [12]利用深度可分离卷积,在轻量级模型中取得了最先进的结果。我们的工作以一种新颖的形式推广了分组卷积和深度可分离卷积。
通道混洗操作 据我们所知,在之前的高效模型设计工作中很少提到通道混洗操作的思想,尽管卷积神经网络库cuda-convnet [20]支持“随机稀疏卷积”层,这相当于先进行随机通道混洗,然后接一个分组卷积层。这种“随机混洗”操作有不同的目的,并且在后来很少被利用。最近,另一项并行工作[41]也采用了这种思想来进行两阶段卷积。但是,[41]并没有专门研究通道混洗本身的有效性及其在小型模型设计中的应用。
模型加速 这个方向旨在加速推理,同时保持预训练模型的准确性。通过修剪网络连接[6,7]或通道[38],可以减少预训练模型中的冗余连接,同时保持性能。文献中提出了量化[31, 27, 39, 45, 44]和因式分解[22,16,18,37]来减少计算中的冗余,从而加快推理速度。在不修改参数的情况下,通过快速傅里叶变换(FFT)[25,35]和其他方法[2]实现的优化卷积算法在实践中减少了时间消耗。蒸馏[11]将大型模型的知识转移到小型模型中,从而使训练小型模型变得更加容易。
3. 方法
3.1. 分组卷积中的通道混洗
现代卷积神经网络[30,33, 34, 32, 9,10]通常由具有相同结构的重复构建块组成。其中,最先进的网络(如Xception [3]和ResNeXt [40])将高效的深度可分离卷积或分组卷积引入构建块中,从而在表示能力和计算成本之间取得了良好的权衡。然而,我们注意到这两种设计都没有充分考虑 1 × 1 1 \times 1 1×1卷积(在[12]中也称为逐点卷积),这需要相当大的复杂度。例如,在ResNeXt [40]中,只有 3 × 3 3 \times 3 3×3层配备了分组卷积。因此,在ResNeXt的每个残差单元中,逐点卷积占据了93.4%的乘加运算(基数 = 32 =32 =32,如[40]所示)。在小型网络中,昂贵的逐点卷积导致满足复杂度约束的通道数量有限,这可能会严重损害准确性。
为了解决这个问题,一个直接的解决方案是在 1 × 1 1 \times 1 1×1层上也应用通道稀疏连接,例如分组卷积。通过确保每个卷积仅在其对应的输入通道组上操作,分组卷积显著降低了计算成本。然而,如果多个分组卷积堆叠在一起,会产生一个副作用:某个通道的输出仅来自输入通道的一个小部分。图1(a)展示了两个堆叠的分组卷积层的情况。显然,某个组的输出仅与该组内的输入相关。这一特性阻碍了通道组之间的信息流动,并削弱了表示能力。
如果我们允许分组卷积从不同的组中获取输入数据(如图1(b)所示),则输入和输出通道将完全相关。具体来说,对于前一层分组层生成的特征图,我们可以首先将每个组中的通道分成几个子组,然后将不同的子组作为下一层的输入。这可以通过通道混洗操作(图1(c))高效且优雅地实现:假设一个具有 g g g组的卷积层,其输出有 g × n g \times n g×n个通道;我们首先将输出通道维度重塑为 ( g , n ) (g, n) (g,n),然后进行转置,最后将其展平作为下一层的输入。注意,即使两个卷积具有不同数量的组,该操作仍然有效。此外,通道混洗也是可微的,这意味着它可以嵌入到网络结构中进行端到端训练。
通道混洗操作使得构建具有多个分组卷积层的更强大结构成为可能。在下一小节中,我们将介绍一个具有通道混洗和分组卷积的高效网络单元。
3.2. ShuffleNet单元
利用通道混洗操作,我们提出了一种专为小型网络设计的新型ShuffleNet单元。我们从图2(a)中的瓶颈单元[9]的设计原则开始。它是一个残差块。在其残差分支中,对于 3 × 3 3 \times 3 3×3层,我们在瓶颈特征图上应用了计算经济型的 3 × 3 3 \times 3 3×3深度卷积[3]。然后,我们将第一个 1 × 1 1 \times 1 1×1层替换为逐点组卷积,随后进行通道混洗操作,以形成ShuffleNet单元,如图2(b)所示。第二个逐点组卷积的目的是恢复通道维度,以匹配捷径路径。为了简化,我们在第二个逐点层之后没有应用额外的通道混洗操作,因为这样做会导致得分相当。批量归一化(BN)[15]和非线性的使用与[9,40]类似,但不同的是,我们没有按照[3]的建议在深度卷积之后使用ReLU。对于ShuffleNet以步长应用的情况,我们只需进行两项修改(见图2(c)):(i)在捷径路径上添加一个 3 × 3 3 \times 3 3×3平均池化;(ii)将元素逐项相加替换为通道串联,这样可以以极小的额外计算成本轻松扩展通道维度。
得益于具有通道混洗的逐点组卷积,ShuffleNet单元中的所有组件都可以高效计算。与ResNet[9](瓶颈设计)和ResNeXt[40]相比,在相同设置下,我们的结构复杂度更低。例如,给定输入尺寸 c × h × w c \times h \times w c×h×w和瓶颈通道 m m m,ResNet单元需要 h w ( 2 c m + 9 m 2 ) hw(2cm+9m^{2}) hw(2cm+9m2)FLOPs,ResNeXt需要 h w ( 2 c m + 9 m 2 / g ) hw(2cm+9m^{2}/g) hw(2cm+9m2/g)FLOPs,而我们的ShuffleNet单元仅需 h w ( 2 c m / g + 9 m ) hw(2cm/g+9m) hw(2cm/g+9m)FLOPs,其中 g g g表示卷积的组数。换句话说,在给定计算预算的情况下,ShuffleNet可以使用更宽的特征图。我们发现这对于小型网络至关重要,因为小型网络通常没有足够的通道来处理信息。
此外,在ShuffleNet中,深度卷积仅在瓶颈特征图上进行。尽管深度卷积通常具有非常低的理论复杂度,但我们发现它很难在低功耗移动设备上高效实现,这可能是由于与其他密集操作相比,其计算/内存访问比更差。这种缺点在[3]中也有提及,其中基于TensorFlow[1]提供了一个运行时库。在ShuffleNet单元中,我们故意仅在瓶颈上使用深度卷积,以尽可能减少开销。
3.3. 网络架构
基于ShuffleNet单元,我们在表1中给出了ShuffleNet的总体架构。所提出的网络主要由堆叠成三个阶段的ShuffleNet单元组成。每个阶段中的第一个构建块应用了步长=2。一个阶段内的其他超参数保持不变,对于下一个阶段,输出通道数加倍。与[9]类似,我们将每个ShuffleNet单元的瓶颈通道数设置为输出通道数的1/4。我们的目的是提供一个尽可能简单的参考设计,尽管我们发现进一步的超参数调整可能会产生更好的结果。
在ShuffleNet单元中,组数 g g g控制逐点卷积的连接稀疏性。表1探索了不同的组数,并调整了输出通道数以确保总体计算成本大致不变( ∼ 140 \sim 140 ∼140 MFLOPs)。显然,在给定复杂度约束下,更大的组数会导致更多的输出通道(因此更多的卷积滤波器),这有助于编码更多信息,尽管由于对应的输入通道有限,这也可能导致单个卷积滤波器的性能下降。在4.1.1节中,我们将研究此数字在不同计算约束下的影响。
为了将网络定制为所需的复杂度,我们可以简单地在通道数上应用一个缩放因子 s s s。例如,我们将表1中的网络表示为“ShuffleNet 1 × 1 \times 1×”,那么“ShuffleNet s × s \times s×”表示将ShuffleNet 1 × 1 \times 1×中的滤波器数量缩放 s s s倍,因此总体复杂度将是ShuffleNet 1 × 1 \times 1×的 s 2 s^{2} s2倍。
4. 实验
我们主要在ImageNet 2012分类数据集[29, 4]上评估我们的模型。我们遵循[40]中使用的大多数训练设置和超参数,但有两个例外:(i)我们将权重衰减设置为 4 e − 5 4 \mathrm{e}-5 4e−5而不是 1 e − 4 1 \mathrm{e}-4 1e−4,并使用线性衰减的学习率策略(从0.5降至0);(ii)我们在数据预处理中使用了稍不激进的尺度增强。类似的修改也在[12]中被引用,因为这类小型网络通常会出现欠拟合而不是过拟合。在4个GPU上训练一个模型进行 3 × 1 0 5 3 \times 10^{5} 3×105次迭代需要1或2天时间,其批量大小设置为1024。为了基准测试,我们在ImageNet验证集上比较了单裁剪的top-1性能,即从 256 × 256 \times 256×输入图像中裁剪出 224 × 224 224 \times 224 224×224的中心视图并评估分类准确性。我们为所有模型使用完全相同的设置以确保公平比较。
4.1. 消融研究
ShuffleNet的核心思想在于逐点分组卷积和通道混洗操作。在本小节中,我们分别对它们进行评估。
4.1.1 逐点分组卷积
为了评估逐点分组卷积的重要性,我们比较了具有相同复杂度的ShuffleNet模型,其分组数从1到8不等。如果分组数等于1,则不涉及逐点分组卷积,然后ShuffleNet单元就变成了“Xception-like”[3]结构。为了更好地理解,我们还将网络的宽度缩放到3种不同的复杂度,并分别比较它们的分类性能。结果如表2所示。
从结果中,我们看到具有分组卷积( g > 1 g>1 g>1)的模型始终比没有逐点分组卷积( g = 1 g=1 g=1)的模型表现更好。较小的模型从分组中获益更多。例如,对于ShuffleNet 1 × 1 \times 1×,最佳条目( g = 8 g=8 g=8)比对应条目好 1.2 % 1.2\% 1.2%,而对于ShuffleNet 0.5 × 0.5 \times 0.5×和 0.25 × 0.25 \times 0.25×,差距分别变为 3.5 % 3.5\% 3.5%和 4.4 % 4.4\% 4.4%。注意,分组卷积在给定复杂度约束下允许更多的特征图通道,因此我们假设性能增益来自更宽的特征图,这有助于编码更多信息。此外,较小的网络涉及更薄的特征图,这意味着它从放大的特征图中获益更多。
表2还显示,对于一些模型(例如ShuffleNet 0.5 × 0.5 \times 0.5×),当分组数变得相对较大(例如 g = 8 g=8 g=8)时,分类分数会饱和甚至下降。随着分组数的增加(因此特征图更宽),每个卷积滤波器的输入通道变得更少,这可能会损害表示能力。有趣的是,我们还注意到,对于像ShuffleNet 0.25 × 0.25 \times 0.25×这样的小型模型,较大的分组数往往能持续带来更好的结果,这表明更宽的特征图为小型模型带来了更多好处。
4.1.2 有通道混洗与无通道混洗
混洗操作的目的是使多个分组卷积层能够实现跨组信息流。表3比较了有无通道混洗的ShuffleNet结构(例如,分组数设置为3或8)的性能。评估是在三种不同复杂度的尺度下进行的。很明显,通道混洗始终能提升不同设置的分类分数。特别是,当分组数相对较大(例如 g = 8 g=8 g=8)时,具有通道混洗的模型显著优于没有通道混洗的模型,这显示了跨组信息交换的重要性。
4.2. 与其他结构单元的比较
VGG[30]、ResNet[9]、GoogleNet[33]、ResNeXt[40]和Xception[3]中最近的领先卷积单元在大模型(例如, ≥ 1 \geq 1 ≥1 GFLOPs)上追求了最先进的结果,但并未完全探索低复杂度条件。在本节中,我们调查了各种构建块,并在相同复杂度约束下与ShuffleNet进行了比较。
为了公平比较,我们使用如表1所示的整体网络架构。我们将第2-4阶段的ShuffleNet单元替换为其他结构,然后调整通道数以确保复杂度保持不变。我们探索的结构包括:
- VGG-like。遵循VGG网络[30]的设计原则,我们使用两层 3 × 3 3 \times 3 3×3卷积作为基本构建块。与[30]不同的是,我们在每个卷积之后添加了一个批量归一化层[15],以使端到端训练更容易。
- ResNet。我们在实验中采用了“瓶颈”设计,该设计已在[9]中被证明更有效。与[9]相同,瓶颈比率 1 { }^{1} 1也是1:4。
- Xception-like。在[3]中提出的原始结构涉及不同阶段的复杂设计或超参数,我们发现这在小型模型上进行公平比较很困难。相反,我们从ShuffleNet中移除了逐点分组卷积和通道混洗操作(也相当于ShuffleNet中 g = 1 g=1 g=1)。派生出的结构与[3]中的“深度可分离卷积”思想相同,这里称为Xception-like结构。
- ResNeXt。我们使用[40]中建议的基数 = 16 =16 =16和瓶颈比率 = 1 : 2 =1:2 =1:2的设置。我们还探索了其他设置,例如瓶颈比率 = 1 : 4 =1: 4 =1:4,并得到了类似的结果。
我们使用完全相同的设置来训练这些模型。结果如表4所示。在不同的复杂度下,我们的ShuffleNet模型性能远超其他大多数模型。有趣的是,我们发现特征图通道数与分类准确率之间存在一种经验关系。例如,在38 MFLOPs的复杂度下,VGG类、ResNet、ResNeXt、Xception类和ShuffleNet模型的第4阶段(见表1)的输出通道数分别为50、192、192、288、576,这与准确率的提升是一致的。由于ShuffleNet的高效设计,在给定计算预算的情况下,我们可以使用更多的通道,从而通常获得更好的性能。
请注意,上述比较不包括GoogleNet或Inception系列[33, 34, 32]。我们发现将这类Inception结构应用于小型网络并非易事,因为Inception模块的原始设计涉及过多的超参数。作为参考,第一个GoogleNet版本[33]以1.5 GFLOPs的代价取得了31.3%的top-1错误率(见表6)。更复杂的Inception版本[34,32]更准确,但复杂度也显著增加。最近,Kim等人提出了一种名为PVANET[19]的轻量级网络结构,它采用了Inception单元。我们重新实现的PVANET(输入尺寸为 224 × 224 224 \times 224 224×224)在557 MFLOPs的计算复杂度下取得了29.7%的分类错误率,而我们的ShuffleNet 2x模型( g = 3 g=3 g=3)在524 MFLOPs下取得了26.3%的分类错误率(见表6)。
4.3 与MobileNets和其他框架的比较
最近,Howard等人提出了MobileNets[12],该网络主要针对移动设备的高效网络架构。MobileNet借鉴了[3]中的深度可分离卷积思想,并在小型模型上取得了最先进的结果。
表5比较了不同复杂度水平下的分类得分。显然,对于所有复杂度,我们的ShuffleNet模型都优于MobileNet。尽管我们的ShuffleNet网络是专为小型模型(<150 MFLOPs)设计的,但我们发现,对于更高的计算成本,它仍然优于MobileNet,例如,在500 MFLOPs的计算成本下,ShuffleNet比MobileNet 1×的准确率高出3.1%。对于更小的网络(~40 MFLOPs),ShuffleNet比MobileNet高出 7.8 % \mathbf{7.8\%} 7.8%。需要注意的是,我们的ShuffleNet架构有50层,而MobileNet只有28层。为了更好地理解,我们还尝试通过删除第2-4阶段中一半的块来构建一个26层的ShuffleNet架构(见表5中的“ShuffleNet 0.5 × 0.5 \times 0.5× shallow( g = 3 g=3 g=3)”)。结果表明,较浅的模型仍然明显优于相应的MobileNet,这意味着ShuffleNet的有效性主要归功于其高效的结构,而不是深度。
表6将我们的ShuffleNet与一些流行的模型进行了比较。结果表明,在具有相似准确率的情况下,ShuffleNet比其他模型更高效。例如,ShuffleNet 0.5 × 0.5 \times 0.5×在理论上比具有相当分类得分的AlexNet[21]快18倍。我们将在第4.5节中评估实际运行时间。
值得一提的是,简单的架构设计使得ShuffleNets能够轻松配备最新的研究成果,如[13, 26]。例如,在[13]中,作者提出了Squeeze-and-Excitation(SE)块,该块在大型ImageNet模型上取得了最先进的结果。我们发现SE模块与骨干ShuffleNets结合使用也有效,例如,将ShuffleNet 2 × 2 \times 2×的top-1错误率降低到24.7%(见表5)。有趣的是,尽管理论复杂度增加微乎其微,但我们发现,在移动设备上,带有SE模块的ShuffleNets通常比“原始”ShuffleNets慢25%~40%,这意味着在实际加速评估中,低成本架构设计至关重要。我们将在第4.5节中进行进一步讨论。
4.4 泛化能力
为了评估迁移学习的泛化能力,我们在MS COCO目标检测[23]任务上测试了我们的ShuffleNet模型。我们采用Faster-RCNN[28]作为检测框架,并使用公开发布的Caffe代码[28, 17]进行默认设置下的训练。与[12]类似,模型在COCO train+val数据集上进行训练,但不包括5000张minival图像,我们在minival集上进行测试。表7展示了在两个输入分辨率下训练和评估结果的比较。将复杂度相当的ShuffleNet 2 × 2 \times 2×与MobileNet(524 vs. 569 MFLOPs)进行比较,我们的ShuffleNet 2 × 2 \times 2×在两个分辨率上都远超MobileNet;我们的ShuffleNet 1 × 1 \times 1×在 600 × 600 \times 600×分辨率下也取得了与MobileNet相当的结果,但复杂度降低了约4倍。我们推测,这一显著增益部分归因于ShuffleNet没有使用任何复杂设计的简单架构。
4.5. 实际加速比评估
最后,我们在搭载ARM平台的移动设备上评估了ShuffleNet模型的实际推理速度。尽管具有较大组数(例如 g = 4 g=4 g=4或 g = 8 g=8 g=8)的ShuffleNet通常具有更好的性能,但在我们当前的实现中发现其效率较低。根据经验, g = 3 g=3 g=3通常在准确性和实际推理时间之间取得适当的平衡。如表8所示,测试采用了三种输入分辨率。由于内存访问和其他开销,我们发现每减少4倍的理论复杂度在我们的实现中通常只带来约2.6倍的实际加速比。然而,与AlexNet [21]相比,我们的ShuffleNet 0.5 × 0.5 \times 0.5×模型在可比的分类精度下仍然实现了约13倍的实际加速比(理论加速比为18倍),这远远快于之前的AlexNet级别的模型或加速方法,如[14,16,22,42,43,38]。
相关文章:
ShuffleNet:一种为移动设备设计的极致高效的卷积神经网络
摘要 https://arxiv.org/pdf/1707.01083 我们介绍了一种名为ShuffleNet的计算效率极高的卷积神经网络(CNN)架构,该架构专为计算能力非常有限的移动设备(例如10-150 MFLOPs)而设计。新架构利用两种新操作:逐…...
AIGC-------AIGC在社交媒体内容生成中的应用
AIGC在社交媒体内容生成中的应用 引言 随着人工智能生成内容(AIGC)的快速发展,社交媒体平台上的内容创作方式发生了巨大变化。AIGC使得内容创作的门槛大大降低,从而让更多的人能够参与到社交媒体内容的创作中,同时也使…...
提取图像中的高频信息
三种方法 1. 傅里叶变换提取高频和低频【有损】2. 傅里叶变换提取振幅和相位【无损】3. 小波变换【不涉及恢复代码】代码1.代码2代码3 1. 傅里叶变换提取高频和低频【有损】 环境:集群210.30.98.11效果: 2. 傅里叶变换提取振幅和相位【无损】 环境:集…...
js函数声明
在 JavaScript 中,函数是一等公民(first-class citizen),这意味着函数可以作为变量、参数和返回值使用。JavaScript 提供了多种定义函数的方式,以下是几种常见的方法: 1. 函数声明(Function De…...
语言模型中的多模态链式推理
神经网络的公式推导 简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模块 实验结果运行代码补充细节安装包下载Flan-T5数据集准备rougenltkall-MiniLM-L6-v2运行 简介 本文主要对2023一篇论文《Multimodal Chain-of-Thought Reason…...
【Java 解释器模式】实现高扩展性的医学专家诊断规则引擎
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
CTF之密码学(Polybius密码)
棋盘密码,也称为Polybius密码或方格密码,是一种基于替换的加密方法。以下是对棋盘密码的详细解析: 一、加密原理 棋盘密码使用一个5x5的方格棋盘,其中填充了26个英文字母(通常i和j被视为同一个字母并放在同一个格子中…...
java excel 导入各种踩坑
在 Java 中处理 Excel 导入时,常见的问题(即“踩坑”)很多,下面列举了处理 Excel 导入时可能遇到的一些问题,并给出了解决方案和优化技巧。 1. POI 库与版本问题 Apache POI 是处理 Excel 的常用库,但是不…...
优化表单交互:在 el-select 组件中嵌入表格显示选项
介绍了一种通过 el-select 插槽实现表格样式数据展示的方案,可更直观地辅助用户选择。支持列配置、行数据绑定及自定义搜索,简洁高效,适用于复杂选择场景。完整代码见GitHub 仓库。 背景 在进行业务开发选择订单时,如果单纯的根…...
js版本之ES5特性简述【String、Function、JSON、其他】(二)
目录 String相关方法 string.charAt() string.charCodeAt() string.concat() string.match() string.search() string.replace() string.split() string.trim() string.slice() string.substr() string.substring() Function相关方法 arguments.length function…...
【redis】哈希类型详解
哈希类型详解 一、哈希类型的介绍二、哈希类型的常用命令2.1 HSET2.2 HGET2.3 HEXISTS2.4 HDEL2.5 HKEYS2.6 HAVLS2.7 HGETALL2.8 HMGET2.9 HLEN2.10 HSETNX2.11 HINCRBY2.12 HINCRBYFLOAT 三、哈希类型命令小结四、哈希类型内部编码五、哈希类型应用场景 一、哈希类型的介绍 …...
每日练题之动态规划(子序列问题讲解 1.最长递增子序列 2.摆动序列)
前言: 需要对「子序列」和「子数组」这两个概念进行区分; 子序列(subsequence):子序列并不要求连续,但是我们调出来的顺序必须和原数组的顺序相同。例如:序列 [4, 6, 5] 是 [1, 2, 4, 3, 7, 6,…...
JSON 性能测试 - WastJson 性能也很快
WAST 是一个高性能 Java 工具集库包,包括 JSON、YAML、CSV、HttpClient、JDBC 和 EL 引擎. WastJson 无论是小中大文本各种数据类型等性能都没有明显的短板,除了推广外可以说是六边形战士,更多测试参考 wast-jmh-test: wast性能测试 (并非所…...
Windows 软件之 FFmpeg
文章目录 前言1 FFmpeg 视频处理1.1 编解码1.2 其它视频编辑命令1.3 视频抽帧 2 FFmpeg 音频处理3 FFmpeg 图片处理3.1 编解码3.2 拼接图片3.3 图片合成视频 附录1:mediainfo.ps1 前言 FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的…...
接口的扩展
1. 接口中新增的方法 JDK7之前接口中只能定义抽象方法。 JDK8的新特性:接口中可以定义有方法体的方法。(默认、静态) JDK9的新特性:接口中可以定义有私有方法体的方法。 有方法体的方法:接口升级时,为了兼容…...
Vue ECharts 基本数据图表绘制详解:让数据飞起来
1. 引言 1.1 什么是数据可视化 大家好,欢迎来到数据可视化的世界!如果你以为数据就是冷冰冰的数字,那你就大错特错了。数据,可是有灵魂的!只要给它一副好看的外衣,比如我们今天要聊的图表,它们…...
目录遍历漏洞-CVE-2021-41773
目录 简介 原理 例子 Apache路径穿越漏洞 环境搭建 漏洞原理 漏洞利用 简介 目录遍历漏洞(也称为路径遍历漏洞)是一种由于Web服务器或Web应用程序对用户输入的文件名称的安全性验证不足而导致的安全漏洞。 原理 目录遍历漏洞允许攻击者在未授权…...
ajax (一)
什么是 AJAX [ˈeɪdʒks] ? 概念:AJAX是浏览器与服务器进行 数据通信 的技术,动态数据交互 怎么用AJAX? 1. 先使用 axios [k‘sio ʊ s] 库, 与服务器进行 数据通信 ⚫ 基于 XMLHttpRequest 封装、代码简单、月下载量在 1…...
cocos creator 3.8 物理碰撞器Collider+刚体RigidBody 8
遇到一个朋友,你来就行的朋友,我过去了,管吃管住,这样的朋友真的很难求。 最近离职了,很难想象,一份策划书一天能给你改n次,一周能郁闷,上一个功能没搞完,让你搞下一个功…...
[Python3学习笔记-基础语法] Python3 基础语法
本篇文章详细介绍Python3的基础语法,主要包括编码、标识符、Python保留字、注释、行缩进、多行语句、Number类型、字符串、空行、print打印等。 这些是Python最基础的东西,掌握好了才能更好的学习后续的内容。 有兴趣共同结伴学习Python的朋友࿰…...
自制游戏:监狱逃亡
第一个游戏,不喜勿喷: #include<bits/stdc.h> #include<windows.h> using namespace std; int xz; int ruond_1(int n){if(xz1){printf("撬开了,但站在你面前的是俄罗斯内务部特种部队的奥摩大帝,你被九把加…...
Linux的开发工具(三)
条件编译 预处理本质:对代码进行裁剪 像网易云音乐有vip和普通用户,可以通过条件编译来,这样只用写一份代码,也只用维护一份代码,是vip就走vip代码,不是就普通用户代码,条件编译来动态裁剪。 …...
飞书会话消息左右排列
飞书会话消息左右排列 1. 飞书登录后,点击头像,弹出菜单有个按钮设置 2. 3....
【数据结构-表达式解析】力扣227. 基本计算器 II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。 注意:不允许使用任何将字符串作为数学表达式计算的内置函数&#…...
vue2面试题10|[2024-11-24]
问题1:vue设置代理 如果你的前端应用和后端API服务器没有运行在同一个主机上,你需要在开发环境下将API请求代理到API服务器。这个问题可以通过vue.config.js中的devServer.proxy选项来配置。 1.devServer.proxy可以是一个指向开发环境API服务器的字符串&…...
列表和字典索引的区别
对于 列表: 索引是自动生成的,由 Python 内部管理。你不能直接为列表中的某个元素设置“自定义索引”。 对于 字典: 键是完全由用户定义的。你可以通过 字典【键】 值 的方式主动创建或更新键值对。 lst [a, b, c] lst[0] x # 修改已…...
【源码】Sharding-JDBC源码分析之SQL中分片键路由ShardingSQLRouter的原理
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...
JavaFX 实现 Loading 效果的组件与案例详解
JavaFX 中的 Loading 组件概述 JavaFX 提供了两个用于显示任务进度的核心组件: ProgressIndicator:以圆形动画的形式展示任务进度,适用于未定义进度的任务。ProgressBar:以水平条的形式展示任务进度,适用于可以量化进…...
Elasticsearch:如何部署文本嵌入模型并将其用于语义搜索
你可以按照这些说明在 Elasticsearch 中部署文本嵌入模型,测试模型并将其添加到推理提取管道。它使你能够生成文本的向量表示并对生成的向量执行向量相似性搜索。示例中使用的模型在 HuggingFace上公开可用。 该示例使用来自 MS MARCO Passage Ranking Task 的公共…...
李继刚:提示词(Prompt)的本质是表达的艺术
看了李继刚在 AI 创新者大会的演讲《提示词的道与术》,收获很大,我分享一下学习笔记。 李继刚:提示词(Prompt)的本质是表达的艺术 一、提示词的本质是表达 本意、文意和解意的概念: 本意:指…...
10 —— Webpack打包模式
开发模式:development ;场景:本地开发 生产模式:production ; 场景:打包上线 这两种模式如何设置给webpack: 方式1.webpack.config.js 配置文件设置mode选项 module.exports { mode:produc…...
OpenSSH 安装
OpenSSH windows安装 启用可选功能安装 OpenSSH(推荐方法) 步骤一:打开 “设置” 应用 点击 “开始” 菜单,选择 “设置” 图标(看起来像一个齿轮)。 步骤二:进入 “应用” 部分 在设置窗口中&…...
国标GB28181设备管理软件EasyGBS国标GB28181视频平台:RTMP和GB28181两种视频上云协议的区别
在当今信息化高速发展的社会中,视频监控技术已经成为各行各业不可或缺的一部分。无论是城市安全、交通管理,还是企业安全、智能家居,视频监控都发挥着至关重要的作用。然而,随着监控点数量的急剧增加,海量视频数据的存…...
Image fusion meets deep learning: A survey and perspective译文
摘要 图像融合是指从不同的源图像中提取和组合最有意义的信息,旨在生成一个更有信息量和有利于后续应用的单图像。深度学习的发展极大地推动了图像融合的发展,而神经网络强大的特征提取和重建能力使融合结果充满希望。最近,几种最新的深度学…...
多维高斯分布的信息熵和KL散度计算
多维高斯分布是一种特殊的多维随机分布,应用非常广泛,很多现实问题的原始特征分布都可以看作多维高斯分布。本文以数据特征服从多维高斯分布的多分类任务这一理想场景为例,从理论层面分析数据特征和分类问题难度的关系注意,本文分…...
物体网格弹性变形---Unity中实现
在游戏引擎场景中的3D物体是由一定数量的点、面组成的,如下图: 要使这些物体变形就是改变3D物体每个顶点状态。 1.首先在Unity场景中增加一个球体,如下图 3D组件默认拥有MeshFilter、meshRenderer、Collider组件,分别用来获取Mes…...
什么是Sass,有什么特点
Sass 概述 什么是 Sass? Sass(Syntactically Awesome Style Sheets)是一种 CSS 预处理器,它扩展了 CSS 的功能,使其更加强大和灵活。Sass 允许开发者使用变量、嵌套规则、混合宏、继承等高级特性,从而编写…...
Spring注入Map学习
Spring注入Map学习 在Spring中 在策略模式中, 会经常用到 根据Bean名称获取Bean的实例 有2个方法很好用 1. 使用Autowired注入 2. 使用构造方法注入 但是奇怪的一点是: 日志打印并没有看到结果, 第一行的 Autowired的结果 是个null 那是因为 注入时机 的问题 注入时机&…...
Java 基础知识 (集合框架 + 并发编程 + JVM 原理 + 数据结构与算法)
文章目录 一.集合框架1. 常见集合接口及其特点List 接口Set 接口Map 接口 2. ArrayList 和 LinkedList 的区别和适用场景ArrayListLinkedList 3. HashSet 和 TreeSet 的特点和用法HashSetTreeSet 4. HashMap 和 TreeMap 的实现原理和使用注意事项HashMapTreeMap 5. 集合遍历方式…...
数据脱敏工具:基于 FFmpeg 的视频批量裁剪
在数据处理和隐私保护领域,数据脱敏是一项重要的任务,尤其是在处理包含敏感信息的视频数据时。本文介绍了一种使用 Python 和 FFmpeg 实现的视频批量裁剪工具,该工具可以将视频中的敏感区域裁剪掉,从而实现数据脱敏。通过使用 PyI…...
从零开始:使用 Spring Boot 开发图书管理系统
如何利用是springboot搭建一个简单的图书管理系统,下面让我们一起来看看吧 文章目录 项目结构1. 主类 LibraryApplication.java功能与注意事项: 2. 模型类 Book.java功能与注意事项: 3. 数据仓库接口 BookRepository.java功能与注意事项&…...
深入浅出:大数据架构中的流处理与实时分析
1. 引言 随着数据产生速度的不断加快,传统的批处理架构已经无法满足实时数据处理和快速响应的需求。流处理成为解决这一问题的关键技术之一,广泛应用于金融、互联网、物联网等领域。流处理技术能够处理不断到来的数据流,实时分析和反馈,使得系统能够迅速做出反应,提供实时…...
基于Multisim的汽车尾灯控制电路设计与仿真
1、电路由四个按键控制,分别对应左转、右转、刹车和检查。 2、当左转或右转键按下时,左侧或右侧的 3个汽车尾灯按照左循环或右循环的顺!2/3 点亮,点亮时间为 1秒。 3、当刹车时,所有的尾灯同时闪烁,闪烁时间为1秒。 4、当检查时…...
WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理
WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理 1. 标题识别elementUI组件爆红 这个原因是: 在官网说明里,才版本2024.1开始,默认启用的 Vue Language Server,但是在 Vue 2 项目…...
【大数据学习 | Spark-Core】详解分区个数
RDD默认带有分区的,那么创建完毕rdd以后他的分区数量是多少? 从hdfs读取文件的方式是最正规的方式,我们通过计算原理可以推出blk的个数和分区数量是一致的,本地化计算。 我们可以发现数据的读取使用的是textInputFormatÿ…...
(二)Sping Boot学习——Sping Boot注意事项
1.springboot默认是扫描的类是在启动类的当前包或者下级包。 2.运行报错 ERROR:An incompatible version [1.2.33] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34] 网上试了很多方法,直接重新安装更新版…...
深入浅出,快速安装并了解汇编语言
1.什么是汇编语言 了解汇编语言需要先从了解机器语言开始,在计算机发展的初期阶段,机器语言是计算机直接理解和执行的二进制代码语言,其核心特点包括直接执行性、资源高效性、学习难度大以及平台依赖性。它主要由指令码构成,这些…...
LLM的原理理解6-10:6、前馈步骤7、使用向量运算进行前馈网络的推理8、注意力层和前馈层有不同的功能9、语言模型的训练方式10、GPT-3的惊人性能
目录 LLM的原理理解6-10: 6、前馈步骤 7、使用向量运算进行前馈网络的推理 8、注意力层和前馈层有不同的功能 注意力:特征提取 前馈层:数据库 9、语言模型的训练方式 10、GPT-3的惊人性能 一个原因是规模 大模型GPT-1。它使用了768维的词向量,共有12层,总共有1.…...
JavaScript中的箭头函数以及编写优化
箭头函数 1.1.1 箭头函数的概念 箭头函数时ES 6之后增加一种编写函数的方法,并且它比函数的表达式要更加简洁 箭头函数不会绑定this,arguments属性箭头函数不能作为构造函数来使用(不能和new一起来使用,会出现错误) //1.之前的方…...
Thymeleaf模板引擎生成的html字符串转换成pdf
依赖引入implementation("org.springframework.boot:spring-boot-starter-thymeleaf")implementation("org.xhtmlrenderer:flying-saucer-pdf")将ITemplateEngine注入到spring管理的类中, Context context new Context(); context.setVariable…...