目标检测指标:AP,mAP

目标检测指标:AP,mAP

论文:A Survey on Performance Metrics for Object-Detection Algorithms

文章目录

摘要

AP通过估计precision × recall 曲线的AUC来评估目标检测模型的准确率。

根据precision × recall 曲线使用的插值方法,有两种不同的AP计算方法。

不同工作中和AP实现中缺乏共识是学术和科学界面临的问题。用不同计算语言编写的度量实现通常与相应的数据集一起分发,共享给定的边界框描述。这些项目确实为社区提供了评估工具,但需要额外的工作来适应其他数据集和边界框格式。本工作回顾了用于对象检测的最常用度量标准,分析了它们的差异、应用和主要概念。

1 介绍

一个目标检测模型的输出由包含边界框(bonding boxes,bboxes)、置信度(confidence levels)和类别(classes)的列表组成。然而,不同模型的输出格式却不尽相同。对于bboxes的表示大多使用左上↖️和右下↘️的坐标:
( x i n i , y i n i , x e n d , y e n d ) (x_{ini},y_{ini},x_{end},y_{end}) (xini,yini,xend,yend)
而YOLO的bboxes表示则是采用中心坐标以及宽度和高度:
( x c e n t e r i m a g e   w i d t h , y c e n t e r i m a g e   h e i g h t , b o x   w i d t h i m a g e   w i d t h , b o x   h e i g h t i m a g e   h e i g h t ) (\frac{x_{center}}{image \ width},\frac{y_{center}}{image \ height},\frac{box \ width}{image \ width}, \frac{box \ height}{image \ height}) (image widthxcenter,image heightycenter,image widthbox width,image heightbox height)

在大多目标检测竞赛中,平均精度(average precision,AP)以及它的变种被用做评价指标进行排名。PASCAL VOC提供了AP以及mAP(所有类别AP的平均值)的源码。Lyft 3D自动驾驶车辆物体识别挑战赛,使用了10个不同阈值下AP的平均值,叫做AP@50:5:95

AP的计算是针对一个类别的,而mAP是当前检测数据集中所有类别的AP的平均值。

2 主要的性能指标

TP、FP、FN

计算AP所需要了解的一些概念:

  • True Positive (TP) : 对真实边界框的正确检测
  • False Positive (FP) : 对一个不存在目标的错误检测或者对一个存在目标的错误检测
  • False Negative (FN) : 未检测到的真实边界框;

原文:

  • True Positive (TP) : A correct detection of a ground-truth bounding box;
  • False positive (FP) : An incorrect detection of a nonexistent object or a misplaced detection of an existing object;
  • False negative (FN) : An undetected ground-truth bounding box;

在目标检测中,不使用true negative (TN,对负样本的正确检测) 。

在上面的定义中,需要明确什么是正确检测,什么是错误检测。通常使用**交并比 (intersection over union, IOU)**去界定,公式如下:
J ( B p , B g t ) = I O U = area ⁡ ( B p ∩ B g t ) area ⁡ ( B p ∪ B g t ) J\left(B_p, B_{g t}\right)=\mathrm{IOU}=\frac{\operatorname{area}\left(B_p \cap B_{g t}\right)}{\operatorname{area}\left(B_p \cup B_{g t}\right)} J(Bp,Bgt)=IOU=area(BpBgt)area(BpBgt)
其中, B p B_p Bp B g t B_{gt} Bgt分别表示预测边界框和真实边界框。可视化如下,红框为 B p B_p Bp,绿框为 B g t B_{gt} Bgt,分子为两者交集,分母为两者并集。
在这里插入图片描述
因此,我们可以设置一个阈值 t t t,当预测边界框与真实边界框的IOU大于等于这个阈值的时候,则为正确检测,否则就是错误检测。

IOU检测
≥ t \geq t t正确检测
< t \lt t <t错误检测

