《SVDNet for Pedestrian Retrieval》理解

Abstract:

这篇文章提出了一个用于检索问题的SVDNet,聚焦于在行人再识别上的应用。我们查看卷积神经网络中全连接层的每一个权重向量,发现它们往往都高度相关。这导致了每个全连接描述中个体之间的相关性,在基于欧几里得距离时会影响检索性能。为了解决这个问题,这篇论文使用了SVD来优化深层表达学习。通过严厉和放松的迭代(RPI)训练框架,我们可以在CNN训练中迭代地整合正交性约束,生成所谓的SVDNet。我们在Market-1501,CUHK03和DukeMTMC-reID数据集上做了评估,证明了RPI可以有效的产生更具区分力的FC描述并显著提高re-ID正确率。在Market-1501数据集上,基于CaffeNet时将rank-1准确率从55.3%提升到80.5%,基于ResNet-50时则从73.8%提升到82.3%。

1. Introduction

这篇论文考虑的问题是行人检索,也称为行人再识别。它目的是检索出有包含所查询人物的图片。

行人再识别不同于图片分类,因为训练集和测试集上包含不同的类别。所以流行的re-ID深度学习方法包含以下几步:1)在训练集上训练深度分类模型,2)使用全连接层提取query与gallery图片的描述3)使用欧几里得距离计算相似度返回一个经过排序的列表。

通过观察训练后的分类模型我们发现全连接层的权重向量往往高度相关由此受到启发。这个问题主要有两个原因。第一个原因与训练样本的non-uniform分布有关。此问题在最后一个FC层尤为明显。FC层的每个单元的输出代表了输入图片与类别的相似度。训练之后对于相似人物(如身穿红色与紫色衣服的人)学习到了高度相关的权重向量,如图1所示。第二个原因是CNN训练时很少有正交化约束。其实学习到的权重向量或许就是自然相关的。

使用欧几里得距离处理检索问题时FC层的权重向量相关度会影响性能。实际上使用欧几里得距离作为检索的判断时,特征向量中每个个体应该尽可能独立。然而,当权重向量相关时,FC层描述——前面CNN层输出在这些权重向量上的投影——会拥有相关性。这最终会导致一些记录在欧几里得距离中起主要作用,造成不良的排序结果。举例来说,测试时两个不同人物的图片通过网络传输产生如上图1所示的绿色和黑色虚线,然后投影到红色,粉红色,蓝色这几个权重向量来组成描述。投影值在红色与粉色向量上很接近,这使得两个描述表现出相似性,而忽略了它们在蓝色向量上投影的差异。总结来说,要想在欧几里得距离下工作,解决FC描述中的冗余是一个重要的问题。

为了解决这个问题,我们提出了SVD-Net,它的特点是FC层包含不相关的权重向量。我们还提出了一种三步训练框架。在第一步,权重矩阵经过SVD分解,由左酉矩阵和奇异值矩阵的乘积替换。第二步,我们保持正交的权重矩阵固定,只训练余下的层。第三步,权重矩阵不再固定,网络整体优化。这三步迭代进行,来约束权重矩阵的正交性。在大型的re-ID数据集上的结果表现出了在baseline网络上的显著提升,我们的结果也是先进水平。

2. Related Work

Deep learning for person re-ID:在行人再识别任务上的深度学习方法可以分为两类:相似度学习和表达学习。也被称为深度度量学习,论文[25,24,1,13,5,19]都使用了图片对或者是triplet的网络输入。在两个早期的工作中,Yi等人在[29]和Li等人在[13]中使用了图片对,并且在学习过程中加入了部分的先验知识。之后Varior等人在论文[25]中加入了LSTMs模块。LSTMs连续处理图片部分,所以能够记住空间连接来提升对于深度特征的区分力。[24]中Varior等人在每个卷积层之后插入了一个门限函数来捕获图片对之间有效的精细模式。上面提到的这些方法在一定程度上都能够有效地学习图片相似性,但是或许在大规模的gallery上会有有效性问题。

