第八章:SegNet——一个用于强大的语义像素级标注的深度卷积编码-解码架构

news/2024/5/10 9:03:45/文章来源:https://blog.csdn.net/ADICDFHL/article/details/131731227

0.摘要

        我们提出了一种新颖的深度架构SegNet,用于语义像素级图像标注。SegNet具有一些吸引人的特性:

        (i)它只需要对完全学习的函数进行前向评估,就可以获得平滑的标签预测;

        (ii)随着深度增加,像素标注考虑了更大的上下文,提高了准确性;

        (iii)在任何深度上,能够轻松可视化特征激活在像素标签空间中的影响。

        SegNet由一系列编码器和相应的解码器堆栈组成,解码器堆栈将输入到一个softmax分类层。解码器帮助将编码器堆栈输出的低分辨率特征映射映射到完整的输入图像尺寸的特征映射。这解决了最近采用为对象分类设计的网络进行像素级标注的深度学习方法的一个重要缺陷。这些方法缺乏将深层特征映射到输入维度的机制,它们采用临时方法来上采样特征,例如通过复制。这导致了嘈杂的预测,并且限制了池化层的数量,以避免过多上采样,从而减少了空间上下文。SegNet通过学习将编码器的输出映射到图像像素标签来克服这些问题。我们在来自CamVid、KITTI的室外RGB场景以及NYU数据集的室内场景上测试了SegNet的性能。我们的结果表明,即使不使用额外的线索(如深度、视频帧或后处理的CRF模型),SegNet也能达到最先进的性能水平。

1.引言

        语义分割是理解和推断场景中观察到的不同对象及其排列方式的重要步骤。这具有广泛的应用范围,包括估计场景几何、推断对象之间的支持关系,以及自动驾驶等。早期依赖于低级视觉线索的方法已经被流行的机器学习算法所取代。特别是,深度学习最近在手写数字识别、语音识别、整体图像分类和图像中对象检测等方面取得了巨大的成功,也在语义像素级标注问题上引起了越来越多的兴趣。然而,这些最新方法试图直接采用为类别预测设计的深度架构来进行像素级标注。尽管结果非常令人鼓舞,但并不完全令人满意。主要问题是,最深层的表示/特征图的分辨率较低,与输入图像的尺寸相比较小,这是由于使用了多个池化层,例如如果使用了3次2×2的非重叠最大池化子采样层,则得到的特征图只有输入维度的1/8。因此,常常使用临时技术将最深层特征图上采样以匹配输入图像的尺寸,通过在一个块内复制特征来实现,即块内的所有像素(在我们的例子中为8×8)具有相同的特征。这经常导致预测结果看起来像是由块组成的。这正是我们通过提出的SegNet架构改进的地方,其中解码器学习将最深层的特征映射到完整的图像尺寸。学习解码有另外两个优点。首先,可以引入更深的层,每个层都有池化-子采样,这增加了像素级标注的空间上下文。这样可以得到平滑的预测,而不像基于补丁的分类器那样。其次,可以使用解码器堆栈进行消融研究,以理解特征的影响,例如[41]中所进行的研究。

        我们从用于构建生成模型的概率自编码器和无监督学习特征层次结构中汲取了我们编码器-解码器类型架构的灵感。我们的主要贡献是以模块化和完全有监督的方式学习编码器-解码器堆栈,用于像素级标注。每增加一个更深的编码器-解码器对,都会增加一个更大的空间上下文,即一个具有4层SegNet和每层7×7的卷积核以及每层2×2的非重叠最大池化的SegNet,在将特征图回溯到输入图像时,具有106×106像素的空间上下文。随着层数的增加,SegNet的预测变得更加平滑,并且表现出高准确度,与使用条件随机场的方法相当甚至超过。SegNet在每一层保持恒定数量的特征,通常设置为64。这具有实际优势,每增加/加深一个编码器-解码器对的计算成本逐渐减少。

        在第2节中,我们回顾了相关的最新文献。我们在第3节中详细描述了SegNet架构以及其定性分析。我们在几个知名的基准数据集上对SegNet进行了定量实验,这些实验在第4节中进行了描述。我们还讨论了我们方法的优点和缺点,包括计算时间。在第5节中,我们总结了未来工作的方向。在我们的大多数实验中,我们使用室外RGB道路场景分析[1,9]和室内RGBD场景分析[33]数据集来衡量定量性能。

 图1.一个四层的SegNet,它接受一个RGB输入图像,并进行前向计算以获取像素级的标签。一堆特征编码器后面跟着相应的解码器。Soft-max层使用最后一个解码器输入的特征对每个像素进行独立分类。编码器使用卷积-ReLU-max池化-子采样的流水线。解码器使用从其编码器传递的池化索引对其输入进行上采样。然后,它使用可训练的滤波器组进行卷积。