因此,可以想象,当要计算一个类别的AP时,需要用哪些东西。以“person”这个类别为例,首先,将数据集中所有类别为“person”的边界框取出,然后将检测模型输出中所有类别为“person”的边界框取出,设定阈值为0.5。然后每个预测边界框计算与真实边界框的IOU,并于阈值比较,大于阈值是TP,小于阈值是FP。另外,在真实边界框中,没有任何一个预测边界框与其IOU大于阈值,那么这个真实边界框就是FN。

在上面的FP中,“对一个不存在目标的错误检测或者对一个存在目标的错误检测”,前者是IOU为0,相当于检测了不存在的目标,后者就是与真实边界框相交了,但相交很少。总之,两者与真实边界框的IOU都小于阈值。

一般情况下,IOU>0.5就认为是比较好了。下图为几种不同的IOU的示例。
在这里插入图片描述

P、R

P   =   T P T P + F P = T P a l l   d e t e c t i o n s P \ = \ \frac{TP}{TP+FP} = \frac{TP}{all \ detections} P = TP+FPTP=all detectionsTP
P,precision,精确率,也叫查准率,预测正确的边界框占所有预测边界框的比例。
R   =   T P T P + F N = T P a l l   g r o u n d   t r u t h s R \ = \ \frac{TP}{TP+FN} = \frac{TP}{all \ ground \ truths} R = TP+FNTP=all ground truthsTP
R,recall,召回率,也叫查全率,预测正确的边界框占真实边界框的比例。

其实,第二个等号后面有一点点小问题,假设当非极大值抑制的阈值设置较大,一个真实检测框上有两个预测框,它们与真实框的阈值都大于0.5,那么all ground truths就是1,TP就是2,R=2,显然不合适,但是用第一个等号后面计算R就是1,没什么问题。当然,非极大值抑制的阈值设置比较大是不好的,会导致很多重叠框。

AP

P和R指标涉及了“边界框,置信度,类别”中的“边界框和类别”,并没有对置信度这一指标进行考量。综合考量就需要使用AP指标了,而AP指标来自于PR曲线。

precision × recall 曲线(PR曲线)可以看作是不同检测器生成的边界框的置信度值下,精准率和召回率之间的权衡。

如下面的表所示。一般情况下,当要求检测器置信度较高时,那么假阳性FP会减少,精准率P上升,同时,可能会漏掉一些真实的目标,导致假阴性FN上升,召回率R变低。反之,降低检测器的置信度标准,假阳性FP上升,精确率P下降,更多的真实目标会被检测到,召回率R提升。

置信度假阳性FP假阴性FN精确率P召回率R
越高⬇️⬆️⬆️⬇️
越低⬆️⬇️⬇️⬆️

我们对一个好检测器的期盼:

  • 能找到所有的真实目标,FN越接近0越好,即高召回率R;
  • 尽可能只识别想要的目标,不去乱猜,FP越接近0越好,即高准确率P;

因此,如果一个检测器在提高召回率的同时精准率保持较高,就可以被认为是好的检测器,这意味着即使置信度阈值发生变化,精准率和召回率仍然能保持较高。因此,PR曲线的曲线下面积(AUC)高往往意味着精准率和召回率都较高。

开个玩笑:究极目标检测器——人,COCO来一张,IOU阈值直接设置到0.8。多扫几遍,直接找到所有的检测目标,置信度全输出100%,无论你置信度怎样变化,P是1,R是1,究极好目标检测器,就是有点慢。

其实也不尽然,有时候看目标检测模型的输出,心想,我去这么小都可以看到吗?

不幸的是,在实际情况下,精准率-召回率曲线通常呈现锯齿状,这对AUC的准确测量提出了挑战。为了解决这个问题,在估计AUC之前,需要对精准率-召回率曲线进行处理,消除锯齿行为。基本上有两种方法来实现:11点插值法(11-point interpolation)和全点插值法(all-point interpolation)。全点插值法就是平常所见COCO和Pascal VOC评价指标的AP。

原文

