当前位置: 首页 > news >正文

【论文#目标检测】YOLO9000: Better, Faster, Stronger

目录

  • 摘要
  • 1.引言
  • 2.更好(Better)
  • 3.更快(Faster)
  • 4.更健壮(Stronger)
    • 使用 WordTree 组合数据集
    • 联合分类和检测
    • 评估 YOLO9000
  • 5.结论

Author: Joseph Redmon; Ali Farhadi
Published in: 2017 IEEE Conference on Computer Vision and Pattern Recognition (CVPR)
Date of Conference: 21-26 July 2017
Date Added to IEEE Xplore: 09 November 2017
ISBN Information:
Electronic ISBN:978-1-5386-0457-1
Print on Demand(PoD) ISBN:978-1-5386-0458-8
Print ISSN: 1063-6919
DOI: 10.1109/CVPR.2017.690
Publisher: IEEE
Conference Location: Honolulu, HI, USA

摘要

我们介绍了YOLO9000,这是一个最先进的实时目标检测系统,能够检测超过9000个目标类别。首先,我们提出了对YOLO检测方法的各种改进,这些改进既包括创新性的,也包括借鉴以往工作的。改进后的模型YOLOv2在标准检测任务(如PASCAL VOC和COCO)上达到了最先进的水平。通过一种新颖的多尺度训练方法,同一个YOLOv2模型可以在不同尺寸下运行,从而在速度和准确性之间提供了一个便捷的权衡。在67帧/秒(FPS)时,YOLOv2在VOC 2007上达到了76.8%的平均精度均值(mAP)。在40帧/秒时,YOLOv2达到了78.6%的平均精度均值,超越了像带有ResNet的Faster R-CNN和SSD这样的最先进的方法,同时仍然运行得更快。最后,我们提出了一种同时进行目标检测和分类训练的方法。使用这种方法,我们在COCO检测数据集和ImageNet分类数据集上同时训练YOLO9000。我们的联合训练使得YOLO9000能够为目标类别进行预测,即使这些类别没有标记的检测数据。我们在ImageNet检测任务上验证了我们的方法。尽管只有44个类别有检测数据,YOLO9000在ImageNet检测验证集上达到了19.7 的平均精度均值。在COCO中不存在的156个类别上,YOLO9000达到了16.0 的平均精度均值。YOLO9000能够实时预测超过9000个不同目标类别的检测。
在这里插入图片描述

1.引言

通用目标检测应当具备快速、准确且能够识别各种不同物体的能力。自神经网络问世以来,检测框架的速度和准确性不断提升。然而,大多数检测方法仍然局限于识别一小部分物体。与分类和标记等其他任务的数据集相比,当前的目标检测数据集规模较小。常见的检测数据集包含数千到数十万张图像,以及数十到数百个标签。而分类数据集则拥有数百万张图像,涵盖数万到数十万类别。

我们希望目标检测能够达到物体分类的水平。然而,为检测目的标记图像的成本远远高于为分类或标记目的标记图像的成本(标记通常是由用户免费提供的)。因此,在不久的将来,我们不太可能看到与分类数据集规模相当的检测数据集。

我们提出了一种新方法,利用我们已经拥有的大量分类数据,并将其用于扩展当前检测系统的范围。我们的方法采用一种分层的目标分类视图,使我们能够将不同的数据集组合在一起。

我们还提出了一种联合训练算法,使我们能够在检测和分类数据上训练目标检测器。我们的方法利用标记了检测信息的图像来学习精确地定位物体,同时利用分类图像来增加其词汇量和鲁棒性。

通过这种方法,我们训练了YOLO9000,这是一个能够实时检测超过9000种不同目标类别的检测器。首先,我们改进了基础的YOLO检测系统,开发出了YOLOv2,这是一个最先进的实时检测器。然后,我们使用我们的数据集组合方法和联合训练算法,在来自ImageNet的超过9000个类别以及COCO的检测数据上训练了一个模型。

我们的所有代码和预训练模型都可以在以下网址在线获取:YOLO: Real-Time Object Detection。

注解
(1)YOLOv2的网络结构可以从其配置文件中找到(yolov2.cfg),使用了Darknet-19作为主干,这里使用了Darknet-19前面18层(因为最后一层是输出层),并且都使用了BN,Leaky ReLU

# Darknet-19
Conv_1 : 3x3x32, s=1, p=1, BN, Leaky ReLU
MaxPool : 2x2, s=2Conv_2 : 3x3x64, s=1, p=1, BN, Leaky ReLU
MaxPool : 2x2, s=2Conv_3 : 3x3x128, s=1, p=1, BN, Leaky ReLU
Conv_4 : 1x1x64, s=1, p=1, BN, Leaky ReLU
Conv_5 : 3x3x128, s=1, p=1, BN, Leaky ReLU
MaxPool : 2x2, s=2Conv_6 : 3x3x256, s=1, p=1, BN, Leaky ReLU
Conv_7 : 1x1x128, s=1, p=1, BN, Leaky ReLU
Conv_8 : 3x3x256, s=1, p=1, BN, Leaky ReLU
MaxPool : 2x2, s=2Conv_9 : 3x3x512, s=1, p=1, BN, Leaky ReLU
Conv_10 : 1x1x256,s=1, p=1, BN, Leaky ReLU
Conv_11 : 3x3x512, s=1, p=1, BN, Leaky ReLU
Conv_12 : 1x1x256, s=1, p=1, BN, Leaky ReLU
Conv_13 : 3x3x512, s=1, p=1, BN, Leaky ReLU
MaxPool : 2x2, s=2Conv_14 : 3x3x1024, s=1, p=1, BN, Leaky ReLU
Conv_15 : 1x1x512, s=1, p=1, BN, Leaky ReLU
Conv_16 : 3x3x1024, s=1, p=1, BN, Leaky ReLU
Conv_17 : 1x1x512, s=1, p=1, BN, Leaky ReLU
Conv_18 : 3x3x1024, s=1, p=1, BN, Leaky ReLU# 额外添加的结构
Conv_19 : 3x3x1024, s=1, p=1, BN, Leaky ReLU
Conv_20 : 3x3x1024, s=1, p=1, BN, Leaky ReLUroute : layers = -9
Conv_21 : 1x1x64, s=1, p=1, BN, Leaky ReLU
reorg : s=2route: layers=-1, -4
Conv_22 : 3x3x1024, s=1, p=1, BN, Leaky ReLU
Conv_23 : 1x1x425, s=1, p=1, Linear

(2)route: layers = -9表示提取第前9个层(Conv_13)的输出特征矩阵,作为Conv_21的输入层;reorg : s=2,表示将特征图的尺寸减半,特征通道扩展,reorg层又称之为pass through层【目标检测】YOLOv2 网络结构(darknet-19 作为 backbone);route : layers = -1, -4,表示将Conv_20和reorg(Conv_21)的输出按照维度进行拼接,再输入到Conv_22之中。
网络中特征的传输结构

Conv_18 --> Conv_19 --> Conv_20
route (layers = -9) : Conv_13 --> Conv_21
reorg (s=2) : reorg(Conv_21)
route (layers = -1, -4) : reorg(Conv_21) && Conv_20 --> Conv_22

