Triplet Loss: A Unified Embedding for Face Recognition and Clustering(论文阅读笔记)(2015CVPR)

论文链接:《FaceNet: A Unified Embedding for Face Recognition and Clustering

摘要

  尽管人脸识别领域最近取得了重大进展[10,14,15,17],但大规模高效地实现人脸验证和识别对现有方法提出了严峻挑战。在这篇论文中,我们提出了一个叫做FaceNet的系统,它可以直接从人脸图像学习到一个紧凑的欧几里德空间的映射,其中距离直接对应于人脸相似性的度量。一旦生成了这个空间,使用以FaceNet嵌入(embeddings)为特征向量的标准技术就可以轻松地实现人脸识别、验证和聚类等任务。

    我们的方法使用一个经过训练的深度卷积网络来直接优化嵌入(embeddings)本身,而不是像以前的深度学习方法那样使用一个中间的bottleneck层。为了进行训练,我们使用了一种新的在线triplet挖掘方法生成的大致对齐的匹配/非匹配人脸patchs的三联体(triplets)。我们的方法的好处是更大的表征效率:我们实现了最好的人脸识别性能,每张人脸只用128字节(即,为每张人脸生成128维的特征向量)。

    在广泛使用的人脸(LFW)数据集中,我们的系统达到了99.63%的新记录精度。YouTube上的DB则达到了95.12%。我们的系统将两个数据集的错误率与最佳公布结果[15]相比降低了30%。

1 引言

  在本文中,我们提出了一个统一的人脸验证(这是同一个人吗?)、识别(这是谁?)和聚类(在这些人脸中找到普通人?)系统。我们的方法是基于学习欧氏嵌入,每幅图像使用深卷积网络。该网络经过训练,使得嵌入空间中L2距离的平方直接对应于人脸相似性:同一个人的脸距离小,不同人的脸距离大。

    一旦产生了这种embeddings,那么前面提到的任务就变得很简单:人脸验证只需要对两个嵌入之间的距离进行阈值化识别成为一个k-NN分类问题;而聚类可以使用离轴技术,如k-means或凝聚聚类来实现。

    以往基于深度网络的人脸识别方法是在一组已知人脸身份的基础上训练一个分类层[15,17],然后利用中间瓶颈层作为特征表示,将识别推广到训练中使用的一组识别之外。这种方法的缺点是它的间接性和低效性:我们必须希望瓶颈表示能很好地泛化到新面孔;通过使用瓶颈层,每个人脸的表征size通常非常大(1000维)。最近的一些工作[15]使用PCA降低了这种维数,但这是一个线性变换,可以在网络的一层轻松学习。

    与这些方法相反,FaceNet基于LMNN使用基于triplet损失函数直接训练输出为128-D的embeddings。我们的triplets由两个匹配的人脸缩略图和一个不匹配的人脸缩略图组成,loss的目的是在一定距离(margin)上将positive pair和阴negative pair区分开。缩略图是从人脸区域crop(随机裁剪)得到,没有二维或三维对齐,只执行缩放和平移。

    在curriculum learning[1]的启发下,我们提出了一种新的在线负人脸样本挖掘策略,该策略保证了随着网络训练,triplets的难度不断增加。为了提高聚类精度,我们还探索了hard-positive挖掘技术,该技术鼓励球状聚类用于单个人的embeddings。

    图1展示了我们的方法所能处理的令人难以置信的可变性。图中显示的是来自PIE[13]的图像对,这些图像对以前被认为是人脸验证系统中非常困难的。

图1所示。光照和姿态不变性。姿态和光照是人脸识别中一个长期存在的问题。这张图显示了在不同的姿态和光照组合下,相同人和不同人的人脸对之间的FaceNet输出距离。距离0.0表示人脸是相同的,4.0对应的是相反的谱,两个不同的identities。您可以看到,1.1的阈值可以正确地对每一对进行分类。

    本文其余部分的综述如下:在第二部分中,我们回顾了这一领域的文献;第3.1节定义了triplet损失,第3.2节描述了我们新的triplet选择和训练过程;在3.3节中,我们描述了所使用的模型架构。最后,在第4和第5节中,我们给出了我们的embeddings的一些定量结果,并定性地探讨了一些聚类结果。

