学习笔记——MMSR 自适应多模态融合的序列推荐

Adaptive Multi-Modalities Fusion in Sequential Recommendation Systems

前几天当我在阅读这篇论文的时候,在网上找到的相关资料很少,所以当时我读这篇论文的时候特别痛苦,精读了两天半.....所以现在我将自己学习笔记分享出来,给后面需要的小伙伴借鉴借鉴。我目前也是处于学习的过程中,本身也比较菜,所以有什么不对的地方欢迎评论区大佬指出。

论文地址:https://arxiv.org/pdf/2308.15980

经过翻译的论文地址:https://pan.baidu.com/s/1Fr44fWbBUwzCnpJv8YfyNQ 提取码: hjqb

官方源码:GitHub - HoldenHu/MMSR

1、前言

本文提出了一种名为MMSR的基于图的方法,用于顺序推荐系统中的自适应多模态融合。MMSR将每个用户的历史记录表示为一个图,其中用户历史序列中每个项目的模态特征由交叉链接的节点表示。同质节点之间的边表示内部模态的顺序关系,异质节点之间的边表示模态之间的相互依赖关系。MMSR结合了双重注意力,并允许通过更新门异步更新每个节点的表示,使每个模态可以优先考虑其固有的顺序性或其与其他模态的相互作用。在六个数据集上的实验中,MMSR始终优于最先进的模型,我们的图传播方法也超过了其他图神经网络。此外,MMSR自然地处理缺失的模态。所提出的方法在跨模态的早期和晚期融合之间取得了平衡,并为每个特征节点的融合顺序提供了自适应选择。本文的贡献包括突出顺序推荐中模态融合的挑战,提出了一种通用的解决方案,并在六个数据集上进行了全面的实验,显示出了显著的准确性和鲁棒性提升。

顺序推荐的核心任务是:给定用户𝑢的历史交互数据H𝑢,找到一个函数𝑓:H𝑢𝑣,来预测用户最有可能消费的下一个项目𝑣

在典型的顺序推荐任务中,历史交互数据只包含item ID信息; 即 H𝑢 = {𝑣1, 𝑣2,  ......𝑣𝑚}

基于这个基础,模态增强的序列推荐也考虑了序列中项目的模态,用H𝑢 = {x1, x2, .... , x𝑚},其中每个x是项目的不同特征通道(包括项目标识符和项目模态)的组合。我们只考虑图像和文本模态,并且一个实例表示为x𝑖 : {𝑣𝑖, 𝑎𝑖, 𝑏𝑖 }

这里,𝑎𝑖𝑏𝑖分别表示项目𝑣𝑖的图像和文本。我们将项目 ID(V)、图像特征(A)和文本特征(B)称为模态的三个特征通道

𝑣 ε V、𝑎 ε A 和 𝑏 ε B

2、基础模型

1、初始嵌入(Initial embedding)方面

P表示用户的输出,P = 𝑓(E),用户历史输入特征的综合嵌入张量表示为 E ∈ Rm×d,3表示三种模态的特征,m表示用户交互序列有m条信息,d表示一共有d个用户。第i个用户输入特征综合表示为Ei∈ Rm

2、Representation learning特征学习方面

对于前期融合,首先融合垂直特征通道(v,a,b),然后再进行水平序列关系的融合(1,2...,m)。

如果使用线性组合进行通道融合,则表示为: E𝑖,: = 𝜎(W(𝑐𝑎𝑡[E𝑖,1; E𝑖,2; E𝑖,3]))  P = M( [E1,:, E2,:, ..., E𝑚,:])

对于后期融合,则顺序颠倒,首先融合水平序列关系(1,2...,m),然后再进行垂直特征通道(v,a,b)的融合。

表示为:E:,𝑗 = M( [E1, 𝑗, E2,𝑗, ..., E𝑚,𝑗 ])   P = 𝜎(W(𝑐𝑎𝑡[E:,1; E:,2; E:,3]))

其中𝑐𝑎𝑡[; ]操作是特征通道拼接,W为线性权重参数,𝜎 是激活函数,M 是序列建模的模型。