Therefore, a particular object detector can be considered good if its precision stays high as its recall increases, which means that if the confidence threshold varies, the precision and recall will still be high. Hence, a high area under the curve (AUC) tends to indicate both high precision and high recall. Unfortunately, in practical cases, the precision × recall plot is often a zigzag-like curve, posing challenges to an accurate measurement of its AUC. This is circumvented by processing the precision × recall curve in order to remove the zigzag behavior prior to AUC estimation.

A P 11 AP_{11} AP11

公式如下:
A P 11 = 1 11 ∑ R ∈ { 0 , 0.1 , … , 0.9 , 1 } P interp  ( R ) \mathrm{AP}_{11}=\frac{1}{11} \sum_{R \in\{0,0.1, \ldots, 0.9,1\}} P_{\text {interp }}(R) AP11=111R{0,0.1,,0.9,1}Pinterp (R)

其中
P interp  ( R ) = max ⁡ R ~ : R ~ ≥ R P ( R ~ ) P_{\text {interp }}(R)=\max _{\tilde{R}: \tilde{R} \geq R} P(\tilde{R}) Pinterp (R)=R~:R~RmaxP(R~)

A P a l l AP_{all} APall

公式如下:
A P a l l = ∑ n ( R n + 1 − R n ) P interp  ( R n + 1 ) \mathrm{AP}_{\mathrm{all}}=\sum_n\left(R_{n+1}-R_n\right) P_{\text {interp }}\left(R_{n+1}\right) APall=n(Rn+1Rn)Pinterp (Rn+1)
其中
P interp  ( R n + 1 ) = max ⁡ R ~ : R ~ ≥ R n + 1 P ( R ~ ) P_{\text {interp }}\left(R_{n+1}\right)=\max _{\tilde{R}: \tilde{R} \geq R_{n+1}} P(\tilde{R}) Pinterp (Rn+1)=R~:R~Rn+1maxP(R~)
后面结合例子,运行一下这两个公式就全明白了。看这些公式,倒是看明白一件事情,为什么是——AP,Average Precision, A P 11 AP_{11} AP11求了11个P值,然后取平均, A P a l l AP_{all} APall是一种加权平均,两者都是平均精确度。不过在这上面召回率R也发挥了作用,之前只听AP和P,还以为AP和R没啥关系呢,实则AP是P和R的权衡考量。

上述公式只是一个类别的计算,而往往展示给我们的如COCO的AP50是80个类的均值,Pascal VOC的mAP是20个类AP的均值,所有这些叫平均平均精度比较好,Average/mean了两次。这样说的话,VOC的mAP比COCO的AP50的缩写更准确一点。
m A P = 1 N ∑ i = 1 N A P i \mathrm{mAP}=\frac{1}{N} \sum_{i=1}^N \mathrm{AP}_i mAP=N1i=1NAPi
其中 N N N 是类别总数。

COCO的AP@50: 5: 95平均了三次

例子

红框是detection,共A~V,X,Y共24个(26个字母没W和Z),绿框是真实目标的检测框共15个。红框的数字是置信度,至于是否超过30%的IOU阈值只能自己感觉了,不过基本大差不差。

在这里插入图片描述

下表为当IOU阈值为30%的时候,准确度P和召回率R的情况:

在这里插入图片描述

按照上面的公式去计算 A P 11 AP_{11} AP11

R R R R ~ \tilde{R} R~ P ( R ~ ) P(\tilde{R}) P(R~) P i n t e r p ( R ) P_{interp}(R) Pinterp(R)
11个R值表中所有比R值大的召回率RecallRecall对应的Precision值Precision集合中的最大值
00.0666, 0.0666, 0.1333, … , 0.46661, 0.5, 0.6666, … , 0.29161
0.10.1333, 0.1333, 0.1333, … , 0.46660.6666, 0.5, 0.4, … ,0.29160.6666
0.20.2, 0.2, 0.2666, … , 0.46660.3, 0.2727, 0.3333, … , 0.29160.4285
0.30.3333, 0.4, 0.4, … , 0.46660.3846,0.4285, 0.4, … , 0.29160.4285
0.40.4, 0.4, 0.4, … , 0.46660.4285, 0.4, 0.375, … , 0.29160.4285
0.5
0.6-0.9