2 相关工作

  类似于最近其他使用深度网络的研究[15,17],我们的方法是一种纯数据驱动的方法直接从人脸的像素中学习其表示。我们不是使用工程特征,而是使用一个大的标记人脸数据集以实现姿势、光照和其他变化条件不变性。

    在本文中,我们探讨了两种不同的深度网络架构,它们最近在计算机视觉社区中获得了巨大的成功。两者都是深度卷积网络[8,11]。第一个架构基于Zeiler&Fergus[22]模型该模型由多个交错的卷积层、非线性激活层、局部响应归一化层和最大池化层组成。此外,我们还添加了几个1×1×d卷积层,灵感来自于[9]的工作。第二种架构基于Szegedy等人的Inception模型,该模型最近被用作ImageNet 2014[16]的获胜方法。这些网络使用混合层,这些混合层并行运行几个不同的卷积和池化层,并将它们的响应连接起来。我们发现,这些模型可以将参数的数量减少至多20倍,并且有潜力减少可比较性能所需的FLOPS。

    有大量的人脸验证和识别工作。对它的回顾超出了本文的范围,因此我们只简要讨论最近相关的工作。

    [15,17,23]的工作都采用了一个复杂的多阶段系统,将深度卷积网络的输出用PCA进行降维,然后采用SVM进行分类。

    Zhenyao等人利用深度网络将人脸“warp”成一个标准的正面视图,然后学习CNN将每张脸分类为属于一个已知身份的人脸。在人脸识别中,采用了基于PCA的网络输出和SVM的集成方法。

    Taigman等人提出了一种多阶段方法可以把人脸对齐到一般的三维形状模型。一个多分类网络被训练来执行4000多个身份的人脸识别任务。作者还用所谓的暹罗网络进行了实验,他们直接优化了两个面部特征之间的 L1 距离。他们在LFW上的最佳表现(97.35%)源于三个使用不同对齐和颜色通道的网络的集成。预测的距离(非线性支持向量机预测基于χ2内核)的网络使用非线性支持向量机相结合。

    Sun等人[14,15]提出了一种紧凑的,因此相对便宜的计算网络。他们使用了25个这样的网络,每个网络在不同的人脸patch上运行。对于他们在LFW上的最终表现(99.47%[15]),作者结合了50个响应(常规和翻转)。采用PCA和联合贝叶斯模型[2],有效地对应于嵌入空间中的线性变换。他们的方法不需要显式的2D/3D对齐。该网络采用分类和验证损失相结合的方法进行训练。验证损失类似于我们使用的triplet损失[12,19],因为它使相同身份的人脸之间的 L2 距离最小化,并强制不同身份的人脸之间的距离保持一定的margin主要的不同之处在于,只有图像对的比较,而triplet损失则鼓励相对距离约束

    Wang等人在[18]中探索了类似的损失,用于根据语义和视觉相似性对图像进行排序。

3 方法

  FaceNet使用深度卷积网络。我们讨论了两种不同的核心架构:Zeiler&Fergus[22]风格的网络和最近出现的[16]类型的网络。这些网络的详细情况见第3.3节。

    考虑到模型的细节,并将其视为一个黑盒子(参见图2),我们方法的最重要部分在于整个系统的端到端学习。为了达到这个目的,我们使用了triplet损失它直接反映了我们在人脸验证、识别和聚类方面想要达到的效果。也就是说,我们努力将图像 x 嵌入到特征空间 中,使相同身份的所有人脸之间的平方距离(不依赖于成像条件)都很小,而来自不同 identities 的一对人脸图像之间的平方距离很大。