2.文献综述

        像素级的语义分割是一个正在进行的研究课题,受到具有挑战性的数据集的推动[1,33,9]。目前表现最好的方法大多依赖于手工设计的特征,通常用于每个像素独立分类。通常,将一个补丁输入分类器,如随机森林[32,2]或提升[36,20],以预测中心像素的类别概率。基于外观[32]、SfM和外观[2,36,20]的特征已经在CamVid测试中进行了探索。这些分类器产生的每个像素的噪声预测(通常称为一元项)然后通过使用二元或高阶CRF [36,20]进行平滑处理,以提高准确性。最近的方法旨在通过尝试预测补丁中所有像素的标签而不仅仅是中心像素的标签来产生高质量的一元项。这改善了基于随机森林的一元项的结果[18],但是结构较薄的类别分类效果较差。从CamVid视频计算得到的密集深度图也被用作使用随机森林进行分类的输入[43]。另一种方法认为,使用流行的手工设计特征和时空超像素化的组合可以获得更高的准确性[39]。在CamVid测试中,最近表现最好的技术[20]通过使用来自PASCAL VOC数据集的额外训练数据来学习对象检测器,解决了标签频率不平衡的问题。所有这些技术的结果表明,在标签频率不平衡存在时,需要改进像素级别的分类。CRF模型的后处理[36]主要提高了主要类别(如天空、道路、建筑物)的准确性,对于标志、杆子、行人等同样重要但结构较薄的类别的准确性影响较小。这凸显了在存在标签频率不平衡时需要更好的像素级分类的需求。

        与此同时,自从发布了NYU数据集[33],室内RGBD像素级语义分割也变得流行起来,该数据集展示了深度通道在改善分割中的有用性。他们的方法使用RGB-SIFT、深度-SIFT和位置等特征作为输入,通过神经网络分类器预测像素一元项。然后,使用CRF对噪声一元项进行平滑处理。通过使用更丰富的特征集,包括LBP和区域分割,可以获得更高的准确性[28],然后再使用CRF进行处理。在最近的工作中[33],使用基于RGB和深度的线索的组合来同时推断类别分割和支持关系。另一种方法专注于实时联合重建和语义分割,其中使用随机森林作为分类器[13]。Gupta等人[12]在执行类别分割之前使用边界检测和分层分组。所有这些方法的共同特点是使用手工设计的特征对RGB或RGBD图像进行像素级分类。

        深度学习在场景分割方面的应用才刚刚开始。也有一些尝试将用于分类的网络应用于分割,特别是通过复制最深层特征块以匹配图像尺寸[7,6,11,8]。然而,由此得到的分类结果是块状的[11]。另一种方法使用循环神经网络[26]将几个低分辨率的预测合并起来,以创建输入图像分辨率的预测。总体而言,尽管其中一些技术已经在手工设计的特征上取得了改进[7]。

        我们的工作受到Ranzato等人提出的无监督特征学习架构的启发[27]。关键的学习模块是一个编码器-解码器网络,其中编码器由一个滤波器组卷积、tanh压缩函数、最大池化和子采样组成,以获得特征图。对于每个样本,在池化过程中计算的最大位置的索引被存储并传递给解码器。解码器使用已存储的池化索引进行特征图的上采样,也被称为开关,并学习解码器滤波器组来重构输入图像。这种架构被用于无监督预训练特征层次结构。类似的解码技术被用于可视化训练好的卷积网络[42]来进行对象分类;转置编码器核被设置为解码器核,后面跟着一个非线性函数,池化索引被用于上采样。Ranzato的架构主要集中在逐层特征学习上,使用小的输入块进行训练,尽管在测试时使用的是全尺寸的图像作为输入。Kavukcuoglu等人通过使用测试尺寸的图像/特征图来学习分层编码器来纠正了这种差异[16]。然而,这两种方法都没有尝试使用深度的编码器-解码器网络进行无监督特征训练,因为它们在每个编码器训练之后丢弃了解码器。在这里,SegNet架构与这些方法不同,因为训练所有的编码器-解码器对的目标都是相同的,即最小化交叉熵标签损失。

        使用深度网络进行像素级预测的其他应用包括图像超分辨率[4]和从单个图像预测深度图[5]。在[5]中,作者讨论了学习从低分辨率特征图进行上采样的需求,这是本文的核心主题。