(3)网络中特征图尺寸的变化
Darknet-19作为主干

InputLayerOutput
InputImage(416x416x3)Conv_1(3x3x32)feature_1(416x416x32)
feature_1(416x416x32)MaxPool(2x2-s-2)feature_2(208x208x32)
feature_2(208x208x32)Conv_2(3×3×64)feature_3(​208×208×64)
feature_3(​208×208×64)MaxPool(2x2-s-2)feature_4(​104×104×64)
feature_4(​104×104×64)Conv_3(3×3×128)feature_5(104×104×128)
feature_5(104×104×128)​Conv_4(1×1×64)feature_6(104×104×64)
feature_6(104×104×64)​Conv_5(3×3×128)feature_7(104×104×128)
feature_7(104×104×128)MaxPool(2×2-s-2)feature_8(52×52×128)
feature_8(52×52×128)​Conv_6(3×3×256)feature_9(52×52×256)
feature_9(52×52×256)Conv_7(1×1×128)feature_10(52×52×128)
feature_10(52×52×128)​Conv_8(3×3×256)​feature_11(52×52×256)
​feature_11(52×52×256)MaxPool(2×2-s-2)feature_12(26×26×256)
feature_12(26×26×256)​Conv_9(3×3×512)​feature_13(26×26×512)
feature_13(​26×26×512)​Conv_10(1×1×256)feature_14(26×26×256)
feature_14(26×26×256)​Conv_11(3×3×512)feature_15(26×26×512)
feature_15(26×26×512)​Conv_12(1×1×256)feature_16(​26×26×256)
​feature_16(26×26×256)​Conv_13(3×3×512)​feature_17(26×26×512)
​feature_17(26×26×512)MaxPool(2×2-s-2)feature_18(13×13×512)
feature_18(13×13×512)​Conv_14(3×3×1024)feature_19(13×13×1024)
feature_19(13×13×1024)​Conv_15(1×1×512)feature_20(13×13×512)
feature_20(13×13×512)​Conv_16(3×3×1024)​feature_21(13×13×1024)
feature_21(13×13×1024)​Conv_17(1×1×512)​feature_22(13×13×512)
​feature_22(13×13×512)​Conv_18(3×3×1024)feature_23(13×13×1024)

YOLOv2添加的模块,最终输出的特征为13x13x425

InputLayerOutput
feature_23(13×13×1024)​​Conv_19(3×3×1024)feature_24(13×13×1024)
feature_24(13×13×1024)​Conv_20(3×3×1024)feature_25(13×13×1024)
​feature_17(26×26×512)Conv_21(1×1×64)feature_26(​26×26×64)
feature_26(​26×26×64)regorg(stride=2)​feature_27(13×13×256)
feature_25(13×13×1024) + ​feature_27(13×13×256)feature_28(13x13x256)
feature_28(13x13x256)Conv_22(3x3x1024)feature_29(13x13x1024)
feature_29(13x13x1024)Conv_23(1x1x425)feature_30(13x13x425)

(4)在yolov2.cfg中,最后还定义了检测头的输出解码方式和训练策略

[region]
# 预定义的锚框长宽(相对于输入图像的归一化参数),两个数字为一组
# 一共5组: (0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434), (7.88282, 3.52778), (9.77052, 9.16828)
anchors =  0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828
bias_match=1	# 是否在锚框匹配时考虑卷积层的偏置项(1=启用)
classes=80		# 类别数量(COCO数据集为80个类别)
coords=4		# 锚框的参数数量,一定为4,因为是(x, y, w, h)
num=5			# 锚框的数量,与anchors对应
softmax=1		# 是否使用softmax(1=使用)
jitter=.3		# 随机抖动比例(图像尺寸会在 70% 到 130% 范围内随机变化)
rescore=1		# 是否用真实框与预测框的IoU值重新计算置信度标签(1=使用)object_scale=5		# 正样本(含目标)的置信度损失权重
noobject_scale=1	# 负样本(含目标)的置信度损失权重 
class_scale=1		# 类别预测损失权重
coord_scale=1		# 坐标回归损失权重 absolute=1		# 是否使用 ​绝对坐标编码​(1=启用)
thresh = .6		# 判断正样本的IoU阈值(如果IoU < 0.6,则视为负样本)
random=1		# 是否在训练时随机调整输入图像尺寸(1=启用)

假如输入图像为416x416x3,会被划分成为13x13个网格,单个网格的尺寸为32x32,每个网格的锚框长宽为

第一个 anchor:(0.57273 * 32, 0.677385 * 32) = (18.32736, 21.67632)
第二个 anchor:(1.87446 * 32, 2.06253 * 32) = (59.98272, 66.00096)
第三个 anchor:(3.33843 * 32, 5.47434 * 32) = (106.82976, 175.17888)
第四个 anchor:(7.88282 * 32, 3.52778 * 32) = (252.25024, 112.88896)
第五个 anchor:(9.77052 * 32, 9.16828 * 32) = (312.65664, 293.38496)

锚框在训练过程中不会变化,目标框会基于锚框进行检测

2.更好(Better)

YOLO 相对于最先进的检测系统存在多种不足。与 Fast R-CNN 相比的错误分析表明,YOLO 犯了大量定位错误。此外,YOLO 的召回率相对于基于区域提议的方法较低。因此,我们主要专注于提高召回率和定位精度,同时保持分类准确性。

计算机视觉领域通常倾向于使用更大、更深的网络。更好的性能往往依赖于训练更大的网络或将多个模型组合在一起。然而,对于 YOLOv2,我们希望得到一个更准确且仍然快速的检测器。我们没有扩大网络规模,而是简化了网络,并使表示更容易学习。我们将过去工作中的一些想法与我们自己的新概念结合起来,以提高 YOLO 的性能。结果总结见表 2。
在这里插入图片描述
批量归一化:批量归一化显著提高了收敛速度,同时消除了对其他正则化形式的需求。通过在 YOLO 的所有卷积层上添加批量归一化,我们获得了超过 2% 的平均精度均值(mAP)提升。批量归一化还有助于正则化模型。有了批量归一化,我们可以从模型中移除 Dropout,而不会出现过拟合。

高分辨率分类器:所有最先进的检测方法都使用在 ImageNet 上预训练的分类器。从 AlexNet 开始,大多数分类器的输入图像尺寸小于 256×256。原始的 YOLO 在 224×224 的分辨率上训练分类网络,并在检测时将分辨率提高到 448。这意味着网络必须同时切换到学习目标检测并适应新的输入分辨率。

对于 YOLOv2,我们首先在完整的 448×448 分辨率下对分类网络进行 10 个周期的微调。这使得网络有时间调整其滤波器,以更好地处理高分辨率输入。然后,我们在检测任务上对得到的网络进行微调。这个高分辨率分类网络使我们的 mAP 提升了近 4%。

卷积与锚框:YOLO 使用全连接层直接预测边界框的坐标。与之不同的是,Faster R-CNN 使用手工挑选的先验框来预测边界框。Faster R-CNN 中的区域提议网络(RPN)仅使用卷积层预测锚框的偏移量和置信度。由于预测层是卷积的,RPN 在特征图的每个位置上预测这些偏移量。预测偏移量而不是坐标简化了问题,使网络更容易学习。