图2。模型结构。我们的网络由一个batch输入层和一个深度CNN组成,然后L2归一化,实现了人脸的embedding。接下来是训练中的triplet loss。

    虽然我们没有直接与其他损失进行比较,如[14]式(2)中使用的正负对损失,但我们认为triplet损失更适合于人脸验证。其动机是[14]的损失鼓励将同一identitiy的所有人脸投射到嵌入空间(embedding space)中的一个点上。然而,triplet loss试图在每对人脸之间建立一个从一个人到所有其他人脸的margin。这允许一个人的所有人脸处于一个流上,同时仍然保持距离,从而区别于其他人脸。

3.1 Triplet loss

  embedding由表示。它将图像 x 嵌入到 d 维欧氏空间中。此外,我们将这个embedding限制在 d 维超球面上,即。这种损失是在[19]中最近邻分类的上下文中引起的。在这里,我们想要确保一个特定的人的图像(anchor) 比任何其他人的图像(negative) 更接近同一个人的所有其他图像(positive)。如图3所示。

图3。triplet loss使anchor与positive之间的距离最小化,两者具有相同的identity,并使anchor与不同identity的negative之间的距离最大化。

    因此我们希望:

    其中 α 是一个迫使positive pairs 和 negative pairs之间有一个margin。是训练集中所有可能的三元组(triplets)的集合,基数为 N。

    被最小化的损失 L = 

    生成所有可能的三元组(triplets)将生成许多容易满足的三元组(即满足式(1)中的约束)。这些三元组对训练没有帮助,并且会导致更慢的收敛速度,因为它们仍然会通过网络。关键是要选择hard triplets,他们是活跃的,因此可以帮助改进模型。下一节将讨论triplet选择的不同方法。

3.2 Triplet 选择

  为了确保快速收敛,选择违反式(1)约束的triplets很重要。这意味着,给定 ,我们想要选择一个 (hard positive)。即 ,同样 (hard negative),即

    在整个训练集中计算 argmin 和 argmax 是不可行的。此外,这可能导致训练质量差,因为错误的标签和较差的图像将主导hard positives 和 hard negatives。有两个明显的选择可以避免这个问题:

    1,每n步离线生成triplets,使用最新的网络checkpoint并计算数据子集上的argmin和argmax。
    2,在线生成triplets。这可以通过在一个mini-batch中选择hard positive/negative 样本来实现。

    在这里,我们将重点放在在线生成上,并按照数千个样本的顺序使用较大的mini-batch,并且只在一个mini-batch中计算 argmin 和 argmax。

    为了获得一个有意义的 anchor-positive 距离表示需要确保在每个mini-batch中出现任意一个identity的最小数量的示样本(就是说,在一个mini-batch中要保证每个identity至少出现的数量)。在我们的实验中,我们对训练数据进行抽样,这样每个mini-batch的每个identity就会选择大约40张人脸。此外,随机抽样的negative faces被添加到每个mini-batch。

    我们没有选择 hardest positive,而是在一个mini-batch中使用所有的anchor-positive pairs,同时仍然选择hard negatives。我们没有对 mini-batch 内的 hard anchor-positive pair 和所有 anchor-positive pair 进行并排比较,但我们在实践中发现,所有anchor-positive 方法在训练开始时更稳定,收敛速度略快。

    我们还探索了triplet的离线生成与在线生成的结合,这可能允许使用更小的batch-size,但实验尚未得出结论。

    在训练的早期,选择hardest negative会导致糟糕的局部极小值,特别是它会导致一个崩溃的模型(即,f(x) = 0)。为了缓解这种情况,可以这样选择

    我们称这些负样本为 semi-hard 的,因为它们比正样本离 anchor 更远,但仍然是hard,因为平方距离接近 anchor-positive 的距离。这些 negatives 位于margin α 内。

    如前所述,正确的 triplet 选择对于快速收敛是至关重要的。一方面,我们希望使用小mini-batch的方法,因为在随机梯度下降(SGD)[20]过程中,这些方法可以提高收敛性。另一方面,实现细节使十到数百个样本batches更加有效。然而,与batch-size有关的主要约束是我们从mini-batch中选择hard相关的triplets的方式。在大多数实验中,我们使用大约1800个样本的batch-size。

