Bert基础(十二)--Bert变体之知识蒸馏原理解读

B站视频:https://www.bilibili.com/video/BV1nx4y1v7F5/

白话知识蒸馏

在前面,我们了解了BERT的工作原理,并探讨了BERT的不同变体。我们学习了如何针对下游任务微调预训练的BERT模型,从而省去从头开始训练BERT的时间。但是,使用预训练的BERT模型有一个难点,那就是它的计算成本很高,在有限的资源下很难运行。预训练的BERT模型有大量的参数,需要很长的运算时间,这使得它更难在手机等移动设备上使用。

为了解决这个问题,可以使用知识蒸馏法将知识从预训练的大型BERT模型迁移到小型BERT模型。

我们将了解基于知识蒸馏的BERT变体。首先,我们将了解知识蒸馏及其工作原理。然后,我们将学习DistilBERT模型。通过DistilBERT模型,我们将了解如何利用知识蒸馏将知识从一个预训练的大型BERT模型迁移到一个小型BERT模型中。

接下来,我们将学习TinyBERT模型。我们将了解什么是TinyBERT模型,以及它如何利用知识蒸馏从预训练的大型BERT模型中获取知识。我们还将探讨在TinyBERT模型中使用的几种数据增强方法。

最后,我们将学习如何将知识从一个预训练的大型BERT模型迁移到简单的神经网络中。

1 知识蒸馏简介

知识蒸馏(knowledge distillation)是一种模型压缩技术,它是指训练一个小模型来重现大型预训练模型的行为。知识蒸馏也被称为师生学习,其中大型预训练模型是教师,小模型是学生。让我们通过一个例子来了解知识蒸馏是如何实现的。

假设预先训练了一个大模型来预测句子中的下一个单词。我们将大型预训练模型称为教师网络。我们输入一个句子,让网络预测句子中的下一个单词。它将返回词表中所有单词是下一个单词的概率分布,如图所示。为了更好地理解,我们假设词表中只有5个单词。

在这里插入图片描述

从图中可以看到网络所返回的概率分布,这个概率分布是由softmax函数应用于输出层求得的。我们选择概率最高的单词作为句子中的下一个单词。因为Homework这个单词的概率最高,所以句子中的下一个单词为Homework。

除了选择具有高概率的单词外,能否从网络返回的概率分布中提取一些其他有用的信息呢?答案是肯定的。从下图中可以看到,除了概率最高的单词,还有一些单词的概率也相对较高。具体地说,Book和Assignment这两个单词的概率比Cake和Car略高。

在这里插入图片描述
这表明,除了Homework这个单词,Book和Assignment这两个单词与Cake和Car这样的单词相比,与输入的句子更为相关。这就是我们所说的隐藏知识。在知识蒸馏过程中,我们希望学生网络能从教师网络那里学到这些隐藏知识。

但通常情况下,任何好的模型都会为正确的类别返回一个接近1的高概率,而为其他类别返回非常接近0的概率。在本例中,假设模型已经返回了以下的概率分布。

在这里插入图片描述

从上图中,可以看到模型对Homework这个单词返回了一个非常高的概率,而对其他单词,概率都接近于或等于0。除了真值(正确的词)外,概率分布中没有其他太多的信息。那么如何提取隐藏知识呢?

这里,需要使用带有温度系数的softmax函数,它被称为softmax温度。我们在输出层使用softmax温度,用来平滑概率分布。带有温度系数的softmax函数如下所示。
p i = e x p ( z i / T ) ∑ j e x p ( z i / T ) p_i = \frac{exp(z_i/T)}{\sum_jexp(z_i/T)} pi=jexp(zi/T)exp(zi/T)

在上面的公式中,T 表示temperature,即温度。如果 T = 1 T =1 T=1 ,它就是标准的softmax函数。增加T值,可以使概率分布更加平滑,并提供更多关于其他类别的信息。

如图5-4所示,当 T = 1 T =1 T=1 时,我们将得到与使用标准softmax函数相同的概率分布。当 T = 2 T =2 T=2 时,概率分布会变平滑,而当 T = 5 T =5 T=5 时,概率分布会更加平滑。因此,通过增加 T T T 值,我们可以得到一个平滑的概率分布,从而得到更多关于其他类别的信息。