我们从 YOLO 中移除了全连接层,并使用锚框来预测边界框。首先,我们移除了一个池化层,以提高网络卷积层的输出分辨率。我们还将网络的输入图像尺寸从 448×448 缩小到 416,因为我们希望特征图中有奇数个位置,这样在中心位置上就有一个单一的中心单元。物体,尤其是大物体,往往占据图像的中心位置,因此在中心位置有一个单一的单元来预测这些物体比有四个相邻的单元要好。YOLO 的卷积层将图像下采样了 32 倍,因此使用 416×416 的输入图像,我们得到一个 13×13 的输出特征图。

当我们转向使用锚框时,我们也解耦了类别预测机制与空间位置的关系,并且为每个锚框预测类别和目标性。按照 YOLO 的方式,目标性预测仍然预测真实边界框和提议框的交并比(IOU),类别预测则预测在存在目标的情况下该类别的条件概率。

使用锚框后,我们的准确度略有下降。YOLO 每张图像仅预测 98 个边界框,但使用锚框后,我们的模型预测了超过一千个边界框。在没有使用锚框的情况下,我们的中间模型达到了 69.5% 的 mAP 和 81% 的召回率;使用锚框后,模型的 mAP 为 69.2%,召回率为 88%。尽管 mAP 下降了,但召回率的提高意味着我们的模型有更多的改进空间。

维度聚类:在将锚框与 YOLO 结合使用时,我们遇到了两个问题。第一个问题是框的尺寸是手工挑选的。网络可以学习适当地调整框,但如果我们在一开始就为网络选择更好的先验,我们可以使网络更容易学习预测良好的检测结果。

我们没有手工选择先验,而是对训练集的边界框运行 k-means 聚类,以自动找到良好的先验。如果使用标准的 k-means 和欧几里得距离,较大的框会产生比小框更多的误差。然而,我们真正想要的是能够产生良好 IOU 分数的先验,这与框的大小无关。因此,我们使用以下距离度量公式:
在这里插入图片描述

我们针对不同的 k k k 值运行了 k-means 聚类,并绘制了与最近质心的平均交并比(IOU),见图 2。我们选择 k = 5 k = 5 k=5 作为模型复杂度和高召回率之间的一个良好折衷。聚类得到的质心与手工挑选的锚框有显著不同。短而宽的框更少,而高而细的框更多。
在这里插入图片描述
我们在表 1 中比较了我们的聚类策略与手工挑选的锚框的平均 IOU。在仅有 5 个先验的情况下,质心的表现与 9 个锚框相当,平均 IOU 为 61.0,而手工挑选的锚框为 60.9。如果我们使用 9 个质心,我们会看到更高的平均 IOU。这表明使用 k-means 生成边界框的先验,可以让模型从一个更好的表示开始,并使学习任务变得更加容易。
在这里插入图片描述
直接位置预测。在将锚框与 YOLO 结合使用时,我们遇到了第二个问题:模型不稳定,尤其是在早期迭代中。大部分的不稳定性来自于对框的 ( x , y ) (x, y) (x,y) 位置的预测。在区域提议网络(Region Proposal Network)中,网络预测值 t x t_x tx t y t_y ty,而框的中心坐标 ( x , y ) (x, y) (x,y) 是通过以下公式计算得出的:
在这里插入图片描述
例如,如果预测 t x = 1 t_x = 1 tx=1,则边界框会向右移动一个锚框的宽度;如果预测 t x = − 1 t_x = -1 tx=1,则会向左移动相同的距离。这种公式没有约束,因此任何锚框都可以移动到图像中的任何位置,而不管是哪个位置预测了这个框。由于随机初始化,模型需要很长时间才能稳定地预测出合理的偏移量。

因此,我们没有预测偏移量,而是采用了 YOLO 的方法,预测相对于网格单元位置的坐标。这使得真实值(ground truth)被限制在 0 和 1 之间。我们使用逻辑激活函数来约束网络的预测值落在这个范围内。

网络在输出特征图的每个单元格中预测 5 个边界框。对于每个边界框,网络预测 5 个坐标: t x t_x tx t y t_y ty t w t_w tw t h t_h th t o t_o to。如果单元格从图像的左上角偏移了 ( c x , c y ) (c_x, c_y) (cx,cy),并且边界框先验的宽度和高度分别为 p w p_w pw p h p_h ph,那么这些预测值对应于:
在这里插入图片描述
由于我们对位置预测进行了约束,参数化变得更加容易学习,从而使网络更加稳定。使用维度聚类并直接预测边界框中心位置的方法,比使用锚框的版本使 YOLO 的性能提高了近 5%。
在这里插入图片描述
细粒度特征:这个改进后的 YOLO 在一个 13×13 的特征图上进行检测预测。虽然这对于大物体来说已经足够了,但对于定位小物体可能需要更细粒度的特征。Faster R-CNN 和 SSD 都在不同分辨率的特征图上运行它们的提议网络,以获得一系列分辨率。我们采用了一种不同的方法,简单地添加了一个传递层,将早期层的 26×26 分辨率的特征引入。

传递层通过将相邻特征堆叠到不同的通道而不是空间位置来连接高分辨率特征和低分辨率特征,类似于 ResNet 中的恒等映射。这将 26×26×512 的特征图转换为 13×13×2048 的特征图,可以与原始特征连接。我们的检测器在扩展后的特征图上运行,以便能够访问细粒度特征。这带来了适度的 1% 性能提升。

多尺度训练:原始的 YOLO 使用了 448×448 的输入分辨率。随着锚框的加入,我们将分辨率改为了 416×416。然而,由于我们的模型仅使用卷积层和池化层,因此可以即时调整大小。我们希望 YOLOv2 能够在不同尺寸的图像上稳健运行,因此我们将这一点训练到模型中。

我们没有固定输入图像的大小,而是每隔几次迭代就改变网络的大小。每 10 个批次,我们的网络随机选择新的图像尺寸。由于我们的模型按 32 的因子下采样,我们从以下 32 的倍数中选择:{320, 352, …, 608}。因此,最小的选项是 320×320,最大的是 608×608。我们将网络调整到该尺寸并继续训练。

这种训练机制迫使网络学会在各种输入尺寸上进行良好的预测。这意味着同一个网络可以在不同分辨率下进行检测预测。网络在较小尺寸下运行得更快,因此 YOLOv2 在速度和准确性之间提供了一个便捷的权衡。

在低分辨率下,YOLOv2 作为一个廉价且相当准确的检测器运行。在 288×288 的分辨率下,它的运行速度超过 90 帧/秒,平均精度均值(mAP)几乎与 Fast R-CNN 相当。这使得它非常适合小 GPU、高帧率视频或多个视频流。