3.3 深度卷积网络

  在我们所有的实验中,我们使用随机梯度下降(SGD)和标准的backprop[8,11]和AdaGrad[5]对CNN进行训练。在大多数实验中,我们以0.05的学习率开始,然后我们降低学习率来最终确定模型。这些模型是随机初始化的,类似于[16],并在CPU集群上训练1000到2000小时。在500小时的训练后,loss急剧下降(准确性增加),但是额外的训练仍然可以显著提高性能。margin α 设置为0.2。

    我们使用了两种类型的网络结构,并在实验部分更详细地探讨了它们的优缺点。它们的实际差异在于参数的差异和FLOPS。最佳模型可能因应用程序的不同而有所不同。例如,在数据中心中运行的模型可以有很多参数,并且需要大量的FLOPS,而在mobile phone上运行的模型需要很少的参数,这样它就可以装入内存。所有的模型都采用矫正线性单元(ReLU)作为非线性激活函数。

    第一类如表1所示,在Zeiler&Fergus[22]架构的标准卷积层之间增加了1×1×d卷积层,如[9]所示,模型深度为22层。它总共有1.4亿个参数,每幅图像需要大约16亿次FLOPS。

表1。NN1。这张表展示了我们基于Zeiler&Fergus[22]的模型的结构,该模型的1×1卷积灵感来自[9]。输入和输出大小用描述。kernel 指定为 rows×cols, stride, maxout[6]池池化大小为p = 2。

    我们使用的第二类是基于GoogLeNet风格的Inception模型[16]。这些模型具有20倍更少的参数(大约6.6M-7.5M)和高于5倍的更少FLOPS(在500 -1.6 b之间)。其中一些模型的size(深度和过滤器的数量)大大减小,因此可以在mobile phone上运行。其中,NNS1有26M个参数,每张图像只需要2.2 M次FLOPS。另一个是NNS2,它有4.3M个参数和20M次FLOPS。表2详细描述了我们最大的网络NN2。NN3在架构上是相同的,但是输入size减少为160x160。NN4的输入size只有96x96,因此大大降低了CPU需求(258M FLOPS vs. NN2是1.6B)。除了减小了输入size之外,它在更高的层中不使用5x5卷积,因为感受野已经太小了。一般来说,我们发现5x5的卷积可以在整个过程中去除,而精度只会有微小的下降。图4比较了我们所有的模型。

表2。NN2。NN2 Inception 化身的详细信息。该模型与[16]中描述的模型基本相同。两个主要区别是使用L2 pooling而不是指定的max pooling(m)。也就是说,计算 L2范数 而不是取空间最大值。池化总是3×3(除了最终的平均池化),并且与每个Inception模块中的卷积模块并行。如果池化后存在降维,则用 p 表示。然后将1×1, 3×3和 5×5 池化连接起来,得到最终的输出。

图4。FLOPS vs. accuracy trade-off。图中显示了在不同模型大小和架构的范围内,在FLOPS和Accuracy 之间的trade-off。高亮显示的是我们在实验中关注的四个模型。

4 数据集合评估

  我们在4个数据集上评估我们的方法,除了Labeled Faces in the Wild和YouTube Faces,我们在人脸验证任务上评估我们的方法。即给定一对人脸图像,平方L2距离阈值用于确定相同和不同的分类。所有同一identity的人脸对pairs(i,j)用表示,所有不同 identity 的人脸用 表示。

    我们将所有true accept的集合定义为:

    这些是人脸对(i,j)在阈值为 d 时被正确分类为相同人脸。同样地:

    是所有被错误分类为相同的 pair 的集合(false accept)。 

    然后对一个给定人脸距离 d 的验证率 VAL(d )和假接受率 FAR(d) 定义为:

4.1  抵抗(hold-out)测试集

  我们保留了大约100万幅图像的hold out集合,这与我们的训练集具有相同的分布,但是身份不相关。为了进行评估,我们将其分成5组互不相交的20万幅图像。然后在100k×100k图像对上计算FAR率和VAL率。标准错误报告横跨五个splits。 

4.2 Personal Photos(私人照片)

  这是一个与我们的训练集分布类似的测试集,但是经过手工验证,具有非常干净的标签。它由三个个人摄影集组成,总共约有12k张图片。我们计算了所有12k平方对图像的FAR 和VAL速率。

4.3 Academic Datasets

  Labeled Faces in the Wild(LFW)是一个事实上的学术测试集的人脸验证[7]。我们遵循不受限制、标注外部数据的标准协议,报告平均分类精度和平均标准误差。

  Youtube Faces DB[21]是一个在人脸识别领域中得到广泛应用的新数据集[17,15]。该设置类似于LFW,但是使用视频对而不是验证图像对。

5 实验

  如果没有提到其他,我们使用100M -200M的训练人脸缩略图,包含大约8M个不同的身份。每个图像上运行一个人脸检测器,并在每个人脸周围生成一个紧凑的边界框。这些人脸缩略图被调整为相应网络的输入大小。在我们的实验中,输入大小从 96x96像素到 224x224 像素不等。

5.1 计算准确率代价

  在深入研究更具体实验的细节之前,我们将讨论特定模型所需的准确率与失FLOPS次数之间的trade-off。图4显示了x 轴上的FLOPS和4.2节中用户标记测试数据集上0.001的错误接受率(FAR)。有趣的是,一个模型所需的计算与它所达到的精度之间存在很强的相关性。图中突出显示了我们在实验中更详细讨论的五个模型(NN1、NN2、NN3、NNS1、NNS2)。    

  我们还研究了关于模型参数数量和准确率的 trade-off。然而,在这种情况下情况就不那么清楚了。例如,基于 Inception 的模型NN2实现了与NN1相当的性能,但是只有20th个参数。然而,FLOPS 次数是相当的。显然,如果参数的数量进一步减少,在某一时刻性能将会下降。其他模型架构可能允许在不损失精度的情况下进一步降低,就像本例中的 Inception [16]所做的那样。

5.2 CNN模型的有效性

  现在,我们将更详细地讨论四个所选模型的性能。一方面,我们有传统的基于Zeiler&Fergus的架构,基础结构具有1×1卷积[22,9](见表1),另一方面我们有基于 Inception 结构的模型,它大大减少了模型的 size。总的来说,在最终的性能中,两种体系结构的顶级模型的性能是相当的。然而,我们的一些基于Inception的模型,例如NN3,在显著减少FLOPS和模型大小的同时,仍然实现了良好的性能。

    对我们的Personal photos测试集的详细评估如图5所示。虽然与tiny NNS2相比,最大的模型在精度上有了显著的提高,但后者可以在mobile phone上运行30ms / image,仍然足够精确,可以用于人脸聚类。ROC值在FAR < 10 - 4时急剧下降,表明试验数据ground truth中存在噪声标签。在极低的错误接受率下,单个错误标记的图像可以对曲线产生显著影响。

图5。网络架构。这个图显示了我们在4.2节的personal photo 测试集中四个不同模型的完整ROC曲线。在10E-4 FAR处的急剧下降可以用groundtruth标签中的噪音来解释。模型按性能顺序为:NN2: 224×224输入,基于Inception模型;NN1:基于Zeiler&Fergus的1×1卷积网络;NNS1:小型Inception风格模型,只有220万次FLOPS;NNS2:小型Inception模型,只有20万次FLOPS。

