Learning Discriminative Representations for Skeleton Based Action Recognition

标题:基于骨架的动作识别的学习判别性表示

原文链接:Learning Discriminative Representations for Skeleton Based Action Recognition (thecvf.com)

源码链接:https://github.com/zhysora/FR-Head

发表:CVPR

摘要

最近,人们开始设计基于GCN的模型来从骨架中提取特征,以执行人类动作识别任务,因为骨架表示比其他模态(如RGB帧)更高效、更健壮。然而,当使用骨架数据时,一些重要的线索(如相关项目)也被丢弃了。这导致一些模糊的动作很难被区分,并且往往被错误分类。为了缓解这个问题,我们提出了一个辅助特征精炼头(FR Head),它由空间-时间解耦和对比特征精炼组成,以获得骨架的判别性表示模糊样本在特征空间中被动态发现和校准。此外,FR Head可以被强加在GCNs的不同阶段上,以构建多级精炼以获得更强的监督。我们在NTU RGB+D、NTURGB+D 120和NW-UCLA数据集上进行了大量实验。我们提出的模型获得了与最先进方法竞争力相当的结果,并且可以帮助区分这些模糊的样本。代码可在https://github.com/zhysora/FR-Head获得。

1.介绍

在人与人之间的交流中,动作起着特别重要的作用。这些行为传达了内在的信息,如情感和潜在意图,从而帮助理解这个人。赋予智能机器理解人类行为的同样能力对于自然的人机交互和许多其他实际应用至关重要,并且最近已经引起了很多关注。

如今,由于先进的传感器技术和人体姿势估计算法,获取人类的2D/3D骨架变得更加容易。骨架是一种紧凑而健壮的表示形式,不受视角变化和杂乱背景的影响,因此非常适用于动作识别。利用骨架进行动作识别的典型方法是构建图卷积网络(GCNs)[38]。人体的关节和骨骼自然形成图形,使得GCNs成为提取骨架拓扑特征的理想工具。基于GCN的方法越来越受欢迎,另一个优点是与处理视频帧的模型相比,这些模型可以构建得更轻量化,并且具有较高的计算效率。

然而,利用骨架来识别动作也存在一些限制。一个主要问题是,骨架表示缺乏重要的交互对象和上下文信息,以区分类似的动作。如图1所示,仅基于骨架视图很难区分“写作”、“阅读”和“键盘上打字”。相比之下,模型可以通过关注相关物体从RGB帧中识别它们。这些动作很容易混淆,并且应该受到更多关注。

为了缓解这一缺点,我们提出了一个特征细化模块,利用对比学习来提升模糊动作之间特征的区分能力。我们首先将隐藏特征分解为空间和时间组件,以便网络可以更好地专注于模糊动作之间的区分部分,沿着拓扑(图结构中节点之间的连接关系)和时间维度。然后,我们根据模型在训练期间的预测结果来识别自信(对于某些样本的预测有较高的信心)和模糊样本。确信样本用于维护每个类别的原型(每个类别典型的动作特征),这是通过对比学习损失来实现的,以约束类内和类间距离。同时,模糊样本通过在特征空间中与确信样本更接近或更远来进行校准。此外,前述的特征细化模块可以嵌入到多种类型的GCNs中,以改善分层特征学习。它将产生一个多级对比损失,与分类损失一起进行联合训练,以提高模糊动作的性能。我们的主要贡献总结如下:

• 我们提出了一个判别性特征细化模块,以提高基于骨架的动作识别中模糊动作的性能。它使用对比学习来约束确信样本和模糊样本之间的距离。它还以轻量级的方式将原始特征图分解为空间和时间组件,以实现高效的特征增强
该特征细化模块是即插即用的,并且与大多数基于GCN的模型兼容。它可以与其他损失一起进行联合训练,但在推断阶段被丢弃。
• 我们在NTU RGB+D、NTU RGB+D 120和NW-UCLA数据集上进行了大量实验,将我们提出的方法与最先进的模型进行了比较。实验结果表明了我们方法的显著改进。

2.相关工作

2.1. 人体姿势估计