3.SegNet架构和学习方案

        我们实验中使用的四层SegNet架构如图1所示。每个编码器执行密集卷积,ReLU非线性函数,使用2×2的窗口进行非重叠最大池化,最后进行下采样。每个解码器使用存储的池化索引进行输入的上采样,并使用可训练的滤波器组进行卷积。解码器不使用ReLU非线性函数,与反卷积网络[41,42]不同。这样可以更容易地优化每个编码器-解码器对中的滤波器。编码器和解码器的滤波器也是非绑定的,提供了额外的自由度以最小化目标函数。最后一层是一个softmax分类器(没有偏置项),它独立地对每个像素进行分类。softmax的输出是一个K通道图像,其中K是类的数量。

        SegNet使用了一种“平坦”的架构,即每一层的特征数量保持不变(在我们的实验中为64),但具有全连接性。这个选择有两个原因。首先,与具有完全特征连接的扩展深度编码器网络(解码器也是如此)相比,它避免了参数爆炸。其次,随着特征图分辨率变小,每个额外/更深的编码器-解码器对的训练时间保持不变(在我们的实验中稍微减少),这使得卷积更快。请注意,与输入图像相邻的第一个编码器对应的解码器(最靠近输入图像)产生一个多通道的特征图,尽管编码器的输入是3个或4个通道(RGB或RGBD)(见图1)。这个高维特征表示被送入softmax分类器。这与其他解码器不同,其他解码器产生与它们的编码器输入相同大小的特征图。使用2×2的固定池化窗口和非重叠2个像素的步幅。这个小尺寸保留了场景中的细小结构。此外,所有层上的固定内核大小为7×7,以提供宽广的上下文环境,用于平滑标记,即最深层特征图中的像素可以追溯到输入图像中的一个大小为106×106像素的上下文窗口。在这里需要权衡的是上下文窗口的大小和保留细小结构。较小的内核会减少上下文,而较大的内核可能会破坏细小结构。

        SegNet的输入可以是任意的多通道图像或特征图,例如RGB、RGBD、法线图、深度图等。我们对输入进行局部对比度归一化(LCN)作为预处理步骤[23,15]。这一步的优点有多个:

        (i)校正非均匀的场景照明,从而减小动态范围(增加了阴影部分的对比度);

        (ii)突出显示边缘,使网络学习类别的形状;

        (iii)改善收敛性,因为它使输入维度无关联[23]。

        LCN(局部对比度归一化)针对每种模态进行独立处理,即RGB作为三通道输入进行对比度归一化,深度作为RGBD输入的单通道。这样可以避免由于RGB边缘而突出显示伪深度边缘,反之亦然。