5.3 图片质量的敏感性

  表4显示了我们的模型在各种图像大小范围内的鲁棒性。该网络在JPEG压缩方面的健壮性令人惊讶,并且在JPEG质量下降20的情况下表现得非常好。对于大小为120x120像素的人脸缩略图,性能下降非常小,即使在80x80像素的情况下,也显示出可以接受的性能。这是值得注意的,因为网络是在220x220输入图像上训练的。低分辨率人脸的训练可以进一步提高这一范围。

表4。图像质量。左边的表格显示了在不同JPEG质量下,验证率在10E-3精度下的影响。右边的显示了以像素为单位的图像大小如何影响10E-3精度下的验证率。这个实验是用NN1在我们的测试保留数据集的第一个split上完成的。

5.4 Embedding维度

  我们探索了不同的 embedding 维度数,除了表5所示的比较外,我们选择了128个作为所有实验的embedding维数。人们会期望较大的 embedding 至少和较小的 embedding 一样好,但是,它们可能需要更多的训练才能达到相同的精度。尽管如此,表5中报告的性能差异在统计学上并不显著。

表5所示。embedding 维数。下表比较了NN1模型的embedding 维数对4.1节中hold-out集的影响。除了在10E-3处的VAL值外,我们还展示了在五次split中计算出的平均值的标准误差。 

    需要注意的是,在训练过程中使用了一个128维浮点向量,但是它可以被量化到128字节而不损失精度。因此,每个人脸都由一个128维字节向量紧凑地表示,这对于大规模的聚类和识别是理想的。较小的嵌入可以在较小的精度损失下实现,并且可以应用于移动设备。

5.5 训练数据数量

  表6显示了大量训练数据的影响。由于时间的限制,该评估在较小的模型上运行;这种影响在更大的模型上可能更大。很明显,使用数以千万计的样本,我们的personal photo测试集的准确性明显提高,从4.2节开始。与数百万幅图像相比,相对误差降低了60%。使用另一个数量级的更多图像(数亿张)仍然会带来一个小的提升,但是这种提升会逐渐减弱。

表6所示。训练数据的size。此表比较了在使用 96x96 像素输入的较小模型下,经过700小时的训练后的性能。模型架构类似于NN2,但是在Inception模块中没有5x5的卷积。

5.6 LFW上的性能

  我们在LFW上使用标准协议对不受限制的、标记为外部数据的模型进行了评估。使用9个训练splits来选择L2距离阈值。分类(相同或不同)然后执行第十次测试split。所选的最佳阈值为1.242,除第8个split(1.256)之外的所有测试split。

    我们的模型在两种模式下进行评估:

    1,固定中心,从LFW中crop(随机裁剪)产生缩略图。
    2,在提供的LFW缩略图上运行一个专用的人脸检测器(类似于Picasa[3])。如果它没有对齐人脸(这发生在两个图像上),则使用LFW对齐。

图6给出了所有失败案例的概述。它在顶部显示false accept,在底部显示false reject。当使用固定中心crop(1)中描述,我们达到了98.87%±0.15的分类精度;在使用额外的脸对齐(2),破纪录的99.63%±0.09平均数标准误差。这减少了DeepFace在[17]中误报超过7个点,和前面的最先进的在[15]DeepId2 报道的30%。这是NN1模型的性能,但即使是小得多的NN3,其性能也没有统计学上的显著差异。

5.7 Youtube Faces DB上的性能

  我们使用我们的人脸检测器在每个视频中检测到的前100帧的所有pairs的平均相似性。分类精度为95.12%±0.39。使用前1000帧的结果是95.18%。与[17]91.4%的相比,我们将错误率降低了近一半。DeepId2+[15]达到93.2%,我们的方法减少了30%的误差,与我们对LFW的改进相当。