在这里插入图片描述
通过softmax温度,我们可以获得隐藏知识,即先用softmax温度对教师网络进行预训练,获得隐藏知识,然后在知识蒸馏过程中,将这些隐藏知识从教师网络迁移到学生网络。

2 训练学生网络

我们已经学习了如何预训练网络,使其可以预测句子中的下一个单词。这个预训练网络被称为教师网络。现在,让我们来学习如何将知识从教师网络迁移到学生网络。请注意,学生网络并没有经过预训练,只有教师网络经过预训练,并且在预训练过程中使用了softmax温度。

如下图所示,将输入句送入教师网络和学生网络,并得到概率分布作为输出。我们知道,教师网络是一个预训练网络,所以教师网络返回的概率分布是我们的目标。教师网络的输出被称为软目标,学生网络做出的预测则被称为软预测。

在这里插入图片描述
现在,我们来计算软目标和软预测之间的交叉熵损失,并通过反向传播训练学生网络,以使交叉熵损失最小化。软目标和软预测之间的交叉熵损失也被称为蒸馏损失。我们可以从下图中看到,在教师网络和学生网络中,softmax层的T值保持一致,且都大于1。

在这里插入图片描述
我们通过反向传播算法训练学生网络以使蒸馏损失最小化。除了蒸馏损失外,我们还使用另一个损失,称为学生损失。

为了理解学生损失,我们首先了解软目标和硬目标之间的区别。如图所示,采用教师网络返回的概率分布被称为软目标,而硬目标就是将高概率设置为1,其余概率设置为0。

在这里插入图片描述
现在,我们了解一下软预测和硬预测的区别。软预测是学生网络预测的概率分布,其中 T T T大于1,而硬预测是由 T = 1 T =1 T=1得到的概率分布。也就是说,硬预测是指使用标准的softmax函数预测,其中 T = 1 T =1 T=1

学生损失就是硬目标和硬预测之间的交叉熵损失。下图展示了如何计算学生损失和蒸馏损失。可以看出,为了计算学生损失,在学生网络中使用[插图]的softmax函数,得到硬预测。通过在软目标中,将具有高概率的位置设置为1,将其他位置设置为0来获得硬目标。然后,计算硬预测和硬目标之间的交叉熵损失,即学生损失。

在这里插入图片描述
为了计算蒸馏损失,我们使用T大于1的softmax函数计算软预测和软目标之间的交叉熵损失,即蒸馏损失。
最终的损失函数是学生损失和蒸馏损失的加权和,即:
L = α ⋅ 学生损失 + β ⋅ 蒸馏损失 L = \alpha·学生损失 + \beta·蒸馏损失 L=α学生损失+β蒸馏损失

α 和 β \alpha和\beta αβ是用于计算学生损失和蒸馏损失的加权平均值的超参数。我们通过最小化上述损失函数来训练学生网络。

总结一下,在知识蒸馏中,我们把预训练网络作为教师网络,并训练学生网络通过蒸馏从教师网络获得知识。训练学生网络需要最小化损失,该损失是学生损失和蒸馏损失的加权和。

3 DistilBERT模型——BERT模型的知识蒸馏版本

预训练的BERT模型有大量的参数,运算时间也很长,这使得它很难在智能手机等移动设备上使用。为了解决这个问题,Hugging Face的研究人员开发了DistilBERT模型。DistilBERT模型是一个更小、更快、更便宜、轻量级版本的BERT模型。

顾名思义,DistilBERT模型采用了知识蒸馏法。DistilBERT的理念是,采用一个预训练的大型BERT模型,通过知识蒸馏将其知识迁移到小型BERT模型中。预训练的大型BERT模型称为教师BERT模型,而小型BERT模型称为学生BERT模型。

与大型BERT模型相比,DistilBERT模型的速度要快60%,但其大小要小40%。现在,我们对DistilBERT模型有了基本的认识,下面让我们通过细节了解它的工作原理。

3.1 教师−学生架构

让我们详细了解教师BERT模型和学生BERT模型的架构。首先,看一下教师BERT模型,然后再看学生BERT模型。

教师BERT模型

教师BERT模型是一个预训练的大型BERT模型。我们使用预训练的BERT-base模型作为教师。在前面我们已经学习了BERT-base模型是如何进行预训练的。我们已知,BERT-base模型是使用掩码语言模型构建任务和下句预测任务进行预训练的。