人体姿势估计是增强现实、体育分析和医疗保健等领域中各种智能系统的基础构建模块,因此近年来受到了广泛关注。最近的方法利用2D姿势序列的时间信息来减轻3D姿势中的深度歧义[1, 13, 19, 20, 23]。Hossain等人[13]将任务视为序列到序列问题,并构建了循环神经网络(RNN)来学习映射关系。Cai等人[1]通过类似编码器-解码器的图卷积网络(GCN)来利用2D序列的空间-时间关系。Li等人[19]使用Transformer[31]来捕捉2D姿势序列中的长距离关系。

2.2. 基于骨架的动作识别

动作识别从人体姿势估计中受益匪浅。早期的研究将其识别视为一个序列分类任务。Su等人[30]设计了一个自编码器与循环神经网络(RNNs)来从序列中学习高级特征。另一种方法将骨架序列转换为图像样式数据,使用手工设计的方案[9, 37]。Duan等人[10]将RGB帧与2D骨架热图串联起来,然后使用3D卷积神经网络(CNNs)提取特征。这些方法没有明确地利用人体的空间结构

这一领域的主流方法是利用图卷积网络(GCNs)从骨架中提取高级特征,因为人体的关节和骨骼自然构成了一个图形[5,22,38,42]。通过这种方式,充分利用了人体的拓扑结构。Yan等人[38]是首次尝试使用GCNs进行基于骨架的人体动作识别。他们定义了空间和时间维度的基本连接,并引入了一个高效的流程。Zhang等人[42]构建了一个双流体系结构,用于关节和骨骼两种模态。Chen等人[5]改进了[38]中GCNs的设计,并提出了动态学习不同拓扑结构并有效地聚合每个通道的关节特征。

2.3. 对比学习

近年来,对比学习在各个领域取得了显著的进展。通常,对比学习要求使用数据增强技术生成图像的一组转换版本(或“视图”),然后训练网络以区分图像的不同视图。陈等人[2]探索了数据增强的策略,并使用了大批量大小来获得增强的表示。何等人[3,4,12]以更高效的方式实现了对比学习,使用了动量编码器和动态队列。王等人[33]以监督方式定义了正负样本。他们设计了一种度量函数损失来校准这些被错误分类的特征表示,以获得更好的类内一致性和分割性能。受此启发,我们的工作尝试使用类似的思路来为模糊动作细化骨架表示。

2.4. 模糊样本

大多数解决模糊样本的识别任务集中在细粒度图像分类上。例如,Lin等人[32]对两个局部补丁的表示执行双线性池化以学习判别特征。Dubey等人[11]对图像对之间的相似性建模,并利用度量学习来改善特征分布。Zhuang等人[43]设计了一个模块,从一对图像中自适应地发现对比线索,并通过成对交互关注地区分它们。然而,我们尚未找到针对基于骨架的动作识别的相关工作。

3. 方法论

现在我们来详细介绍我们的方法。其概述如图2所示。

3.1. 主干网络

我们模型的输入是一个形状为 T × V × 3 的骨架序列,其中 T 表示时间帧数,V 表示每帧中的关节点数量,3 表示每个关节点的三维坐标。我们的方法建立在 [5] 的基础上。然而,我们将在实验部分展示,它可以改进任何图卷积网络(GCNs)。主干网络由 10 个基本单元组成,称为 TGN。TGN 由一系列的 Temporal CNNs (TCNs) 和 Graph Convolution Networks (GCNs) 构成。具体地,TCNs 通过在时间维度上施加 1D CNNs 来提取时间特征;GCNs 则利用在空间维度上定义的可学习拓扑图来提取空间特征。值得注意的是,两个基本单元是通过步长 1D CNNs 实现的步进 TGNs。它们用于通过减小时间维度同时增加通道维度来生成多尺度特征。然后,应用池化层来获取 1D 高级特征向量。最后,一个具有 softmax 激活函数的全连接(FC)层将特征映射到 K 个候选类别的概率分布。

请注意,主干网络的详细实现并不是我们方法的主要关注点。基本单元的实现可以被任何其他基于 GCN 的网络所替代,比如 [26, 38]。