然而,对于整体融合而言,𝑓会把用户历史张量E作为一个整体处理;Trans2D方法 直接在 E 上应用 2D-attention,我们的方法则是将 E 视为图结构中的一个节点表示

3prediction预测方面

通过使用点积对候选项目 e𝑣 与学习的用户表示 P 进行评分,生成预测概率分数:𝑦ˆ =< P, eTv>。

在训练过程中,模型通过交叉熵损失来衡量并最小化真实值 𝑦 和预测 ˆ𝑦 之间的差异。

如前所述,特征学习阶段的融合顺序至关重要。 当前的方法无法平衡两个顺序的极端情况。 为了解决这个问题,作者提出了 MMSR 框架。在基础模型的基础上,在表征学习阶段引入基于图的神经网络进行特征融合。为每个用户构建多模态序列图之后,利用双重注意力机制来独立聚合异构和同构节点信息,实现自适应顺序合并,从而同时考虑顺序和跨模态方面。

3、Multimodal Sequence Graph Construction多模态序列图的构建

对于每个用户U,将U的历史表示为一个图:a Modality-enriched Sequence Graph (MSGraph)具有丰富模态的序列图

G𝑢 = (N𝑢, R, E𝑢 ),每个用户的图N𝑢和E𝑢是不同的,为方便理解,接下来我们将只讨论一个用户的图,表示G = (N,R,E )

下图右侧说明了模态的节点构造,而左侧详细说明了 MSGraph 中的边缘构造。

1、Nodes and their initialization(节点及其初始化)

每个 MSGraph 应由 𝑚 ×3 个节点组成(其中 𝑚 是序列长度),最终形成节点集 N。

节点集 N 包含三种类型的节点,代表通道的三种不同特征:{𝑣1, ..., 𝑣𝑚}、{𝑎1, ..., 𝑎𝑚} 和 {𝑏1, ..., 𝑏𝑚}。

这三种特征节点分别与矩阵表示张量 E 的第一行(项目 ID 特征)、第二行(图像特征)和第三行(文本特征)相关联。

在节点表示初始化期间,e𝑣 是随机初始化的;对于 e𝑎 和 e𝑏,从对应的模态中提取语义特征;

我们的方法不限于图像和文本模态,为了更好的扩展能力,我们使用单独的模型而不是大型视觉语言模型来进行特征提取。 图像特征 e𝑎 是从在 ImageNet 上预训练的 ResNet-50 模型获得的,而文本特征 e𝑏 是使用预训练的 T-5 模型提取。

该方案可以表示为 "modality 𝑎 ⇒ representation e𝑎(同样适用于𝑏)。

2、Node transformation and compositions(节点的变换和组合)

根据Hou等人的研究,将文本编码与项目表示紧密结合可能是有害的。因此,作者没有将每个模态作为单独的节点使用,而是使用一种叫做“modality codes模态编码”的方式替代原先节点。

“These nodes correspond to discrete indices obtained by mapping the original modality features”

这些节点通过对原始模态特征进行映射,从而获得对应的离散索引。

这种方法有助于缓解项目模态和项目表示之间的紧密绑定。节点利用这些索引来查找嵌入编码表,从而得到名为“modality 𝑎 ⇒ code 𝐼𝐷𝑎⇒ representation e𝑎 ≃ e𝐼𝐷𝑎的方案

为了实现这一点,我们使用线性自动编码器来压缩图像/文本特征向量(为了降维减少计算量)

然后使用K-means按照不同的模态类型对相应的模态特征向量进行聚类。(模型可以学习到模态特征之间的相似性和差异性)

聚类中心的索引则作为code 𝐼𝐷𝑎,初始的 e𝐼𝐷𝑎 则是从这些聚类中心得到的。

我们不仅仅将每个项目模态视为一个独立的索引,还采用了组合技术;这不仅可以将多个模态映射到单个代码,也可以将单个模态映射到多个代码。

使用聚类中心索引作为模态编码的原因:

离散化:聚类中心索引提供了一种将连续的模态特征向量转换为离散编码的方法。