在高分辨率下,YOLOv2 是一个最先进的检测器,在 VOC 2007 上达到了 78.6% 的平均精度均值,同时仍然保持实时速度以上。有关 YOLOv2 与其他框架在 VOC 2007 上的比较,请参见表 3。图 4
在这里插入图片描述
在这里插入图片描述
进一步实验。我们在 VOC 2012 上训练 YOLOv2 进行目标检测。表 4 显示了 YOLOv2 与其他最先进的目标检测系统的比较性能。YOLOv2 实现了 73.4% 的平均精度均值(mAP),同时运行速度远远超过其他方法。我们还在 COCO 数据集上进行了训练,见表 5。在 VOC 指标(IOU = 0.5)下,YOLOv2 达到了 44.0% 的 mAP,与 SSD 和 Faster R-CNN 相当。
在这里插入图片描述
在这里插入图片描述
注解
(1)使用批量归一化(BatchNormalization)的好处很多,在进行网络参数更新时,前一层的输出也会变化,导致后续层也需要适应新的数据分布,这降低了训练的效率。通过将输入数据进行归一化,强制稳定在均值为0,方差为1的标准正态分布附近,这样输入数据更稳定,反向传播梯度更平滑,同时也降低了网络对初始化权重的敏感性。因此,BN层的应用也利于使用更加深层次的网络进行训练
(2)高分辨率分类器,使用输入尺寸更高的数据集,这样网络就能够学习到更多的特征。对比之前的网络,如AlexNet使用的是224x224分辨率,YOLOv2使用的分辨率为448x448
(3)使用锚框,通过预测偏移量来获取预测框,而不是直接预测框,提升了召回率
(4)使用k-means聚类进行锚框的选择,能够获得很好的效果,这里选择的是5个
(5)直接位置预测,使用锚框时,并不会直接预测偏移量,而是预测相对网格位置的单元坐标,是坐标值而不是偏移量,再加上激活函数,最终获得目标框,使用这种方式,提升了5%的效果
(6)细粒度特征,之前为了让网络学到更多的特征,使用的分辨率是448x448和416x416,这里还将26x26尺寸的特征加入进来,学习到了细粒度的特征,提升的效果为1%
(7)多分辨率训练,每10个批次修改一次分辨率,最小的选项是 320×320,最大的是 608×608,这样YOLOv2就支持不同分辨率的推理。随后,评估了分辨率和推理速度的tradeoff,效果不错

3.更快(Faster)

我们希望检测既准确又快速。大多数检测应用,如机器人技术或自动驾驶汽车,都依赖于低延迟的预测。为了最大化性能,我们从一开始就设计 YOLOv2 使其快速运行。

大多数检测框架依赖于 VGG-16 作为基础特征提取器。VGG-16 是一个强大且准确的分类网络,但它过于复杂。VGG-16 的卷积层在 224×224 分辨率下对单张图像进行一次前向传播需要执行 306.9 亿次浮点运算。

YOLO 框架使用基于 Googlenet 架构的自定义网络。这个网络比 VGG-16 快,仅使用 85.2 亿次运算进行一次前向传播。然而,其准确性略逊于 VGG-16。在 224×224 分辨率下,对于单裁剪图像的 top-5 准确率,YOLO 的自定义模型在 ImageNet 上达到了 88.0%,而 VGG-16 为 90.0%。

Darknet-19:我们提出了一个新的分类模型,用作 YOLOv2 的基础。我们的模型基于以往的网络设计工作以及该领域的常识。与 VGG 模型类似,我们主要使用 3×3 的滤波器,并在每次池化步骤后将通道数翻倍。遵循网络中的网络(Network in Network, NIN)的工作,我们使用全局平均池化进行预测,以及在 3×3 卷积之间使用 1×1 滤波器来压缩特征表示。我们使用批量归一化来稳定训练,加速收敛,并正则化模型。

我们的最终模型,称为 Darknet-19,包含 19 个卷积层和 5 个最大池化层。具体描述见表 6。Darknet-19 处理一张图像仅需 55.8 亿次运算,但在 ImageNet 上达到了 72.9% 的 top-1 准确率和 91.2% 的 top-5 准确率。
在这里插入图片描述
分类训练:我们使用随机梯度下降法,在标准的 ImageNet 1000 类分类数据集上训练网络 160 个周期,初始学习率为 0.1,采用 4 次幂的多项式衰减率,权重衰减为 0.0005,动量为 0.9,使用 Darknet 神经网络框架。在训练过程中,我们使用了标准的数据增强技巧,包括随机裁剪、旋转以及色调、饱和度和曝光度的偏移。

如上所述,在 224×224 分辨率的图像上进行初始训练后,我们在更大的尺寸 448 上对网络进行微调。对于这种微调,我们使用上述参数,但仅训练 10 个周期,初始学习率为 10^-3。在这个更高的分辨率下,我们的网络达到了 76.5% 的 top-1 准确率和 93.3% 的 top-5 准确率。

检测训练:我们通过移除最后一个卷积层,并添加三个具有 1024 个滤波器的 3×3 卷积层,以及一个具有检测所需输出数量的最终 1×1 卷积层,来修改这个网络用于检测。对于 VOC,我们预测每个边界框有 5 个坐标和 20 个类别,因此需要 125 个滤波器。我们还从最终的 3×3×512 层添加了一个传递层到倒数第二个卷积层,以便我们的模型可以使用细粒度特征。

我们训练网络 160 个周期,初始学习率为 10^-3,在 60 和 90 个周期时将其除以 10。我们使用 0.0005 的权重衰减和 0.9 的动量。我们使用与 YOLO 和 SSD 类似的数据增强方法,包括随机裁剪、颜色偏移等。我们在 COCO 和 VOC 上使用相同的训练策略。

注解
(1)分类训练,YOLOv2的训练过程是,在低分辨率(ImageNet,224x224)上进行预训练,随后使用高分辨率(448x448)进行微调10个周期,最后在检测数据集上(448x448)进行调整网络。经过高分辨率微调,可以处理高分辨率的细节,从而更好的适应检测数据集。
(2)假设检测任务需要识别 ​小鸟​(小目标):
​YOLOv1:
从 224×224 直接切换到 448×448 分辨率训练时,网络需同时学习放大的小鸟细节和检测任务,导致初期预测框位置混乱,收敛缓慢。
​YOLOv2:
在 448×448 分类微调阶段,网络已学会放大后的小鸟羽毛纹理等细节,检测训练时只需专注于定位和分类,收敛更快且精度更高

4.更健壮(Stronger)

我们提出了一种同时在分类和检测数据上进行训练的机制。我们的方法使用标记了检测信息的图像来学习检测特定的信息,如边界框坐标预测和目标性,以及如何对常见物体进行分类。它使用只有类别标签的图像来扩展其能够检测的类别数量。

在训练过程中,我们将来自检测和分类数据集的图像混合在一起。当我们的网络看到一个标记了检测信息的图像时,我们可以基于完整的 YOLOv2 损失函数进行反向传播。当它看到一个分类图像时,我们只从架构的分类特定部分反向传播损失。

这种方法带来了一些挑战。检测数据集通常只包含常见物体和一般性标签,如“狗”或“船”。而分类数据集则拥有更广泛和深入的标签范围。例如,ImageNet 包含了超过一百种狗的品种,包括“诺福克梗(terrier)”、“约克夏梗(terrier)”和“贝德灵顿梗(terrier)”。如果我们想要同时在这两个数据集上进行训练,我们需要一种合理的方式来合并这些标签。