因为BERT是使用掩码语言模型构建任务进行预训练的,所以可以使用预训练的BERT-base模型来预测掩码单词。预训练的BERT-base模型如下图所示。

从图中可以看到,输入一个带掩码的句子,预训练的BERT模型输出了词表中所有单词是掩码单词的概率分布。这个概率分布包含隐藏知识,我们需要将这些知识迁移到学生BERT模型中。下面,让我们看看这是如何实现的。

在这里插入图片描述
学生BERT模型

与教师BERT模型不同,学生BERT模型没有经过预训练。学生BERT模型必须向老师学习。它是一个小型BERT模型,与教师BERT模型相比,它包含的层数较少。教师BERT模型包含1.1亿个参数,而学生BERT模型仅包含6600万个参数。

因为学生BERT模型中的层数较少,所以与教师BERT模型(BERT-base模型)相比,它的训练速度更快。

DistilBERT模型的研究人员将学生BERT模型的隐藏层大小保持在768,与教师BERT模型(BERT-base模型)的设置一样。他们发现,减少隐藏层的大小对计算效率的影响并不明显,所以,他们只关注减少层数。

3.2 训练学生BERT模型(DistilBERT模型)

训练学生BERT模型可以使用预训练的教师BERT模型所使用的相同数据集。我们知道,BERT-base模型是使用英语维基百科和多伦多图书语料库数据集进行预训练的,同样,我们可以使用这些数据集来训练学生BERT模型(小型BERT模型)。

我们可以从RoBERTa模型中借鉴一些训练策略。RoBERTa是一个BERT变体。这里,我们只使用掩码语言模型构建任务来训练学生BERT模型,并在该任务中使用动态掩码,同时在每次迭代中采用较大的批量值。

如下图所示,将一个含掩码的句子作为输入送入教师BERT模型(预训练BERT-base模型)和学生BERT模型,得到词表的概率分布。接下来,计算软目标和软预测之间的交叉熵损失作为蒸馏损失。

在这里插入图片描述
在计算蒸馏损失时,我们同时计算了学生损失,即掩码语言模型损失,也就是硬目标(事实真相)和硬预测( T = 1 T=1 T=1的标准softmax函数预测)之间的交叉熵损失,如下图

在这里插入图片描述
除了蒸馏损失和学生损失,还需计算余弦嵌入损失(cosine embedding loss)。它是教师BERT模型和学生BERT模型所学的特征向量之间的距离。最小化余弦嵌入损失将使学生网络的特征向量更加准确,与教师网络的嵌入向量更接近。

可见,损失函数是以下3种损失之和:

  • 蒸馏损失;
  • 掩码语言模型损失(学生损失);
  • 余弦嵌入损失。

我们通过最小化以上3个损失之和来训练学生BERT模型(DistilBERT模型)。经过训练,学生BERT模型会习得教师BERT模型的知识。

DistilBERT模型可以达到BERT-base模型几乎97%的准确度。由于DistilBERT模型更加轻便,因此我们可以很容易地将其部署在任何终端设备上。与BERT模型相比,它的运算速度快了60%。

DistilBERT模型在8块16 GB的V100 GPU上进行了大约90小时的训练。Hugging Face已对外公开预训练的DistilBERT模型。正如原始BERT模型,我们也可以下载预训练好的DistilBERT模型,并为下游任务进行微调。

研究人员针对问答任务对预训练的DistilBERT模型进行了微调,并将其部署在iPhone 7 Plus上。他们将DistilBERT模型的运算速度与基于BERT-base模型的问答任务的运算速度做了比较,发现DistilBERT模型的运算速度比BERT-base模型快了71%,但模型大小只有207 MB。

4 TinyBERT模型简介

TinyBERT模型是BERT模型的另一个有趣的变体,它也使用了知识蒸馏法。通过DistilBERT模型,我们学会了如何将知识从教师BERT模型的输出层迁移到学生BERT模型中。但除此之外,还能从教师BERT模型的其他层迁移知识吗?答案是肯定的。

在TinyBERT模型中,除了从教师BERT模型的输出层(预测层)向学生BERT模型迁移知识外,还可以从嵌入层和编码层迁移知识。

让我们看一个例子。假设有一个N层编码器的教师BERT模型。为了避免重复,下图中只显示了预训练的教师BERT模型中的一个编码器层。输入一个含掩码的句子,教师BERT模型返回词表中所有被掩盖单词的logit向量。