图2.(a)模块化训练从优化第一个编码器和解码器权重开始。Soft-max可以预训练或随机初始化。(b)一旦第一对被训练好,我们插入一个更深的内部编码器-解码器对,并在保持外层编码器-解码器和Soft-max权重不变的情况下优化这些权重。然后依次训练更深的对。注意编码器和解码器的权重是解耦的。

 3.1训练SegNet

        大多数深度学习方法使用随机梯度下降(SGD)进行训练[22]。SGD需要足够的专业知识来初始化适当大小的权重,适应适当的学习率和动量参数,两者都控制着步长。因此,我们采用L-BFGS [25]进行训练,这是基于Ngiam等人的对比研究 [21],他们主张特别适用于自编码器的L-BFGS。L-BFGS(有限内存Broyden-Fletcher-Goldfarb-Shanno(L-BFGS))的收敛速度更快,更稳定。它在大批量处理中也表现良好,这对于最大化强大GPU的吞吐量非常有用。我们使用零均值单位方差的高斯分布N(0;1)来初始化所有层和soft-max权重,并将卷积核归一化为单位L2范数。我们从网络中获得了良好的预测性能,无需特殊的逐层权重初始化或任何学习率调整。我们还使用逆频率加权来纠正训练集中的任何标签不平衡问题[32]。

        我们使用最大化GPU利用率并避免GPU-CPU内存传输的小批量训练。通常,每个小批量选择25-50个随机图像(有放回)。优化器每个小批量运行20次迭代,并为每个层运行10个时期。我们经验性地观察到,目标在5-6个时期后趋于稳定,因此我们额外运行4个时期作为保证。请注意,经过10个时期后,每个输入样本大约会对优化器产生200次“影响”。我们训练与输入层最接近的编码器-解码器权重。Soft-max层可以首先训练或随机初始化,然后在整个实验过程中保持不变。接下来,我们引入一个更深的编码器-解码器层(参见图2),在保持较浅层编码器-解码器权重不变的同时训练它们的权重。请注意,目标保持不变,即在小批量上最小化标签交叉熵损失。这与无监督特征学习方法不同,后者重构了所讨论层的输入[27,16],因此每个层的目标会有所变化。另一方面,解卷积网络[42]在每个更深层上优化相同的重构目标。与我们的方法的区别在于:

        (i)目标是无监督的;

        (ii)没有编码器来学习前馈表示,因此在测试时需要进行优化步骤以生成用于识别的特征。

        我们逐步添加更深的编码器-解码器对,并在保持前一对权重不变的同时训练它们。总之,我们在实验中使用了4层网络,即4个编码器和4个解码器。一旦编码器-解码器堆栈被训练好,我们发现训练soft-max层没有优势,因为它只依赖于线性判别函数。

        我们编写了自己的Matlab GPU兼容的SegNet实现,使用了minFunc优化库[31]。我们的代码已在NVIDIA Tesla K40、GTX GeForce 880M和GTXGeForce780 GPU上进行了测试。我们将很快公开我们的轻量级Matlab代码。在当前的代码优化状态下,在CamVid数据集(367张360×480的训练图像)上训练一个4层深的SegNet大约需要一周时间。未经优化的测试时间约为每帧2秒:大部分计算时间用于在前向传递路径中执行张量卷积,并在反向传播期间执行基于FFT的卷积。

3.2可视化SegNet

        我们进行了一项消融研究,以对SegNet的特征进行一些了解。Zeiler等人的研究[41]研究了训练网络中每个层的特征激活的影响[19]。使用反卷积网络将特征激活映射回图像像素空间。SegNet的架构是根据编码器激活进行训练的,并且我们利用这一点来可视化特征激活在像素标签空间中的效果(哪一层)。最近的一项研究[38]表明,在深度网络的每一层中,编码有用的类信息的是“方向”或“空间”(一组特征激活),而不是个别单元(特征激活)。因此,我们的研究重点在于每一层的一部分特征激活的预测效果。

        对于给定的层,我们计算训练集中每个样本的特征激活/特征图。然后计算每个特征图的均方根值,即8j 2 f1::64g qN1 Pi2I(fji)2,其中fji是给定层中像素i处的第j个特征图值。这为每个特征图分配了一个单一的值,例如,对于SegNet的第4层,CamVid训练集中的每个训练样本将有一个64维的向量。现在,我们计算所有样本中每个向量的前N个元素的直方图。这个直方图显示了训练集中该层中最活跃的特征。对于任意的N,我们将其余的特征图设为零(消融),并对给定的输入样本进行像素级标记解码。请注意,由于我们的训练是模块化的,这可以在添加每个更深的层之后进行。图3展示了基于前N个特征激活的标记在所有层上的一些结果。

        首先,我们观察到随着深度的增加,预测结果变得更加平滑,这是由于输入空间中更大的空间上下文所导致的。更有趣的是,第4层中排名前1的特征几乎完全预测出静态场景类别,并“填补”了缺失的汽车,例如用人行道代替。考虑到被激活以表示汽车的特征被置零,这个预测是合理的,并且表明网络能够学习到空间上下文/类别位置信息。类似地,树被填充为建筑物,护栏被延伸为电线杆。相比之下,对于较浅的层,这种效果不太明显,并且效果变得更差。这表明深层次的子特征集更加“调谐”于特定的场景类别,这与之前的研究结果相吻合[41]。我们在这里还要补充的是,我们尝试了通过依次选择每个特征图并将其余特征图置零来进行消融研究的努力,但得到的结果并没有明显的可解释性。另外,有趣的是,为了使较浅的层产生更好的预测结果,“N”必须设置为约5或10。相应的直方图至少有50%的特征被激活,而第4层的前1层次的激活率约为15%,这表明更深层次的特征更加“调谐”于相关类别的组合。

 