大多数分类方法使用 softmax 层来计算所有可能类别的最终概率分布。使用 softmax 层假设类别是互斥的。这给合并数据集带来了问题,例如,你不会想使用这个模型将 ImageNet 和 COCO 合并起来,因为“诺福克梗(terrier)”和“狗”这两个类别并不是互斥的。

我们也可以使用多标签模型来合并数据集,这种模型不假设类别互斥。然而,这种方法忽略了我们已知的数据结构,例如,COCO 中的所有类别都是互斥的。

分层分类:ImageNet 的标签来源于 WordNet,这是一个语言数据库,它对概念及其相互关系进行了结构化[12]。在 WordNet 中,“诺福克梗”和“约克夏梗”都是“梗”的下义词,而“梗”是一种“猎犬”,“猎犬”是一种“狗”,“狗”是一种“犬科动物”,等等。大多数分类方法假设标签具有扁平结构,然而在合并数据集时,结构正是我们所需要的。

WordNet 被构建成一个有向图,而不是树,因为语言是复杂的。例如,“狗”既是一种“犬科动物”,也是一种“家畜”,而这两者都是 WordNet 中的同义词集合。为了简化问题,我们通过从 ImageNet 中的概念构建一个分层树,而不是使用完整的图结构。

为了构建这棵树,我们检查 ImageNet 中的视觉名词,并查看它们通过 WordNet 图到达根节点(在这种情况下是“物理对象”)的路径。许多同义词集合在图中只有一条路径,因此我们首先将这些路径添加到我们的树中。然后,我们迭代地检查剩余的概念,并添加那些尽可能少地扩展树的路径。因此,如果一个概念有两条通往根节点的路径,其中一条路径会向我们的树中添加三条边,而另一条路径只添加一条边,那么我们选择较短的路径。

最终结果是 WordTree,一个视觉概念的分层模型。使用 WordTree 进行分类时,我们在每个节点上预测条件概率,即在给定同义词集合的情况下,该同义词集合的每个下义词的概率。例如,在“梗”节点上,我们预测:
在这里插入图片描述
如果我们想要计算某个特定节点的绝对概率,我们只需沿着树的路径到达根节点,并将条件概率相乘。因此,如果我们想知道一张图片是否是诺福克梗(Norfolk terrier),我们计算如下:
在这里插入图片描述
为了分类的目的,我们假设图像中包含一个物体: Pr ( physical object ) = 1 \text{Pr}(\text{physical object}) = 1 Pr(physical object)=1

为了验证这种方法,我们在使用 1000 类 ImageNet 构建的 WordTree 上训练 Darknet-19 模型。为了构建 WordTree1k,我们将所有中间节点加入其中,这使得标签空间从 1000 扩展到 1369。在训练过程中,我们将真实标签向上传播到树的顶部,因此如果一张图像被标记为“诺福克梗”,它也会被标记为“狗”和“哺乳动物”等。为了计算条件概率,我们的模型预测一个包含 1369 个值的向量,并且我们在所有属于同一概念的下义词的同义词集合上计算 softmax,见图 5。
在这里插入图片描述
使用与之前相同的训练参数,我们的分层 Darknet-19 实现了 71.9% 的 top-1 准确率和 90.4% 的 top-5 准确率。尽管我们添加了 369 个额外的概念,并让我们的网络预测一个树状结构,我们的准确率仅略有下降。以这种方式进行分类也有一些好处。在新的或未知的物体类别上,性能会优雅地下降。例如,如果网络看到一张狗的图片,但不确定是什么种类的狗,它仍然会以高置信度预测“狗”,但会在下义词之间分散较低的置信度。

这种公式也适用于检测。现在,我们不再假设每张图像都有一个物体,而是使用 YOLOv2 的目标性预测器来给出 Pr ( physical object ) \text{Pr}(\text{physical object}) Pr(physical object) 的值。检测器预测一个边界框和一个概率树。我们沿着树向下遍历,在每个分支处选择置信度最高的路径,直到我们达到某个阈值,然后我们预测那个物体类别。

注解
(1)对于wordtree的理解是,父类和子类的关系,类似于树结构,例如 物体 → 动物 → 犬科 → 狗 → 哈士奇,根节点是物体(object),上一层是动物,逐层向上,最后是哈士奇。置信度的计算方式为 P ( 物体 ) ∗ P ( 动物 ) ∗ P ( 犬科 ) ∗ P ( 狗 ) ∗ P ( 哈士奇 ) P(物体) * P(动物) * P(犬科) * P(狗) * P(哈士奇) P(物体)P(动物)P(犬科)P()P(哈士奇)

使用 WordTree 组合数据集

我们可以使用 WordTree 以合理的方式将多个数据集组合在一起。我们只需将数据集中的类别映射到树中的同义词集合。图 6 展示了使用 WordTree 将 ImageNet 和 COCO 的标签组合在一起的示例。WordNet 非常多样化,因此我们可以使用这种技术与大多数数据集结合。
在这里插入图片描述

联合分类和检测

现在我们已经可以使用 WordTree 组合数据集,我们可以训练我们的联合模型进行分类和检测。我们希望训练一个非常大规模的检测器,因此我们使用 COCO 检测数据集和完整的 ImageNet 发布中的前 9000 个类别来创建我们的组合数据集。我们还需要评估我们的方法,因此我们加入了 ImageNet 检测挑战中尚未包含的任何类别。这个数据集对应的 WordTree 有 9418 个类别。ImageNet 是一个更大的数据集,因此我们通过过采样 COCO 来平衡数据集,使得 ImageNet 只比 COCO 大 4 倍。

使用这个数据集,我们训练了 YOLO9000。我们使用基础的 YOLOv2 架构,但只使用 3 个先验框而不是 5 个,以限制输出大小。当我们的网络看到一个检测图像时,我们正常地反向传播损失。对于分类损失,我们只在标签对应的级别或更高级别反向传播损失。例如,如果标签是“狗”,我们不会将错误分配给树中更深层次的预测,如“德国牧羊犬”与“金毛猎犬”,因为我们没有这些信息。

当它看到一个分类图像时,我们只反向传播分类损失。为此,我们只需找到预测该类别最高概率的边界框,并仅计算其预测树的损失。我们还假设预测的边界框与真实标签的重叠至少有 0.3 的交并比(IOU),并基于此假设反向传播目标性损失。

通过这种联合训练,YOLO9000 学会了使用 COCO 中的检测数据在图像中找到物体,并使用 ImageNet 中的数据对这些物体进行广泛的分类。

评估 YOLO9000

我们在 ImageNet 检测任务上评估了 YOLO9000。ImageNet 检测任务与 COCO 只共享 44 个目标类别,这意味着 YOLO9000 对大多数测试类别的检测数据一无所知。YOLO9000 的整体平均精度均值(mAP)为 19.7%,在它从未见过任何标记检测数据的 156 个独立目标类别上,mAP 为 16.0%。这个 mAP 高于 DPM 的结果,但 YOLO9000 是在不同的数据集上训练的,并且只有部分监督[4]。它还在同时实时检测其他 9000 个类别。

YOLO9000 在学习新的动物种类方面表现良好,但在学习服装和设备等类别时却遇到了困难。新的动物种类更容易学习,因为目标性预测可以从 COCO 中的动物很好地泛化。相反,COCO 没有任何类型的服装的边界框标签,只有人的标签,因此 YOLO9000 在建模“太阳镜”或“泳裤”等类别时会遇到困难。