在这里插入图片描述
在DistilBERT模型中,我们用教师BERT模型的输出层产生的logit向量(1)训练学生BERT模型以产生同样的logit向量。除此以外,在TinyBERT模型中,我们还用教师BERT模型产生的隐藏状态和注意力矩阵(2)来训练学生BERT模型以产生相同的隐藏状态和注意力矩阵。接下来,从教师BERT模型中获取嵌入层的输出(3)来训练学生BERT模型,使其产生与教师BERT模型相同的嵌入矩阵。

因此,在TinyBERT模型中,除了将知识从教师BERT模型的输出层迁移到学生BERT模型外,我们还将中间层的知识迁移到学生网络中,这有助于学生BERT模型从教师BERT模型那里获得更多的信息。比如,注意力矩阵包含语法信息。通过迁移教师BERT模型的注意力矩阵中的知识,有助于学生BERT模型从教师BERT模型那里获得语法信息。

除此之外,在TinyBERT模型中,我们使用了一个两阶段学习框架,即在预训练阶段和微调阶段都应用知识蒸馏法。下面,我们将了解两阶段学习究竟是如何进行的。

4.1 教师−学生架构

为了理解TinyBERT模型的工作原理,我们首先了解一下预设条件和所使用的符号。下图展示了TinyBERT模型的教师−学生架构。

在这里插入图片描述
教师BERT模型

如上图所示,教师BERT模型由N个编码器组成。将输入句送入嵌入层,得到输入嵌入。接下来,将输入嵌入传递给编码器层。这些编码器层利用自注意力机制学习输入句的上下文关系并返回特征。然后,将该特征送入预测层。

预测层是一个前馈网络。如果执行的是掩码语言模型构建任务,那么预测层将返回词表中所有单词是掩码单词的logit向量。

我们使用预训练的BERT-base模型作为教师BERT模型。BERT-base模型包含12层编码器和12个注意力头,其所生成的特征大小(隐藏状态维度 d d d)为768。教师BERT模型包含1.1亿个参数。

学生BERT模型

如图5-13所示,学生BERT模型的架构与教师BERT模型相似,但不同的是,学生BERT模型由M 个编码器组成,且N大于M 。也就是说,教师BERT模型中的编码器层数大于学生BERT模型中的编码器层数。

我们使用具有4层编码器的BERT模型作为学生BERT模型,并将特征大小(隐藏状态维度[插图])设置为312。学生BERT模型只包含1450万个参数。

现在我们了解了TinyBERT模型的教师−学生架构,但蒸馏究竟是如何进行的?我们如何将知识从教师BERT模型迁移到学生BERT模型(TinyBERT模型)?

4.2 TinyBERT模型的蒸馏

我们已知除了从教师BERT模型的输出层(预测层)向学生BERT模型迁移知识外,也可以从其他层迁移知识。下面,让我们看看在以下各层中,蒸馏是如何进行的。

  • Transformer层(编码器层)
  • 嵌入层(输入层)
  • 预测层(输出层)

下图显示了教师BERT模型和学生BERT模型(TinyBERT模型)的架构。

在这里插入图片描述
注意,在教师BERT模型中,索引0表示嵌入层,1表示第1个编码器,2表示第2个编码器。N表示第N个编码器,而N+1表示预测层。同样,在学生BERT模型中,索引0表示嵌入层,1表示第1个编码器,2表示第2个编码器。M表示第M个编码器,M+1表示预测层。

将知识从教师BERT模型迁移到学生BERT模型的过程如下。

n = g ( m ) n=g(m) n=g(m)

上面的公式表示使用映射函数g,将知识从教师BERT模型的第n层迁移到学生BERT模型的第m层。也就是说,学生BERT模型的第m层学习到了教师BERT模型的第n层的信息。

举例如下:

  • 0 = g ( 0 ) 0 = g(0) 0=g(0)表示将知识从教师BERT模型的第0层(嵌入层)迁移到学生BERT模型的第0层(嵌入层);
  • N + 1 = g ( M + 1 ) N+1 = g(M+1) N+1=g(M+1)表示将知识从教师BERT模型的第[插图]层(预测层)迁移到学生BERT模型的第[插图]层(预测层)。

现在,我们对TinyBERT模型中的知识蒸馏方法有了基本的认识。下面将讲解知识蒸馏是如何在每一层发生的。