第二种基于CNN的行人再识别方法关注于特征学习,它将训练样本划分成预定义的类别,并使用FC描述来做检索。在[33,34]中,使用一个CNN分类模型对视频帧或图片标注框进行学习。Xiao等人在论文[26]中从多个re-ID数据集联合学习到通用的特征表达。Zheng等人在[31]中提出了类似于pictorial的PoseBox结构学习姿态不变的特征来解决空间的不对齐。为了结合特征学习与相似度学习的优点,Zheng等人在[35]和Geng等人在[10]中结合了contrastive loss和identification loss来提高对于学习特征的区分能力。我们这篇论文采用了分类模型,在不失有效性潜能的同时表现出了有竞争力的准确率。

PCANet and truncated SVD for CNN:我们澄清了SVDNet与几个“外观相似”的工作之间的区别。PCANet被提出用于图片分类。它的特点是级联的PCA过滤器。PCANet与SVDNet相同的地方是它们都学习正交的投影方向。SVDNet与PCANet在两个主要方面有所不同。首先,SVDNet是在CNN的权重矩阵上施加SVD,PCANet是在原始输入和特征上施加PCA。第二个不同是,PCANet中的滤波器是用无监督方式学习的。它不像SVDNet那种依赖于后向传播。实际上,SVDNet建立了CNN与SVD之间的联系。SVDNet的参数是通过后向传播与使用SVD分解进行学习。

Truncated SVD被广泛应用于CNN模型压缩。SVDNet与它们有两点不同。首先,Truncated SVD用来分解FC层的权重然后用几个重要的向量进行重建,SVDNet不去重建权重矩阵,但是将其替换为左酉矩阵和奇异值矩阵。第二,Truncated SVD在可以接受的预测损失下减少了模型大小和测试时间,但是SVDNet显著的提高了检索准确率,没有对模型大小产生影响。

Orthogonality in the weight matrix:我们注意论文[27]的目的是使CNN滤波器正交化,但是我们的网络不同。在论文[27]中,正交化的正则化效果有益于深层网络的后向传播,从而提高分类准确率。论文[27]中提出的正则化也许并不会直接有益于特征学习过程。但这篇论文中,正交化可以用于产生适用于检索的不相关描述。我们的网络或许不适合提高分类效果。

3. Proposed Method

这一部分描述了SVDNet的结构,训练方法以及工作机制。

3.1. Architecture

SVDNet往往接在主要网络后,例如CaffeNet和ResNet-50。主要的差别是SVDNet使用Eigenlayer作为倒数第二个FC层,如下图2所示。Eigenlayer包含一个正交的权重矩阵,是一个不包含偏差的线性层。不使用偏差是因为偏差会干扰到学习到的正交性。实际上,我们的初步实验表明了加上ReLU激活层和偏差会对re-ID表现造成损失,所以我们选择使用线性层来实现Eigenlayer。选择将Eigenlayer放在倒数第二个FC层而不是倒数第一个FC层是因为对最后一个FC层施加正则化模型不会收敛,这或许是因为最后一个FC层的权重相关性是由训练样本的分布决定的。训练过程中,来自前面层的特征传递到Eigenlayer层作为输入。它们与Eigenlayer层权重的内积组成输出特征,与最后一个c维度的层形成全连接,这里的c是训练类别的个数。

测试时,我们提取query与gallery图片学习到的嵌入。这一步,我们能够使用Eigenlayer的输入或者输出作为特征表达,如上图2所示。我们的实验表明了这两个特征拥有类似的表现,说明Eigenlayer不仅提高了输出的表现还提高了输入的表现。原因有点不明确,我们认为这来源于CNN的后向传播训练,在此期间,带有Eigenlayer的权重矩阵的正交性会直接影响到输入特征的特性。

3.2.Training SVDNet