减少重复:在图中,同一模态的不同实例(项目1的𝑎和项目2的𝑎)可能会有非常相似的特征。通过使用聚类中心索引,可以将这些相似的实例映射到相同的模态编码,从而减少图中的重复节点,降低图的稀疏性,增强图的连通性提高计算效率。

保持语义信息:聚类中心通常代表了一类模态特征的典型特征。使用这些中心的索引作为模态编码,可以保留模态特征的语义信息,同时减少特征空间的维度。

例如,𝑎1和𝑎2都可以在图中共享一个公共模态节点,并且𝑎1可以对应于由𝐼𝐷𝑎1每个单独模态表示的多个代码。通过这样做,我们显著增强了每个MSGraph中特征的连通性。 为了实现这一点,我们将每个模态通道聚类为C类,并选择离聚类中心最近的K个节点作为每个单独模态相应的代码集。选择的过程是基于模态特征向量和聚类中心向量之间的余弦相似度。  这里的 K 是一个超参数,它决定着每个模态所连接的代码数量。 为了简洁起见,我们将模态代码称为模态。

3、Edges and Relation Types(图的边以及关系类型)

在MSGraphs中,我们将边指定为节点之间的关系E,包括同质关系Eℎ𝑜𝑚𝑜和异构关系Eℎ𝑒𝑡𝑒。

两者都可以表示为 E : (𝑛𝑠, 𝑟, 𝑛𝑜),表示主节点 𝑛𝑠 和宾语节点 𝑛𝑜 之间的关系 𝑟(其中𝑛 属于 N)。

在同质关系 Eℎ𝑜𝑚𝑜 中,𝑛𝑠𝑛𝑜 应该属于同一类型的节点,例如都包含项 (𝑣, 𝑟, 𝑣) 或 (𝑎, 𝑟, 𝑎)。

在异构关系Eℎ𝑒𝑡𝑒中,𝑛𝑠𝑛𝑜则属于不同的节点类型,如(𝑣,𝑟,𝑎)或(𝑎,𝑟,𝑏)。

𝑟 ∈ R 包含 3 种类型的顺序关系:transition是指序列中直接相邻的关系

transition-in, transition-out, and bi-directional transitions(转入、转出和双向转换)

举个例子:如果在项目 B 之前选择项目 A(也就是说已经选择了A),则从 A 到 B 是转出关系,而从 B 到 A 是转入关系。

对于不同的模态,我们还按照序列顺序在相邻的节点之间建立直接的连接。如果两个模态之间存在来回关系,我们将其标记为双向关系。此外,对于同一项目不同特征通道而言,只会存在一种关系r;并且我们还为每个节点引入了自循环关系,以保留其原始信息。

4、Node Representation(节点表示)

在MSGraph中,每个节点都被指定为一个独立的表示。然而,图在对顺序任务建模时带来了挑战,因为它们破坏了固有的顺序性质;当图由于重复节点而无法重构序列时,这个问题很明显,特别是当模态编码会加剧这种重复。此外,不同节点类型对序列内用户偏好的影响可能会有所不同;例如,图像对用户偏好的短期影响可能比文本更明显。

作者提出了一种解决方案,将位置嵌入和节点类型嵌入集成到每个节点的初始化表示e𝑛中,此外,节点在序列中的位置由一组位置索引捕获,因为模态节点将占据多个位置。 每个位置索引对应于一个单独的嵌入,位置嵌入 epo𝑛 是通过对这些嵌入求平均而获得的。 该平均向量指示节点相对于序列的开头或结尾的位置偏差。

最后,节点表示为,其中𝑊是用于拼接嵌入向量的权重参数。

5、Representation Propagation Layers(传播层的表示)

给定用户图 G𝑢 ,其下一步的传播需要聚合每个节点的邻居信息。 这个过程也可以被称为模态融合,同时考虑模态之间的顺序和相互依赖性。

5.1、Synchronous Graph Neural Networks(同步图神经网络)

 最直观的想法是使用图神经网络将节点信息同步融合在一起,这里的同步是指所有节点从上一层到下一层同时更新,没有特定的顺序。我们将中心节点表示为 𝑛𝑖 ,将它在图中对应的邻居集表示为 𝑁𝑖 。聚合器将每个节点的表示,从上一层hi(L)迭代更新到下一层hi(L+1)。其中hi(0)被节点~ei初始化。