3.2. 特征细化头

我们的主要思想是提高基于骨架的模型在相似且容易被误分类的模糊动作上的性能。为了实现这一目标,我们提出了一个即插即用的模块,用于优化主干网络内的多层特征,称为特征细化头(FR Head)。它首先将隐藏的特征图解耦为空间和时间组件,然后使用全局类原型和模糊样本进行对比学习损失。值得注意的是,所提出的FR Head仅用于训练。在推断期间,不会增加额外的计算成本或内存消耗。

3.2.1 多层特征选择

为了学习更具有判别性的特征表示,我们将主干网络分为四个阶段,分别位于 TGN 的第 1、第 5、第 8 和最后一层,并在每个阶段上施加一个 FR Head。第 5 层和第 8 层采用步进操作。每个 FR Head 通过计算对应的对比学习(CL)损失来细化相应的隐藏特征,其详细内容将在第 3.2.3 节中讨论。为了平衡不同层级,我们为每个阶段添加一个加权参数多级对比学习损失可以定义为加权平均和:
L_{CL} = \sum_{i=1}^{4} \lambda_i \cdot L_i^{CL} \qquad(1)
其中L_{CL}是多级对比学习损失,\lambda_i控制第 i 阶段的超参数L_i^{CL}由第 i 阶段计算的局部对比学习损失。

3.2.2 空间-时间解耦

由于人类活动的复杂性,粗糙的建模特征会导致在空间外观或时间转换相似的模糊动作之间产生混淆。

例如,“把东西放进袋子里”可以通过时间线索与“从袋子里拿东西出来”很容易区分。然而,与“伸手进口袋”相比,更需要集中精力在空间信息上。因此,我们提出了一个空间-时间解耦模块,同时挖掘空间和时间信息,以提高动作表示的判别能力

如图2所描述,原始特征图被送入两个并行分支以进行有效的特征增强。具体来说,每个分支包括一个空间/时间池化层,它仅保留相关维度的平均值,以及一个1×1卷积层,用于将特征压缩到固定大小。然后,输出特征被展平为具有通道大小C_h的统一表示。最后,在每个分支的顶部添加了一个CL损失。我们通过将两个分支的损失相加来完成空间-时间解耦特征细化
L_i^{CL} = CL(F_i^s) + CL(F_i^t)\qquad(2)
其中F_i^sF_i^t分别表示第 i 阶段的空间特征和时间特征CL(·) 是用于计算具有特定特征向量的CL损失的函数

3.2.3 对比特征细化

正如图2所示,我们以对比学习的方式进行特征细化。这个想法受到 [33] 的启发。每个样本将通过其真实动作以及其他模糊动作进行细化。

确信样本聚类。给定一个动作标签 k,如果一个样本被正确预测,即为真正例(TP),我们将其视为确信样本,以区别于模糊样本。显然,确信样本的特征往往具有更好的类内一致性。如图3所示,我们聚集这些特征,通过指数移动平均(EMA)更新相应类别的全局表示(即原型)。假设 s_{TP}^k 是一个批次中动作 k 的确信样本集合,其大小为 n_{TP}^k,EMA 操作可以定义为:

P_k = (1 - \alpha) \cdot \frac{1}{n_{k_{TP}}} \sum_{i \in s_{k_{TP}}} F_i + \alpha \cdot P_k\qquad(3)

其中P_k是动作 k 的原型F_i是从样本 i 中提取的特征。\alpha是动量项,我们通过经验将其设置为 0.9。在训练过程中,原型成为动作 k 的聚类中心的稳定估计,能够细化新样本的特征。每个样本应该接近相关原型,同时远离其他原型。两个特征向量之间的距离定义为 dis(·, ·),使用余弦距离实现:

dis(u, v) = \frac{u^Tv}{||u||_2||v||_2} \qquad(4)

其中 u、v 是一维向量。|| · ||2 是 L2 范数。

对“原型成为动作 k 的聚类中心的稳定估计"的理解:

通过对自信样本的特征进行聚合,并通过指数移动平均(EMA)不断更新,原型逐渐学习到了代表动作类别 k 的特征的平均表征。随着训练的进行,原型的位置会逐渐稳定下来,最终成为该类别的特征空间中心点(该类别特征的典型表示)的稳定估计。这个稳定的估计可以帮助模型更好地区分不同的动作类别,并且能够适应新样本的到来。

发现模糊样本。为了在训练阶段发现模糊样本,我们聚集了被错误分类的样本,这些样本往往与其他类别非常相似。给定一个动作标签 k,有两种类型的模糊样本。如果动作 k 的样本被错误分类为其他类别,则被称为假阴性(FN)如果其他类别的样本被错误分类为动作 k,则被称为假阳性(FP)。假设s_{FN}^ks_{FP}^k 分别是动作 k 的假阴性和假阳性样本集合,它们的大小分别为n_{FN}^kn_{FP}^k。如图3所示,我们在一个批次中聚集这些样本,并计算均值作为中心表示:

\boldsymbol{\mu}_{FN}^{k}=\frac{1}{n_{FN}^{k}}\sum_{j\in s_{FN}^{k}}F_{j},\boldsymbol{\mu}_{FP}^{k}=\frac{1}{n_{FP}^{k}}\sum_{j\in s_{FP}^{k}}F_{j}\quad(5)

其中\mu_{k_{FN}}\mu_{k_{FP}}分别代表类别 k 的假阴性和假阳性样本的中心表示。需要注意的是,我们不维护这些模糊样本的全局表示,因为这些样本的预测在训练阶段不稳定,并且数量远少于真正例样本。

为什么”不维护这些模糊样本的全局表示“?

由于模糊样本的预测不稳定且数量较少,将它们的特征聚合到原型中可能会引入噪声或不确定性,可能会使得原型偏离真实的动作特征,导致模型在分类时产生误差或性能下降。

模糊样本校准。为了校准模糊样本的预测,我们以动作 k 的确信样本 i 为锚点,并在特征空间中计算一个补偿项。对于那些应该被分类为动作 k 的 FN 样本(实际上被错误分类为别的样本),引入一个补偿项 φi:
\phi_i = \begin{cases} 1 - \text{dis}(F_i, \mu_{FN}^k), & \text{if } i \in s_k^{TP} \text{ and } n_{FN}^k > 0; \\ 0, & \text{otherwise.} \end{cases}\qquad(6)

通过最小化补偿项 φi,FN 样本(动作 k 的样本被错误分类为其他类别)应该在特征空间中更接近于确信样本。当没有 FN 样本或余弦距离收敛到 1 时,φi 达到最小值 0。这可能会促使模型将这些模糊样本纠正为动作 k。

这个公式描述了对模糊样本的校准过程。

- φi是用于校准样本i的补偿项。
- 如果样本i被正确分类为动作k(即属于s_{TP}^k),并且在同一批次中存在FN(False Negative)样本(那些被错误分类为其他类别的动作k样本),φi的计算方式为,1减去样本i与动作k的FN样本集合的中心表示µkFN  之间的余弦距离。这个计算会使得FN样本更靠近其正确类别的中心表示。
- 如果样本i不是确信样本(即不在s_{TP}^k中),或者该批次不存在FN样本(即nkFN <= 0),则补偿项φi被设为0,因为在这种情况下没有必要进行校准。

这个校准过程旨在通过调整模糊样本的特征表示,使得它们更接近其正确的类别中心,从而提高模型对这些模糊样本的分类准确性。

另一方面,对于那些属于其他类别的FP样本(其他类别的分类为k类别),引入了一个惩罚项ψi:

\psi_i=\begin{cases}1+\operatorname{dis}(F_i,\boldsymbol{\mu}_{FP}^k),\operatorname{if}i\in s_{TP}^k\text{and}n_{FP}^k>0;\\0,\text{otherwise}.\end{cases}\qquad(7)

类似地,通过最小化惩罚项ψi ,惩罚项ψi 惩罚了FP样本与特征空间中确信样本之间的距离。当不存在FP样本,或余弦距离趋于 -1 时,ψi 达到最小值 0。这可能防止模型将这些模糊样本识别为动作 k。