计算:
A P 11 = 1 11 ( 1 + 0.6666 + 0.4285 + 0.4285 + 0.4285 ) = 26.84 % AP_{11} = \frac1{11}(1+0.6666+0.4285+0.4285+0.4285)=26.84\% AP11=111(1+0.6666+0.4285+0.4285+0.4285)=26.84%
原论文计算的 A P a l l AP_{all} APall
A P all  = 1 ∗ ( 0.0666 − 0 ) + 0.6666 ∗ ( 0.1333 − 0.0666 ) + 0.4285 ∗ ( 0.4 − 0.1333 ) + 0.3043 ∗ ( 0.4666 − 0.4 ) = 24.56 % \begin{aligned} \mathrm{AP}_{\text {all }} & =1 *(0.0666-0)+0.6666 *(0.1333-0.0666)+0.4285 *(0.4-0.1333)+0.3043 *(0.4666-0.4)=24.56\% \end{aligned} APall =1(0.06660)+0.6666(0.13330.0666)+0.4285(0.40.1333)+0.3043(0.46660.4)=24.56%

对于 A P a l l AP_{all} APall的计算,按照所给的公式,并不能直接得出和原论文一样的式子,因为其省略了一些步骤。原论文的公式没有说 R n R_n Rn指的是什么,根据推测,于是就将其看作是表中的每一个recall值,特别地,认为 R 0 = 0 R_0=0 R0=0

R n R_{n} Rn R n   v a l u e R_{n}\ value Rn value P ( R n ) P(R_{n}) P(Rn) P i n t e r p ( R n ) P_{interp}(R_n) Pinterp(Rn) R n − R n − 1 R_{n}-R_{n-1} RnRn1
R 0 R_{0} R00---
R 1 R_{1} R10.0666110.0666
R 2 R_{2} R20.06660.510
R 3 R_{3} R30.13330.66660.66660.0667
R 4 R_{4} R40.13330.50.66660
R 5 R_{5} R50.13330.40.66660
R 6 R_{6} R60.13330.33330.66660
R 7 R_{7} R70.13330.28570.66660
R 8 R_{8} R80.13330.250.66660
R 9 R_{9} R90.13330.22220.66660
R 10 R_{10} R100.20.30.42850.0667
R 11 R_{11} R110.20.27270.42850
R 12 R_{12} R120.26660.33330.42850.0666
R 13 R_{13} R130.33330.38460.42850.0667
R 14 R_{14} R140.40.42850.42850.0667
R 15 R_{15} R150.40.40.42850
R 16 R_{16} R160.40.3750.42850
R 17 R_{17} R170.40.35290.42850
R 18 R_{18} R180.40.33330.42850
R 19 R_{19} R190.40.31570.42850
R 20 R_{20} R200.40.30.42850
R 21 R_{21} R210.40.28570.42850
R 22 R_{22} R220.40.27270.42850
R 23 R_{23} R230.46660.30430.30430.0666
R 24 R_{24} R240.46660.29160.30430

按照这样进行计算的话,

A P all  = 1 ∗ ( 0.0666 − 0 ) + 0.6666 ∗ ( 0.1333 − 0.0666 ) + 0.4285 ∗ ( 0.2 − 0.1333 ) + 0.4285 ∗ ( 0.2666 − 0.2 ) + 0.4285 ∗ ( 0.3333 − 0.2666 ) + 0.4285 ∗ ( 0.4 − 0.3333 ) + 0.3043 ∗ ( 0.4666 − 0.4 ) = 24.56 % \begin{align} \mathrm{AP}_{\text {all }} & = 1 * (0.0666 - 0) \\ &\quad + 0.6666 * (0.1333 - 0.0666) \\ &\quad + 0.4285 * (0.2 - 0.1333) \\ &\quad + 0.4285 * (0.2666 - 0.2) \\ &\quad + 0.4285 * (0.3333 - 0.2666) \\ &\quad + 0.4285 * (0.4 - 0.3333) \\ &\quad + 0.3043 * (0.4666 - 0.4) \\ & = 24.56\% \end{align} APall =1(0.06660)+0.6666(0.13330.0666)+0.4285(0.20.1333)+0.4285(0.26660.2)+0.4285(0.33330.2666)+0.4285(0.40.3333)+0.3043(0.46660.4)=24.56%
插值前后的PR曲线对比:

将R作为横轴,P作为纵轴,绘制PR曲线。R是递增或者不变的,P时而递增,时而不变,时而递减,从而造成了PR曲线呈现锯齿状。

下面的两幅图像分别是插值后的曲线。

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

题外话-为什么要插值

AUC(Area Under the Curve)是通常用于评估二分类模型的性能。它是 ROC 曲线(Receiver Operating Characteristic Curve,受试者工作特征曲线)下的面积,取值范围在0-1之间,AUC越接近与1,模型的分类效果越好。

ROC曲线的绘制和PR曲线的绘制方法一样,ROC曲线计算的两个概率为真阳性率 (TPR)、假阳性率 (FPR),分别表示模型正确预测为正类的比例(召回率),模型错误地将负类预测为正类的比例。计算不同阈值下的TPR和FPR,接下来以FPR为横轴,TPR为纵轴,连接不同的点绘制出ROC曲线。

那么为什么,ROC曲线可以直接连接点来绘制,而PR曲线要来插值呢?

ROC曲线中,TPR和FPR不会出现锯齿状的情况,一般情况下,随着阈值的下降,TPR和FPR都是非递减的,即逐步增大或者保持不变。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression

# 1. 生成一个示例数据集
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)

# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 3. 训练一个逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)

# 4. 获取预测概率
y_probs = model.predict_proba(X_test)[:, 1]  # 预测为正类的概率

# 5. 计算 FPR 和 TPR
fpr, tpr, thresholds = roc_curve(y_test, y_probs)

# 6. 计算 AUC
roc_auc = auc(fpr, tpr)

# 7. 绘制 ROC 曲线
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')  # 对角线代表随机猜测
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc="lower right")
plt.show()

在这里插入图片描述

# 输出出来看看
for i, j, k in zip(fpr, tpr, thresholds):
    print(i, j, k)
    
# 0.0 0.0 inf
# 0.0 0.0064516129032258064 0.9999033225668299
# 0.0 0.3870967741935484 0.9608405238251244
# 0.006896551724137931 0.3870967741935484 0.9606797417680791
# 0.006896551724137931 0.4645161290322581 0.9429496860114247
# 0.013793103448275862 0.4645161290322581 0.9376365787112844
# 0.013793103448275862 0.4838709677419355 0.9358461731156758
# 0.020689655172413793 0.4838709677419355 0.9352570352185332
# 0.020689655172413793 0.49032258064516127 0.9334172228945368
# 0.027586206896551724 0.49032258064516127 0.9316159594166492
# 0.027586206896551724 0.5096774193548387 0.9198797972920243
# 0.034482758620689655 0.5096774193548387 0.9183739292910866
# 0.034482758620689655 0.5419354838709678 0.9087877675251759

AUC,曲线下面积,我们一般用积分去求,但是这些是离散的点,直接积分不适用,因此采用数值积分的方法去求近似面积。在计算 ROC 曲线的AUC时,常用的是梯形法则(Trapezoidal Rule)。其实就是学积分的时候,将曲线分割成一个一个的小梯形。

使用这种方法的话,是不是锯齿状都能算。主要原因是锯齿状的这种波动会导致估算误差(不太懂!!!)。

AUC是非递减的,类楼梯,而PR是锯齿状。但是插值后的PR,比如计算 A P a l l AP_{all} APall的那幅图,由锯齿状平滑成楼梯状了,这下全都是楼梯了,不过一个是上楼梯一个是下楼梯。