训练SVDNet的过程如下图所示。我们首先简要介绍第0步,然后再描述严格和放松的迭代策略(RPI),(第1,2,3步)。

Step 0.我们首先向网络中添加了一个线性层。然后微调网络直到收敛。注意到第0步之后的权重向量还是高度相关的。实验中,我们展示了CNN模型在第0步之后的re-ID表现,将对线性层的各种输出维度进行评估。

Restraint and Relaxation Iteration(RPI):这是训练SVDNet的关键步骤,包含三步。

·Decorrelation:我们按来施加SVD。这里W是线性层的权重向量,U是左酉矩阵,S是奇异值矩阵,V是右酉矩阵。经过分解,我们将W替换成US。然后线性层使用的所有特征向量作为权重向量并命名为Eigenlayer。

·Restraint:主干网络一直训练直到收敛,但是Eigenlayer层被固定。

·Relaxation:Eigenlayer层不固定,微调继续进行。

经过步骤1和2,权重向量是正交的,但是步骤3是放松训练。W不再是固定状态。所以训练进入另一个关于”restraint and relaxation”的迭代t(t=1,...,T)。

虽然简单,但是这种方法背后的机制很有趣。我们尝试在章节3.3深入研究这种机制。所有涉及到的分析中都是使用在ImageNet上进行预训练的CaffeNet作为主干网络。

3.3 Mechanism Study

Why is SVD employed?我们的想法是在CNN已经学习到的内容上找出一系列正交的投影方向。对于线性层,W空间的一组基是一个可能的解(例如由W列向量组成的线性子空间)。事实上存在了很多的正交基。所以我们决定使用W的奇异向量作为一个新的投影方向并且使用对应的奇异值来加权投影结果。所以我们将替换成US。经过这一步特征表达在整个样本空间的区分能力会保持不变。数学证明如下:

给出两幅图片,我们定义为Eigenlayer层前面对应的特征,分别是Eigenlayer输出的特征。之间的欧几里得距离计算如下:

上式的U,S,V如前面所定义的。因为V是一个单位正交阵,所以等式2又等于:

等式3表明了将替换成US,还是不变的。因此,算法流程中的第1步使得微调之后的CNN模型的区分能力是百分百保留的。

下面有一些其他的分解方法作为SVD的补充。但是这些方法都没有保留住CNN模型的区分能力。为了证明这一点,我们将SVD与以下几种做对比。

1. 使用原始的W(定义为Orig)

2. 将W替换为US(定义为US)

3. 将W替换成U(定义为U)