图3. SegNet特征消融研究。SegNet的所有层都使用64个特征。从右到左的四列显示了在各个深度上使用部分特征激活并将其余特征置零时所获得的预测结果。请注意,即使只考虑前1个特征激活,在第4层的深度上,标记的质量也显著提高。有趣的是,这些激活似乎主要针对静态场景类别进行了调整,只有在更多特征被激活时才会标记其他类别(如汽车)。当激活的特征较少时,缺失的类别(汽车)会被用人行道填充,这是合理的。同时显示了作为前N个激活的一部分的激活特征的百分比;深层次的特征激活较少,但更加精细调整。

4.实验和分析

        有许多用于语义解析的室外场景数据集可供选择[10,30,1,9]。在这些数据集中,我们选择了CamVid [1]和KITTI [9]数据集,其中包含11个语义类别,如道路、建筑物、汽车、行人等。这些类别的频率存在很大的不平衡[1]。在数据集中,道路、天空、建筑物像素大约是行人、电线杆、标志符号、汽车、骑自行车者的40-50倍,这使得对较小类别进行标记非常具有挑战性。该数据集包含视频序列,因此我们能够将我们的方法与使用运动和结构[20,36,2]和视频片段[39]的方法进行基准测试。其他数据集有更平衡的标签频率,并且是静态图像数据集。选择CamVid而不是SIFT-flow、LabelMe的另一个原因是训练集的大小较小(367),可以在合理的时间内使用标准GPU训练SegNet。CamVid数据集还包含白天和黄昏(照明较差)条件下的训练和测试图像(233张)。图4显示了SegNet预测与几种众所周知的算法(一元、一元+CRF)的定性比较结果。定性结果显示了SegNet在分割整个场景的同时,对小型类别(汽车、行人、骑自行车者)的分割能力。图4中显示的其他方法使用基于运动的结构线索。由于缺乏这个线索,SegNet会错过一些标签(汽车),但会用其他合理的上下文相关类别填充。基于CRF的结果很平滑,但不能保留小类别。更密集的模型[17]可能更好,但推理成本更高。表1在数值上比较了算法,并证明了它在最近的竞争方法上的优越性。

        KITTI数据集是目前公开可用的最大的道路场景数据集。最近,这个数据集中的一些图像已经被手动标记(8个类别),用于推断密集的3D语义地图[29]。请注意,图像的大小大约为376×1241,所以我们裁剪中心的360×480使其与CamVid数据集兼容。我们使用这个数据集来分析在KITTI测试集上使用CamVid数据进行监督预训练的效果。首先,我们在这里补充说明,仅使用预训练的SegNet(使用CamVid数据)在KITTI样本上进行测试的结果表现很差。这是因为数据集之间的照明差异。因此,我们对KITTI数据集进行了三种其他的训练变体的实验:

        (i)从随机初始化训练SegNet的所有层,表示为SegNet(R);

        (ii)使用CamVid训练的参数初始化,并只训练一个具有隐藏层的softmax分类器,表示为SegNet(SM);

        (iii)使用CamVid训练的参数初始化,并仅训练SegNet的第4层,仅进行2个epoch,表示为SegNet(L4)。

        如预期,SegNet(R)在场景中获得了高质量的预测结果(图5)。CamVid预训练和第4层训练的良好性能表明:

        (i)可以使用较浅的层将有用的语义线索在数据集之间进行传递,

        (ii)在计算预算有限的情况下,首先训练SegNet的最深层是有益的。

        表3显示,即使没有使用时间线索[29],SegNet(R)也具有竞争力。对于室内RGBD场景,纽约大学(NYU)数据集(第2版)是一个包含795个训练和654个测试图像的最大基准数据集,具有14个类别(物体、家具、墙壁、天花板等)的标签比较。NYU数据集已被用于评估Farabet等人的多尺度深度学习场景解析方法。因此,这个基准对比他们使用特定特征上采样的方法与我们的学习上采样方法是有用的。我们还注意到,与SegNet的1:4M参数相比,他们学习了大约1.2M的参数。其他方法要么使用较小的NYU数据集[28],要么使用不同的性能度量[12],要么在一小部分类别上进行测试。表2中的定量分析显示,在13个类别中,SegNet的预测结果在9个类别中优于多尺度卷积网络(仅有2个池化层)。这表明SegNet可以通过使用更深的层来增加上下文来处理尺度变化。总体结果仍然远未令人满意,需要借助高度、深度归一化等线索(在[13]中使用)来提高性能。图6中的定性结果显示,预测结果在大部分情况下是正确的,但缺乏清晰的边缘。这是由于输入分辨率较低(320×240),类边缘周围缺乏真实值,以及深度插值错误所导致的。另一个原因是在我们测试的不同数据集上,SegNet的参数保持不变。我们计划在未来更详细地研究NYU数据集。更多的结果可以在补充材料中查看。