以下是最先进的图聚合器的示例,作为促进同步信息传播的潜在候选者。

1)GCNAggregator(图卷积网络聚合器)

考虑中心节点的邻域信息并使用卷积运算对其进行聚合。 其公式表示如下:

其中𝜎和𝑊(L)是第L层的激活函数和变换矩阵;𝑑(𝑖, 𝑗) = 1/ √︁ |𝑁𝑖 ||𝑁𝑗 |是归一化因子;如下图所示

2)GATAggregator(图注意力网络聚合器)

进一步考虑每个邻居对中心节点有不同影响,结合注意力机制为邻居分配不同的权重。公式如下:

𝛼ij(L)表示第L层的节点 𝑖 和节点 𝑗 之间的注意力分数;主要流程为:线性变化、特征拼接、点积计算和softmax归一化

首先,节点 i 和节点 j 的特征向量会与矩阵权重W(L)进行线性变换,将两个节点的原始特征映射到一个新的特征空间中;

接着,节点 i 和 j 经过线性变换后的特征向量会被拼接在一起。这个拼接的操作是为了将两个节点的信息组合起来,以便后续计算它们之间的相互作用;

然后,会使用一个可学习的权重向量 a 与拼接后的特征向量进行点积(dot product)。点积是一种衡量两个向量间相似度的运算,结果越大表示两个节点越相似,从而在更新节点状态时给予更多的关注;

最后,点积的结果会通过softmax函数进行处理。Softmax函数可以将点积的结果转换为一个概率分布,使得所有邻居节点的注意力权重加起来等于1。这样,每个邻居节点的权重都在0到1之间,反映了它们在更新节点状态时的相对重要性。

用一个简洁的公式表示就是:

5.2、Our Graph Neural Network(图神经网络)重点!!!!!

使用上述图神经网络存在一些缺点:

首先,对于 3 种类型的节点(项目ID节点、图像节点和文本节点)和 5 种类型的关系(项目ID间的顺序关系、图像模态内的顺序关系、文本模态内的顺序关系、项目ID与图像之间的相互依赖关系和项目ID与文本之间的相互依赖关系),应考虑两者的异质性。

其次,如前所述,融合的顺序很重要,因此同步更新并不是最优的。一些先验的模态信息可能对相应的项目表示更有利,因此应该首先合并。

第三,项目、图像和文本节点的表示不在同一空间,因此不适合直接融合它们。

不同模态的包含信息可能会干扰彼此的表征,从而导致侵入性融合问题;此问题在聚合期间也仍然存在。 基于这些考虑,作者提出了一种Heterogeneity-aware, Asynchronous, and Non-invasive graph neural network(异构感知、异步更新、非侵入性图神经网络,简称 HAN-GNN)

1)Heterogeneity-aware,异构感知

为了聚合同质和异构邻居节点,作者采用分而治之的策略。

对于同质节点 𝑛𝑗 ε 𝑁𝑖,𝑛𝑗表示通过边 (𝑛𝑖, 𝑟, 𝑛𝑗 ) ε Eℎ𝑜𝑚𝑜 连接到中心节点 𝑛𝑖 的邻居节点,其类型相同 𝑡𝑗 = 𝑡𝑖(𝑡属于三个通道的索引),Eℎ𝑜𝑚𝑜表示图中所有同质关系的集合,Eℎ𝑒𝑡𝑒表示图中所有异构关系的集合。

对于异构节点 𝑛𝑗 ∈ 𝑁𝑖 且 𝑡𝑗 ≠ 𝑡𝑖,它们代表与中心节点类型不同的邻居节点。这些节点通过边连接 (𝑛𝑖, 𝑟, 𝑛𝑗) ∈ Eℎ𝑒𝑡𝑒。

中心节点 𝑛𝑖 是指在图神经网络的某次迭代中被更新的节点。在每次迭代中,中心节点会收集来自其邻居节点的信息。