4. 将W替换成(定义为

5. 将W=QR(Q-R分解)替换成QD,这里的D是从上三角阵中提取的对角阵(定义为QD)

在Market-1501上的对比见下表1.我们将FC层替换成1024维的线性层并微调网络直到收敛(算法1中的第0步)。之后我们使用方法2-5来替代微调后的W。这四种方法都是将W更新为一个正交矩阵,但是表1指出,只有将W替换成US才能保持re-ID的准确率,其他的方法都会使准确率下降。

When does performance improvement happen?如上证明所示,Alg.1中的第一步将替换成US并没有立刻带来准确率提升,但是保证了不变。不仅如此,经过这一步操作,模型偏离了原始的微调结果,训练样本上的loss会在一定范围内增大。但是ALg.1中第二步和第三步会解决这个问题。这两步的主要的效果是提高Eigenlayer输入特征和输出特征的区分能力。一方面,约束步骤学习Eigenlayer层的上游和下游层,它依然保持了正交特性。我们在图5中展示了这一步提高了准确率。另一方面,relaxation步将会使模型再次偏移正交状态,但是会更接近收敛。这一步,如图5所示,表现变差。但是使用RPI,整体的效果会提升。有趣的是教育孩子时,也鼓励一种交替的relaxation和restraint策略。

Correlation diagnosing:目前为止,我们还没有提出一种度量来评估向量相关。实际上,向量间相关度可以使用相关系数来估计。但是据我们所知,它无法评估向量集整体之间的相关度。在这篇论文中,我们提出下面的策略来估计总体相关度。给出一个权重向量:

k是W中权重向量的个数(CaffeNet FC7层的k=4096),是W中的权重向量。给出W,我们定义于运算来度量W所有列向量的相关度:

从等式5,我们可以看到S(W)的值落在。当W为正交阵时S(W)的值为1,当所有的权重向量都相同时S(W)获得最小值。所以当S(W)接近或者很小时,权重向量有高的相关度。比如,在我们的baseline中直接使用微调后的CaffeNet,=0.0072。表明FC7层的权重向量高度相关。我们会在章节4.5中展示,S可以有效地指示SVDNet训练地收敛。

Convergence Criteria for RPI:实际应用中什么时候停止RPI是一个很重要的问题。我们使用等式5来评估经过relaxation步W的正交性,发现随着迭代的进行,S(W)的值增加。这表示W中权重向量的相关度经过RPI一步步减小。所以当S(W)变得稳定时,模型就收敛了,RPI也就结束。详细的如下图5所示。

4. Experiment

4.1.Datasets and Settings

Datasets:这篇论文使用Market-1501,CUHK03,DukeMTMC-reID这3个数据集来评估。Market-1501数据集包含1501个个体,由6个相机捕捉的19732张gallery图片和12936张训练图像组成。所有的标注框由DPM检测器生成。大多数相关实验都是在Market-1501数据集上进行的。CUHK03数据集包含1467个个体的13164张图片。每一个个体都是使用2个相机观察到的。CUHK03同时提出了手动标注的和DPM检测的标注框,在这篇论文中我们使用后者。对CUHK03进行了20次随机的训练测试集划分,最后给出平均结果。DukeMTMC-reID数据集由8个相机捕捉,用于跨相机追踪。我们采用了论文[37]的结果作为re-ID基准。它包含1404个个体(一半用来训练,一半用来测试),16522张训练图片,228张query图片和17661张gallery图片。对于Market-1501与DukeMTMC-reID我们分别使用论文[32]和[37]中提供的评估包。

在三个数据集上我们都使用了CMC与mAP进行表现评估。

Backbones:我们主要使用了两种在ImageNet上预训练的模型作为主干网络,分别是CaffeNet和ResNet-50。在使用CaffeNet时,我们直接将原始的FC7层替换成Eigenlayer,这是为了以免认为效果提升来自于更深的结构。当使用ResNet-50作为主干网络时,我们在最后一个FC层前插入Eigenlayer,因为ResNet没有隐藏的FC层,而且在50层结构中增加一层的影响可以忽略。在Market-1501上的一些实验,我们还使用了VGGNet和Tiny CaffeNet作为主干网络来展示SVDNet在不同结构上的效果。Tiny CaffeNet就是将CaffeNet的FC6层与FC7层的维度分别减小到1024和512。

4.2.Implementation Details

Baseline:下面是论文[33]的操作,baseline使用的是经过微调后的CaffeNet与ResNet-50。使用的都是默认配置,除了最后的FC层输出的维度改为了训练个体数。CaffeNet baseline使用0.001的学习率训练了60个epoch,然后又使用0.0001的学习率训练了20个epoch。ResNet baseline训练了60个epoch。开始的学习率是0.001,在25和50个epoch时减小了10倍。在测试时,CaffeNet的FC6或FC7层与ResNet-50的Pool5层或FC层用作特征表达。

在Market-1501上,CaffeNet和ResNet-50使用FC6(Pool5)达到的rank-1准确率为55.3(73.8%),这与论文[33]中的结果一致。

Detailed setting:使用CaffeNet作为主干的SVDNet通过25个RPI达到最终的收敛。除最后一轮restraint与relaxation外,每一轮RPI我们都使用0.001的学习率迭代了2000次。对于最后的restraint训练我们使用了5000次迭代(学习率为0.001)+3000次迭代(学习率为0.0001)。Batch size设置为64。使用ResNet作为主干网络的SVDNet通过7个RPI达到最终收敛,我们使用了8000次迭代,并在5000轮后将学习率减小10倍。1到3轮RPI的初始学习率为0.001,后面的RPI的的初始学习率为0.0001。Batch size大小设置为32。

所有模型中Eigenlayer的输出维度设置为1024。将在章节4.4中分析超参数的影响。章节4.5会说明为什么使用不同的主干网络时会设置不同的RPI次数。

4.3.Performance Evaluation

The effectiveness of SVDNet:我们在三个re-ID基准上做了测试。整体结果如下表2。

每种主干网络的提升都是显著的:当使用CaffeNet作为主干网络时,在Market-1501上rank-1准确率从55.3%提升到80.5%,mAP从30.4%上升到55.9%。在CUHK03(DukeMTMC-reID)数据集上,rank-1准确率提升了26.3%(20.7%),mAP上升了24.7%(17.5%)。当使用ResNet作为主干网络时,rank-1准确率在Market-1501,CUHK03,DukeMTMC-reID上分别上升了8.4%,15.6%,11.2%。对应的mAP上升了14.2%,13.7%和12.7%。一些Market-1501上的检索例子如下图3。

Comparison with state of the art:我们将SVDNet与最先进的方法对比。表3列出了在Market-1501与CUHK03上的比较结果。与目前已经发表的论文相比,SVDNet取得了有竞争力的表现。我们在Market-1501上达到的rank-1=82.3%,mAP=62.1%,在CUHK03上的rank-1=81.8%,mAP=84.8%。论文[38]中的re-ranking方法在Market-1501上的mAP比我们高,因为re-ranking利用了gallery图像之间的关系。我们推测,在re-ranking方法上使用SVDNet也会带来效果提升。与一些未发表的Arxiv论文相比,我们的一些数字比论文[10]和论文[35]稍低。论文[10]和论文[35]都使用了verification与classification loss的结合,我们会进一步将这一策略运用到SVDNet中。

不仅如此,SVDNet在相对简单CNN网络上的表现是惊人的。在Market-1501上,使用CaffeNet作为主干网络的SVDNet达到了80.5%的rank-1与55.9%的mAP,这远远超出了其他基于CaffeNet的方法。另外,使用VGGNet与Tiny CaffeNet作为主干网络分别达到了79.7%与77.4%的rank-1准确率。在CUHK03上,使用CaffeNet作为主干网络的SVDNet甚至超过了一些基于ResNet的方法(除了DLCE(R))。这个现象说明我们的方法可以通过高效计算获得一个可接受的结果。

在表4中,使用论文[38]提出的新的训练/测试策略(称为CUHK03-NP)对DukeMTMC-reID和CUHK03进行了比较总结。因为DukeMTMC和CUHK03-NP最近才成为基准所以只有相对较少的结果。在DukeMTMC-reID上,这篇文章的rank-1=76.7%,mAP=56.8%,这高于一些有竞争力的方法,甚至是最近的GAN。在CUHK03-NP上,这篇文章的rank-1=41.5%,mAP=37.3%,也高于大部分方法。

4.4. Imapact of Output Dimension

我们改变Eigenlayer输出层的维度。图4画出了在CaffeNet和ResNet-50上的结果。

当不使用RPI训练时,这个网络与baseline模型没有本质区别。可以看到倒数第二层的输出维度显著影响了表现。当输出维度增加,re-ID结果先增加,然后到达一个平台期再快速下降。在这种方案中,我们发现使用低维更加有益,可能是因为减少了FC层滤波器的冗余。

输出维度对SVDNet最终效果的影响还展示了另一种趋势。当输出维度增加,效果会逐渐提升到一个稳定的水平,这表明我们的模型可以对有害的冗余免疫。

4.5.RPI Boosting Procedure

这个实验揭示了每个restraint步与relaxation步如何改变re-ID表现以及SVDNet如何一步步达到一个稳定的结果。在我们的实验中,每个RPI中都使用了25个restraint phase与relaxation phase。Eigenlayer的输出维度设置为2048。我们测试了所有CNN模型的re-ID表现与S(W)的值。我们也增加了baseline模型的训练epoch,使其与SVDNet的训练相同,比较没有RPI训练的模型的S(W)的值。结果如下图5所示,可以由此得出四个结论。

第一,每次RPI,rank-1正确率有一个“上升和下降”的过程来响应restraint和relaxation步骤:restraint训练时W保持正交性,表现提升,表明学习到的特征的区分能力增加。第二,随着RPI的进行,整体的准确率提升,当模型收敛时达到一个稳定值。第三,使用S(W)来判断正交性作为RPI的收敛条件是很有效的。RPI训练时,S(W)逐渐增加直到达到稳定,没有RPI时,S(W)会在一个相对低的值范围波动,表明了权重向量之间的高度相关。第四,使用ResNet作为主干网络的SVDNet相对CaffeNet的仅需要很少的RPI次数达到收敛。

4.6. Comparison of Decorrelation Methods

在章节3.3中,介绍了一些分解方法。我们证明了只有将W替换成US才能保持Eigenlayer输出特征的区分能力,其他三种方法都只会在一定程度上导致表现下降。这里我们给出使用RPI训练时的最终表现。

Market-1501数据集上的结果如表5所示。可以看到将W替换成US这种分解方法达到了最高的表现,接着就是”U”,”QD”和“”。事实上与原始“Orig”相比,“”并没有带来可见的提升。这个实验说明了不仅仅是正交本身,分解方法对于SVDNet也很重要。

5. Conclusions

在这篇论文中,提出了SVDNet作为行人检索或ReID的表达学习。在全连接层的权重矩阵的投影方向上施加去相关。通过restraint和relaxation的迭代,向量相关度逐渐下降。在这种策略下,re-ID表现经过反复的增加和降低,最终达到一个稳定水平。由于权重向量之间的关联减小,学习到的特征更适合应用到使用欧几里得距离的检索任务中。在Market-1501,CuHK03和DukeMTMC-reID数据集上都得到了显著的提升,re-ID准确率也接近最先进的表现。

未来我们会进一步研究SVDNet以更多地了解其工作原理。我们也会将SVDNet运用到一般的实例检索问题中。

《SVDNet for Pedestrian Retrieval》理解的更多相关文章

  1. Person Re-identification 系列论文笔记(五):SVD-net

    SVDNet for Pedestrian Retrieval Sun Y, Zheng L, Deng W, et al. SVDNet for Pedestrian Retrieval[J]. 2 ...

  2. ICCV 2017论文分析(文本分析)标题词频分析 这算不算大数据 第一步:数据清洗(删除作者和无用的页码)

    IEEE International Conference on Computer Vision, ICCV 2017, Venice, Italy, October 22-29, 2017. IEE ...

  3. 行人重识别(ReID) ——基于深度学习的行人重识别研究综述

    转自:https://zhuanlan.zhihu.com/p/31921944 前言:行人重识别(Person Re-identification)也称行人再识别,本文简称为ReID,是利用计算机视 ...

  4. 论文阅读笔记(三)【AAAI2017】:Learning Heterogeneous Dictionary Pair with Feature Projection Matrix for Pedestrian Video Retrieval via Single Query Image

    Introduction (1)IVPR问题: 根据一张图片从视频中识别出行人的方法称为 image to video person re-id(IVPR) 应用: ① 通过嫌犯照片,从视频中识别出嫌 ...

  5. HHL论文及代码理解(Generalizing A Person Retrieval Model Hetero- and Homogeneously ECCV 2018)

    行人再识别Re-ID面临两个特殊的问题: 1)源数据集和目标数据集类别完全不同 2)相机造成的图片差异 因为一般来说传统的域适应问题源域和目标域的类别是相同的,相机之间的不匹配也是造成行人再识别数据集 ...

  6. Valse2019笔记——弱监督视觉理解

    程明明(南开大学):面向开放环境的自适应视觉感知 (图片来自valse2019程明明老师ppt) 面向识别与理解的神经网络共性技术 深度神经网络通用架构 -- VggNet(ICLR'15).ResN ...

  7. HTTP协议学习--- (十一)理解HTTP幂等性

    在httpcomponent 文档中看到如下段落: 1.4.1. HTTP transport safety It is important to understand that the HTTP p ...

  8. Information retrieval信息检索

    https://en.wikipedia.org/wiki/Information_retrieval 信息检索 (一种信息技术) 信息检索(Information Retrieval)是指信息按一定 ...

  9. BI 商业智能理解结构图

    本文章是在本人实习阶段对BI(商业智能 Business Intelligence)的理解:(如有不足之处请多指教,谢谢) BI 系统负责从多个数据源中搜集数据,并将这些数据进行必要的转换后存储到 ...

随机推荐

  1. Java多线程——实现

    "java多线程的实现--几乎都要和java.lang.Thread打交道" 方式一:继承于Thread类 1.创建一个继承于Thread类的子类 2.重写Thread类的run( ...

  2. 前端面试 -Vue2系列

    vue 1为啥用Vue? 1MVVM 数据的双向绑定 2指令系统 不需要操作DOM 3组件化 2v-show和v-if.v-for v-show 通过 display:none 隐藏元素,DOM还在. ...

  3. 图片查看器——viewer.js

    使用简介 https://github.com/FNNDSC/viewerjs(需要点击遮罩层关闭弹框的复制下面内容) https://www.jianshu.com/p/d98db3815823 v ...

  4. 【远古黑历史】List链表及其功能

    前言 我知道有学校是禁用STL的, 但STL是真的香,加个蛋,嗯,好吃 所以,本人希望有更多OIer能使用STL,减少工作量! 初见STL 首先,什么是STL? STL,全称 Standard Tem ...

  5. 使用client-go实现自定义控制器

    使用client-go实现自定义控制器 介绍 我们已经知道,Service对集群之外暴露服务的主要方式有两种:NodePort和LoadBalancer,但是这两种方式,都有一定的缺点: NodePo ...

  6. 用简单的 Node.js 后台程序浅析 HTTP 请求与响应

    用简单的 Node.js 后台程序浅析 HTTP 请求与响应 本文写于 2020 年 1 月 18 日 我们来看两种方式发送 HTTP 请求,一种呢,是命令行的 curl 命令:一种呢是直接在浏览器的 ...

  7. PPP PPOE详解

    PPP协议是在串行线IP协议SLIP(Serial Line Internet Protocol)的基础上发展起来的.由于SLIP协议具有只支持异步传输方式.无协商过程(尤其不能协商如双方IP地址等网 ...

  8. VMWare中CentOS安装VM-Tools

    查看CD-ROM驱动器的设备信息 可以通过下面几个命令来查看 dmesg命令 dmesg | egrep -i --color 'cdrom|dvd|cd/rw|writer' /proc/sys/d ...

  9. 企业应用架构研究系列二十六:信号量SemaphoreSlim与Semaphore

    在进行多线程程序的开发和设计的过程中,不可避免的需要引入semaphore信号量这个组件,这是.net框架提供的一个对多线程计数互斥的方案,就是允许指定的线程个数访问特定的资源而增加的 一个" ...

  10. Spring Boot中的微信支付(小程序)

    前言 微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的. logo 一.申请流程和步骤 图1-1 注册微信支付账号 获取微信小程序APPID 获取微信商家的商户 ...