表1.在CamVid [1]上的定量结果。我们将SegNet-4层与其他方法进行比较。SegNet在几个具有挑战性的类别(汽车、行人、电线杆)上表现最好,同时在其他类别上保持竞争性的准确性。即使与使用运动结构[2]、CRF[36,20]、密集深度图[43]、时间线索[39]的方法相比,SegNet的类别平均值和全局平均值也是最高的。

表2.在NYU v2 [33]上的定量结果。SegNet在13个类别中的9个类别上的表现优于使用相同输入(和后处理)的多尺度卷积网络。[13]中的方法使用额外的线索,如地面平面检测和列归一化深度,以实现更高的准确性。

 表3.在KITTI数据集[9,29]上的定量结果。SegNet的整体性能更好,并且在类别之间可比较。栅栏类别类似于建筑物,需要其他线索(如[29]中使用的时间信息)来提高准确性。

 

 

 图4.在CamVid白天和黄昏测试序列上的结果样本。各种一元预测的演变以及与外部训练的检测器[20]和CRF模型[36]结合的一元预测。SegNet的预测结果比其他方法更好地保留了小类别,如电线杆(第2、4列)、骑自行车者(第3列)、远侧人行道(第2列),同时产生了整体平滑的预测结果。CRF的结果虽然平滑,但即使使用了基于SfM的线索,仍然会漏掉几个重要的类别。在黄昏的情况下,SfM线索尤其有价值(第3行)。在这里,SegNet未能标记出汽车(第4列),但它用非常合理的预测结果填充了这部分。

 图5.第1行和第2行展示了KITTI测试样本。请注意与图4中CamVid样本的照明差异。第3行:当所有层都从随机初始化开始,使用KITTI训练集进行训练的预测结果。第4行:SegNet使用CamVid数据集进行预训练,只有第4层在KITTI训练集上进行了两个时期的训练。有监督的预训练可以在额外的计算工作量下产生良好的结果。第5行:从预训练权重开始,只训练一个带有隐藏层的软最大分类器所得到的结果较差。未知类别被黑化。

 图6.第1行和第2行:来自NYU v2数据集的室内场景及其地面真值。第3行:SegNet使用RGBD输入的预测结果。没有使用额外的信息,如地面平面拟合、列像素深度归一化[13]或多尺度输入[6]。尽管预测结果在很大程度上是正确的,但类别之间的边缘不够清晰,主要是由于输入分辨率低,类别边缘附近的插值深度值造成的。