猜想:由于点太少,导致曲线不够光滑。或许有一条真实反映模型能力的PR图线,由无数个点组成,十分光滑。插值后的PR曲线,比插值的锯齿状PR曲线更加解决理想真实的PR曲线,所以采用了插值的方法。

其实 A P 11 AP_{11} AP11的动机很明确,召回率比0大的时候,找个最高精确率代表模型水平,召回率比0.1大的时候,找个最高精确率代表模型水平,依次类推到0.9。只选择11个区间,虽说笼统,但也全面。


题题外话-为什么要叫做ROC

为什么要叫ROC —— Receiver Operating Characteristic Curve —— 接收者操作特征曲线

GPT:

ROC 曲线的名字——Receiver Operating Characteristic curve(接收者操作特征曲线)来源于其最早的应用背景:雷达信号检测。尽管如今它已广泛用于机器学习和统计学中的分类模型性能评估,但它的名称和历史背景源自二战时期雷达信号处理的应用。

名称由来

ROC 曲线最初是在第二次世界大战期间由美国的工程师和科学家发展出来的。当时,雷达技术用于检测敌方飞机或其他目标,而需要解决的核心问题是如何在检测到真实目标的情况下,尽量减少误报(即不把噪声当成目标)。

  • Receiver(接收者):指的是雷达的信号接收者。在当时的雷达系统中,接收器需要从噪声中分辨出信号(例如飞机),这需要做出决策:是信号还是噪声。
  • Operating(操作):指的是操作接收器的决策过程。操作员或机器需要根据接收到的信号和噪声水平选择不同的阈值,以决定是否发出警报(认为有目标存在)。
  • Characteristic(特征):指的是接收者操作过程中产生的特征关系——即在不同的阈值下,系统如何在真实信号识别噪声误报之间做出权衡。

4 目标检测数据集

这部分主要总结主要的目标检测数据集以及它们使用的AP变种。

PASCAL VOC

更多详细内容参考这个链接:目标检测数据集PASCAL VOC简介

PASCAL —— Pattern Analysis, Statical Modeling and Computational Learning,是一个组织

VOC —— Visual Object Classes

Pascal挑战赛于2005年开始举办,2012年终止。一开始只有4类,后来发展到20个类。下表是PASCAL中的20个类别。

其中较为常用的两个数据集为PASCAL VOC 2007和PASCAL VOC 2012,07的时候类别达到20个类。这两个数据集是互斥的,没有重复的图片。

Pascal VOC的AP计算使用的是11点插值法

MS COCO

MS —— MicroSoft

COCO —— Common Objects in COntext

20万张图像,80个类。通常使用的是COCO2017

主要评价指标为AP@50:5:95,从0.5, 0.55, 0.6, 0.65, …, 0.95,10个不同IOU阈值下AP的平均值,使用 A P a l l AP_{all} APall的计算方式。也报告0.5和0.75IOU阈值下的AP。

在这里插入图片描述

官方给的说明coco-eval:

  1. 除非另有说明,平均精度(AP)和平均召回率(AR)是通过多个交并比(IoU)值取平均计算的。具体而言,我们使用了10个IoU阈值,范围为0.50到0.95,间隔为0.05。这与传统方法不同,传统上AP是在单一IoU为0.50时计算的(对应于我们的指标APIoU=0.50)。在多个IoU上的平均奖励了定位更准确的检测器。
  2. AP在所有类别上取平均。传统上,这被称为“平均平均精度”(mAP)。我们对AP和mAP(以及AR和mAR)不做区分,并假设上下文可以清楚地说明两者的区别。
  3. AP(在所有10个IoU阈值和80个类别上取平均)将决定挑战赛的获胜者。这被认为是在COCO数据集上衡量性能时最重要的单一指标。
  4. 在COCO数据集中,小物体的数量多于大物体。具体来说,约41%的物体是小物体(面积< 3 2 2 32^2 322),34%是中等物体( 3 2 2 32^2 322 <面积< 9 6 2 96^2 962),24%是大物体(面积> 9 6 2 96^2 962)。面积是根据分割掩码中的像素数量来衡量的。
  5. AR是给定每张图像的固定检测数量时的最大召回率,并在类别和IoU上取平均。AR与在这篇论文中使用的同名指标相关,但这里是基于每个类别计算的。
  6. 所有的度量都允许每张图像最多进行100次最高评分的检测(跨所有类别)。
  7. 目标检测的边界框和分割掩码的评估指标在所有方面都是相同的,唯一的区别是IoU的计算方式(分别在边界框或掩码上进行)。

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

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