4.3 Transformer层蒸馏

Transformer层就是编码器层。我们知道在编码器层,使用多头注意力来计算注意力矩阵,然后将隐藏状态的特征作为输出。在Transformer层蒸馏中,我们除了将知识从教师的注意力矩阵迁移到学生中,也将知识从教师的隐藏状态迁移到学生中。因此,Transformer层蒸馏包括两次知识蒸馏。

  • 基于注意力的蒸馏
  • 基于隐藏状态的蒸馏

首先,让我们了解基于注意力的蒸馏是如何工作的。

基于注意力的蒸馏

在基于注意力的蒸馏中,我们将注意力矩阵中的知识从教师BERT模型迁移到学生BERT模型。注意力矩阵含有不少有用的信息,如句子结构、指代信息等。这些信息有助于更好地理解语言。因此,将注意力矩阵的知识从教师迁移到学生中非常有用。

为了进行基于注意力的蒸馏,可以通过最小化学生BERT模型和教师BERT模型注意力矩阵的均方误差来训练学生网络。基于注意力的蒸馏损失 L a t t n L_{attn} Lattn的计算公式如下所示。

L a t t n = 1 n ∑ i = 1 h M S E ( A i S , A i T ) L_{attn} = \frac1n\sum_{i=1}^hMSE(A_i^S,A_i^T) Lattn=n1i=1hMSE(AiS,AiT)

因为Transformer采用多头注意力机制,所以,上面公式中的符号含义如下。

  • h h h表示注意力头的数量。
  • A i S A_i^S AiS表示学生网络的第 i i i个注意力头的注意力矩阵。
  • A i T A_i^T AiT表示教师网络的第 i i i个注意力头的注意力矩阵。
  • MSE表示均方误差。

可见,我们通过最小化学生和教师的注意力矩阵之间的均方误差来进行基于注意力的蒸馏。需要注意的是,我们使用的是一个未归一化的注意力矩阵,即未被softmax函数处理过的注意力矩阵。这是因为未归一化的注意力矩阵表现得更好且能更快地收敛。这一过程如图所示。
在这里插入图片描述
从上图中,可以看到我们是如何将注意力矩阵中的知识从教师BERT模型迁移到学生BERT模型中的。

基于隐藏状态的蒸馏

现在,让我们看看如何进行基于隐藏状态的蒸馏。隐藏状态是编码器的输出,也就是特征值。因此,在基于隐藏状态的蒸馏中,我们是将知识从教师编码器的隐藏状态迁移到学生编码器的隐藏状态。用 H S H^S HS表示学生的隐藏状态, H T H^T HT表示教师的隐藏状态。然后,通过最小化 H T H^T HT H S H^S HS之间的均方误差来进行蒸馏,如下所示。

L h i d n = M S E ( H S , H T ) L_{hidn} = MSE(H^S,H^T) Lhidn=MSE(HS,HT)

H T H^T HT H S H^S HS的维度是不同的。d表示 H T H^T HT的维度,而 d ‘ d^` d表示 H S H^S HS的维度。我们已知教师BERT模型是BERT-base模型,而学生BERT模型是TinyBERT模型,所以d总是大于 d ‘ d^` d

因此,为了使学生的隐藏状态 H S H^S HS与教师的隐藏状态 H T H^T HT在同一个维度上,我们将 H S H^S HS乘以矩阵 W h W^h Wh进行线性变换。请注意, W h W^h Wh的值是在训练中学习的。我们将损失函数进行改写,如下所示。

L h i d n = M S E ( H S W h , H T ) L_{hidn} = MSE(H^SW_h,H^T) Lhidn=MSE(HSWh,HT)

从上面的公式可以看出,将 H S H^S HS与矩阵 W h W^h Wh相乘,从而对 H S H^S HS进行变换,使其与 H T H^T HT在同一维度上。如图所示,我们可以看到隐藏状态的知识是如何从教师BERT模型迁移到学生BERT模型的。

在这里插入图片描述
嵌入层蒸馏

在嵌入层蒸馏中,知识将从教师的嵌入层迁移到学生的嵌入层。我们用 E S E^S ES表示学生的嵌入矩阵, E T E^T ET表示教师的嵌入矩阵,那么通过最小化 E S E^S ES E T E^T ET之间的均方误差来训练网络进行嵌入层蒸馏,如下所示。
L e m b d = M S E ( E S , E T ) L_{embd} = MSE(E^S,E^T) Lembd=MSE(ES,ET)