GCN/GAT 使用权重矩阵 𝑊 进行分层聚合,从而将原始隐藏向量 ℎ 转换为值向量,而作者的方法是通过建立 WQ、WK 和 WV将原始向量分别转换为查询(query)、键(key)和值(value)向量。并且考虑到三种不同的节点类型𝑡,指定了三组参数(𝑊Q,t,𝑊K,t,𝑊V,t)。

WQ(Query矩阵):用于将节点的原始特征向量转换为查询向量。在注意力机制中,查询向量用于与键向量进行比较,以确定节点间的关系强度。

WK(Key矩阵):用于将节点的原始特征向量转换为键向量。键向量与查询向量一起用于计算注意力系数,这些系数决定了在聚合过程中各个邻居节点的重要性。

WV(Value矩阵):用于将节点的原始特征向量转换为值向量。值向量实际上包含了节点的特征信息,这些信息在计算完注意力系数后被聚合。

为了计算同质节点的注意力,由于它们的共享空间允许直接比较。 因此我们采用基于内容的注意力机制。

对于 (𝑛𝑖, 𝑟, 𝑛 𝑗 ) ∈ Eℎ𝑜𝑚𝑜 ,它们的注意力分数为:

其中 ⊙ 是按元素相乘;𝑡𝑖和𝑡𝑗分别表示𝑛𝑖和𝑛𝑗的类型,在同质节点之间,两者是相同的,因此𝑊V,ti(L)𝑊V,tj(L)也是相同的

关于 Eℎ𝑜𝑚𝑜 中的顺序关系类型,对于节点 𝑛𝑖 和 𝑛𝑗 之间的每个关系 𝑟,我们为每个关系类型定义一个单独的参数 𝑎𝑟

关于这个参数𝑎𝑟,通常是通过训练过程中的反向传播来学习和优化的。这样模型可以根据数据自动调整不同关系类型的重要性,以实现最佳的推荐效果。

对于异构节点的注意力计算,由于异构节点位于不同的特征空间,直接比较它们的特征向量可能没有意义。为了解决这个问题,文章中提到使用类型特定的转换矩阵 𝑊𝑡𝑗≠𝑊𝑡𝑖​​ 来将不同类型节点的特征向量转换到一个共同的空间中。这意味着每个模态或类型的节点都有自己的转换矩阵,用于将其特征向量映射到一个共享的特征空间。

利用键值对注意力来评估节点各自转换后的相关性。 对于 (𝑛𝑖, 𝑟, 𝑛𝑗 ) ∈ Eℎ𝑒𝑡𝑒 ,注意力分数为:

无论同质节点还是异构节点,得到注意力分数后,都使用公式(14)计算最终的注意力权重:

符号*表示ℎ𝑜或ℎ𝑒,分别表示同质或异质信息的个体聚合。

这两个公式合起来不就是transformer的缩放点积注意力吗?

为了融合两种邻居源(同质邻居和异构邻居)的信息,在同质和异构节点的注意力计算完后,一种直接的方法是将它们连接起来并同时更新下一层中的组合表示。拼接后的向量包含了来自不同邻居的组合信息,这个组合的表示将被用作更新当前节点状态的输入。“同时更新”意味着在图神经网络的下一层中,当前节点将直接使用这个拼接后的向量来计算其新的特征表示,而不是分别处理来自不同邻居的信息。

假设一个节点 𝑛𝑖 有两个邻居节点 𝑛𝑗​ 和 𝑛𝑘​,其中 𝑛𝑗​ 是同质邻居(假设与 𝑛𝑖​ 同为图像节点),而 𝑛𝑘是异构邻居(假设是文本节点)。在拼接方法中,𝑛𝑖​ 会收集来自 𝑛𝑗​ 和 𝑛𝑘​ 的特征向量,将它们拼接成一个新向量,然后使用这个新向量在图神经网络的下一层中更新自己的状态。

2)Asynchronous updating异步更新

同步更新忽略了融合顺序的影响。 因此作者提出了一种具有两个定义的更新顺序的异步更新策略。

在每一层中,可以首先聚合同质信息以进行节点更新,然后使用这些更新的表示进行异构信息聚合,或者反之亦然。