相关文章

Chromium HTML Tags与c++接口对应关系分析

一、HTML 标签(HTML Tags) <a> <head> <img>等等这些标签在c中的接口是如何定义和查找的呢&#xff1f; 更多标签参考&#xff1a; HTML <a> target 属性 (w3school.com.cn) 二、html_tag_names.json5 (third_party\blink\renderer\core\html\htm…

基于SpringBoot的体育商城购物系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【AI大模型】初识LangChain:功能强大的语言模型框架

目录 &#x1f354; 什么是LangChain &#x1f354; LangChain主要组件 2.1 Models 2.1.1 LLMs (大语言模型) 2.1.2 Chat Models (聊天模型) 2.1.3 提示模板 2.1.4 Embeddings Models(嵌入模型) 2.2 Prompts 2.3 Chains(链) 2.4 Agents (代理) 2.5 Memory 2.6 Inde…

爬虫post收尾以及cookie加代理

爬虫post收尾以及cookie加代理 目录 1.post请求收尾 2.cookie加代理 post收尾 post请求传参有两种格式&#xff0c;载荷中有请求载荷和表单参数&#xff0c;我们需要做不同的处理。 1.表单数据&#xff1a;data字典传参 content-type: application/x-www-form-urlencoded; …

鸿蒙开发案例:HarmonyOS NEXT语法实现2048

【实现的功能】 • 游戏逻辑&#xff1a;实现了2048游戏的核心逻辑&#xff0c;包括初始化游戏盘面、添加随机方块、处理四个方向的滑动操作等。 • UI展示&#xff1a;构建了游戏的用户界面&#xff0c;显示得分、游戏盘面&#xff0c;并提供了重新开始按钮。 • 用户交互&…

【Docker基础六】docker-compose安装zookeeper、kafka、kafdrop

本文使用 Bitnami/Kafka 提供的kafka容器镜像。详情参考&#xff1a;bitnami/kafka - Docker 镜像 |Docker 中心 创建Docker Compose文件 创建一个名为 docker-compose.yml 的文件&#xff0c;并复制以下内容 version: "3.8" services:zookeeper:image: docker.io…

【C语言】赋值运算符自增、自减

C语言中用来表示赋值&#xff0c;将符号右边的常量或变量的值&#xff0c;赋值给左边的变量。 等号用来表示&#xff0c;一般用于判断条件&#xff0c;属于关系运算的一种&#xff0c;所以会有返回值&#xff0c;1或0。 #include <stdio.h> /* 功能&#xff1a;赋值运算…

微信小程序后台搭建—node+mysql

想必大家都有一个困扰&#xff0c;想要用微信小程序作为前端&#xff0c;但是后端不知道如何用node连接微信小程序&#xff0c;我最近也一直困扰许久&#xff0c;所以我就想用node写后端接口在连接微信小程序&#xff0c;记录一下学习笔记 前言 前端:微信小程序 后端:nodeexpr…

QT QML 练习8-Simple Transformations

简单的转换&#xff08;Simple Transformations&#xff09; 转换操作改变了一个对象的几何状态。QML元素对象通常能够被平移&#xff0c;旋转&#xff0c;缩放。下面我们将讲解这些简单的操作和一些更高级的用法。 我们先从一个简单的转换开始。用下面的场景作为我们学习的开始…

去掉CODESYS的用户管理密码

