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 4e5而不是 1 e − 4 1 \mathrm{e}-4 1e4,并使用线性衰减的学习率策略(从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]。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python基础导包

Python项目代码结构与导包详解 目录 引言 Python项目的基本结构 2.1 单文件项目2.2 多模块项目2.3 包结构项目2.4 示例项目结构 模块与包 3.1 模块&#xff08;Module&#xff09;3.2 包&#xff08;Package&#xff09;3.3 子包&#xff08;Subpackage&#xff09; 导包&a…

学习Zookeeper

Zookeeper有手就行 1. 初识ZooKeeper1.1 安装ZooKeeper1.2 ZooKeeper命令操作1.2.1 Zookeeper数据模型1.2.2 Zookeeper 服务端常用命令1.2.3 Zookeeper客户端常用命令 2. ZooKeeperJavaAPl操作2.1 Curator介绍2.2 CuratorAPI常用操作2.2.0 引入Curator支持2.2.1 建立连接2.2.2 …

ctfshow-Misc入门(1-16)

misc1 查看图片得到flag misc2 1、打开文本&#xff0c;发现以“塒NG”开头 3、修改文件格式为png格式 4、查看图片&#xff0c;得到flag *遇到的问题&#xff1a;无法直接修改后缀名 *解决方法&#xff1a;需要点击文件夹&#xff0c;然后点击查看&#xff0c;将文件拓…

由于centos停更,yum、docker等不支持,采用阿里云仓库搭建K8S

一&#xff1a;准备 服务器信息主机名IP地址Centos7.9node1-master192.168.35.130Centos7.9node2192.168.35.131 # 查看系统版本 cat /etc/centos-release # 查看内核版本 uname -sr二&#xff1a;服务器前置操作 每个节点都需要操作 #使用 hostnamectl set-hostname设置主机…

什么是串口通信

串口通信&#xff08;Serial Communications&#xff09;是一种广泛使用的通信方式&#xff0c;特别是在计算机与外部设备之间的数据传输中。以下是对串口通信及其流程的详细介绍&#xff1a; 一、串口通信概述 定义&#xff1a;串口通信是指外设和计算机间&#xff0c;通过数…

Java 8 Stream API 在数据转换中的应用 —— 将列表转换为映射

文章目录 背景原因1. 数据库设计或约束问题2. 业务逻辑问题3. 测试数据4. 数据库同步问题5. 编程错误 如何避免和处理键冲突1. 数据库层面2. 业务逻辑层面3. 测试数据管理4. 代码层面示例代码 总结 背景 本文实际生产案例讲解配套文章&#xff1a;sysUserList 中为何会出现多个…

实践指南:EdgeOne与HAI的梦幻联动

在当今快速发展的数字时代&#xff0c;安全和速度已成为网络服务的基石。EdgeOne&#xff0c;作为腾讯云提供的边缘安全加速平台&#xff0c;以其全球部署的节点和强大的安全防护功能&#xff0c;为用户提供了稳定而高效的网络体验。而HAI&#xff08;HyperApplicationInventor…

词云图大师(WordCloudMaster): 探索创意无限的词云世界!

在信息化时代&#xff0c;如何以一种新颖且富有创意的方式表达数据、文字或想法&#xff1f;答案是词云图&#xff01;而词云图大师(WordCloudMaster)&#xff0c;正是您的绝佳选择。 无论是个人创意项目&#xff0c;还是专业工作中的数据可视化&#xff0c;词云图大师都能以强…

二分法(折半法)查找【有动图】

二分法&#xff0c;也叫做折半法&#xff0c;就是一种通过有序表的中间元素与目标元素进行对比&#xff0c;根据大小关系排除一半元素&#xff0c;然后继续在剩余的一半中进行查找&#xff0c;重复这个过程直至找到目标值或者确定目标值不存在。 我们从结论往回推&#xff0c;…

PL/I语言的起源?Objective C语言起源哪里?JavaScript的起源?Java的起源?B语言的起源?C++语言的起源?C#的起源?