最后,以样本 i 为锚点,所提出的 CL 损失函数可以定义为:

\begin{aligned} \mathrm{CL}(F_{i})& =-\mathrm{log}\frac{e^{\mathrm{dis}(F_{i},P_{k})/\tau-(1-p_{ik})\psi_{i}}}{e^{\mathrm{dis}(F_{i},P_{k})/\tau-(1-p_{ik})\psi_{i}+\sum_{l\neq k}e^{\mathrm{dis}(F_{i},P_{l})/\tau}}} \\ &-\log\frac{e^{\mathrm{dis}(F_{i},P_{k})/\tau-(1-p_{ik})\phi_{i}}}{e^{\mathrm{dis}(F_{i},P_{k})/\tau-(1-p_{ik})\psi_{i}+\sum_{l\neq k}e^{\mathrm{dis}(F_{i},P_{l})/\tau}}} \end{aligned}\qquad(8)

其中 p_{ik} 是样本 i 对类别 k 的预测概率分数。这意味着具有较弱置信度的TP样本(被正确预测)会从那些模糊样本获得更强的监督。

对公式8的理解:

存在其他类别分类为k类别的情况:

\operatorname{dis}(F_{i},P_{k})/\tau衡量了模糊样本 Fi​ 与目标类别 k 的原型 Pk​ 之间的余弦距离。如果这个距离较小,则表示模糊样本与目标类别的特征较为相似,模型正确地将其分类为目标类别 k 的可能性较大。\tau 是一个温度参数,它控制了距离在损失函数中的重要性。

②(1−pik​) 表示了模糊样本 Fi​ 被正确分类为目标类别 k 的概率的补数。如果模糊样本被正确分类,(1−pik​) 将接近于 0,相应地,如果模糊样本被错误分类,则 (1−pik​) 将接近于 1。

③ψi​ 是一个惩罚项,用于惩罚模糊样本被错误分类为目标类别 k 的情况。它考虑了模糊样本与其他类别原型之间的距离。如果模糊样本与其他类别的原型更接近于模糊样本与目标类别的原型,则 ψi​ 的值会增加,从而增加了模糊样本被错误分类的损失(将模糊样本分类为原本应该属于的非k类别)。

④:\sum_{l\neq k}e^{\mathrm{dis}(F_i,P_l)/\tau}表示样本i的特征向量Fi 和类别l(非类别k)的原型Pl之间的余弦距离;

存在样本i被错误分类为其他非k类别的情况

①:ϕi​ 是一个补偿项,用于补偿模糊样本被错误分类为其他类别的情况。如果模糊样本实际属于目标类别 k 但被错误分类为其他类别,则 ϕi​ 的值会增加,从而减少了模糊样本被错误分类的损失。

目标是最小化模糊样本的错误分类,通过惩罚其他类别分类为k类别的情况并补偿k类别样本被分类为其他类别的情况,从而提高模型的性能和鲁棒性。

3.3训练目标

我们使用交叉熵(CE)损失来训练我们的网络:
L_{\text{CE}} = -\frac{1}{N} \sum_i \sum_c y_{ic} \log(p_{ic})\qquad (9)
其中,N 是批次中样本的数量。 y_{ic}是样本 i 的标签的one-hot表示。如果 c 是样本 i 的目标类别,则 y_{ic} = 1p_{ic}是网络预测样本 i 属于类别 c 的概率得分。

通过对所有样本和所有类别的预测概率分布与真实标签之间的交叉熵进行求和,来衡量模型的预测与真实情况之间的差异。

最后,交叉熵损失与我们提出的多级对比损失相结合,形成完整的学习目标函数:
L = L_{CE} + w_{cl} \cdot L_{CL}
其中 L_{CL}L_{CE}在公式 1 和 9 中定义。w_{cl}是对比损失的平衡超参数。

L_{CL} = \sum_{i=1}^{4} \lambda_i \cdot L_i^{CL} \qquad(1)
其中L_{CL}是多级对比学习损失,\lambda_i控制第 i 阶段的超参数L_i^{CL}由第 i 阶段计算的局部对比学习损失。