注解
(1)YOLO9000的训练集来自ImageNet和COCO,一共9418个类别,但是只是用了3个先验框,YOLOv2使用了5个

5.结论

我们介绍了 YOLOv2 和 YOLO9000,这两个实时目标检测系统。YOLOv2 在多种检测数据集上达到了最先进的水平,并且比其他检测系统更快。此外,它可以在多种图像尺寸下运行,以在速度和准确性之间提供平滑的权衡。

YOLO9000 是一个实时框架,通过联合优化检测和分类,能够检测超过 9000 个目标类别。我们使用 WordTree 来组合来自不同来源的数据,并利用我们的联合优化技术同时在 ImageNet 和 COCO 上进行训练。YOLO9000 是朝着缩小检测和分类之间数据集规模差距迈出的重要一步。

我们的许多技术可以推广到目标检测之外的领域。我们对 ImageNet 的 WordTree 表示提供了一个更丰富、更详细的图像分类输出空间。使用分层分类进行数据集组合在分类和分割领域将是有用的。像多尺度训练这样的训练技术可能会在各种视觉任务中带来益处。

对于未来的工作,我们希望使用类似的技术进行弱监督图像分割。我们还计划在训练期间使用更强大的匹配策略,将弱标签分配给分类数据,以改进我们的检测结果。计算机视觉拥有大量标记数据。我们将继续寻找方法,将不同来源和结构的数据结合起来,以构建更强大的视觉世界模型。

致谢:我们感谢 Junyuan Xie 在构建 WordTree 方面提供的有益讨论。这项工作得到了 ONR N00014-13-1-0720、NSF IIS-1338054、NSF-1652052、NRI-1637479、Allen 杰出研究者奖以及 Allen 人工智能研究所的支持。

相关文章:

【论文#目标检测】YOLO9000: Better, Faster, Stronger

目录 摘要1.引言2.更好&#xff08;Better&#xff09;3.更快&#xff08;Faster&#xff09;4.更健壮&#xff08;Stronger&#xff09;使用 WordTree 组合数据集联合分类和检测评估 YOLO9000 5.结论 Author: Joseph Redmon; Ali Farhadi Published in: 2017 IEEE Conference …...

C++异常处理时的异常类型抛出选择

在 C 中选择抛出哪种异常类型&#xff0c;主要取决于错误的性质以及希望传达的语义信息。以下是一些指导原则&#xff0c;帮助在可能发生异常的地方选择合适的异常类型进行抛出&#xff1a; 1. std::exception 适用场景&#xff1a;作为所有标准异常的基类&#xff0c;std::e…...

centos 7 搭建FTP user-list用户列表

在 CentOS 7 上搭建基于 user_list 的 FTP 用户列表&#xff0c;你可以按以下步骤操作&#xff1a; 1. 安装 vsftpd 服务 若还未安装 vsftpd&#xff0c;可以使用以下命令进行安装&#xff1a; bash yum install -y vsftpd2. 启动并设置开机自启 vsftpd 服务 bash systemctl…...

vulnhub-Tr0ll ssh爆破、wireshark流量分析,exp、寻找flag。思维导图带你清晰拿到所以flag

vulnhub-Tr0ll ssh爆破、wireshark流量分析&#xff0c;exp、寻找flag。思维导图带你清晰拿到所以flag 1、主机发现 arp-scan -l 2、端口扫描 nmap -sS -sV 192.168.66.185 nmap -sS -A -T4 -p- 192.168.66.185 nmap --scriptvuln 192.168.66.185经典扫描三件套&#xff0c;…...

k8s中service概述(二)NodePort

NodePort 是 Kubernetes 中一种用于对外暴露服务的 Service 类型。它通过在集群的每个节点上开放一个静态端口&#xff08;NodePort&#xff09;&#xff0c;使得外部用户可以通过节点的 IP 地址和该端口访问集群内部的服务。以下是关于 NodePort Service 的详细说明&#xff1…...

搭建Redis哨兵集群

停掉现有的redis集群 因为这篇文章我是在 搭建完redis主从集群之后写的&#xff0c;如果要是没有搭建过这些&#xff0c;可以直接略过。要是从我上一篇 搭建redis主从集群过来的&#xff0c;可以执行下。 docker compose down 查找下redis相关进程 ps -ef | grep redis 可以看…...

.Net SSO 单点登录方式

SSO单点登录目的 之前一般来讲系统简单&#xff0c;登录后 本地 cookie 加服务器 session 存储用户身份信息&#xff0c;以此为依据来判断用户再次登录时免验证 但随着互联网发展&#xff0c;很多应用 部署在不同的服务器上&#xff0c;而用户体系是一套&#xff0c;那么按照原…...

SQL 基础 BETWEEN 的常见用法

在SQL中&#xff0c;BETWEEN是一个操作符&#xff0c;用于选取介于两个值之间的数据。 它包含这两个边界值。BETWEEN操作符常用于WHERE子句中&#xff0c;以便选取某个范围内的值。 以下是BETWEEN的一些常见用法&#xff1a; 选取介于两个值之间的值&#xff1a; 使用 BETWE…...

ngx_http_add_location

声明在 src\http\ngx_http_core_module.c ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,ngx_http_core_loc_conf_t *clcf); 定义在 src\http\ngx_http.c ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,ngx_http…...

深入探索ArkUI中的@LocalBuilder装饰器:构建高效可维护的UI组件

在ArkUI框架中&#xff0c;组件化开发是提升代码复用性和维护性的关键手段。随着项目复杂度的增加&#xff0c;开发者常常面临如何在保持组件封装性的同时&#xff0c;灵活处理组件内部逻辑的问题。传统的Builder装饰器虽然提供了强大的自定义构建能力&#xff0c;但在某些场景…...

视频知识库初步设想

