【论文笔记】Contrastive Learning for Sign Language Recognition and Translation

🍎个人主页:小嗷犬的个人主页
🍊个人网站:小嗷犬的技术小站
🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。
基本信息
标题: Contrastive Learning for Sign Language Recognition and Translation
作者: Shiwei Gan, Yafeng Yin, Zhiwei Jiang, K. Xia, Linfu Xie, Sanglu Lu
发表: IJCAI 2023
摘要
当前端到端手语处理架构中广泛存在两个问题。一个是 CTC 尖峰 现象,这削弱了连续手语识别(CSLR)中的视觉表征能力。另一个是 暴露偏差 问题,这导致在手语翻译(SLT)推理过程中翻译错误的累积。
在这篇论文中,我们通过引入对比学习来解决这些问题,旨在增强视觉级特征表示和语义级错误容忍度。
具体来说,为了缓解 CTC 尖峰现象并增强视觉级表示,我们设计了一种视觉对比损失,通过最小化同一手语视频中不同增强样本帧之间的视觉特征距离,从而使模型能够进一步探索特征,利用大量未标记的帧以无监督的方式。
为了缓解暴露偏差问题并提高语义级错误容忍度,我们设计了一种语义对比损失,通过将预测的句子重新输入到语义模块,并比较真实序列和预测序列的特征,使模型暴露于自身的错误中。
此外,我们提出了两种新的指标,即空白率和连续错误词率,直接反映我们在两个问题上的改进。在当前手语数据集上的广泛实验结果证明了我们方法的有效性,该方法达到了最先进的性能。
主要贡献
- 为了缓解 CSLR 中的 CTC 尖峰现象并增强视觉级特征表示,我们提出了一种视觉对比损失,通过利用大量未标记的帧来探索特征。
- 为了缓解 SLT 中的暴露偏差问题并提高语义级错误容忍度,我们提出了一种语义对比损失,通过将预测序列重新输入到语义模块中,使模型暴露于自身的翻译错误。
- 提出了两种新的指标,即空白率和连续错误词率,以反映我们在两个问题上的改进。
- 广泛的实验表明,所提出的损失函数和框架在 CSLR 和 SLT 上达到了最先进的性能。
方法
在这一节中,我们首先概述了我们的框架。然后,我们简单地描述了 CSLR 中的 CTC 尖峰现象,并提出了一种增强视觉表示的可视对比损失。
接着,我们描述了 SLT 中的暴露偏差问题,并提出了一种增强语义层错误容忍度的语义对比损失。最后,我们设计了联合损失,以训练我们的模型同时适用于 CSLR 和 SLT。
总体框架
对于一个包含 n n n 帧的手语视频 f = { f i } i = 1 n f=\{f_i\}_{i=1}^n f={fi}i=1n,CSLR 的目标是学习从 f f f 到 g = { g i } i = 1 ϑ g=\{g_i\}_{i=1}^\vartheta g={gi}i=1ϑ 的映射,其中 g g g 包含 ϑ \vartheta ϑ 个手语符号,而 SLT 的目标是将 f f f 翻译成包含 t t t 个单词的口语句子 w = { w i } i = 1 t w=\{w_i\}_{i=1}^t w={wi}i=1t。
如图 1 所示,CSLR 和 SLT 的过程可以简化如下。
视觉特征提取
视觉模块 V E \mathcal{VE} VE 处理帧以获得视觉特征 v = V E ( f ) v=\mathcal{VE}(f) v=VE(f),其中 v v v 包含 m m m 个向量, v = { v i ∈ R d v } i = 1 m v=\{v_i \in \mathbb{R}^{d_v}\}_{i=1}^m v={vi∈Rdv}i=1m( m ≤ n m \leq n m≤n), d v d_v dv 是 v i v_i vi 的维度。
时间特征提取
时间模块 T E \mathcal{TE} TE 从 v v v 中提取全局上下文信息以获得 u = T E ( v ) u=\mathcal{TE}(v) u=TE(v),其中 u = { u i ∈ R d t } i = 1 m u=\{u_i \in \mathbb{R}^{d_t}\}_{i=1}^m u={ui∈Rdt}i=1m, d t d_t dt 是 u i u_i ui 的维度。
识别和翻译
对于 CSLR,添加了一个全连接层,权重为 W r W_r Wr 和偏差 b r b_r br,以及一个 softmax 层 S M SM SM,以获得识别的手语序列的最终概率矩阵: R = S M ( W r ∗ u + b r ) R = SM(W_r *u + b_r) R=SM(Wr∗u+br)。
对于SLT,需要一个 RNN-like 或 transformer 解码器 S E SE SE,以获得第 i i i 步的翻译概率矩阵: Y i = S M ( W y ∗ S E ( u , { y j } j = 0 i − 1 ) + b y ) Y_i = SM(W_y*\mathcal{SE}(u, \{y_j\}_{j=0}^{i-1}) + b_y) Yi=SM(Wy∗SE(u,{yj}j=0i−1)+by) 中, W y W_y Wy 和 b y b_y by 是语义模块中全连接层的权重和偏差。
视觉级对比学习用于 CTC 尖峰现象
CTC 尖峰现象
在 CSLR 中,CTC 损失通过最大化所有可能路径的概率来解决未分段手语视频的时间分类问题,这些路径将帧与标记的 gloss 序列 g g g 在概率矩阵 R \mathbf{R} R 中对齐。
理想情况下,有必要为每一帧标注一个特定的类别。然而,考虑到无意义的帧和连续出现的相同 gloss,CTC 引入了 blank
token,并进一步定义了一个多对一映射 B \mathcal{B} B,该映射简单地从路径中删除所有重复的 token 和 blank
(例如,在图 2 中, B ( P a t h B ) = B ( a − a a − ) = a a \mathcal{B}(PathB) = \mathcal{B}(a-aa-) = aa B(PathB)=B(a−aa−)=aa)。因此,CTC损失可以形式化如下:
L C T C ( R , g ) = − ∑ π ∈ B − 1 ( g ) log ( p ( π ) ) \mathcal{L}_{CTC}(\mathbf{R}, g) = -\sum_{\pi \in \mathcal{B}^{-1}(g)} \log(p(\pi)) LCTC(R,g)=−π∈B−1(g)∑log(p(π))
其中 p ( π ) = ∏ i = 1 m R i π i p(\pi) = \prod_{i=1}^{m} \mathbf{R}_i^{\pi_i} p(π)=∏i=1mRiπi, π \pi π 表示一个对齐路径(即, B ( π ) = g \mathcal{B}(\pi) = g B(π)=g),而 R i π i \mathbf{R}_i^{\pi_i} Riπi 是第 i i i 个 token π i \pi_i πi 的概率。
然而,CTC 损失会导致尖峰现象。如图 2 所示,当模型无法自信地区分手势边界时,它倾向于将帧分类为 blank
token,因为预测 blank
token 是减少损失 L C T C \mathcal{L}_{CTC} LCTC 的更安全选择。例如, B ( P a t h A ) = B ( a a a b b ) = a b \mathcal{B}(PathA) = \mathcal{B}(aaabb) = ab B(PathA)=B(aaabb)=ab 和 B ( P a t h C ) = B ( − a − − b ) = a b \mathcal{B}(PathC) = \mathcal{B}(-a--b) = ab B(PathC)=B(−a−−b)=ab 都是标签序列 ‘ab’ 的正确路径,而 CTC 偏好 PathC 而不是 PathA ,这导致只有少数帧对最终结果有贡献。由于在训练过程中大多数帧被分类为 blank
token,视觉模块没有得到充分训练,无法在测试集上提供有效的手语特征。
视觉级的对比学习
为了应对尖峰现象,我们的直观想法是通过使用更多数据训练视觉模块来增强视觉表示能力。
然而,与图像分类任务(ResNet 使用的 128 万张标记图像)或 NLP 任务(Transformer 使用的 450 万句对)不同,当前手语任务中的数据对(视频-手势对或视频-句子对)相当有限,通过手动标记每一帧来增加样本以单独训练视觉模块是不现实的。
但是,手语视频提供的未标记帧是丰富的,例如,Phoenix14 训练集中的 5672 个样本提供了 963,664 帧,Phoenix14T 训练集中的 7096 个样本提供了 827,354 帧。
因此,我们引入了视觉级的对比学习,通过比较同一手势视频的不同增强视图的视觉特征,使得视觉模块能够以无监督的方式进一步探索大量未标记帧中的特征。
为了构建视觉对比损失,我们首先需要从包含 n n n 个未标记帧的手势视频 f = { f i } i = 1 n f=\{f_i\}^n_{i=1} f={fi}i=1n 生成两个增强视频。
如图 3 所示,我们引入两种不同的增强:软增强 S A \mathcal{SA} SA 和硬增强 H A \mathcal{HA} HA,以获得增强视频 f s f^s fs 和 f h f^h fh,
f s = S A ( f ) , f h = H A ( f ) f^s = \mathcal{SA}(f), \quad f^h = \mathcal{HA}(f) fs=SA(f),fh=HA(f)
然后,视觉模块 V E \mathcal{VE} VE 将两个增强视频映射到帧级别的视觉特征向量 v s = { v i s } i = 1 m v^s=\{v_i^s\}^m_{i=1} vs={vis}i=1m 和 v h = { v i h } i m = 1 v^h=\{v_i^h\}^m_i=1 vh={vih}im=1,如下所示。
v s = V E ( f s ) , v h = V E ( f h ) v^s = \mathcal{VE}(f^s), \quad v^h = \mathcal{VE}(f^h) vs=VE(fs),vh=VE(fh)
接下来,如图 3 所示,一个投影 MLP 头 P R O v i \mathcal{PRO}_{vi} PROvi 和一个预测 MLP 头 P R E v i \mathcal{PRE}_{vi} PREvi 被附加到将视觉特征映射到应用对比损失的空间。
z s = P R O v i ( v s ) , z h = P R O v i ( v h ) z^s = \mathcal{PRO}_{vi}(v^s), \quad z^h = \mathcal{PRO}_{vi}(v^h) zs=PROvi(vs),zh=PROvi(vh)
p s = P R E v i ( z s ) p^s = \mathcal{PRE}_{vi}(z^s) ps=PREvi(zs)
在得到 p s p^s ps 和 z h z^h zh 后,我们的相似性函数 S \mathcal{S} S 计算每个 p s p^s ps 和 z h z^h zh 在帧级别的负余弦相似性,如下所示。这里, ∣ ∣ ⋅ ∣ ∣ 2 ||\cdot||_2 ∣∣⋅∣∣2 是 ℓ 2 ℓ_2 ℓ2 范数。
S ( p i s , z i h ) = − p i s ∣ ∣ p i s ∣ ∣ 2 ⋅ z i h ∣ ∣ z i h ∣ ∣ 2 \mathcal{S}(p_i^s, z_i^h) = -\frac{p_i^s}{||p_i^s||_2} \cdot \frac{z_i^h}{||z_i^h||_2} S(pis,zih)=−∣∣pis∣∣2pis⋅∣∣zih∣∣2zih
当使用 S \mathcal{S} S 计算 p s p^s ps 和 z h z^h zh 的相似性时,我们可以得到所有帧的平均损失,如下所示。
S ( p s , z h ) = 1 m ∑ i = 1 m S ( p i s , z i h ) \mathcal{S}(p^s, z^h) = \frac{1}{m} \sum_{i=1}^{m} \mathcal{S}(p_i^s, z_i^h) S(ps,zh)=m1i=1∑mS(pis,zih)
最后,遵循 SimSiam,我们进一步以对称方式获得 p h = P R E v i ( z h ) p^h=\mathcal{PRE}_{vi}(z^h) ph=PREvi(zh),并定义对称化的视觉对比损失 L V i C o \mathcal{L}_{ViCo} LViCo 如下,
L V i C o = S ( p s , d e t a c h ( z h ) ) + S ( p h , d e t a c h ( z s ) ) 2 \mathcal{L}_{ViCo} = \frac{\mathcal{S}(p^s, detach(z^h)) + \mathcal{S}(p^h, detach(z^s))}{2} LViCo=2S(ps,detach(zh))+S(ph,detach(zs))
其中 d e t a c h ( ⋅ ) detach(\cdot) detach(⋅) 函数表示停止梯度操作,这意味着 z h z^h zh 和 z s z^s zs 被视为常量而不是具有梯度的变量。
语义级对比学习以解决暴露偏差
暴露偏差
在 SLT 中,seq2seq 架构(更精确地说是自回归架构)通常通过最大似然估计(MLE)进行训练。
如图 4 所示,以 RNN 类解码器为例,基于 MLE 的训练通过最大化下一个词 y i y_i yi 基于其前一个真实词 w i − 1 w_{i-1} wi−1(称为 teacher forcing)的概率来进行优化,如下所示。
这里, θ \theta θ 表示模型参数, θ ∗ \theta^* θ∗ 表示更新后的参数, h i − 1 h_{i-1} hi−1 是语义模块的第 ( i − 1 ) (i-1) (i−1) 个隐藏状态, u u u 表示时间特征。
θ ∗ = arg max θ ∏ i = 1 t P θ ( y i ∣ w i − 1 , h i − 1 , u ) \theta^* = \argmax_\theta \prod_{i=1}^{t} P_\theta(y_i | w_{i-1}, h_{i-1}, u) θ∗=θargmaxi=1∏tPθ(yi∣wi−1,hi−1,u)
而在推理阶段,模型需要根据自身生成的前缀词 y i − 1 y_{i-1} yi−1 来预测 Y i y i Y_i^{y_i} Yiyi(即词 y i y_i yi 的概率)。
Y i y i = P θ ∗ ( y i ∣ y i − 1 , h i − 1 , u ) Y_i^{y_i} = P_{\theta^*}(y_i | y_{i-1}, h_{i-1}, u) Yiyi=Pθ∗(yi∣yi−1,hi−1,u)
由于在训练过程中接触到了真实数据,模型可能会过度依赖正确的前缀词。而在推理过程中,错误预测的词 y i − 1 y_{i-1} yi−1 可能会加剧沿生成序列的误差传播,模型生成的目标概率分布将逐渐扭曲(称为暴露偏差)。暴露偏差会导致性能显著下降,尤其是在训练样本的序列分布不足以覆盖测试样本的序列分布时。
语义级对比学习
为了解决暴露偏差问题,最直接的解决方案是计划采样。计划采样在训练过程中决定是否以概率 α α α 使用真实词 w i − 1 w_{i-1} wi−1 或预测词 y i − 1 y_{i-1} yi−1。通过这种方式,模型可以通过暴露其自身的错误来削弱对真实词的依赖。
然而,直接将计划采样应用于 Transformer 模型并不简单,因为与 RNN 类解码器不同,Transformer 基于整个前缀序列 { y j } j = 0 i − 1 \{y_j\}_{j=0}^{i-1} {yj}j=0i−1 而不是最后一个词 y i − 1 y_{i-1} yi−1 生成第 i i i 个词。
此外,计划采样训练是一个随时间进行的顺序过程,因此阻碍了并行训练。
在这篇论文中,遵循让模型暴露自身错误的相同理念,我们通过比较语义模块(即解码器模块)中不同输入(真实序列输入和预测序列输入)的语义特征来引入语义级对比学习,以减轻暴露偏差。
与计划采样相比,我们的方法可以用于 RNN 类解码器和 Transformer 解码器,并且可以轻松并行训练。
为了构建语义对比损失,我们首先需要基于真实句子 w w w 获得翻译句子 y y y。具体来说,对于时间特征 u = { u i } i = 1 m u=\{u_i\}_{i=1}^m u={ui}i=1m,语义模块 S E \mathcal{SE} SE 将 u u u 和 w w w 作为输入以获得语义特征(即隐藏状态) h w h^w hw,
h w = S E ( u , w ) h^w = \mathcal{SE}(u, w) hw=SE(u,w)
然后,采用全连接层和 softmax 函数 S M \mathcal{SM} SM 来获得翻译句子的可能性矩阵 Y \mathbf{Y} Y,并通过 argmax 操作进一步获得翻译句子 y y y,
Y = S M ( W y ∗ h w + b y ) \mathbf{Y} = \mathcal{SM}(W_y * h^w + b_y) Y=SM(Wy∗hw+by)
y = argmax ( Y ) y = \text{argmax}(\mathbf{Y}) y=argmax(Y)
之后,如图 5 所示,我们将预测的句子 y y y 重新输入到语义模块中以获得另一个语义特征 h y h^y hy,如下所示。这里,重新输入预测序列 y y y 可以被视为重新输入增强的真实词 w w w,也可以被视为一种计划采样的形式。
h y = S E ( u , y ) h^y = \mathcal{SE}(u, y) hy=SE(u,y)
接下来,类似于图 3 中的视觉模块,添加了一个投影 MLP 头 P R O s e \mathcal{PRO}_{se} PROse 和一个预测 MLP 头 P R E s e \mathcal{PRE}_{se} PREse 以获得 ρ w \rho^w ρw 和 ξ w \xi^w ξw。此外,采用了相似性函数 S \mathcal{S} S 来计算 ρ w \rho^w ρw 和 ξ g \xi^g ξg 之间的距离,
ρ w = P R O s e ( h w ) , ρ y = P R O s e ( h y ) \rho^w = \mathcal{PRO}_{se}(h^w), \quad \rho^y = \mathcal{PRO}_{se}(h^y) ρw=PROse(hw),ρy=PROse(hy)
ξ w = P R E s e ( ρ w ) \xi^w = \mathcal{PRE}_{se}(\rho^w) ξw=PREse(ρw)
最后,我们也得到 ξ y = P R E s e ( ρ y ) \xi^y = \mathcal{PRE}_{se}(\rho^y) ξy=PREse(ρy),并定义对称化的语义对比损失 L S e C o \mathcal{L}_{SeCo} LSeCo 如下,
L S e C o = S ( ξ w , detach ( ρ y ) ) + S ( ξ y , detach ( ρ w ) ) 2 \mathcal{L}_{SeCo} = \frac{\mathcal{S}(\xi^w, \text{detach}(\rho^y)) + \mathcal{S}(\xi^y, \text{detach}(\rho^w))}{2} LSeCo=2S(ξw,detach(ρy))+S(ξy,detach(ρw))
CSLR 和 SLT 的联合损失
为了使用提议的对比损失优化我们的模型,我们需要基于不同的输入两次推断我们的模型 M O \mathcal{MO} MO。一种包含软增强视频 f s f_s fs 和标记的词序列 w w w。另一种包含硬增强视频 f h f^h fh 和预测的词序列 y y y,其中 y = arg max ( Y ) y = \arg\max(\mathbf{Y}) y=argmax(Y)。
R , Y , ( p s , z s ) , ( ρ w , ξ w ) = M O ( f s , w ) \mathbf{R}, \mathbf{Y}, (p^s, z^s), (\rho^w, \xi^w) = \mathcal{MO}(f^s, w) R,Y,(ps,zs),(ρw,ξw)=MO(fs,w)
R ′ , Y ′ , ( p h , z h ) , ( ρ y , ξ y ) = M O ( f h , y ) \mathbf{R}', \mathbf{Y}', (p^h, z^h), (\rho^y, \xi^y) = \mathcal{MO}(f^h, y) R′,Y′,(ph,zh),(ρy,ξy)=MO(fh,y)
在获得 ( p s , z s , p h , z h ) , ( ξ w , ρ w , ρ y , ξ y ) (p^s, z^s, p^h, z^h), (\xi^w, \rho^w, \rho^y, \xi^y) (ps,zs,ph,zh),(ξw,ρw,ρy,ξy) 后,我们可以分别计算对比损失 L V i C o , L S e C o \mathcal{L}_{ViCo}, \mathcal{L}_{SeCo} LViCo,LSeCo。同时,我们得到两个识别概率矩阵 R , R ′ \mathbf{R}, \mathbf{R}' R,R′ 和两个翻译概率矩阵 Y , Y ′ \mathbf{Y}, \mathbf{Y}' Y,Y′。为了实现 CSLR 和 SLT 的联合目标,我们采用 CTC 损失 L C T C \mathcal{L}_{CTC} LCTC 和交叉熵损失 L C E \mathcal{L}_{CE} LCE 来训练我们的模型,如下所示,
L s o f t = L C T C ( R , g ) + L C E ( Y , w ) \mathcal{L}_{soft} = \mathcal{L}_{CTC}(\mathbf{R}, g) + \mathcal{L}_{CE}(\mathbf{Y}, w) Lsoft=LCTC(R,g)+LCE(Y,w)
L h a r d = L C T C ( R ′ , g ) + L C E ( Y ′ , w ) \mathcal{L}_{hard} = \mathcal{L}_{CTC}(\mathbf{R}', g) + \mathcal{L}_{CE}(\mathbf{Y}', w) Lhard=LCTC(R′,g)+LCE(Y′,w)
最后,我们得到带有平衡权重 α \alpha α 的联合损失 L \mathcal{L} L,其中 α \alpha α 是一个超参数,如下所示,
L = L s o f t + L h a r d + α ( L V i C o + L S e C o ) \mathcal{L} = \mathcal{L}_{soft} + \mathcal{L}_{hard} + \alpha (\mathcal{L}_{ViCo} + \mathcal{L}_{SeCo}) L=Lsoft+Lhard+α(LViCo+LSeCo)
实验
空白率和连续错误词率
为了验证我们的方法是否能够有效处理 CTC 尖峰现象和暴露偏差问题,我们提出了两个新的指标:空白率( B R BR BR)和连续错误词率( C W W R CWWR CWWR)。
B R BR BR 是一个直接反映尖峰现象严重程度的指标,可以表示为以下形式:
B R = # B l a n k # T o t a l R BR = \frac{\#Blank}{\#TotalR} BR=#TotalR#Blank
其中 # B l a n k \#Blank #Blank 表示识别序列中 blank
token 的数量,而 # T o t a l R \#TotalR #TotalR 表示识别序列中所有 token 的总数。
C W W R CWWR CWWR 是一个直接反映模型在翻译中依赖先前预测词汇程度的指标,可以表示为以下公式:
C W W R = ∑ # C W # T o t a l T CWWR = \frac{\sum \#CW}{\#TotalT} CWWR=#TotalT∑#CW
其中 # C W \#CW #CW 表示连续错误单词的数量,而 # T o t a l T \#TotalT #TotalT 表示翻译序列中单词的总数。
主实验
消融实验
总结
在这篇论文中,我们引入对比学习来解决手语任务中广泛存在的两个问题:连续手语识别(CSLR)任务中的 CTC 尖峰现象和手语翻译(SLT)任务中的暴露偏差。
具体来说,为了解决 CTC 尖峰现象,我们设计了一种视觉对比损失,通过从大量未标记的帧中学习特征来增强视觉模块。
为了解决暴露偏差问题,我们设计了一种语义对比损失,通过让模型暴露在自己的错误中来增强语义模块。
此外,我们提出了两种新的指标,即空白率(Blank Rate)和连续错误词率(Consecutive Wrong Word Rate),以直接反映我们在两个问题上的改进。
在公共手语数据集上的实验结果证明了我们方法的有效性。
相关文章:
【论文笔记】Contrastive Learning for Sign Language Recognition and Translation
🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: Contrastive Learning for…...
《C++设计模式》策略模式
文章目录 1、引言1.1 什么是策略模式1.2 策略模式的应用场景1.3 本文结构概览 2、策略模式的基本概念2.1 定义与结构2.2 核心角色解析2.2.1 策略接口(Strategy)2.2.2 具体策略实现(ConcreteStrategy)2.2.3 上下文(Cont…...
细说STM32F407单片机轮询方式CAN通信
目录 一、项目介绍 二、项目配置 1、时钟、DEBUG、USART6、NVIC、GPIO、CodeGenerator 2、CAN1 (1)Bit Timings Parameters组,位时序参数 (2)Basic Parameters组,基本参数 (3)…...
perf:对hutool的BeanUtil工具类做补充
分享一个自定义的BeanUtil,继承的是hutool的工具类,然后自己扩充了几个方法; 1、实现了两个对象覆盖非空属性的功能(经常使用),不需要设置CopyOptions; 2、两个对象,对指定前缀的属…...
【数据结构】栈与队列(FIFO)
在阅读该篇文章之前,可以先了解一下堆栈寄存器和栈帧的运作原理:<【操作系统】堆栈寄存器sp详解以及栈帧>。 栈(FILO) 特性: 栈区的存储遵循着先进后出的原则。 例子: 枪的弹夹,最先装进去的子弹最后射出来,最后装入的子弹…...
02.01、移除重复节点
02.01、[简单] 移除重复节点 1、题目描述 编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。 2、解题思路 为了实现这一目标,我们可以使用一个哈希表(或集合)来记录已经遇到的节点值,逐步遍历链表并删…...
Spring thymeleaf 的快速默认搭建使用
Spring thymeleaf 的快速默认搭建使用 thymeleaf 的搭建Pom 文件 thymeleaf 的使用Controller返回参数String资源文件路径访问端点显示HTML页面 thymeleaf 的搭建 Pom 文件 Pom 文件引入 spring-boot-starter-thymeleaf 依赖 <dependency><groupId>org.springfra…...
unity学习3:如何从github下载开源的unity项目
目录 1 网上别人提供的一些github的unity项目 2 如何下载github上的开源项目呢? 2.1.0 下载工具 2.1.1 下载方法1 2.1.2 下载方法2(适合内部项目) 2.1.3 第1个项目 和第4项目 的比较 第1个项目 第2个项目 第3个项目 2.1.4 下载方法…...
印象笔记07——试一试PDF标注
印象笔记07——试一试PDF标注 [!CAUTION] 根据第六期,我再次查询了资料,印象笔记还是有一些可圈可点的功能的(当然部分有平替),针对会员作用,开发使用场景虽然是逆向的,但我坚信这是一部分人的现…...
Logback的使用
1、基本认识 logback官方文档:http://logback.qos.ch 具体样例:https://www.baeldung.com/logback 从下面依赖关系图可以看见,Springboot的核心启动器spring-boot-stater依赖了spring-boot-starter-looging,而这个就是日志的启动器…...
沙箱模拟支付宝支付3--支付的实现
1 支付流程实现 演示案例 主要参考程序员青戈的视频【支付宝沙箱支付快速集成版】支付宝沙箱支付快速集成版_哔哩哔哩_bilibili 对应的源码在 alipay-demo: 使用支付宝沙箱实现支付功能 - Gitee.com 以下是完整的实现步骤 1.首先导入相关的依赖 <?xml version"1…...
微信小程序滑动解锁、滑动验证
微信小程序简单滑动解锁 效果 通过 movable-view (可移动的视图容器,在页面中可以拖拽滑动)实现的简单微信小程序滑动验证 movable-view 官方说明:https://developers.weixin.qq.com/miniprogram/dev/component/movable-view.ht…...
Redis的常用命令
Redis中文字典网站 redis 命令手册https://redis.com.cn/commands.html Keys * 查看当前库所有的key exists ke 判断某个key是否存在 type key查看你的key是什么类型 Del key删除执行的key数据 unlink key非阻塞删除,仅仅将keys从keyspace元数据中删除…...
国内Ubuntu环境Docker部署 ComfyUI
国内Ubuntu环境Docker部署 ComfyUI 趁着这两天用docker部署了 Stable Diffusion,顺手也安排上 ComfyUI。 ComfyUI相比 Stable Diffusion 原生的 WEB UI,更容易让人了解其出图的过程,极其适合学习与研究。拼接其强大的插件节点、不仅能够实现文…...
Meta 的新策略,将 AI 生成的角色整合到其社交媒体平台
一、Meta新年规划及引人注目的举措 多元规划背景:在新的一年,Meta制定了多维度的战略规划,旨在巩固并拓展其在科技领域的影响力。增强现实与元宇宙是其长期布局的重点方向,期望借此塑造未来互联网的交互形态;面对TikTo…...
玩转OCR | 腾讯云智能结构化OCR初次体验
目录 一、什么是OCR(需要了解) 二、产品概述与核心优势 产品概述 智能结构化能做什么 举例说明(选看) 1、物流单据识别 2、常见证件识别 3、票据单据识别 4、行业材料识别 三、产品特性 高精度 泛化性 易用性 四、…...
蓝桥杯JAVA--003
需求 2.代码 public class RegularExpressionMatching {public boolean isMatch(String s, String p) {if (p.isEmpty()) {return s.isEmpty();}boolean firstMatch !s.isEmpty() && (s.charAt(0) p.charAt(0) || p.charAt(0) .);if (p.length() > 2 && p…...
STC51和STM32单片机烧录引脚的完整名称
STC51 和 STM32 单片机烧录引脚的完整名称 1. STC51 单片机的烧录引脚 STC51 单片机通过 串口(UART) 进行程序下载,主要引脚如下: 引脚名称完整英文名称说明TXDTransmit Data串口发送引脚,用于发送数据。RXDReceive…...
阿里云大模型ACP高级工程师认证模拟试题
阿里云大模型ACP高级工程师认证模拟试题 0. 引言1. 模拟试题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题单选题单选题多选题多选题单选题多选题单…...
深入理解计算机中的补码、反码、原码
问题: 我们每天用的钟表,其实只有1~12这12个数字,但我们日常会说13点、17点之类的。 问:13点在钟表上哪个位置? 答:很简单嘛,1点的位置。 你不觉得奇怪吗,为啥13点会和1点在同一个位…...
调试:用电脑开发移动端网页,然后用手机真机调试
一、背景 电脑开发移动端,然后想真机调试... 二、实现 2.1、电脑和手机链接相同局域网 2.2、pnpm run dev 启动项目 2.3、浏览器访问 localhost:3001/login 2.4、Windowsr 输入cmd,在cmd输入 ipconfig 2.5、浏览器访问 ip地址加/login 2.6、手机端…...
深入浅出:Spring Boot 自定义消息转换器的实现与应用
Spring Boot 作为当前最流行的 Java Web 开发框架之一,广泛应用于微服务架构、企业级应用等多个场景。Spring Boot 提供了灵活且易于扩展的架构,其中消息转换器(Message Converter)是其重要组成部分。消息转换器在 Spring Boot 中…...
基于AI大模型的医院SOP优化:架构、实践与展望
一、引言 1.1 研究背景与意义 近年来,人工智能(AI)技术取得了迅猛发展,尤其是大模型的出现,为各个领域带来了革命性的变化。在医疗领域,AI 医疗大模型正逐渐崭露头角,展现出巨大的应用潜力。随着医疗数据的海量积累以及计算能力的大幅提升,AI 医疗大模型能够对复杂的…...
Maven项目集成SQL Server的完整教程:从驱动配置到封装优化
前言 在最近的系统对接过程中,由于对方团队不熟悉技术,最终选择直接提供 SQL Server 视图。本文详细记录了使用 Maven 集成 SQL Server 驱动的过程,以及从配置到查询的各个关键步骤,还包括注意事项与常见问题,希望对需…...
Java 21 优雅和安全地处理 null
在 Java 21 中,判断 null 依然是开发中常见的需求。通过使用现代 Java 提供的工具和特性,可以更加优雅和安全地处理 null。 1. 使用 Objects.requireNonNull Objects.requireNonNull 是标准的工具方法,用于快速判断并抛出异常。 示例 import java.util.Objects;public c…...
Java(四十四)file
Java中的file类:代表文件或者文件夹(目录)类,也就是说将文件或者文件夹通过File类来封装成对象。 一:常用的构造方法: 使用file类,需要通过构造方法创建一个file对象。 1:public File(String pathname) public static void main(String[] args) {File fl = new File(&…...
【51项目】51单片机自制小霸王游戏机
视频演示效果: 纳新作品——小霸王游戏机 目录: 目录 视频演示效果: 目录: 前言:...
【ArcGISPro/GeoScenePro】检查多光谱影像的属性并优化其外观
数据 https://arcgis.com/sharing/rest/content/items/535efce0e3a04c8790ed7cc7ea96d02d/data 操作 其他数据 检查影像的属性 熟悉检查您正在使用的栅格属性非常重要。...
《新概念模拟电路》-三极管
三极管 本系列文章主要学习《新概念模拟电路》中的知识点。在工作过程中,碰到一些问题,于是又翻阅了模电这本书。我翻阅的是ADI出版的,西安交通大学电工中心杨建国老师编写的模电书。 <模电>和《数电》这两本书是电子学的专业基础课&…...
K 近邻算法入门指南:明氏距离与皮尔森距离的基础讲解
1、K近邻算法介绍 K近邻(k-Nearest Neighbor,KNN)分类算法的思路是:在特征空间中,如果一个样本附近的k个最近样本的大多数属于某一个类别,则该样本也属于这个类别。K近邻算法中,所选择的邻居都是已经正确分类的对象。…...
如何验证imap是否生效
要验证您的 Outlook 邮箱是否启用了 IMAP 并且正常工作,可以按照以下步骤进行操作: 1. 确认 Outlook 邮箱是否启用 IMAP 步骤: 登录到您的 Outlook Web 账户: 打开浏览器,访问 Outlook.com 或 Microsoft 365 Outlook…...
MySQL 06 章——多表查询
多表查询,也称为关联查询,是指两个表或多个表一起完成查询操作 前提条件,这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段的。这个关联字段可能建立了外键,也可能没…...
转换VMware Esxi 虚拟机到 Windows2019 Hyper-V Server
Hyper-v专用P2V工具disk2vhd实际应用 工具介绍 disk2vhd是一个非常小的P2V转换工具,可以将你的物理服务器或Esxi vm 转换成为VHD或者vhdx格式的虚拟硬盘文件,然后在虚拟平台上作为一台虚拟机来使用。目前disk2vhd的最新版本是2.0.1,已经可以…...
头歌实训2-1:面向对象程序设计-基础部分
第1关:定义银行员工类BankEmployee 本关任务:编写银行员工类BankEmployee,要求: 1.银行员工类的属性包括姓名name,工号num,工资salary 2.姓名name和工号num设置为私有属性,并将salay设置为默认参数3000 平…...
超高分辨率 图像 分割处理
文章大纲 制造业半导体领域高分辨率图像半导体数据集开源的高分辨率晶圆图像数据集1. WM-811K数据集2. Kaggle上的WM-811K Clean Subset数据集医疗 病理领域高分辨率图像1. Camelyon+2. CAMELYON173. CPIA Dataset4. UCF-WSI-Dataset航拍 遥感中的高分辨率 图像航拍遥感领域高分…...
使用 apply 方法将其他列的值传入 DataFrame 或 Series 的函数,来进行更灵活的计算或操作
可以使用 apply 方法将其他列的值传入 DataFrame 或 Series 的函数,来进行更灵活的计算或操作。apply 方法允许你逐行或逐列地对 DataFrame 或 Series 的元素进行操作,而且你可以将其他列的值作为参数传递给函数。 示例:使用 apply 结合其他…...
[CTF/网络安全] 攻防世界 warmup 解题详析
查看页面源代码,发现source.php 得到一串代码,进行代码审计: <?phpclass emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php"];…...
力扣第389题—找不同
class Solution:def findTheDifference(self, s: str, t: str) -> str:# 对字符串 s 和 t 进行排序a sorted(s)b sorted(t)# 比较排序后的两个列表for i in range(len(a)):if a[i] ! b[i]:return b[i]# 如果前面的比较没有找到差异,那么差异字符在 t 的最后一个…...
vite6+vue3+ts+prettier+eslint9配置前端项目(后台管理系统、移动端H5项目通用配置)
很多小伙伴苦于无法搭建一个规范的前端项目,导致后续开发不规范,今天给大家带来一个基于Vite6TypeScriptVue3ESlint9Prettier的搭建教程。 目录 一、基础配置1、初始化项目2、代码质量风格的统一2.1、配置prettier2.2、配置eslint2.3、配置typescript 3、…...
滴滴数据分析80道面试题及参考答案
如何衡量分类好坏? 衡量分类好坏有多种方法,常用的有准确率、精确率、召回率、F1 值、ROC 曲线与 AUC 值等。 准确率:是指分类正确的样本数占总样本数的比例,计算公式为:准确率 = (分类正确的样本数)/(总样本数)。准确率越高,说明分类器整体的分类效果越好,但在正负…...
嵌入式应用软件开发中C语言方向面试题
嵌入式应用软件开发中C语言方向面试题随笔 前言一、C语言基础二、嵌入式开发相关三、硬件相关知识五、实际编程问题前言 做嵌入式开发这么多年了,简单记录下C语言方向常见面试题,这里是应用软件方向的。 一、C语言基础 C语言的指针与数组的区别是什么?指针:指针是一个变量…...
vue3中mixins替代方案
使用自定义 Hooks(Composables) 自定义 Hooks 是一种基于函数的代码复用方式,可以在 setup 函数中使用。它允许将组件的逻辑分割成更小的、可复用的部分。 useCounter.js //useCounter.js import { ref, onMounted } from vue;export func…...
线性代数自学资源推荐我的个人学习心得
1.前言 自己这个学期的课程基本上就结束了,因此我自己就开始学习下个学期的课程--线性代数,也是我们在大学里面的最后一门数学课程了; 之前有过一些这个线性代数的基础,当时主要是参加这个数学建模比赛去学习这个matlab吗&#…...
WordPress Crypto 插件 身份认证绕过漏洞复现(CVE-2024-9989)
0x01 产品简介 WordPress Crypto插件是指那些能够为WordPress网站提供加密货币支付、信息显示或交易功能的插件。这些插件通常与WordPress电子商务插件(如WooCommerce)集成,使网站能够接受多种加密货币支付,或展示加密货币实时信息。支持多种加密货币支付,付款直接进入钱…...
软件逆向之OD基础
OD程序目录 plugin:存放OD所有插件 UDD:存放程序临时的数据,比如:程序注释、断点等 ollydbg.ini:存放OD自身配置的属性表 OLLYDBG.HLP:OD的帮助手册 OD断点 1.软件断点: 介绍:…...
C++并发编程之内存顺序一致性
std::memory_order_seq_cst 是 C11 引入的内存模型中的一种内存顺序(memory order),全称为 Sequential Consistency(顺序一致性)。它是 C 中最严格的内存顺序,提供了最强的同步保证。下面详细解释其含义、意…...
软件测试面试题整理
一、人格相关问题 1、自我介绍结构 姓名工作年限简单介绍上家公司的行业主要负责内容个人优势短期内的职业规划应聘该岗位的原因 2、对未来的发展方向怎么看 3、你对测试最大的兴趣在哪里?为什么? 二、技术相关问题 1、测试理论以及应用 1、给你一个…...
Java中如何实现线程安全的单例模式?
目录 1、懒汉式(线程安全) 2、饿汉式(线程安全) 3、双重校验锁(线程安全) 4、静态内部类(推荐) 5、枚举(最佳方法) 6、总结 在Java中,实现线…...
MYsql--------ubantu中安装mysql
在Ubuntu平台上下载、启动和关闭MySQL的方法如下: 下载安装MySQL 更新软件包列表:打开终端,输入以下命令,确保软件包列表是最新的。sudo apt update安装MySQL服务器:执行以下命令安装MySQL服务器。在安装过程中&…...
【Ubuntu】不能连上网络
1. ping路由器的IP地址 ping 192.168.1.1 如果ping不通的话,可能是网络故障导致的。需要重启配置ip地址。配置文件 sudo vi /etc/network/interface 2. ping 8.8.8.8 如果ping不通的话,可能是路由器不能链接往外网; 或者路由器显示了当…...