作者将这两种不同的更新顺序称为“先同质则后异构”(或ℎ𝑜ℎ𝑒)和“先异构则后同质”(ℎ𝑒ℎ𝑜)。

ℎ𝑜ℎ𝑒为例子,这个两阶段范式可以被表示为hi(L)>hi(L),ho>hi(L),hohe

在第一阶段:同质信息聚合(Homogeneous Aggregation)

节点使用公式14中的同质聚合方法,但是保持层数不变(即不进入下一层)。这意味着,虽然节点的特征被更新,但这个过程被视作在同一层内进行。

第二阶段:异质信息聚合(Heterogeneous Aggregation)

节点接着聚合来自异质邻居的信息,使用的是公式14中的异构聚合,此时输入的是第一阶段的输出,而不是原始节点特征,输出的信息则会进入下一层

如下图所示,在 HAN-GNN 中,不同类型节点用不同颜色标识,每个节点都有两条潜在的聚合路由,从 hi(L)hi(L+1)

要么选择 heho 要么选择 hohe 路径。

作者还引入更新门,使用以下门选择机制自适应地选择每个节点的最佳路径,公式为:

3)Non-invasive fusion非侵入性融合

以ℎ𝑒ℎ𝑜,hi(L)—>hi(L),he—>hi(L),heho为例子,具体讲解这个概念。

具体来说,经过第一阶段(不进入下一层)我们得到了hi(L),he信息

在第 2 阶段(进入下一层),理论上应该使用Wv,tj(L) hj(L),he 来聚合来自同质邻居的信息,然而直接使用 hj(L),he 进行聚合可能会导致信息过度融合,从而使特征表示退化。为了解决这个问题,引入了非侵入式融合技术。即使在第二阶段计算注意力时基于中间状态 hj(L),he,但在聚合过程中,仍然使用第一阶段的原始价值向量 Wv,tj(L) hj(L) 而不是 Wv,tj(L) hj(L),he。

Wv,tj(L) hj(L),he  表示节点 𝑗 在第 𝑙 层的变换后的值向量,用于在聚合过程中贡献其信息。

其中ei,j(L),ho是节点 𝑖 和其同质邻居 𝑗 之间的注意力分数,

为什么这样做就算是非侵入式融合?

非侵入式融合的核心在于在聚合过程中尽可能少地修改或“侵入”原始的数据表示。通过在计算注意力时考虑异质信息,但在聚合时坚持使用原始数据,这种方法在利用异质信息增强模型的同时,保持了对原始数据的尊重和保护。这样,模型可以在不牺牲原始数据质量的前提下,有效地整合和利用来自不同模态或类型的信息,从而在复杂任务中实现更好的性能。

6、User Interest Representation and Prediction用户兴趣表示与预测

经过 𝐿 层聚合,得到最终的特征向量 v(𝐿),𝑣∈N𝑣,并且设置项目的隐藏状态集合,形成最终的输出Z ∈ R|N𝑣𝑑

其中 N𝑣 表示节点集的item ID。得到的 Z 可以被认为是经过了模态融合的特征表示。

因此,关键在于输出用户表示 P = P(Z) 的映射函数 P : R|N𝑣𝑑R𝑑,促进对下一项的预测。

根据我们的观察,使用基于图的表示是一个挑战,因为它往往会减少单个项目的影响,从而使区分相似序列变得困难,

为了解决这个问题,我们不使用平均池化,而是采用最后池化,我们从序列中选择最后一项作为池化表示。具体来说,

我们将其表示为P = Z|H𝑢 |

7、Model Comparison & Complexity Analysis模型比较与复杂性分析

与 GCN 的复杂度 𝑂(𝐿|U||E𝑢|) 和 Graphomer 的 𝑂(𝐿|U||N𝑢|2) 相比,HAN-GNN 的复杂度为 𝑂(2𝐿|U||E𝑢|),因为有每层传播有两个阶段(heho或者hohe)。

|U| 表示用户数量,|E𝑢| 和 |N𝑢| 分别表示每个用户图中的平均边数和平均节点数。