5.8 Face聚类

  我们的紧凑的embedding使自己可以用来将用户的个人照片聚集到具有相同身份的人群中。与纯粹的验证任务相比,集群在分配方面施加的约束会导致真正惊人的结果。图7显示了使用聚集聚类生成的用户个人照片集合中的一个集群。这是一个清晰的展示难以置信的不变的遮挡,照明,姿势,甚至年龄。
 

热门文章

暂无图片
编程学习 ·

javascript 实现所有浏览器异步加载的工具

javascript 实现所有浏览器异步加载的工具 //异步加载 实现 function loadScript(url, callback){ //新建一个script 元素 var script = document.createElement(‘script’); //再往script中添加类型 script.type=“text/javascript”; if(script.readyState){ //每当 rea…
暂无图片
编程学习 ·

python学习记录

变量和简单数据类型 message="Hello Python world!" print(message)message就是一个变量,绿色部分用双引号括起来的(也可以用单引号)就是一个字符串。变量的命名和使用: 1.变量名只能包含字母、数字和下划线。字母下划线可以打头数字不可以。 2.变量名不能包含空…
暂无图片
编程学习 ·

C语言实现为终端程序--webshell基石

之前对ssh一直很困惑它是如何实现的,网上也没有相关代码实例,所以自己花了一段时间研究了一下。本篇博客主要写了两个程度:服务端和客户端,通过客户端可以远程登录服务端,执行shell命令。代码实现的比较糙,但是基本原理一看就明白。一、主要核心思想:1)创建pty虚拟终端…
暂无图片
编程学习 ·

MySQL不完全干货教程(持续更新中)

已经有很多教程面面俱到、事无巨细,但实际上能用到的、消化的内容很少。本文聚焦于常见的使用场景,给出MySQL用法和基本原理说明。为便于实践和消化,同时提供了很多案例和脚本。 为了读者进一步深入学习、掌握自我升级的方法,提供了一些权威文档的参考。希望能帮助MySQL初中…
暂无图片
编程学习 ·

吐血整理各种二叉树(BST、AVL、Red Black、B、B+)

前言 没有必要过度关注二叉树的增删改导致的结构改变,规则操作什么的了解一下就好,看不下去就跳过,本文过多的XX树操作图片纯粹是为了作为规则记录,该文章主要目的是增强下个人对各种常用XX树的设计及缘由的了解,也从中了解到常用的实现案例使用XX树实现的原因。 数据在计…
暂无图片
编程学习 ·

当我们谈论算法我们在谈论什么:由疫情核酸检测想到的分治算法(Divide-and-Conquer)

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_159 北京的疫情一波未平一波又起,由此看来,战“疫”将是一场旷日持久的战争,绝不能掉以轻心、轻易言胜。病毒随时都会死灰复燃,以生命为代价换来的经验教训值得我们每一个人久久深思。笔者所在的小区也开始组织居民批量进…
暂无图片
编程学习 ·

使用MicroPython计算任意位数圆周率