同样,学生的嵌入矩阵和教师的嵌入矩阵的维度也不同。因此,需要将学生的嵌入矩阵 E S E^S ES乘以 W e W_e We,使其与教师的嵌入矩阵处于同一空间。得到的损失函数如下所示。

L e m b d = M S E ( E S W e , E T ) L_{embd} = MSE(E^SW_e,E^T) Lembd=MSE(ESWe,ET)

预测层蒸馏

在预测层蒸馏中,我们迁移的是最终输出层的知识,即教师BERT模型产生的logit向量。与DistilBERT模型的蒸馏损失相似,我们通过最小化软目标和软预测之间的交叉熵损失来进行预测层蒸馏。用 Z S Z^S ZS表示学生网络的logit向量, Z T Z^T ZT表示教师网络的logit向量,损失函数表示如下。

L p r e d = − s o f t m a x ( Z T ) ⋅ l o g − s o f t m a x ( Z S ) L_{pred} = -softmax(Z^T)· log_-softmax(Z^S) Lpred=softmax(ZT)logsoftmax(ZS)

4.4 最终损失函数

包含所有层的蒸馏损失的损失函数如下所示。

在这里插入图片描述
从上面的公式中,可以得出以下结论。

  • 当m为0时,表示训练层是嵌入层,所以使用嵌入层损失。
  • 当m大于0且小于或等于M时,表示训练层是Transformer层(编码器层),所以用隐藏状态损失和注意力层损失之和作为Transformer层的损失。
  • 当m为M+1时,表示训练层是预测层,所以使用预测层损失。最终的损失函数如下所示。

最终的损失函数如下所示。
L = ∑ m = 0 M + 1 λ m L l a y e r ( S m , T g ( m ) ) L = \sum_{m=0}^{M+1}\lambda_mL_{layer}(S_m,T_{g(m)}) L=m=0M+1λmLlayer(Sm,Tg(m))

在上面的公式中, L l a y e r L_{layer} Llayer表示第m层的损失函数, λ m \lambda_m λm为一个超参数,它用来控制第m层的权重。我们通过最小化上面的损失函数来训练学生BERT模型(TinyBERT模型)。

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

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

相关文章

物联网实验

实验1 基于ZStack光敏传感器实验 1.实验目的 我们通过上位机发指令给协调器,协调器把串口接收到的指令通过Zigbee协议无线发送给带有光敏传感器的终端节点,获取到数据以后把数据返回给上位机,实现无线获取数据的目的。 2.实验设备 硬件&a…

企业鸿蒙原生应用元服务备案实操包名公钥签名信息

一、鸿蒙应用/元服务如何查询包名? 登录 AppGallery Connect ,点击“我的应用”,输入应用名称可查询到需要备案的鸿蒙应用/元服务包名。 二、鸿蒙应用/元服务如何获取公钥和签名信息? (1)登录 AppGaller…

【IC验证】类的一些问题

1、句柄悬空 在声明句柄和创建对象以后,句柄是悬空的,在仿真没开始时内容为null。但是对于结构体和module的例化,仿真开始之前变量就给了一个不确定的值(32hxxxx) 但是对于放在initial块里面的,在仿真之前…

龙蜥社区「人人都可以参与开源」——体验开源成为“开源人“

龙蜥社区「人人都可以参与开源」体验开源——让更多的人了解开源! 龙蜥社区开源概述:龙蜥社区开源的探索过程:龙蜥社区收获总结:AtomGit评测:服务设计上:功能结构上:安全设计上: AtomGit测评总结: 龙蜥社区开源概述: 在追求技术的路上少不了…