5.结论

        我们提出了SegNet,这是一种完全可训练的深度架构,用于将输入图像以前馈方式映射到其像素级语义标签的联合特征学习和映射。该架构的一个亮点是与基于局部补丁的分类器相比,它能够生成平滑的分割标签。这是由于深层特征编码使用了大的空间上下文来进行像素级标注。据我们所知,这是第一个通过深度学习方法学习将低分辨率编码器特征映射到语义标签的方法。SegNet在室外和室内场景的定性和定量准确性都非常有竞争力,即使没有使用任何CRF后处理。我们还展示了预训练的SegNet在其他数据集上通过少量额外计算工作获得良好性能的能力。SegNet的编码器-解码器架构还可以进行无监督训练,并能够在测试时处理输入中的缺失数据。

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

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

相关文章

SpringBoot+actuator和admin-UI实现监控中心

使用SpringBoot很久了&#xff0c;但是很少使用到SpringBoot的查看和监控&#xff0c;将来八成也不会用到&#xff0c;万一有机会用到呢&#xff1f;所以记录一下以前学习SpringBootactuator和adminUI实现监控中心的方式 Springboot的版本2.0.x <parent><groupId>…

keepalived安装配置详解

文章目录 高可用介绍keepalived安装、使用vip漂移抓包脑裂脑裂有没有危害&#xff1f;如果有危害对业务有什么影响&#xff1f; keepalived架构双vip架构 Healthcheck实现 notifyVRRP选举格式 高可用 介绍 高可用性&#xff08;High Availability&#xff09;是指系统或服务能…

Word2Vec实现文本识别分类

深度学习训练营之使用Word2Vec实现文本识别分类 原文链接环境介绍前言前置工作设置GPU数据查看构建数据迭代器 Word2Vec的调用生成数据批次和迭代器模型训练初始化拆分数据集并进行训练 预测 原文链接 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&…

pycharm新建分支并提送至GitHub

文章目录 前言pycharm创建本地分支Push至远程分支 前言 当我们写的项目代码越来越多时&#xff0c;一个master分支无法满足需求了&#xff0c;这个时候就需要创建分支来管理代码。 创建分支可以快速的回滚到某个节点的版本&#xff0c;也可以多个开发者同时开发一个项目&#…

剑指oferr68-II.二叉树的最近公共祖先

为什么这道题的难度是easy&#xff0c;我感觉挺难的啊&#xff0c;我想了挺久没有一点思路就直接看题解了。题解有两种解法&#xff0c;先看第一种存储父节点 class Solution {Map<Integer,TreeNode> parent new HashMap<Integer,TreeNode>();Set<Integer>…

windows nodejs 版本切换

一、按健winR弹出窗口&#xff0c;键盘输入cmd,然后敲回车。然后进入命令控制行窗口&#xff0c;并输入where node查看之前本地安装的node的路径。 二、找到上面找到的路径&#xff0c;将node.exe所在的父目录里面的所有东西都删除。 三、从官网下载安装包 https://github.com/…

Raft算法之日志复制

Raft算法之日志复制 一、日志复制大致流程 在Leader选举过程中&#xff0c;集群最终会选举出一个Leader节点&#xff0c;而集群中剩余的其他节点将会成为Follower节点。Leader节点除了向Follower节点发送心跳消息&#xff0c;还会处理客户端的请求&#xff0c;并将客户端的更…

AP5193 DC-DC宽电压LED降压恒流驱动器 LED电源驱动IC

产品 AP5193是一款PWM工作模式、外围简单、内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度降压LED恒流驱动芯片。电流2.5A。AP5193可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5193 工作频率可以通过RT 外部电阻编程来设定&#xff0c;同时…

linux下一个iic驱动(按键+点灯)-互斥

一、前提&#xff1a; 硬件部分&#xff1a; 1. rk3399开发板&#xff0c;其中的某一路iic&#xff0c;这个作为总线的主控制器 2. gd32单片机&#xff0c;其中的某一路iic&#xff0c;从设备。主要是按键上报和灯的亮灭控制。&#xff08;按键大约30个&#xff0c;灯在键的…

day34-servlet 分页