虽然 HAN-GNN 比 GCN 等简单的网络更复杂,但与 Graphormer 等更复杂的网络相比,HAN-GNN 的复杂性更低,同时仍然提供卓越的性能。

在用户图中,每个节点按顺序连接到其前后节点,以及至少 2 个其他模态节点;

每个节点有 4 条边,|E𝑢|  = 𝑂(4|N𝑢|) = 𝑂( 4/3 |H𝑢|), |H𝑢| 表示用户的交互序列长度(三种模态进行融合,所以4要除以3)。 因此,当用户历史记录超过 2 × 4/3 = 2.66 时,HAN-GNN 比 Graphomer 更有效。 在平均用户历史长度在 7 到 9 之间变化的典型情况下,我们的方法要高效得多。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

服务器安全,你必须知道的六个知识点

服务器安全 如今没有什么是安全的。各种系统安全漏洞的数量呈爆炸式增长。令人担忧的主要原因之一是服务器安全性。 接下来&#xff0c;就如何提升服务器安全&#xff0c;写几点见解。 虽然很多企业在服务器的安全性方面做了足够多&#xff0c;但是&#xff0c;黑客仍然能够…

Python数据分析与可视化(Python绘图详解)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Qt圆角窗口

Qt圆角窗口 问题&#xff1a;自己重写了一个窗口&#xff0c;发现用qss设置圆角了&#xff0c;但是都不生效&#xff0c;不过子窗口圆角都生效了。 无边框移动窗口 bool eventFilter(QObject *watched, QEvent *evt) {static QPoint mousePoint;static bool mousePressed f…

群晖Docker如何修改配置文件(ContainerManager)

群晖Docker与其他linux操作系统的docker启动方式存在差异,默认的Docker配置文件位置也不一样。所以本章教程,主要介绍如何找到群晖Docker下的默认配置文件。 一、登录SSH 为了方便操作,需要开启SSH,并通过SSH链接到群晖NAS主机。登录之后,切换到root用户 sudo -i二、编辑配…

车载测试项目实操学习:CAN通信测试、UDS诊断测试、自动化测试、功能安全测试、CAN一致性测试、HIL测试:9-20

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xff…

企业文档管理系统哪个好?2024年热门的10款文档管理系统软件推荐

在信息化时代&#xff0c;企业每天都会生成海量的文档、数据和资料。 如何有效管理这些文档&#xff0c;确保信息安全、版本控制和协同办公顺畅&#xff0c;是每个企业都必须面对的挑战。 2024年&#xff0c;随着技术的不断进步&#xff0c;市场上涌现出了众多优秀的文档管理…

Selenium自动化测试环境搭建详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本主要介绍以Java为基础&#xff0c;搭建Selenium自动化测试环境&#xff0c;并且实现代码编写的过程。 1、Selenium介绍 Selenium 1.0 包含 core、IDE、RC、gri…

C++进阶 set和map讲解

set 和 map set 和 multiset set set 类的介绍 set 是基于红黑树实现的有序容器。它的插入、删除、查找操作的时间复杂度均为 O(log n)。遍历时&#xff0c;set 的迭代器按照中序遍历&#xff0c;因此它总是以升序排列元素。 set 的声明如下&#xff0c;T 表示 set 的关键字类…

Kubernetes集群部署(kubernetes)

三台主机恢复到docker快照状态&#xff1b; 检查驱动器类型为sytemd&#xff1b; 设置各个节点的主机名&#xff1b; 然后同步会话&#xff0c;修改hosts文件&#xff1b; 在k8s运行过程中不建议使用交换分区&#xff1b; 关闭交换分区&#xff1b; 但是这种方法是临时性的&am…

JavaSE--零基础的开始笔记02:基础语法--标识符,关键字,变量

一.标识符 Java 语言中&#xff0c;对各种变量、方法和类等要素命名时使用的字符序列称为标识符。 Java 标识符有如下命名规则&#xff1a; 标识符由字母、下划线“_” 、美元符“$”或数字组成。 标识符应以字母、下划线 、美元符开头。 Java 标识符大小写敏感&#xff0c…

【Linux笔记】虚拟机内Linux内容复制到宿主机的Window文件夹(文件)中