计算任意精度的圆周率是个有趣的主题,得益于python的强大计算能力,我们在MicroPython中也可以轻松的计算pi的数值。先输入下面的代码:""" 文件:pi.py 说明:用MicroPython计算任意精度圆周率计算 作者:未知 版本: 时间: 修改:邵子扬2016.5v1.1 http://b…
暂无图片
编程学习 ·

学习node.js前,浏览器的一些工作原理知识的补充

浏览器概述 1、人机交互(UI) 2、网络请求部分(Socket) 3、JavaScript引擎(解析执行JavaScript) 4、渲染引擎(渲染HTML,CSS)又叫排版引擎或浏览器内核 5、数据库存储(cookie、HTML5的本地存储Localstorage、SessionStorage)渲染引擎 主流的渲染引擎有 Chrome浏览器:…
暂无图片
编程学习 ·

Linux 防火墙安装与配置

IPTABLES构建防火墙应用iptables 介绍iptables 常用规则命令常见参数说明 iptables 介绍iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的“安全框架“中,这个“安全框架”才是真正的防火墙,这个框…
暂无图片
编程学习 ·

Java中的递归

Java中的递归(涉及到面试)举个例子: package com.wang.digui; /* 递归*/ public class Demo {public static void main(String[] args) {int calcetor = calcetor(3);System.out.println(calcetor);}//算阶乘的public static int calcetor(int n){if (n == 1){return 1;}els…
暂无图片
编程学习 ·

Java数据类型

数据类型 Java属于一种强类型语言 什么是强类型语言? 即要求变量的使用需要严格符合规定,要求所有变量都必须先定义后再使用,若不按规定就会报错! Java的数据类型分为两类 基本类型(primitive type) Java语言提供了八种基本类型:六种数字类型(四个整数型,两个浮点型),…
暂无图片
编程学习 ·

free_spirit(在栈上爆破一个可以被free的fake_chunk)

free_spirit(在栈上爆破一个可以被free的fake_chunk)首先检查一下程序的保护机制然后,我们用IDA分析一下,功能3存在8字节溢出,将会把v7下面的buf指针覆盖掉,而覆盖了buf指针,就能实现任意地址写。那么,我们劫持函数栈返回地址为one_gadget即可,为了绕过结尾对buf的检查…
暂无图片
编程学习 ·

【leetcode C语言实现】剑指 Offer 07.重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树:限制: 0 <= 节点个数 <= 5000 来源:…
暂无图片
编程学习 ·

11.1 函数的默认参数

11.1 函数的默认参数 之前我们学过的,如果函数由形参,那么调用函数时要传递对性的实参。 事实上,函数可以有默认参数,这样如果不传递实参,则按照默认值给形参传值。函数声明和实现只能有一个默认参数,不能重复定义默认参数。 如果某个形参有了默认参数,则位于这个形参之…
暂无图片
编程学习 ·

LeetCode 590. N叉树的后序遍历

目录结构1.题目2.题解1.题目给定一个 N 叉树,返回其节点值的后序遍历。例如,给定一个 3叉树 :返回其后序遍历: [5,6,3,2,4,1].说明: 递归法很简单,你可以使用迭代法完成此题吗?来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/n-ary-tree-postorder-traver…
暂无图片
编程学习 ·

GIS开发:如何开发一个MBTiles Server

MBTiles是一个存储地图切片的数据库,以SQLite数据为基础,将地图切片按照缩放级别、横行和纵行的顺序,存储在其中。 常见的Geoserver可以加载插件,对MBTiles进行发布,github上也有开源的MBTiles Server,也可以进行MBTiles发布。 在只需要地图的切片情况下,如何进行一个MB…
暂无图片
编程学习 ·

vue项目里引用 gojs 流程图

要实现的需求 流程图,支持字体图标,颜色,可连接线,点击时右侧展示相关的详细信息 调研了多种可拖拽流程图的技术,如:bpmn.js,gojs等,由于bpmn-js功能冗余,GOJS相对于更加轻量级,最终选用GOJS开发此功能 gojs 文字区块 使用TextBlock类显示文本。 设置TextBlock.text属性…
暂无图片
编程学习 ·

2020.6.27 HTML总结

HTML总结: 一、HTML基本结构 <html><head><title>这是一个文本</title></head> ​ <body>文本</body> </html>< html >元素是 HTML 页面的根元素 < head > 元素包含了文档的元(meta)数据,如 < meta charse…
暂无图片
编程学习 ·

JAVA知识笔记语法

关键字和标识符 1.java关键字的使用 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词) 特点:关键字中所字母都为小写 具体哪些关键字:2.保留字:现Java版本尚未使用,但以后版本可能会作为关键字使用。 具体哪些保留字:goto 、const 注意:自己命名标识符时要…