0目录 servlet 1.分页 分页逻辑1&#xff1a;数据库中20条记录&#xff0c;要求每页5条数据&#xff0c;则一共有4页 分页逻辑2&#xff1a;数据库中21条记录&#xff0c;要求每页5条数据&#xff0c;则一共有5页 分页逻辑3&#xff1a;数据库中19条记录&#xff0c;要求每页…

数字 IC 设计职位经典笔/面试题(二)

共100道经典笔试、面试题目&#xff08;文末可全领&#xff09; FPGA 中可以综合实现为 RAM/ROM/CAM 的三种资源及其注意事项&#xff1f; 三种资源&#xff1a;BLOCK RAM&#xff0c;触发器&#xff08;FF&#xff09;&#xff0c;查找表&#xff08;LUT&#xff09;&#xf…

【算法基础】2.1栈和队列(单调栈和单调队列)

文章目录 例题3302. 表达式求值&#xff08;栈的应用&#xff09;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;830. 单调栈知识点解法 154. 滑动窗口 &#xff08;单调队列&#xff09;知识点解法 相关链接 & 相关题目 例题 3302. 表达式求值&…

基于weka手工实现多层感知机(BPNet)

一、BP网络 1.1 单层感知机 单层感知机&#xff0c;就是只有一层神经元&#xff0c;它的模型结构如下1&#xff1a; 对于权重 w w w的更新&#xff0c;我们采用如下公式&#xff1a; w i w i Δ w i Δ w i η ( y − y ^ ) x i (1) w_iw_i\Delta w_i \\ \Delta w_i\eta(y…

RabbitMQ 同样的操作一次成功一次失败

RabbitMQ 是一个功能强大的消息队列系统&#xff0c;广泛应用于分布式系统中。然而&#xff0c;我遇到这样的情况&#xff1a;执行同样的操作&#xff0c;一次成功&#xff0c;一次失败。在本篇博文中&#xff0c;我将探讨这个问题的原因&#xff0c;并提供解决方法。 我是在表…

创作一周年纪念日【道阻且长,行则将至】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; 技术之外的往事 &#x1f383;所处时段&#xff1a; 大学生涯[1/2] 文章目录 一、起点一切皆有定数 二、成果尽心、尽力 三、相遇孤举者难起&#xff0c;众行者易趋 四、未来长风破浪会有时&#xff0c;直挂云…

markdown2html 转化流程

定义一个extensions function markedMention() {return {extensions: [{name: mention,level: inline,start(src) {// console.log("markedMention start....", src);return src.indexOf(#)},tokenizer(src, tokens) {const rule /^(#[a-zA-Z0-9])\s?/const match…

JMeter websocket接口测试

前言 在一个网站中&#xff0c;很多数据需要即时更新&#xff0c;比如期货交易类的用户资产。在以前&#xff0c;这种功能的实现一般使用http轮询&#xff0c;即客户端用定时任务每隔一段时间向服务器发送查询请求来获取最新值。这种方式的弊端显而易见&#xff1a; 有可能造…

解决Gson解析json字符串,Integer变为Double类型的问题

直接上代码记录下。我代码里没有Gson包&#xff0c;用的是nacos对Gson的封装&#xff0c;只是包不同&#xff0c;方法都一样 import com.alibaba.nacos.shaded.com.google.common.reflect.TypeToken; import com.alibaba.nacos.shaded.com.google.gson.*;import java.util.Map;…

idea-控制台输出乱码问题

idea-控制台输出乱码问题 现象描述&#xff1a; 今天在进行IDEA开发WEB工程调式的时候控制台日志输出了乱码&#xff0c;如下截图 其实开发者大多都知道乱码是 编码不一致导致的&#xff0c;但是有时候就是不知到哪些地方不一致&#xff0c;今天我碰到的情况可能和你的不相同…

前端框架Layui实现动态表格效果用户管理实例(对表格进行CRUD操作-附源码)

目录 一、前言 1.什么是表格 2.表格的使用范围 二、案例实现 1.案例分析 ①根据需求找到文档源码 ②查询结果在实体中没有该属性 2.dao层编写 ①BaseDao工具类 ②UserDao编写 3.Servlet编写 ①R工具类的介绍 ②Useraction编写 4.jsp页面搭建 ①userManage.jsp ②…