【智能算法】人工电场算法(AEFA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2019年,A Yadav等人受库伦定律和运动定律启发,提出了人工电场算法(Artificial Electric Field Algorithm,AEFA)。 2.算法原理 2.1算法思…

二维相位解包理论算法和软件【全文翻译- DCT相位解包裹(5.3.2)】

5.3.2 基于 DCT 的方法 在本节中,我们将详细介绍如何通过 DCT 算法解决非加权最小二乘相位解缠问题,而不是通过FFT.我们将使用公式 5.53 所定义的二维余弦变换。我们开发的算法等同于 FFT 方法 2(第 5.3.1 节)。与 FFT 方法 I 等价的 DCT 算法也可以推导出来,但我们将其作…

selenium 如何获取 session 指定的数据

代码核心在于这几个部分: 其一:使用元素定位来获取页面上指定需要抓取的关键字; 其二:将页面上定位得到的数据永久存储到本地文件中。 具体来梳理一下从访问URL开始到爬取数据整个流程下来的各个节点我们都做了哪些工作。 我们来看…

C语言——详解字符函数和字符串函数(二)

Hi,铁子们好呀!之前博主给大家简单地介绍了部分字符和字符串函数,那么这次,博主将会把这些字符串函数给大家依次讲完! 今天讲的具体内容如下: 文章目录 6.strcmp函数的使用及模拟实现6.1 strcmp函数介绍和基本使用6.1.1 strcmp函…

Vulnhub靶机练习笔记-Os-hackNos-1

vulnhub靶机下载 https://www.vulnhub.com/entry/hacknos-os-hacknos,401/ 靶场环境: NAT模式 kali:192.168.242.131 靶机:192.168.242.142 渗透 nmap探测靶机 开放了80和22端口 dirsearch对80端口进行目录扫描,发现drupal…

nacos derby.log无法的读取+derby数据库启动失败分析解决

排查思路分析 日志报错: derby.log文件权限不够(root权限),无法读取,我用普通用户启动。 使用命令chown xx:xx derby.log修改属主和属组为普通用户后,又报出其他错误。 数据库启动不了,无…

图片怎么批量改格式png改jpg?一键批量搞定方法

在创建幻灯片或演示文稿时,使用jpg格式可以减小文件大小,方便分享和传输。转换png格式的图片为jpg,可以确保文件大小的合理控制,同时保持图像的可视质量,当遇到需要批量处理的时候,许多小伙伴都不太懂图片怎…

鸿蒙OS开发学习:【尺寸适配实现】

概述 在鸿蒙开发中,尺寸适配是一个重要的概念,它可以帮助我们在不同屏幕尺寸的设备上正确显示和布局我们的应用程序。本文将介绍如何在鸿蒙开发中实现尺寸适配的方法。 流程图 详细步骤 1. 定义适配方案 在鸿蒙开发中,我们可以通过定义适…

基于springboot+vue实现的的成人教育教务系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…

Windows Nginx 启动

先解压 nginx安装包,进入到安装目录下(配置环境变量没有用) 解压后的目录结构如上。 #启动服务 默认是80端口, #如果端口被占用,是启动不了的,会生成error log在log目录下 start nginx#停止nginx 服务 nginx -s stop#重新加载配置…

C语言进阶课程学习记录-第29课 - 指针和数组分析(下)

C语言进阶课程学习记录-第29课 - 指针和数组分析(下) 数组名与指针实验-数组形式转换实验-数组名与指针的差异实验-转化后数组名加一的比较实验-数组名作为函数形参小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程,图片全部来源于课…

数字社会下的智慧公厕:构筑智慧城市的重要组成部分

智慧城市已经成为现代城市发展的趋势,而其中的数字化转型更是推动未来社会治理体系和治理能力现代化的必然要求。在智慧城市建设中,智慧公厕作为一种新形态的信息化公共厕所,扮演着重要角色。本文智慧公厕源头实力厂家广州中期科技有限公司&a…

线圈大小的测量和圈数的绕制办法

测量一根线圈的大小,让线圈多出来一公分多一点!!! 我在这简称样圈 然后在模具上进行绕制。 把样圈放在模具上,松紧度要刚好,确定好模具 具体位置 线记在 中间铁心上 开始绕制 这叫做一圈 绕好相应的圈数后…

如何通过代码混淆绕过苹果机审,解决APP被拒问题

目录 iOS代码混淆 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 混淆前后对比 iOS代码混淆 …

自定义树形筛选选择组件

先上效果图 思路:刚开始最上面我用了el-input,选择框里面内容用了el-inputel-tree使用,但后面发现最上面那个可以输入,那岂不是可以不需要下拉就可以使用,岂不是违背了写这个组件的初衷,所以后面改成div自定…

【ZZULIOJ】1053: 正弦函数(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 输入x,计算上面公式的前10项和。 输入 输入一个实数x。 输出 输出一个实数,即数列的前10项和,结果保留3位小数。 样例输入 Copy 1 样例输出 Copy 0.841 c…