方法论部分主要介绍了作者提出的一种用于改进骨架动作识别模型性能的方法。以下是该方法的总结:

1. **骨干网络(Backbone)**:模型输入为骨架序列数据,采用由一系列时间卷积神经网络(Temporal CNNs)和图卷积网络(Graph Convolution Networks)构成的基本单元组成的骨干网络,用于提取时间和空间特征

2. **特征优化头(Feature Refinement Head)**:为了提高模型在相似和容易混淆的动作中的性能,作者提出了一个可插拔的模块,用于优化骨干网络内的多级特征。该模块分别针对每个级别的特征进行对比学习损失的优化,以平衡不同级别的影响,并采用空间-时间分离技术来优化动作表示

3. **对比特征优化(Contrastive Feature Refinement)**:通过对比学习的方法对特征进行优化,利用自信样本(TP)和模糊样本(FP)来调整特征空间中的样本表示自信样本的特征用于更新全局原型,而模糊样本则用于校准预测和优化特征表示。

4. **训练目标(Training Objective)**:采用交叉熵损失函数结合多级对比学习损失来进行模型训练,通过平衡超参数w_{cl}来控制对比损失的影响

总的来说,该方法通过优化骨干网络中的多级特征表示,并利用对比学习的方法来调整特征空间中的样本表示,从而提高骨架动作识别模型的性能。

4.实验

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

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

相关文章

面试题:MySQL 优化篇

定位慢查询 &#x1f496; 开源工具 调试工具&#xff1a;Arthas&#xff08;阿尔萨斯&#xff09;运维工具&#xff1a;Prometheus&#xff08;普罗米修斯&#xff09;、Skywalking &#x1f496; MySQL 慢查询日志 # 开启 MySQL 慢查询日志开关 slow_query_log1 # 设置慢…

k8s入门到实战(七)—— 回顾:使用yaml文件配置pv、pvc、configmap部署mysql服务

实战&#xff1a;部署 mysql 服务 回顾加深 pv、pvc、configmap 删除所有 deployment、pv、pvc、configmap、StorageClass创建一个 nsf 挂载目录给 mysql mkdir -p /nfs/data/mysql创建 yaml 文件mysql-server.yaml # 创建pv apiVersion: v1 kind: PersistentVolume metadat…

黑马鸿蒙笔记 3

目录 11.ArkUI组件-Column和Row 12.ArkUI组件-循环控制 13.ArkUI组件-List 14.ArkUI组件-自定义组件 15.ArkUI组件-状态管理State装饰器 16.ArkUI组件-状态管理-任务统计案例 17.ArkUI组件-状态管理-PropLinkProvideConsume 11.ArkUI组件-Column和Row Colum和Row的交叉…

QT-飞机水平仪图标

QT-飞机水平仪图标 一、演示效果二、关键程序三、下载链接 一、演示效果 二、关键程序 #include <stdio.h> #include <stdlib.h> #include <string.h>#include <QtCore> #include <QtGui> #include <QDebug> #include <QTableWidget&g…

Oracle Solaris 11.3开工失败问题处理记录

1、故障现像 起初是我这有套RAC有点问题&#xff0c;我想重启1个节点&#xff0c;结果发现重启后该节点的IP能PING通&#xff0c;但SSH连不上去&#xff0c;对应的RAC服务也没有自动启动。 操作系统是solaris 11.3。由于该IP对应的主机是LDOM&#xff0c;于是我去主域上telnet…

【BlossomRPC】接入注册中心

文章目录 NacosZookeeper自研配置中心 RPC项目 配置中心项目 网关项目 这是BlossomRPC项目的最后一篇文章了&#xff0c;接入完毕注册中心&#xff0c;一个完整的RPC框架就设计完成了。 对于项目对注册中心的整合&#xff0c;其实我们只需要再服务启动的时候将ip/port/servic…

Qt6.6添加多媒体模块Multimedia报错问题

问题 QT包含多媒体模块Multimedia时提示未知的模块&#xff1a; error: Project ERROR: Unknown module(s) in QT: multimedia 在帮助文档中只可以找到QMediaPlayer类&#xff0c;但是点进去是空的&#xff0c;这是因为没有安装多媒体模块及对应的帮助文档。 解决 使用在线…

● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

● 435. 无重叠区间 class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if len(intervals)1:return 0intervalssorted(intervals,keylambda x:(x[0],x[1]))res0for i in range(1,len(intervals)):if intervals[i][0]<intervals[i-1][…

代码随想录算法训练营第41天|343. 整数拆分 |96.不同的二叉搜索树

代码随想录算法训练营第41天|343. 整数拆分 |96.不同的二叉搜索树 详细布置 今天两题都挺有难度&#xff0c;建议大家思考一下没思路&#xff0c;直接看题解&#xff0c;第一次做&#xff0c;硬想很难想出来。 343. 整数拆分 https://programmercarl.com/0343.%E6%95%B4%E6%…

【Go】十三、面向对象:方法

文章目录 1、面向对象2、结构体实例的创建3、结构体之间的转换4、方法5、结构体值拷贝6、方法的注意点7、方法和函数的区别8、跨包创建结构体实例 1、面向对象 Go的结构体struct ⇒ Java的Class类Go基于struct来实现OOP相比Java&#xff0c;Go去掉了方法重载、构造函数和析构函…

css- 4

1.浮动 1. 浮动最初用于实现文字环绕效果 2. 现在&#xff0c;浮动是主流的布局方式之一 1.1元素浮动之后的特点 元素浮动之后&#xff0c;称为浮动元素&#xff0c;具有如下特点&#xff1a; 1. 浮动元素脱离文档流 2. 多个浮动的元素会水平排列&#xff0c;一行放不下自动换…

Redis高级面试题-2024

说说你对Redis的理解 Redis是一个基于Key-Value存储结构的开源内存数据库&#xff0c;也是一种NoSQL数据库。 它支持多种数据类型&#xff0c;包括String、Map、Set、ZSet和List&#xff0c;以满足不同应用场景的需求。 Redis以内存存储和优化的数据结构为基础&#xff0c;提…

chatglm.cpp编译与执行

ChatGLM3介绍 ChatGLM3是由智谱AI和清华大学KEG实验室联合发布的对话预训练模型。作为第三代大型语言模型&#xff0c;ChatGLM3不仅理解和生成人类语言&#xff0c;还能执行代码、调用工具&#xff0c;并以markdown格式进行响应。其目标是打造更智能、更安全的代码解释器和工具…

【力扣一刷】代码随想录day27(39. 组合总和、40.组合总和II、131.分割回文串)

目录 【39. 组合总和】中等题 【40.组合总和II】中等题 【131. 分割回文串】中等题 【39. 组合总和】中等题 思路&#xff1a; 确定终止条件&#xff1a;sum target时记录路径并返回。剪枝&#xff1a;当前节点的路径之和已经大于sum就不可能再等于sum了&#xff0c;结束该分支…

16进制的字符串转byte[]数组 以及将字节数组转换成十六进制的字符串

16进制的字符串转byte[]数组 public class ClientString16 {@Testpublic void get16Str(){String str="48 47 12 00 14 12 16 08 15 0d 30 0f 02 30 30 30 30 30 30 30 30 30 30 00 c2";byte[] bytes = hexStringToByteArray(str);getBytetoString(bytes);//String …

【御控物联】JavaScript JSON结构转换(12):对象To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、核心构件之转换映射三、案例之《JSON对象 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换…

【御控物联】JavaScript JSON结构转换(8):数组To数组——多层属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON数组 To JSON数组》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

Java

1.学生和老师都会有work方法&#xff0c;学生的工作是学习&#xff0c;老师的工作是教书&#xff0c;我利用了一个接口来实现&#xff1b; 2.同时&#xff0c;老师和学生都是人&#xff0c;并且都有姓名&#xff0c;姓名&#xff0c;年龄和身高等特征&#xff0c;我用了一个继承…

http协议补充

7.7实现http请求 class httprequest { public:void Deserialize(std::string content){while (true){auto pos content.find(sep);if (pos std::string::npos){break;}std::string temp content.substr(0, pos);if (temp.empty()){break;}req_header_.push_back(temp);cont…