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

深度学习笔记之BERT(二)BERT精简变体:ALBERT

深度学习笔记之BERT——BERT精简变体:ALBERT

  • 引言
    • 回顾:ResNet对于反向传播的作用
    • BERT的配置
    • BERT的问题/缺陷
    • ALBERT
    • ALBERT的策略
    • BERT VS ALBERT

引言

上一节从 Word2vec \text{Word2vec} Word2vec上下文信息的局限性角度出发,介绍了 BERT \text{BERT} BERT是如何优化这一问题的,以及 BERT \text{BERT} BERT的训练策略。本节将介绍 BERT \text{BERT} BERT的一种精简变体 ALBERT \text{ALBERT} ALBERT

回顾:ResNet对于反向传播的作用

ResNet \text{ResNet} ResNet一节中,介绍了残差连接这一技巧的优势。其前馈计算过程可描述为:
x ′ = H ( x ) = F ( x ) + x x' = \mathcal H(x) = \mathcal F(x) + x x=H(x)=F(x)+x
其中, x x x表示上一网络层模块的输出; F ( ⋅ ) \mathcal F(\cdot) F()即表示下一网络层模块。这种使用于网络层模块之间的技巧本质上解决一个核心问题:抑制梯度消失现象,使梯度信息在深度神经网络中能够传播得更远

常规的深度神经网络中,不可避免的问题是反向传播过程中,随着神经网络层的加深产生的梯度消失现象。在反向传播的初期,梯度结果是清晰、明显的,例如初始梯度: ∂ L ∂ W N \begin{aligned}\frac{\partial \mathcal L}{\partial \mathcal W_{N}}\end{aligned} WNL(这里 W N \mathcal W_{N} WN表示损失函数前的最后一个神经网络层的权重信息);随着反向传播的加深,梯度消失的现象逐渐明显,模型传播的梯度会变得模糊、轻微
∂ L ∂ W N ⋅ ∂ W N ∂ W N − 1 ⋅ ∂ W N − 1 ∂ W N − 2 ⋯ ∂ W 1 ∂ W 0 \frac{\partial \mathcal L}{\partial \mathcal W_{N}} \cdot \frac{\partial \mathcal W_{N}}{\partial \mathcal W_{N-1}} \cdot \frac{\partial W_{N-1}}{\partial W_{N-2}} \cdots \frac{\partial \mathcal W1}{\partial \mathcal W_0} WNLWN1WNWN2WN1W0W1