PL/I语言的起源 在20世纪50~60年代&#xff0c;当时主流的编程语言是COBOL/FORTRAN/ALGOL等&#xff0c;IBM想要设计一门通用的编程语言&#xff0c;已有的编程语言无法实现此要求&#xff0c;故想要设计一门新语言&#xff0c;即是PL/I. PL/I是Programming Language/One的缩写…

labview关于文件路径的问题

在调用文件或拆分文件的时候经常会用到拆分路径函数和创建路径函数&#xff0c;最常用的也是当前应用程序目录或者是当前VI目录。 这里我们看到应用程序目录和VI目录在同一项目中&#xff0c;应用程序目录更像是根目录&#xff0c;往下拆分成了各个VI的子目录。 接下来我们来拆…

Vue + Websocket播放PCM(base64转ArrayBuffer、 字符串转ArrayBuffer)

文章目录 引言I 音视频处理相关概念和APIII 案例:基于开源库 pcm-player方式播放借助MediaSource和Audio对象播放音频流。基于原生api AudioContext 播放操作III 格式转换js字符串转ArrayBufferbase64 转 ArrayBufferIV 解决pcm-player分片播放问题引言 需求: 基于webscoket传…

钉钉授权登录

一.找开钉钉开发平台【钉钉开放平台 (dingtalk.com)】 二。点击菜单【应用开发】->左边【钉钉应用】->【创建应用】 三。创建应用-》保存成功后&#xff0c;点击自己【新建的应用】&#xff0c;进入详细页面 四。进入应用详细页面。左边【分享设置】 注意&#xff1a;进…

kali中信息收集的一些常用工具

这里只是代表个人所见&#xff0c;所以肯定会有其他的没提到&#xff0c;希望大家体谅 前言 信息收集分为主动和被动的 主动就是通过自己的机器去和对方比如通信后获得的数据 被动是指不是在自己这里获取的&#xff0c;可以是第三方平台获取到的&#xff0c;与目标没有通信 …

Apple Vision Pro开发003-PolySpatial2.0新建项目

unity6.0下载链接:Unity 实时开发平台 | 3D、2D、VR 和 AR 引擎 一、新建项目 二、导入开发包 com.unity.polyspatial.visionos 输入版本号 2.0.4 com.unity.polyspatial&#xff08;单独导入&#xff09;&#xff0c;或者直接安装 三、对应设置 其他的操作与之前的版本相同…

YB2503HV:高效率降压IC,助力电动车、太阳能设备等领域的能源转换

今天我要向大家介绍一款引人注目的产品—— YB2503HV 100V 3A SOP8内置MOS 高效率降压IC。这款单片集成芯片具备可设定输出电流的开关型降压恒压驱动器功能&#xff0c;可广泛应用于电动车、太阳能设备、电子电池充电等领域。让我们一起来看看它的特点和应用吧&#xff01; 首先…

@EnableConfigurationProperties @ConfigurationProperties

EnableConfigurationProperties && ConfigurationProperties的使用时机 今天在写properties时想到了这个问题&#xff0c;为什么有时候我需要写EnableConfigurationProperties有时候又不需要呢&#xff1f;下面就详细讲讲。 Data Component ConfigurationProperties(pr…

【Unity踩坑】在Mac上安装Cocoapods失败

在集成Unity Ad时&#xff0c;如果是第一次在iOS上集成&#xff0c;会在Mac上安装Cocoapods。 安装时提示下面的错误&#xff1a; Error installing cocoapods:The last version of drb (> 0) to support your Ruby & RubyGems was 2.0.5. Try installing it with gem…

HBU算法设计与分析 贪心算法

1.最优会场调度 #include <bits/stdc.h> using namespace std; const int N1e55; typedef pair<int,int> PII; PII p[N]; priority_queue<int,vector<int>,greater<int>> q; //最小堆 存储最早结束的会场的结束时间 int n; //其实这个题可以理…

FPGA学习-FFT变换-解决频率低信号进行FFT运算的取点问题

FPGA学习-FFT变换-解决频率低信号进行FFT运算的取点问题 前言一、FFT输入二、FFT配置波形分析 前言 首次接触FFT变换是在OFDM中&#xff0c;QAM后的实部信号与虚部信号需要进行FFT转化&#xff0c;将频域信号转化为时域信号&#xff0c;最终通过DA接口转化为模拟信号。当时对于…