一、共享文件夹 I、Windows宿主机上创建一个文件夹 目录&#xff1a;D:\Centos_iso\shared_files II、在VMware中设置共享文件夹 1、打开VMware Workstation 2、选择需要设置的Linux虚拟机&#xff0c;点击“编辑虚拟机设置”。 3、在“选项”标签页中&#xff0c;选择“共…

初识模版!!

初识模版 1.泛型编程1.1 如何实现一个交换函数呢&#xff08;使得所有数据都可以交换&#xff09;&#xff1f;1.2 那可以不可以让编译器根据不同的类型利用该模子来生成代码呢&#xff1f; 2.模版类型2.1 模版概念2.2 函数模版的原理2.3 函数模板的实例化2.4 模板参数的匹配原…

【C++初阶】探索STL之——String类的模拟实现

【C初阶】String类的模拟实现 1.string类2.string类的构造和赋值实现3.类的析构实现4.类的iterator5.类的修改&#xff08;Modify&#xff09;实现6.类的capacity实现7.类access的实现8.类relational operators的实现9.类find、insert、erase的实现10.operator>>和operat…

官方力荐:LDR6020 PD技术,让Type-C接口充放OTG不再是梦!

PD&#xff08;Power Delivery&#xff09;芯片赋能Type-C接口&#xff1a;解锁充电与数据传输的双重魔法 一、PD芯片的科技内核 高速充电与智能数据传输&#xff1a; PD芯片深谙USB Power Delivery规范&#xff0c;支持高功率传输协议&#xff0c;实现快速充电的同时&#x…

数据中台过时了?为什么现在都在说数据飞轮

数据中台作为一种集中式的数据管理与服务平台&#xff0c;在解决企业数据管理困境中发挥着重要作用&#xff0c;如数据孤岛、数据标准化、数据共享与复用等问题。通过统一的数据采集、处理、存储和服务&#xff0c;数据中台构建了一个全局性的数据枢纽&#xff0c;满足各业务部…

【YOLO目标检测道路交通标识数据集】共2838张、已标注txt格式、有训练好的yolov5的模型

目录 说明图片示例 说明 数据集格式&#xff1a;YOLO格式 图片数量&#xff1a;2838 标注数量(txt文件个数)&#xff1a;2838 标注类别数&#xff1a;56 标注类别名称&#xff1a; mand_straight forb_right prio_priority_road info_crosswalk forb_weight_over_3.5t inf…

亿发工单系统:让任务风平浪静

在现代企业的日常运营中&#xff0c;工单管理系统已经成为必不可少的工具&#xff0c;无论是生产制造、IT运维&#xff0c;还是客服支持&#xff0c;工单系统的存在都是为了高效处理任务、跟踪进展、分配资源。然而&#xff0c;现实中的工单管理&#xff0c;往往不是“风平浪静…

【FPGA】编程方式

FPGA编程方式 1 什么是PLD&#xff1f;2 什么是颗粒度&#xff1f;3 可编程逻辑器件的编程方式有哪些&#xff1f;3.1 SRAM 编程技术3.2 Flash/EEPROM 编程技术3.3 反熔丝编程技术3.4 编程技术比较 参考资料 1 什么是PLD&#xff1f; 可编程逻辑器件 英文全称为&#xff1a;pr…

Cocos Creator3.x设置动态加载背景图并且循环移动

效果图 项目结构 项目层级结构&#xff1a; 预制&#xff1a; 代码 import { _decorator, CCFloat, Component, Node, Sprite, instantiate, Prefab, assert } from cc; const { ccclass, property } _decorator;/*** 背景脚本*/ ccclass(Background) export class Backg…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL19

使用3-8译码器①实现逻辑函数 描述 下表是74HC138译码器的功能表. E3 E2_n E1_n A2 A1 A0 Y0_n Y1_n Y2_n Y3_n Y4_n Y5_n Y6_n Y7_n x 1 x x x x 1 1 1 1 1 1 1 1 x x 1 x x x 1 1 1 1 1 1 1 1 0 x x x x x 1 1 1 1 1 …