首先在成功连接PLC的情况下&#xff08;CODESYS登录成功&#xff09;情况下&#xff1a; 1. 2. 3. 4.CODESYS自动化应用进阶&#xff08;二&#xff09;&#xff1a;如何安装使用CODESYS RTE及使用CODESYS RTE过程中常见的问题_哔哩哔哩_bilibili 视频在00&#xff1a;57&…

基于Spring Boot的企业客户管理系统

目录 前言 功能设计 系统实现 获取源码 博主主页&#xff1a;百成Java 往期系列&#xff1a;Spring Boot、SSM、JavaWeb、python、小程序 前言 本论文主要论述了如何使用JAVA语言开发一个企业客户管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&am…

仿 Mac 个人网站开发 |项目复盘

一、前言 1.1 灵感来源 早年有幸看到国外大佬做的一个 基于 Web 的 Windows XP 桌面娱乐系统, 那时刚好有搭建一个个人博客的想法, 所以就想是否可以基于 WEB 实现一个仿 Mac UI 的个人博客, 以应用的形式来展示博客各个功能! 1.2 相关链接(求个 Star) 前端开源代码后端开源…

OpenAI 实时语音Realtime API接口申请: 助力开发者打造快速语音对话体验

OpenAI发布宣布推出Realtime API的公开测试版&#xff0c;所有付费开发者都可以在他们的应用中构建快速的语音对话体验。该API支持六种预设语音&#xff0c;类似于ChatGPT的高级语音模式&#xff0c;使自然的语音对话成为可能。 此外&#xff0c;Chat Completions API也新增了音…

【微服务】springboot远程docker进行debug调试使用详解

目录 一、前言 二、线上问题常用解决方案 2.1 微服务线上运行中常见的问题 2.2 微服务线上问题解决方案 2.3 远程debug概述 2.3.1 远程debug原理 2.3.2 远程debug优势 三、实验环境准备 3.1 搭建springboot工程 3.1.1 工程结构 3.1.2 引入基础依赖 3.1.3 添加配置文…

linux下使用mpi求自然数和

搭建MPI并行计算环境&#xff0c;编写 MPI程序&#xff0c;求和 1 23....1 0000。 要求: 1.使用100个进程; 2.进程0计算1 2...100, 进程1计算101 102... 200, ..... 进程99计算9901 9902... 10000; 3.调用计时函数,分别输出每个进程的计算时间; 4.需使用MPI集群通信函数和同…

【数据结构】时间、空间复杂度详解

大家有没有遇到过&#xff0c;为什么有些程序跑得飞快&#xff0c;而有些程序却慢得让人抓狂&#xff1f;我们可能都是这样认为的&#xff1a;他写的程序效率高等等&#xff0c;确实如此。但这背后隐藏着两个重要的概念&#xff1a;时间复杂度和空间复杂度。它们就像程序的“效…

MySQL的多表查询之联合查询

union联合查询 union用于合并两个或多个select语句的结果集 unnion将两个表上下拼在一起 要求&#xff1a; –两边select语句的字段数必须一致 –两边可以有不同数据类型的字段 –字段名默认按左边的表来设置 select column_name from table1 union select column_name from …

【Kubernets】配置类型资源 Etcd, Secret, ConfigMap

文章目录 所有资源概览Etcd详细说明一、基本概念二、主要功能三、架构与组件四、数据模型与操作五、安全与认证六、集群部署与管理 Secret详细说明一、Secret 的类型二、Secret 的创建三、Secret 的使用四、Secret 的更新与删除五、Secret 的安全性 ConfigMap详细说明一、Confi…

【分布式训练(5)】无法 kill PID?如何 kill 休眠中的 GPU 占用进程

【分布式训练 debug】VS Code Debug 技巧&#xff1a;launch.json实用参数 【分布式训练&#xff08;2&#xff09;】深入理解 DeepSpeed 的 ZeRO 内存优化策略 (三阶段的区别) 【分布式训练&#xff08;3&#xff09;】accelerator deepspeed debug 报错 “Timed out waiting…

华为OD机试 - 最大利润 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…