ResNet \text{ResNet} ResNet使用一个技巧解决了 2 2 2件事情:
无论神经网络层数有多深,总会存在保底的梯度稳定传递回上一层;以一个常规网络层 x ′ = F [ G ( x ) ] x' = \mathcal F[\mathcal G(x)] x=F[G(x)]与对应残差网络层 x ′ = F [ G ( x ) ] + G ( x ) x' = \mathcal F[\mathcal G(x)] + \mathcal G(x) x=F[G(x)]+G(x)之间结果对比如以下:
这里 σ \sigma σ表示激活函数。
{ Normal:  ∂ x ′ ∂ x = ∂ F [ G ( x ) ] ∂ G ( x ) ⋅ ∂ G ( x ) ∂ x = { σ ′ [ W T G ( x ) + b ] ⋅ W } ⋅ ∂ G ( x ) ∂ x ResNet:  ∂ x ′ ∂ x = ∂ { F [ G ( x ) ] + G ( x ) } ∂ G ( x ) ⋅ ∂ G ( x ) ∂ x = { 1 + σ ′ [ W T G ( x ) + b ] ⋅ W } ⋅ ∂ G ( x ) ∂ x \begin{cases} \begin{aligned} & \text{Normal: }\frac{\partial x'}{\partial x} = \frac{\partial \mathcal F[\mathcal G(x)]}{\partial \mathcal G(x)} \cdot \frac{\partial \mathcal G(x)}{\partial x} = \left\{\sigma' \left[\mathcal W^T\mathcal G(x) + b \right] \cdot \mathcal W\right\} \cdot \frac{\partial \mathcal G(x)}{\partial x} \\ \quad \\ & \text{ResNet: } \frac{\partial x'}{\partial x} = \frac{\partial \{ \mathcal F[\mathcal G(x)] + \mathcal G(x)\}}{\partial \mathcal G(x)} \cdot \frac{\partial \mathcal G(x)}{\partial x} = \left\{1 + \sigma' \left[\mathcal W^T\mathcal G(x) + b \right] \cdot \mathcal W \right\} \cdot \frac{\partial \mathcal G(x)}{\partial x} \end{aligned} \end{cases} Normal: xx=G(x)F[G(x)]xG(x)={σ[WTG(x)+b]W}xG(x)ResNet: xx=G(x){F[G(x)]+G(x)}xG(x)={1+σ[WTG(x)+b]W}xG(x)
在这种梯度传递方式下,使其保证:残差网络在方向传播过程中传播的残差梯度是有效的,而不同于常规神经网络中,随着反向传播层数的加深,传回的梯度信息忽略不计或者传回一些接近噪声的信息。从而最终呈现出类似互补的现象:

  • 在接近输出层的部分,经过深度神经网络若干次的前馈计算,它包含的初始信息是最少的;相反,其对应反向传播是最初始的部分,因而它的梯度是最活跃的,最终导致:当前层梯度中梯度信息自身占主导地位
  • 在接近输入层的部分,经过多次反向传播计算,虽然使用 ResNet \text{ResNet} ResNet抑制了梯度衰减,但梯度信息在一次又一次反向传播计算中被稀释了,但这部分同样是初始信息参与最多的部分。从而导致:当前层梯度中初始信息占主导地位

BERT的配置

BERT \text{BERT} BERT的研究人员在发布该模型时提出了两种标准配置:

BERT-base \text{BERT-base} BERT-base
BERT-base \text{BERT-base} BERT-base对应的编码器层数 L = 12 \mathcal L = 12 L=12,每层编码器使用的注意力头的个数 A = 12 \mathcal A = 12 A=12,输入特征向量的维度 H = 768 \mathcal H = 768 H=768,如果词表 token \text{token} token的大小是 30 , 000 30,000 30,000,那么 BERT-base \text{BERT-base} BERT-base中包含的参数量大小是:

  • 模型初始是一个 Embedding \text{Embedding} Embedding层,需要将 Token \text{Token} Token映射成相应维度为 H \mathcal H H Embedding \text{Embedding} Embedding向量。该层对应的权重的参数量大小是: 30 , 000 ∗ H 30,000 * \mathcal H 30,000H

  • 在自注意力机制中, Q , K , V \mathcal Q,\mathcal K,\mathcal V Q,K,V映射层对应的权重矩阵 W Q , W K , W V \mathcal W_{\mathcal Q},\mathcal W_{\mathcal K},\mathcal W_{\mathcal V} WQ,WK,WV的大小均为 ( 768 , 64 ) (768,64) (768,64),那么 12 12 12个头对应的每个权重维度大小为 ( 768 , 12 ∗ 64 ) (768,12*64) (768,1264),对应参数数量为 H ∗ H \mathcal H *\mathcal H HH;最终多头注意力机制中的参数量为 3 ∗ H ∗ H 3 * \mathcal H * \mathcal H 3HH;

    自注意力机制的末尾还包含一个维度不发生变化的全链接层 Linear ( H , H ) \text{Linear}(\mathcal H,\mathcal H) Linear(H,H),该层权重对应的参数量大小是 H ∗ H \mathcal H * \mathcal H HH,最终自注意力机制对应的总参数量为 H 2 ∗ 4 \mathcal H^2 * 4 H24

  • 编码器自注意力机制后是一个 FeedForword Network \text{FeedForword Network} FeedForword Network,由一对全连接层组成: Linear ( H , 4 ∗ H ) , Linear ( 4 ∗ H , H ) \text{Linear}(\mathcal H,4 * \mathcal H),\text{Linear}(4 * \mathcal H,\mathcal H) Linear(H,4H),Linear(4H,H),两个层权重的参数量大小均为 H 2 ∗ 4 \mathcal H^2 * 4 H24,最终该部分的参数量大小为 H 2 ∗ 8 \mathcal H^2 * 8 H28

至此, BERT-base \text{BERT-base} BERT-base的参数量为:
L \mathcal L L个编码器均包含同样的结构。
I = 30 , 000 ∗ H + L ∗ ( H 2 ∗ 4 + H 2 ∗ 8 ) = 107 , 974 , 656 ≈ 110 M \mathcal I = 30,000 * \mathcal H + \mathcal L * (\mathcal H^2 *4 + \mathcal H^2 * 8) =107,974,656 \approx 110M I=30,000H+L(H24+H28)=107,974,656110M
可以看出, BERT-base \text{BERT-base} BERT-base中大约包含 1.1 1.1 1.1亿参数。

BERT-large \text{BERT-large} BERT-large
BERT-large \text{BERT-large} BERT-large结构和 BERT-base \text{BERT-base} BERT-base相同,只不过参数规格有所变化。其编码器层数 L = 24 \mathcal L = 24 L=24,自注意力头数量 A = 16 \mathcal A = 16 A=16,输入特征向量维度 H = 1024 \mathcal H = 1024 H=1024。至此, BERT-large \text{BERT-large} BERT-large的参数量为:
W Q , W K , W V \mathcal W_{\mathcal Q},\mathcal W_{\mathcal K},\mathcal W_{\mathcal V} WQ,WK,WV的大小依然是 ( H , 64 ) (\mathcal H,64) (H,64)
I = 332 , 709 , 888 ≈ 340 M \mathcal I = 332,709,888 \approx 340M I=332,709,888340M

相应地, BERT-large \text{BERT-large} BERT-large中大约包含 3.4 3.4 3.4亿参数。

BERT的问题/缺陷

  • 无论是 BERT-base \text{BERT-base} BERT-base还是 BERT-large \text{BERT-large} BERT-large,这中规模的参数量,这使它极难训练。诚然对 Token \text{Token} Token进行更好的表示,但该模型对计算资源也有更高的要求。

  • 模型退化:在 NLP \text{NLP} NLP领域的研究趋势——规模越大、参数量越多,模型的表征就越完整,模型性能越高。但实际上, ALBERT \text{ALBERT} ALBERT的研发团队研究表明,这种逻辑并不完全正确。

    他们将 BERT-large \text{BERT-large} BERT-large中的输入特征以及隐藏层单元数量 H = 1024 → 2048 \mathcal H = 1024 \rightarrow 2048 H=10242048,并称之为 BERT-xlarge \text{BERT-xlarge} BERT-xlarge,但该模型无论在语言建模任务还是阅读理解测试 ( RACE ) (\text{RACE}) (RACE)中,该模型的表现明显不如 BERT-large \text{BERT-large} BERT-large,在 RACE \text{RACE} RACE任务中的准确率呈现断崖式下跌( Acc:73.9 \text{Acc:73.9} Acc:73.9% → 54.3 \rightarrow \text{54.3} 54.3%)

    下面是原文中 BERT-large \text{BERT-large} BERT-large BERT-xlarge \text{BERT-xlarge} BERT-xlarge随着迭代步骤的增加,损失函数准确率的变化情况:
    BERT-largeVS BERT-xlarge
    从第一张图(左)可以看出: BERT-large \text{BERT-large} BERT-large相比于 BERT-xlarge \text{BERT-xlarge} BERT-xlarge更快地达到下降效果,并趋于稳定;相比之下, BERT-xlarge \text{BERT-xlarge} BERT-xlarge损失函数的波动更剧烈。第二张图(右)可以看出: BERT-large \text{BERT-large} BERT-large相比于 BERT-xlarge \text{BERT-xlarge} BERT-xlarge在初始有限的迭代步骤内,准确率提升的更快,最终准确率也高于 BERT-xlarge \text{BERT-xlarge} BERT-xlarge

    很明显,规模越大,模型性能越高被局限在模型没有退化的前提下,为什么会出现模型退化这种现象呢 ? ? ? 个人认为,在模型未退化的范畴内,参数量大优于参数量小是因为:在模型中各神经元被充分激活的条件下,反向传播过程中,更多的神经元能够传回更多、更丰富的梯度信息

    如果不限制地对模型参数进行扩张,模型中神经元数量越来越多。由于数据体量不变,会导致:反向传播过程中,绝大多数神经元没有被充分激活,这种半激活状态下的模型效果自然会大打折扣。

ALBERT

BERT \text{BERT} BERT的缺陷,就是参数量过大,导致训练难以及潜在出现的神经元/参数冗余现象,针对这个问题, ALBERT \text{ALBERT} ALBERT通过两种技巧对参数量进行优化:

  • Embedding \text{Embedding} Embedding层参数的因子分解( Factorized Embedding Parameterization \text{Factorized Embedding Parameterization} Factorized Embedding Parameterization): BERT \text{BERT} BERT系列模型,它的 Embedding \text{Embedding} Embedding直接作为后续自注意力层的输入, W Q , W K , W V \mathcal W_{\mathcal Q},\mathcal W_{\mathcal K},\mathcal W_{\mathcal V} WQ,WK,WV直接与 Embedding \text{Embedding} Embedding进行计算;但如果想要提高隐藏层的维度 H \mathcal H H,那我们不得不一并提高 Embedding \text{Embedding} Embedding的维度 E \mathcal E E并使 E = H \mathcal E = \mathcal H E=H,再进行计算时,参数的增长会是一个平方级的增加
    参数量级表示为 O ( V ∗ H ) \mathcal O(\mathcal V * \mathcal H) O(VH),其中 V \mathcal V V表示 Token \text{Token} Token的数量,也就是词汇表词语的数量; H \mathcal H H则表示神经元维数,再没有因子分解的情况下,将所有的 Token \text{Token} Token转化为相应的 Embedding \text{Embedding} Embedding需要的参数量。

    因子分解的思路是: Embedding \text{Embedding} Embedding维度 E \mathcal E E H \mathcal H H不相关。具体做法是:在 Embedding \text{Embedding} Embedding后面额外增加一个参数矩阵 W ∈ R E ∗ H \mathcal W \in \mathbb R^{\mathcal E * \mathcal H} WREH Embedding \text{Embedding} Embedding进行维度变换。此时就可以赋予 E \mathcal E E一个较小的值来约束参数数量,最终参数量级表示为 O ( V ∗ E + E ∗ H ) \mathcal O(\mathcal V * \mathcal E + \mathcal E * \mathcal H) O(VE+EH)
    下图表示当 V = 30000 , E = 128 , H = 768 \mathcal V=30000,\mathcal E=128,\mathcal H=768 V=30000,E=128,H=768时,对应参数数量的对比结果 factorized
    原文提供的基于 Embedding \text{Embedding} Embedding因子分解对于各类任务效果表示如下:
    factorized result
    通过观察可以发现:在未执行参数共享的状态下,使用 Embedding \text{Embedding} Embedding因子分解技巧,各任务准确率随着 Embedding \text{Embedding} Embedding维数的增加而增加,但相差普遍不大,并且参数量最多相差近 30 30 30%。也就是说:削掉 30 30 30%参数,同样可以得到与原来相差不大的效果。

  • 跨层参数共享( Cross-Layer Parameter Sharing \text{Cross-Layer Parameter Sharing} Cross-Layer Parameter Sharing):无论是 BERT \text{BERT} BERT还是 Transformer \text{Transformer} Transformer,各个 Transformer block \text{Transformer block} Transformer block内的参数,包括 self-attention \text{self-attention} self-attention、全连接部分,均是相互独立的,这导致:每增加一个 Block \text{Block} Block,参数量都会上升 ALBERT \text{ALBERT} ALBERT则尝试:只学习第一层参数,剩下的所有层的参数重新使用第一层参数,最终待学习的参数仅变成了一层参数
    这里的层并非仅仅指一个 Block \text{Block} Block,可以将所有的 self-attention \text{self-attention} self-attention进行共享,或者所有的全连接部分进行共享,或者所有的 Block \text{Block} Block进行共享
    浅谈一下为什么要用第一层参数:由于存在 ResNet \text{ResNet} ResNet结构,会导致:每一层的传回梯度都是残差梯度,差异在于:初始层中梯度信息不占主要部分,但该梯度信息同样有效,只有选择第一层,才能够对初始信息进行更好地优化。

    下面是原文中对 BERT-large \text{BERT-large} BERT-large ALBERT-large \text{ALBERT-large} ALBERT-large相比,使用欧式距离和余弦相似度作为标准,各层输入输出分布稳定性的一个对比情况:
    BERT-large VS ALBERT-large
    左图描述的是各层输入输出分布之间的欧氏距离,以及欧式距离随着层级变化的一个变化趋势右图描述的是各层输入输出分布之间的余弦相似度,以及相似度随着层级的一个变化趋势。两者本质上均是描述各层输入输出分布之间的差异性趋势

    蓝色线的 ALBERT-large \text{ALBERT-large} ALBERT-large所描述的线更加平滑,这意味着:各层输入输出的分布相差不大,并且各层之间的输入输出分布相差都不大;相反,红色线描述的 BERT-large \text{BERT-large} BERT-large,其在接近末尾时变动变化很大,这意味着对应层的输入输出分布之间差异更大。这也说明跨层参数共享对于网络参数的稳定性有积极的影响

    另一角度观察, BERT-large \text{BERT-large} BERT-large的差异性更大意味着差异性大的若干层对输出分布起更关键作用,而 ALBERT-large \text{ALBERT-large} ALBERT-large相邻层的差异性普遍相差不大,可以解释为:产生输出分布结果的“关键点”分摊给了每一层,并共同发生作用。这也说明 BERT-large \text{BERT-large} BERT-large ALBERT-large \text{ALBERT-large} ALBERT-large对应参数找到的解分布存在差异。

    由于跨层参数共享的方式有很多种,原文将:

    • 无共享 ( not-shared ) (\text{not-shared}) (not-shared)
    • 基于 Block ( \text{Block}( Block( attention \text{attention} attention,全连接 ) ) )跨层参数共享 ( all-shared ) (\text{all-shared}) (all-shared)
    • 基于自注意力跨层参数共享 ( shared-attention ) (\text{shared-attention}) (shared-attention)
    • 基于全连接跨层参数共享 ( shared-FFN ) (\text{shared-FFN}) (shared-FFN)

    4 4 4种跨层参数共享方式进行比对,比对结果如下:
    4method
    从表中可以看出:

    • 在隐藏层单元格式均使用 768 768 768的条件下,可以使用精度换时间的方式进行高效运算。例如 ALBERT-base(shared-attention,E=128) \text{ALBERT-base(shared-attention,E=128)} ALBERT-base(shared-attention,E=128)相比 ALBERT-base(not-shared,E=768) \text{ALBERT-base(not-shared,E=768)} ALBERT-base(not-shared,E=768)仅差不到一个点,但能节省约 40 40 40%的计算资源;
      实际上 ALBERT-base(not-shared,E=768) \text{ALBERT-base(not-shared,E=768)} ALBERT-base(not-shared,E=768) BERT-base \text{BERT-base} BERT-base还多了 768 ∗ 768 768*768 768768个参数~
    • 相比于 shared-attention \text{shared-attention} shared-attention Feed-Forward \text{Feed-Forward} Feed-Forward层的参数共享会对最终精度产生更大的负面影响。
  • Dropout \text{Dropout} Dropout移除
    ALBERT \text{ALBERT} ALBERT作者在实验过程中发现的奇特现象,即便训练了 1 , 000 , 000 1,000,000 1,000,000 step \text{step} step,依然没有产生类似过拟合的现象,并在后续通过移除 Dropout \text{Dropout} Dropout来提升模型能力。右图描述了在 1.2M \text{1.2M} 1.2M左右个 step \text{step} step之后,移除 Dropout \text{Dropout} Dropout Mask LM \text{Mask LM} Mask LM准确率的提升效果:
    remove_dropout

ALBERT的策略

在介绍 BERT \text{BERT} BERT策略中提到一个下句预测 ( Next Sentence Prediction,NSP ) (\text{Next Sentence Prediction,NSP}) (Next Sentence Prediction,NSP),但在随后的实践中, RoBERTa,XLNet \text{RoBERTa,XLNet} RoBERTa,XLNet等论文已经阐明了该任务并没有给模型的训练带来收益。因此, ALBERT \text{ALBERT} ALBERT提出了另一个任务——句子顺序预测 ( Sentence-order Prediction,SOP ) (\text{Sentence-order Prediction,SOP}) (Sentence-order Prediction,SOP)。具体采样方式是:

  • 从文档中选取两个连续句子作为一个正样本
  • 将上述两个句子调换顺序,并作为一个负样本
    这里区别于 BERT \text{BERT} BERT,NSP是随机选取两个句子作为负样本,并判别他们的关联关系

基于这种方式的二分类任务提高了多种下游任务的表现:
SOP

BERT VS ALBERT

类似于 BERT-xlarge \text{BERT-xlarge} BERT-xlarge ALBERT \text{ALBERT} ALBERT也有自己的 large \text{large} large版本,并与 BERT \text{BERT} BERT相关模型进行对比:
BERT VS ALBERT
可以发现: ALBERT-xxlarge \text{ALBERT-xxlarge} ALBERT-xxlarge参数量少于 BERT-large \text{BERT-large} BERT-large情况下,各项指标均优于 BERT-large \text{BERT-large} BERT-large。从训练实践的角度观察:
ALBERT-xxlarge VS BERT-large
可以发现: ALBERT-xxlarge \text{ALBERT-xxlarge} ALBERT-xxlarge使用更少的迭代步骤、更短的时间,能够得到优于 BERT-large \text{BERT-large} BERT-large的结果。需要注意的是,这仅仅是训练时间,而不是 Inference \text{Inference} Inference时间,也就是说:在前馈计算的时候实现网络共享,但在反向传播过程中,依然需要一个一个 Block \text{Block} Block将梯度传递回去。

Reference \text{Reference} Reference
ALBERT详解

相关文章:

深度学习笔记之BERT(二)BERT精简变体:ALBERT

深度学习笔记之BERT——BERT精简变体:ALBERT 引言回顾:ResNet对于反向传播的作用BERT的配置BERT的问题/缺陷ALBERTALBERT的策略BERT VS ALBERT 引言 上一节从 Word2vec \text{Word2vec} Word2vec上下文信息的局限性角度出发,介绍了 BERT \text{BERT} BE…...

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel(1-注解使用)Easyexcel(2-文件读取)Easyexcel(3-文件导出)Easyexcel(4-模板文件)Easyexcel(5-自定义列宽) 注解 ColumnWidth Data…...

Linux 安装 Git 服务器

一、安装 Git 1. 在 CentOS/RHEL 中使用以下命令: sudo yum update -y # 或者 sudo dnf update -y (在较新的系统中) sudo yum install git -y验证安装:git --version 2. 配置 Git 用户 git config --global user.name "Your Name" git co…...

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云 C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用 发布于 2021-06-10 00:10:59 7.1K0 举报 文章被收录于专栏:c#学习笔记 一、介绍 DockPanelSuite是托管在…...

c++-有关输出、信息输入、趣味输入应用、运算符、变量、浮点数数据类型的基础知识

C是一种功能强大且广泛使用的编程语言,它可以用于开发各种类型的应用程序。在这篇文章中,我们将介绍C程序的输出、信息输入、趣味输入应用、运算符、变量和浮点数数据类型的基础知识。 目录 输出 信息输入 趣味输入应用 运算符 变量 浮点数数据类…...

STM32-- keil 的option for target使用

keil版本号 1.device界面 如:stm32f103c8t6的工程,可以直接在device这里修改成stm32f103vct6,虽然引脚不一样,但是很多一样的地方,可以直接使用,有些不修改也可以下载程序。 2.target xtal的设置不起作用了…...

Python 使用 Token 认证方案连接 Kubernetes (k8s) 的详细过程

在 Kubernetes 中,使用 Token 认证是一种常见的客户端身份验证方式,尤其适用于 ServiceAccount。以下是详细的步骤,包括如何查看 Token、获取 API 服务地址、配置远程连接,以及如何在 Python 中连接 k8s。 1. 获取 Token 首先&a…...

神经网络(系统性学习二):单层神经网络(感知机)

此前篇章: 神经网络中常用的激活函数 神经网络(系统性学习一):入门篇 单层神经网络(又叫感知机) 单层网络是最简单的全连接神经网络,它仅有输入层和输出层,没有隐藏层。即&#x…...

3D Gaussian Splatting在鱼眼相机中的应用与投影变换

paper:Fisheye-GS 1.概述 3D 高斯泼溅 (3DGS) 因其高保真度和实时渲染而备受关注。然而,由于独特的 3D 到 2D 投影计算,将 3DGS 适配到不同的相机型号(尤其是鱼眼镜头)带来了挑战。此外,基于图块的泼溅效率低下,尤其是对于鱼眼镜头的极端曲率和宽视野,这对于其更广泛…...

MATLAB的语音信号采集与处理分析

1、基本描述 本文描述的系统是一个全面而精细的语音信号处理平台,核心组件由MATLAB的高级功能模块构建而成。系统的核心交互界面,借助于MATLAB的uifigure函数搭建,为用户提供了一个直观且响应迅速的操作环境。通过设计的GUI按钮,如…...

H.265流媒体播放器EasyPlayer.js H5流媒体播放器如何验证视频播放是否走硬解

随着技术的不断进步和5G网络的推广,中国流媒体播放器行业市场规模以及未来发展趋势都将持续保持稳定的增长,并将在未来几年迎来新的发展机遇。流媒体播放器将继续作为连接内容创作者和观众的重要桥梁,推动数字媒体产业的创新和发展。 EasyPla…...

深度学习:ResNet每一层的输出形状

其中 /**在输出通道数为64、步幅为2的7 7卷积层后,接步幅为2的3 3的最大汇聚层,与GoogLeNet区别是每个卷积层后增加了批量规范层**/ b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.BatchNorm2d(64), nn.ReLU(),nn.MaxPool2d(kernel_s…...

牛客题库 21738 牛牛与数组

牛牛与数组题目链接 题目大意 牛牛喜欢这样的数组: 1:长度为n 2:每一个数都在1到k之间 3:对于任意连续的两个数A,B,A<=B 与(A % B != 0) 两个条件至少成立一个请问一共有多少满足条件的数组,对 1 e 9 + 7 1e^9+7 1e9+7 取模 输入格式 输入两个整数 n , k n,k n,…...

学会Lambda,让程序Pythonic一点

Lambda是Python里的高阶用法&#xff0c;要把代码写得Pythonic&#xff0c;就需要了解这些高阶用法&#xff0c;想说自己是一名真正的Python程序员&#xff0c;先要把代码写得Pythonic。 今天聊下Lambda的用法&#xff0c;写篇简短的用法说明。 Lambda是匿名函数的意思&#…...

旋转向量v和旋转矩阵R

旋转向量v和旋转矩阵R 旋转向量 v 和旋转矩阵 R 是三维空间中描述旋转的两种数学表示方式。两者的关系通过 Rodrigues 公式 建立。 1. 旋转向量v 2. 旋转矩阵R 3. 旋转向量v和旋转矩阵R的关系 两者通过 Rodrigues 公式 和特殊的矩阵运算互相转换&#xff1a; 4. 代码示例 1…...

CSS浮动:概念、特性与应用

CSS浮动是网页设计和开发中常见的布局技术之一&#xff0c;以下是CSS浮动相关的所有重要知识点&#xff1a; 一、浮动的定义与语法 浮动&#xff08;float&#xff09;属性可以指定一个元素应沿其容器的左侧或右侧放置&#xff0c;允许文本和内联元素环绕它。浮动属性最初只用…...

类和对象(下)

1.取地址运算符重载 1.1 const成员函数 • 将const修饰的成员函数称之为const成员函数&#xff0c;const修饰成员函数放到成员函数参数列表的后 ⾯。 • const实际修饰该成员函数隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何成员进行修改。 const 修饰D…...

后端接受大写参数(亲测能用)

重要点引入包别引用错了 import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data;JsonSerialize Data public class Item {JsonProperty(value "Token")private String token…...

Android仿前端分页组件pagination

仿前端pagination Android仿前端分页组件pagination 最近Android原生有个需求就是做个分页组件&#xff0c;不用上拉加载&#xff0c;因为数据量太大用户喜欢前端的方式&#xff0c;UI主要是拼凑比较简单&#xff0c;主要补充了一些判断越界和数据不全的细节&#xff0c;记录方…...

网络安全中常用浏览器插件、拓展

引言 现在的火狐、Edge&#xff08; Chromium内核&#xff09;、Chrome等浏览器带有插件、拓展&#xff08;Plugin&#xff09;的功能。这些插件中有的可以过滤广告&#xff0c;有的提供便捷的翻译&#xff0c;有的提供JavaScript脚本支持&#xff0c;方便用户的使用也大大的增…...

Vue 使用 Cropper.js 实现图片裁剪功能

前言 图片裁剪功能无论是用户头像的裁剪&#xff0c;还是图片内容的精确调整&#xff0c;都成为了提升用户体验的关键一环。Vue.js 结合 Cropper.js 这一功能丰富的图片裁剪库&#xff0c;可以轻松实现高效、直观的图片裁剪功能。本文将详细介绍如何在 Vue.js 项目中集成并使用…...

Python 3 和 JSON 数据格式

Python 3 和 JSON 数据格式 Python 3 是一种广泛使用的编程语言,以其简洁明了的语法和强大的功能而闻名。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Python 3 提供了内置的 json 模块,使得在 Python 程序…...

Halo 正式开源: 使用可穿戴设备进行开源健康追踪

在飞速发展的可穿戴技术领域&#xff0c;我们正处于一个十字路口——市场上充斥着各式时尚、功能丰富的设备&#xff0c;声称能够彻底改变我们对健康和健身的方式。 然而&#xff0c;在这些光鲜的外观和营销宣传背后&#xff0c;隐藏着一个令人担忧的现实&#xff1a;大多数这些…...

第一个autogen与docker项目

前提条件&#xff1a;在windows上安装docker 代码如下&#xff1a; import os import autogen from autogen import AssistantAgent, UserProxyAgentllm_config {"config_list": [{"model": "GLM-4-Plus","api_key": "your api…...

React第四节 组件的三大属性之state

前言 状态 state适用于类式组件中&#xff0c;而再函数式组件中需要使用 useState HOOK 模拟状态; React的组件就是一个状态机&#xff0c;通过与用户的交互&#xff0c;实现不同的状态&#xff0c;根据不同的状态展现出不一样的UI视图 并不是组件中所有的属性 都是组件的状态…...

在 CentOS 系统上直接安装 MongoDB 4.0.25

文章目录 步骤 1&#xff1a;配置 MongoDB 官方源步骤 2&#xff1a;安装 MongoDB步骤 3&#xff1a;启动 MongoDB 服务步骤 4&#xff1a;验证安装步骤 5&#xff1a;可选配置注意事项 以下是在 CentOS 系统上直接安装 MongoDB 4.0.25 的详细步骤&#xff1a; 步骤 1&#x…...

C++知识点总结(58):序列型动态规划

动态规划Ⅰ 一、基础1. 意义2. 序列 dp 解法 二、例题1. 最大子段和2. 删数最大子段和&#xff08;数据强度&#xff1a;pro max&#xff09;3. 最长上升子序列&#xff08;数据强度&#xff1a;pro max&#xff09;4. 3 或 5 的倍数序列5. 数码约数序列 一、基础 1. 意义 动…...

【系统架构设计师】真题论文: 论网络安全体系设计(包括解题思路和素材)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2014年 试题4)解题思路论文素材参考网络安全体系设计目标与原则网络安全体系的主要组成部分网络安全体系设计流程真题题目(2014年 试题4) 随着社会信息化的普及,计算机网络已经在各行各业得到了广泛…...

TypeScript学习笔记(三)

类型详细介绍 七、常用类型与语法 1.any any 的含义是&#xff1a;任意类型&#xff0c;一旦将变量类型限制为 any , 那就意味着放弃了对该变量的类型检查。 // 明确的表示a的类型是 any —— 【显式的any】 let a: any // 以下对a的赋值&#xff0c;均⽆警告 a 100 a 你…...

logstash 解析数组格式json数据:split, json

1&#xff0c;需求说明 原始数据格式&#xff1a; 1条 &#xff08;2*2&#xff09;》4个指标数据 [{"app":"aa","url":"www.1.com","metrics":[{"name":"cpu","value":11},{"name&quo…...

修改一下达梦disql 提示符

经常用disql的有时某些信息希望提示一下&#xff0c;默认的只显示SQL> 为了方便使用&#xff0c;可以在 glogin.sql 中增加些内容。 vi $DM_HOME/bin/disql_conf/glogin.sql增加以下几行 set time on set lineshow offcol global_name new_value global_name SELECT ins…...

Vue通用组件设计原则

在 Vue.js 开发中&#xff0c;设计通用组件是一项重要的任务&#xff0c;可以提升代码的复用性和可维护性。以下是通用组件设计的主要原则和最佳实践&#xff1a; 1. 清晰的职责划分 通用组件应该具有单一的职责&#xff0c;专注于完成某一类特定功能&#xff0c;而不依赖具体…...

uniapp页面样式和布局和nvue教程详解

uniapp页面样式和布局和nvue教程 尺寸单位 uni-app 支持的通用 css 单位包括 px、rpx px 即屏幕像素。rpx 即响应式px&#xff0c;一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准&#xff0c;750rpx恰好为屏幕宽度。屏幕变宽&#xff0c;rpx 实际显示效果会等比放大…...

Ubuntu问题 -- 设置ubuntu的IP为静态IP (图形化界面设置) 小白友好

目的 为了将ubuntu服务器IP固定, 方便ssh连接人在服务器前使用图形化界面设置 设置 找到自己的网卡名称, 我的是 eno1, 并进入设置界面 查看当前的IP, 网关, 掩码和DNS (注意对应eno1) nmcli dev show掩码可以通过以下命令查看完整的 (注意对应eno1) , 我这里是255.255.255.…...

【Java】期末复习章节 未完待续(版)

文章目录 【01算法类】1.1 使用冒泡排序算法对数组a{9, 7, 4, 6, 3, 1,10}&#xff0c;按由小到大的规律排序数组中的元素。1.2 从键盘输入一个4位整数n&#xff0c;判断n是否是回文数。&#xff08;回文数是指&#xff0c;将其数字反转排列的数与其本身相同。例如&#xff1a;…...

C语言数据结构——详细讲解 双链表

从单链表到双链表&#xff1a;数据结构的演进与优化 前言一、单链表回顾二、单链表的局限性三、什么是双链表四、双链表的优势1.双向遍历2.不带头双链表的用途3.带头双链表的用途 五、双链表的操作双链表的插入操作&#xff08;一&#xff09;双链表的尾插操作&#xff08;二&a…...

经验笔记:Git 中的远程仓库链接及上下游关系管理

Git 中的远程仓库链接及上下游关系管理 1. 远程仓库的链接信息 当你克隆一个远程仓库时&#xff0c;Git 会在本地仓库中记录远程仓库的信息。这些信息包括远程仓库的 URL、默认的远程名称&#xff08;通常是 origin&#xff09;&#xff0c;以及远程仓库中的所有分支和标签。…...

Swift闭包的本质

1 闭包的本质其实是一个引用类型&#xff1a;存储在堆空间上&#xff0c;由堆分配空间&#xff0c;且生命周期由ARC&#xff08;自动引用计数机制&#xff09;管理 2 捕获值&#xff1a;闭包会捕获上下文使用到的变量&#xff08;引用类型会保持引用关系&#xff09;&#xff…...

【SKFramework框架核心模块】3-2、音频管理模块

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群&#xff1a;398291828小红书小破站 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…...

常用Rust日志处理工具教程

在本文中&#xff0c;我想讨论Rust中的日志。通过一些背景信息&#xff0c;我将带您了解两个日志库&#xff1a;env_logger和log4rs。最后&#xff0c;我将分享我的建议和github的片段。 Rust log介绍 log包是Rust中日志API的事实标准&#xff0c;共有五个日志级别&#xff1…...

深入理解索引(二)

1.引言 在数据库和数据结构中&#xff0c;索引&#xff08;Index&#xff09;是一种用于提高数据检索速度的重要机制。本文将详细深入介绍索引。 2. 为什么要使用索引 大家在使用索引之前一定要搞清楚使用索引的目的&#xff0c;因为索引的不当使用可能不但起不到正向作用&a…...

Python 开发工具 -- PyCharm 简介

一、PyCharm 简介 PyCharm 是由 JetBrains 打造的一款 Python IDE。 PyCharm 具备一般 Python IDE 的功能&#xff0c;比如&#xff1a;调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试、版本控制等。 另外&#xff0c;PyCharm 还提供了一些很好的功能用…...

C# 属性 学习理解记录

字段和属性 左边字段&#xff0c;右边属性 拓展&#xff0c;属性安全&#xff1a; 1、设置public private 和protected 等&#xff0c;只读&#xff0c;只写&#xff0c; 2、在get set 方法时&#xff0c;验证&#xff0c;异常时抛出错误...

使用chrome 访问虚拟机Apache2 的默认页面,出现了ERR_ADDRESS_UNREACHABLE这个鸟问题

本地环境 主机MacOs Sequoia 15.1虚拟机Parallels Desktop 20 for Mac Pro Edition 版本 20.0.1 (55659)虚拟机-操作系统Ubuntu 22.04 服务器版本 最小安装 开发环境 编辑器编译器调试工具数据库http服务web开发防火墙Vim9Gcc13Gdb14Mysql8Apache2Php8.3Iptables 第一坑 数…...

【大数据学习 | Spark-Core】Spark的分区器(HashPartitioner和RangePartitioner)

之前学过的kv类型上面的算子 groupby groupByKey reduceBykey sortBy sortByKey join[cogroup left inner right] shuffle的 mapValues keys values flatMapValues 普通算子&#xff0c;管道形式的算子 shuffle的过程是因为数据产生了打乱重分&#xff0c;分组、排序、join等…...

第六届国际科技创新学术交流大会(IAECST 2024)暨第四届物流系统与交通运输国际学术会议(LSTT 2024)

重要信息 会议官网&#xff1a;www.lstt.org 大会时间&#xff1a;2024年12月6-8日 大会地点&#xff1a;中国-广州 大会简介 第六届国际科技创新学术交流大会暨第四届物流系统与交通运输国际学术会议&#xff08;LSTT 2024&#xff09;将于2024年12月6-8日在广州举办&…...

看Threejs好玩示例,学习创新与技术(ogl)

本文标题可能看的你莫名奇妙&#xff0c;什么是ogl&#xff1f;ogl是一个新的三维引擎库&#xff0c;可以简单任务是非常简化的ThreeJS。下面图是它的一个示例&#xff0c;可见虽然它是一个麻雀&#xff0c;但五脏还是比较全的。 1、先说OGL OGL的代码非常简单&#xff0c;主要…...

读书笔记_《创华为.任正非传》_精华书摘

人生经历 43岁&#xff0c;开始创建华为 爷爷:金华火腿乡间厨师 父亲: 1910年生&#xff0c;北平民大经济系读书->职业学校任教->国民党兵工厂会计&#xff0c;组织读书会(读书会后来有很多人在新中国成立后成为高级干部。) 母亲: 高中毕业&#xff0c;乡村教师&#xf…...

4.4 MySQL 触发器(Trigger)

触发器是一种特殊的数据库对象&#xff0c;在特定事件&#xff08;如INSERT、UPDATE或DELETE&#xff09;触发时自动执行定义好的操作。它可以帮助我们实现更高效的数据管理和业务规则的约束。 1. 简介 1.1 什么是触发器 触发器&#xff08;Trigger&#xff09;是由用户定义的…...

遗传算法(Genetic Algorithm, GA)

简介 遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是一种基于自然选择和遗传机制的优化算法&#xff0c;由 John Holland 于20世纪70年代提出。它是一种模拟生物进化过程的启发式搜索算法&#xff0c;被广泛应用于函数优化、机器学习、调度问题等领域。 代码说明 …...