将视频字幕提取出来作为知识库来源定位,下一步设想:把视频上的图片信息也精简出来作为定位。 下面是测试例子: 入参: {"model":"deepseek-ai/DeepSeek-R1-Distill-Llama-8B","messages":[{"role":"system","cont…...

微信小程序中使用Less样式方法

在微信小程序中使用Less样式&#xff0c;可以通过以下步骤实现。主要原理是借助Visual Studio Code&#xff08;VSCode&#xff09;的插件将Less文件自动编译为小程序支持的.wxss文件&#xff0c;或通过微信开发者工具的扩展功能直接集成Less编译环境。以下是具体方法&#xff…...

2024年MathorCup数学建模A题移动通信网络中PCI规划问题解题全过程文档加程序

2024年第十四届MathorCup高校数学建模挑战赛 A题 移动通信网络中PCI规划问题 原题再现&#xff1a; 物理小区识别码(PCI)规划是移动通信网络中下行链路层上&#xff0c;对各覆盖小区编号进行合理配置&#xff0c;以避免PCI冲突、PCI混淆以及PCI模3干扰等现象。PCI规划对于减少…...

本周安全速报(2025.3.18~3.24)

合规速递 01 2025欧洲网络安全报告&#xff1a;DDoS攻击同比增长137%&#xff0c;企业应如何应对&#xff1f; 原文: https://hackread.com/european-cyber-report-2025-137-more-ddos-attacks/ 最新的Link11《欧洲网络安全报告》揭示了一个令人担忧的趋势&#xff1a;DDo…...

力扣刷题-热题100题-第23题(c++、python)

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/reverse-linked-list/solutions/551596/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 记录前一个指针&#xff0c;当前指针&am…...

YAML是什么?

YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一种以数据为中心、高度可读的序列化语言&#xff0c;广泛应用于配置文件、数据交换和自动化工具中。以下从多个维度对其进行全面解析&#xff1a; 1. 定义与历史演变 全称与定位&#xff1a; YAML的全称最初为“Yet…...

期权交易投资怎么操作?新手期权操作指南

期权就是股票&#xff0c;唯一区别标的物上证指数&#xff0c;会看大盘吧&#xff0c;新手做期权交易两个方向认购做多&#xff0c;认沽做空&#xff0c;双向t0交易没了&#xff0c;跟期货一样&#xff0c;对的&#xff0c;玩的也是合约&#xff0c;唯一区别没有保证金不会爆仓…...

音视频学习(三十):fmp4

FMP4&#xff08;Fragmented MP4&#xff09;是 MP4&#xff08;MPEG-4 Part 14&#xff09;的扩展版本&#xff0c;它支持流式传输&#xff0c;并被广泛应用于DASH&#xff08;Dynamic Adaptive Streaming over HTTP&#xff09;和HLS&#xff08;HTTP Live Streaming&#xf…...

破局AI落地困局 亚信科技“四位一体手术刀“切开产业智能三重枷锁

当全球进入以AI为核心竞争力的新经济周期&#xff0c;政企机构的数字化转型正面临关键转折点&#xff1a;IDC数据显示&#xff0c;2023年超过67%的中国企业在AI落地环节遭遇"技术断层"&#xff0c;高昂的试错成本与碎片化解决方案让智能转型陷入僵局。在此背景下&…...

android 去掉状态栏的方法汇总

在 Android 开发中&#xff0c;隐藏或去除状态栏&#xff08;Status Bar&#xff09;有多种方法&#xff0c;具体实现方式取决于应用场景和目标 Android 版本。以下是常用的 ​6 种方法及其代码示例&#xff1a; 在 Android 开发中&#xff0c;隐藏或去除状态栏&#xff08;Sta…...

jenkins+1panel面板java运行环境自动化部署java项目

本文章不包含1panel面板安装、jenkins部署、jenkins连接git服务器等操作教程&#xff0c;如有需要可以抽空后期补上 jenkins安装插件Publish Over SSH 在系统配置添加服务器 查看项目的工作空间 项目Configure->构Post Steps选择Send files or execute commands over SSH…...

VLAN综合实验报告

一、实验拓扑 网络拓扑结构包括三台交换机&#xff08;LSW1、LSW2、LSW3&#xff09;、一台路由器&#xff08;AR1&#xff09;以及六台PC&#xff08;PC1-PC6&#xff09;。交换机之间通过Trunk链路相连&#xff0c;交换机与PC、路由器通过Access或Hybrid链路连接。 二、实验…...

雷军从 6 楼扔涂有防弹涂层西瓜,西瓜完好无损,这种防弹涂层是什么材质?用在车上效果怎么样?

雷军展示的“防弹涂层”是一种基于第四代高分子材料聚脲&#xff08;Polyurea&#xff09;的升级技术&#xff0c;其核心特性是通过纳米级交联结构形成弹性防护层&#xff0c;兼具柔韧性与刚性&#xff0c;能够有效吸收冲击能量并抵御尖锐物体的穿刺。以下是关于该涂层材质及在…...

信奥赛CSP-J复赛集训(模拟算法专题)(31):P2692 覆盖

信奥赛CSP-J复赛集训&#xff08;模拟算法专题&#xff09;&#xff08;31&#xff09;&#xff1a;P2692 覆盖 题目背景 WSR 的学校有 B B B 个男生和 G G G 个女生都来到一个巨大的操场上扫地。 题目描述 操场可以看成是 N N N 行 M M M 列的方格矩阵&#xff0c;如下…...

数据库联表Sql语句建一个新表(MySQL,Postgresql,SQL server)

数据库联表Sql语句建一个新表(MySQL,Postgresql,SQL server) 如果你想基于 SELECT USERS.ID,USERS.NAME,USERS.EMAIL,USERS.ID_CARD,USERS.V_CARD,USERS.ADDRESS,v_card.type,v_card.amount FROM USERS JOIN v_card on USERS.V_CARDv_card.v_card 这个查询结果创建一个新表&am…...

【Go】结构体的基本使用

go语言不是面向对象的语言 但是结构体类似于面向对象 结构体的定义 package mainimport "fmt"type Student struct {id intname stringage intschool string }func main() {s : Student{1, "luobozi", 18, "znl"}fmt.Println(s) }结构…...

统计可重复列表中的TOP N

文章目录 方案1&#xff1a;HashMap统计 全排序实现步骤&#xff1a;代码实现&#xff1a;优缺点&#xff1a; 方案2&#xff1a;HashMap统计 最小堆&#xff08;优先队列&#xff09;实现步骤&#xff1a;代码实现&#xff1a;优缺点&#xff1a; 方案3&#xff1a;Java Str…...

《jQuery Mobile 页面:深入解析与优化实践》

《jQuery Mobile 页面:深入解析与优化实践》 引言 jQuery Mobile 是一个流行的前端框架,专为移动设备设计,提供了丰富的UI组件和简洁的API,使得开发者可以快速构建出美观且响应式的移动页面。本文将深入解析jQuery Mobile的页面构建方法,并探讨一些优化实践,以帮助开发…...

C#中 String类API(函数)

字符串属性 string str "打工人";Console.WriteLine(str);char s str[0];Console.WriteLine(s); 字符串内置API(函数) 1. Concat 拼接字符串 string s1 "打";string s2 "工";string s3 "人";string sthstring.Concat(s1, s2, s…...

【Linux 维测专栏 5 -- linux pstore 使用介绍】

文章目录 Linux pstore 功能简介1. pstore 概述2. pstore 的核心功能3. pstore 的工作原理4. pstore 的使用示例5. pstore 的优势6. 典型应用场景配置示例1)DTS配置2)config配置运行测试及log问题小结Linux pstore 功能简介 1. pstore 概述 pstore(Persistent Storage)是…...

AI赋能:科技写作的革新之路

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术正以惊人的速度渗透到各个领域&#xff0c;科技写作也不例外。AI不仅改变了写作的方式&#xff0c;还极大地提升了写作的效率和质量。本文将探讨AI技术在科技写作中的应用&#xff0c;并分享一些实用的AI工…...

如何为你的github开源项目选择合适的开源协议?

如何为你的github开源项目选择合适的开源协议&#xff1f; 导言 在github开源世界中&#xff0c;选择一个合适的开源协议是至关重要的。它不仅定义了他人如何使用你的代码&#xff0c;还决定了你的项目能否被广泛接受和传播&#xff0c;还能避免侵权问题。 然而&#xff0c;面…...

struts2漏洞攻略

S2-057远程执行代码漏洞 靶场&#xff1a; /struts2/s2-057 1&#xff0c;搭建好环境后访问 http://47.108.150.249:8081/struts2-showcase/ 2&#xff0c;在url处进行输⼊ 在url输入http://47.108.150.249:8081/struts2-showcase/${(123123)}/actionChain1.action 后刷新可…...

LVGL学习1

LVGL知识点 架构图 参考&#xff1a;Getting Started — LVGL documentation display、screen、widget的关系 参考&#xff1a; Widget Basics — LVGL documentation Overview — LVGL documentation 简单说&#xff0c;display就是硬件的显示设备&#xff0c;也就是一个一…...

【SpringCloud】微服务的治理以及服务间的远程调用

目录 一、微服务的诞生 二、服务注册和发现 2.1 需求的产生 2.2 注册中心原理 2.3 Nacos注册中心 2.4 Nacos安装部署教程 2.5 配置Nacos 三、OpenFeign 3.1 认识OpenFeign 3.2 快速入门 3.2.1 引入依赖 3.2.2 启动OpenFeign 3.2.3 编写OpenFeign客户端 3.2.4 使…...

钞票准备好了吗?鸿蒙电脑 5 月见

3月20日&#xff0c;在华为 Pura 先锋盛典及鸿蒙智行新品发布会上&#xff0c;华为常务董事、终端BG董事长、智能汽车解决方案BU董事长余承东表示&#xff0c;华为终端全面进入鸿蒙时代&#xff0c;今年5月将推出鸿蒙电脑。 在3月20日的华为Pura先锋盛典及鸿蒙智行新品发布会上…...

【2025】基于springboot+uniapp的企业培训打卡小程序设计与实现(源码、万字文档、图文修改、调试答疑)

基于 Spring Boot uniapp 的企业培训打卡小程序设计与实现 系统功能结构图如下&#xff1a; 一、课题背景 在当今快节奏的商业环境中&#xff0c;企业培训对于员工的成长和企业的发展至关重要。为了满足企业对高效培训管理和员工便捷学习的需求&#xff0c;基于 Spring Boot …...

poetry安装与使用

文章目录 安装方法虚拟环境构建方法* 创建新虚拟环境【新环境使用】* 使用仓库拉取的代码构建虚拟环境【远端仓库拉取使用】 常用命令注意事项 安装方法 安装命令&#xff08;全局安装&#xff0c;不要在虚拟环境中安装&#xff0c;方便后面创建环境使用&#xff09; pip3 inst…...

聊聊langchain4j的Code Execution Engine

序 本文主要研究一下langchain4j的Code Execution Engine 步骤 pom.xml <dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-code-execution-engine-graalvm-polyglot</artifactId><version>1.0.0-beta2</ver…...

军事级加密通信系统——基于QML的战术地图加密传输

目录 基于QML的战术地图加密传输一、引言二、理论背景与安全需求2.1 战术地图数据的敏感性与安全性要求2.2 QML与PyQt5集成优势2.3 加密算法与数据传输模型三、系统架构与数据流图四、QML前端界面设计与交互功能4.1 QML界面优势与设计理念4.2 功能要求4.3 QML文件示例五、加密传…...

ffmpeg系列(三)—— 音频重采样

SwrContext 一、SwrContext 的重要字段 SwrContext 是音频重采样的核心配置对象&#xff0c;其关键字段决定了重采样的行为和性能。以下是常用字段及其作用&#xff1a; 字段名称类型作用典型值示例in_sample_rateint输入音频的采样率&#xff08;Hz&#xff09;。44100out_…...

android Kotlin原理

目录 一,概述 1.1 kotlin协程序原理: 1.2 核心概念 二,协程调度器之Dispatchers 三,协程能进行线程恢复的原理 一,概述 1.1 kotlin协程序原理: 1,内部线程池管理线程使用到了自旋和挂起 2,传统的线程之所以重,是因为线程的执行&#xff0c;等待唤醒需要操作系统来完成 …...

MyBatis-Plus(Ⅲ)IService详解

目录 一、逐一演示 1.save&#xff08;插入一条&#xff09; 结果 断言&#xff08;引入概念&#xff09; 2.saveBatch&#xff08;批量插入&#xff09; 结果 3.saveOrUpdateBatch&#xff08;批量插入&更新&#xff09; 结果 4.removeById&#xff08;通过id删除…...

2024年认证杯SPSSPRO杯数学建模C题(第二阶段)云中的海盐全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 C题 云中的海盐 原题再现&#xff1a; 巴黎气候协定提出的目标是&#xff1a;在2100年前&#xff0c;把全球平均气温相对于工业革命以前的气温升幅控制在不超过2摄氏度的水平&#xff0c;并为1.5摄氏度而努力。但事实上&#xff0c;许多之前的…...

PostgreSQL 存储过程

简介 PostgreSQL 中的存储过程&#xff08;Stored Procedure&#xff09;是一种在数据库中定义的可重复使用的程序单元&#xff0c;用于封装复杂的业务逻辑和数据处理操作 示例 简单示例 创建存储过程 CREATE PROCEDURE insert_users (user_account TEXT, hashed_password…...

GGUF 和 llama.cpp 是什么关系

这是个非常关键的问题&#xff0c;咱们来细说下&#xff1a;GGUF 和 llama.cpp 是什么关系&#xff0c;它们各自干什么&#xff0c;如何配合工作。 &#x1f527; 一、llama.cpp 是什么&#xff1f; llama.cpp 是 Meta 的开源大语言模型 LLaMA&#xff08;Language Model from…...

(UI自动化测试web端)第二篇:元素定位的方法_class定位

看代码里的【 driver.find_element_by_class_name( )】()里的路径怎么写&#xff1f; 那我们现在说的就是在元素定位时&#xff0c;根据网页的实际情况来选择适合的元素定位的写法。文章主要介绍了class定位在正常工作当中的使用。 第三种定位 方式&#xff1a;class定位 ⽅法…...

闲聊IT - 面向服务架构(SOA)的发展历史

SOA的发展历史 面向服务架构&#xff08;SOA&#xff09;是随着企业信息化进程的发展逐渐形成的&#xff0c;它的出现是为了应对传统软件架构在现代企业复杂需求面前的局限性。SOA的起源和发展过程可以追溯到20世纪90年代末期&#xff0c;并随着互联网技术的普及、分布式计算以…...

31天Python入门——第9天:再学函数

你好&#xff0c;我是安然无虞。 文章目录 再学函数1. 变量在函数中的作用域2. 函数的参数传递.补充学习: 不定长参数*args和**kwargs 3. 值传递和引用传递补充学习: 把函数作为参数传递 4. 匿名函数5. python中内置的常用函数zip()map()filter()all()any() 6. 函数练习 再学函…...

卡特兰数在数据结构上面的运用

原理 Catalan数是一个数列&#xff0c;其第n项表示n个不同结点可以构成的二叉排序树的数量。Catalan数的第n项公式为&#xff1a; &#xfffc; 其中&#xff0c;&#xfffc;是组合数&#xff0c;表示从2n个元素中选择n个元素的组合数。 Catalan数的原理可以通过以下方式理解&…...