读书笔记:多Transformer的双向编码器表示法(Bert)-1

news2024/12/24 9:36:37

多Transformer的双向编码器表示法

Bidirectional Encoder Representations from Transformers,即Bert;

在这里插入图片描述

本笔记主要是对谷歌Bert架构的入门学习:

  • 介绍Transformer架构,理解编码器和解码器的工作原理;
  • 掌握Bert模型架构的各个部分,了解如何进行模型的预训练、模型微调(将预训练的结果用于下游任务);
  • 学习Bert的不同变体、基于知识蒸馏的变体;
  • 一些其他模型架构;
  • 用于获取句子特征的Sentence-Bert模型以及一些用于特定领域的Bert模型(医学or生物学);
  • VideoBert模型;

目标是熟练掌握Bert及其变体来执行实际的自然语言处理任务;利用Bert模型超强的理解能力来简化自然语言处理任务;

章节目录

  • 第1章 Transformer概览
  • 第2章 了解Bert模型(掩码语言模型构建和下句预测)
  • 第3章 Bert实战
  • 第4章 Bert变体:ALBERT、RoBERTa、ELECTRA和SpanBERT
  • 第5章 Bert变体:基于知识蒸馏
  • 第6章 用于文本摘要任务的BERTSUM模型
  • 第7章 将Bert模型应用于其他语言
  • 第8章 Sentence-Bert模型和特定领域的Bert模型
  • 第9章 VideoBERT模型和BART模型

要求环境 Python3

第一部分 开始使用BERT

  • 第1章 Transformer概览
  • 第2章 了解Bert模型(掩码语言模型构建和下句预测)
  • 第3章 Bert实战

第1章 Transformer概览

自注意力机制

Transformer完全依赖于注意力机制,并摒弃了循环;使用了一种特殊的注意力机制,称为自注意力(self-attention)

实例:文本翻译(从英文翻译为法文)

  • 向编码器输入一句话(原句)
  • 让其学习到这句话的特征1;
  • 在将特征作为输入传输给解码器;
  • 最后通过解码器生成输出句(目标句);

N个编码器:

Transformer中的编码器不止一个,而是由一组N个编码器串联而成,一个编码器的输出作为下一个编码器的输入;

原句的特征会由最后一个编码器输出,编码器的作用就是提取原句中的特征;

Transformer原论文中“Attention is all your need”中,作者使用的N=6;

关于Transformer的学习可以参考之前总结的blog:

  • 《Transformer应用实践(学习篇)》
  • 《Transformer应用实践(补充)》

每个编码器的组成:

I am good -> 【多头注意力层 -> 前馈网络层 】-> …

每一个编码器的构造都是相同的,并且包含两个部分:

  • 多头注意力层
  • 前馈网络层

首先我们要了解“自注意力机制”:

以一句话为例:“A dog ate the food beacause it was hungry”,计算机模型要理解it的意思是dog还是food,自注意力机制有助解决该问题;

模型会一次计算每个单词的特征值,当计算每个词的特征值时,模型都需要遍历每个词与句子中其他词的关系;模型可以通过词与词之间的关系来更好的理解当前词的意思;

  • it的特征值 由它本身与句子中其他词的关系计算所得;
  • 关系越紧密,相应的注意力表示权重也就也大;

我们以一个简单的句子“I am good”为例:

  • 首先,需要将词转化为其他对应的词嵌入向量;需要注意的是,嵌入只是的特征向量,这个特征向量也是需要通过训练获得的;
  • 这个句子的词嵌入向量,可以表示为矩阵X = [x1, x2, x3];矩阵X的维度是[句子的长度 x 词嵌入向量维度],可以是512;
  • 现在,通过X创建3个新的矩阵:
    • 查询query矩阵Q:相当于问题提示
    • 键key矩阵K:类似问题的标准答案
    • 值value矩阵V:相当于我们期待的答案

关于三个新的矩阵QKV我们来具体看下:

  • 要创建这三个矩阵,需要先创建另外三个权重矩阵,分别为WQ/WK/W^V,用矩阵X分别乘以权重矩阵,就会得到Q、K、V三个矩阵;
  • 值得注意的是:三个权重矩阵的初始值是随机的,其最优值需要通过训练获得;
  • 这些权重矩阵的值越优,通过计算所得的查询矩阵、键矩阵、值矩阵也会越精确;

Q、K、V三个矩阵的行数与X一致,它们的每一行分别表示一个单词的q、k、v向量;向量的维度由参与计算的权重矩阵决定,可以是64;

那么,为什么要使用Q、K、V三个矩阵?如何才能用自注意力模型?我民额继续;

理解注意力机制:

已经计算得到Q、K、V矩阵,是要应用于注意力机制的;我们知道,要计算一个词的特征值,自注意力机制会使该词与给定句子中所有词联系起来;了解一个词与句子中所有词相关程度有助于更精确地计算特征值;

自注意力机制的4个步骤:

  • 1.计算Q与K^T的点积:
    • Q和K的shape一致,KT表示K矩阵的转置;Q的每一行代表一个词的查询向量q,KT的每一列表示相应词的键向量k,那么点积的结果是一个 词数x词数的矩阵,它的每一行计算的是 q1和k1、k2、k3的点积;
    • 通过计算两个向量的点积可以知道它们之间的相似度;这样通过计算q1和k1、k2、k3的点积,就可以了解单词“I”与句子“I am good”中所有单词的相似度,显然q1与k1的点积值最大,因为“I”这个词与自己的关系要比与其他词的关系更紧密;
    • 综上,计算Q和K^T的点积,得到了句子中每个词与所有其他词的相似度分数矩阵,即Q·K^T
  • 2.将Q·K^T 矩阵除以键向量维度的平方根:
    • 这样做的目的,主要是为了获得稳定的梯度;
    • 如果用dk 表示键向量维度(这里使用64),那么它的平方根就是8;
  • 3.使用softmax函数对目前所得相似度分数进行归一化处理:
    • 应用softmax函数可以将数值分布在0~1的范围内,且每一行(向量)的所有数之和等于1(即百分之百);
    • 然后得到的矩阵,成为“分数矩阵”,通过这些分数,可以了解到句子中每个词与所有词的相关程度,softmax(Q·K^T/√dk)
  • 4.计算注意力矩阵Z:
    • 注意力矩阵要包含的是句子中每个单词的注意力值,通过将分数矩阵乘以值矩阵V得到;
    • 注意力矩阵Z就是值分量(WordNum x 64)与分数(WordNum x WordNum)加权之后求和的结果,即“分数加权的值向量之和”,Z = softmax(Q·K^T/√dk)V (WordNum x 1);
import numpy as np
test_a = np.array([[1,2,3],[4,5,6],[4,5,6]])
test_b = np.array([[1,4,5,6],[2,7,8,9],[3,10,11,12]])
print(test_a.shape,test_b.shape)
# 点积计算
np.matmul(test_a, test_b)
(3, 3) (3, 4)

array([[ 14,  48,  54,  60],
       [ 32, 111, 126, 141],
       [ 32, 111, 126, 141]])
# 求和
np.matmul(test_a, test_b).sum(axis=1)
array([176, 410, 410])

单词“I”的自注意力值:假设“I”的分数向量是[0.9, 0.07, 0.03],那么其自注意力值就包含了90%的值向量v1(I)、7%的值向量v2(am)、3%的值向量v3(good);

再看之前的例子,“A dog ate the food beacause it was hungry”,计算机模型要理解it的意思是dog还是food,可以计算it这个词的自注意力值,它对dog词的值分量的权重会更大;

这也说明了:通过自注意力机制,我们可以了解一个词与句子中所有词的相关程度;

注意力矩阵Z由句子中所有单词的自注意力值组成,公式为Z = softmax(Q·K^T/√dk)V

自注意力机制也被称为“缩放点积注意力机制”;

多头注意力层:

  • 指我们使用多个注意力头,而不只是一个,使用的计算注意力矩阵方法,同求Z;
  • 以之前it指代的例子来说,它实际上是由其他词(这里是dog)的值向量控制(假设权重是100%),由于这个词的含义是模糊的,此时这种控制关系是有用的,但为了确保结果准确,不能依赖单一的注意力矩阵,应该设计多个,并将其结果串联起来;

使用多头注意力的逻辑为:使用多个注意力矩阵,可以提高注意力矩阵的准确性;

我们知道:为了计算注意力矩阵,需要创建三个新的矩阵QKV,为此还要引入三个新的权重矩阵;要计算多个注意力矩阵,就需要这样的多组数据;

假设我们有8个注意力矩阵,Z1到Z8,将所有的注意力头(就是注意力矩阵)串联起来,并将结果乘以一个新的权重矩阵W0,从而得到最终的注意力矩阵;

Multi-head attention = Concatenate(Z1,Z2...,Z8) W0

位置编码

位置编码:(position encoding)

指词在句子中的位置编码;仍以“I am good”为例,在循环神经网络RNN中,句子是逐字送入学习网络,最终完全理解整个句子;但在Transformer网络则是将句子中所有词并行输入到神经网络(并行有助于缩短训练时间,同时有利于学习长期依赖);

既然是并行输入,那么就无法保留词序,而词序有很重要,因此也要为Transformer输入一些关于词序的信息;

对于给定的句子:

  • 首先计算每个单词在句子中的嵌入值,词嵌入维度可以表示为dmodel,那么输入矩阵的维度就是[句子长度 x 嵌入维度],如3 x 512;
  • 如果把输入矩阵直接传给Transformer,模型就无法理解词序,因此需要给输入矩阵添加一些表明词序的信息,以便神经网络可以理解句子含义,这里要用到的技术就是“位置编码”技术;

位置编码矩阵P,其shape与X相同,只需将P添加到X中,再输入神经网络,就可以让输入矩阵既包含词的嵌入,也包含词在句子中的位置信息,X = X + P

一种计算位置编码矩阵P的方式——“使用正弦函数来计算位置编码”

  • pos表示词在句子中的位置,i表示在输入矩阵中的位置;
  • 当i是偶数时,使用sin函数,i为奇数时,使用cos函数(示意图中10000^0,表示10000的0次幂);
  • I的pos=0,am的pos=1,。。。
  • 最后将输入矩阵X与计算所得位置编码矩阵P进行逐元素相加即可输入到编码器模块;

在这里插入图片描述

  • I am good
  • 词嵌入矩阵 + 位置编码矩阵
  • 输入编码器,提取特征值

而一个编码器模块是由 多头注意力层 和前馈网络层 两部分组成,而此前我们已经了解了多头注意力层,接下来看下前馈网络层;

理解编码器

前馈网络层:

在编码器模块中,前馈网络层 接在 多头注意力层后;它由两个有ReLU激活函数的全连接层组成,前馈网络的参数在句子的不同位置是相同的,但在不同的编码器模块上是不同的;

编码器的“叠加和归一组件”:

  • 它同时连接一个子层的输入和输出,示意如下:
输入矩阵 编码器模块编码器模块编码器模块编码器模块编码器模块
输入多头注意力层→叠加和归一组件前馈网络层→叠加和归一组件
   
 
  • 叠加和归一化组件实际上包含了一个残差连接与层的归一化;层的归一化可以防止每层的值剧烈变化,从而提高模型训练速度;

现在回顾下编码器及前后的部分:

  • 输入值的嵌入:将输入转换为嵌入矩阵(即输入矩阵);
  • 位置编码:将位置编码嵌入输入矩阵;
  • 编码器1 … 编码器N:使用输入矩阵作为编码器输入;
  • 编码器接受输入,在内部:
    • 首先将其送入多头注意力层,该子层运算后输出注意力矩阵;
    • 将注意力矩阵输入到下一子层,即前馈网络层,输出特征值;
  • 后续编码器的输入是前一编码器的输出;

N个叠加的编码器的输出特征值记为R,再把R作为输入传给解码器,解码器将基于这个输入生成目标句;

理解解码器

I am good => 通过编码器学习原句,并计算特征值 => 解码器将特征值作为输入,生成目标句”我很好“;

类似编码器叠加N个,解码器也可以有N个叠加,一个解码器的输入会作为输入传给下一个解码器;值得注意的是:编码器输出的特征值,将作为输入传给所有解码器,因此一个解码器有两个输入,一个是来自前一解码器的输出,另一个是编码器输出的特征值;

生成目标句的过程:

  • 使用t表示时间步,当t=1时,解码器输入<sos>表示句子开始,生成目标句的第一个词”我“;
  • t=2时,解码器使用当前的输入和上一步(t-1)生成的单词,预测句子中的下一个单词,即将<sos>和”我“作为输入,并试图生成目标句中的下一个词;
  • 在每一步中,解码器都将上一步新生成的单词与输入的词结合起来,并预测下一个单词;
  • 在最后一步t=4时,解码器的输入是<sos>、我、很、好作为输入,试图生成下一个词,如果生成的标记为<eos>则表示句子结束;就意味着解码器已经完成了对目标句的生成;

对于解码器的输入,实际同样需要将其转换为嵌入矩阵,为其添加位置编码

解码器模块:

 解码器模块解码器模块解码器模块 
带掩码的多头注意力层→多头注意力层→前馈网络层

内部包含三个子层:

  • 带掩码的多头注意力层
  • 多头注意力层
  • 前馈网络层

相比编码器模块,多了带掩码的多头注意力层;

带掩码的多头注意力层:

  • 以翻译任务为例,参与训练的样本需要包含两部分,即原句和目标句;
  • 解码器可以直接将整个目标句稍作修改作为输入,将<sos>标记添加到目标句的开头,并在每一步将下一个预测词与输入结合起来,以预测目标句;

过程举例说明如下:

  • <sos>我很好输入解码器(实际输入是添加了位置编码的嵌入矩阵X),预测输出为我很好<eos>
  • 解码器中的第一层 带掩码的多头注意力层,与编码器中的多头注意力层有一点不同:
    • 为了运行自注意力机制,我们需要创建三个新矩阵Q K V,由于是多头,因此Q K V一共创建h组;每组中的Q K V可通过X分别乘以权重矩阵W^Q W^K W^V而得;
    • 而自注意力机制会将一个单词与句子中的所有单词联系起来,从而提取每个词的更多信息,但是,在测试期间,解码器只将上一步生成的词作为输入
    • 如t=2时,解码器的输入应只有[<sos>, "我"],并没有其他词;我也也需要实现这样的方式来训练模型:模型的注意力机制应该只与该词之前的单词有关;
    • 要做到这一点,可以掩盖后边所有还没有被模型预测的词,如当预测<sos>相邻的词,模型应只看见<sos>,那么就应该掩盖<sos>后边的词;
<sos>    掩码    掩码    掩码    
<sos>    我      掩码    掩码  
<sos>    我      很      掩码
<sos>    我      很      好

这样的掩码有助于自注意力机制只注意模型在测试期间可以使用的词;

我们知道:

  • 计算注意力矩阵的第一步是计算 查询矩阵Q与键矩阵转置的点积,第二步除以键向量维度的平方根以缩放,第三步应用softmax函数,将分值归一化;
  • 我们需要在应用softmax前,完成对数值的掩码转换;可以使用负无穷大来掩盖,测试代码如下;
  • 最后将softmax函数的结果与V相乘,得到注意力矩阵Z,h个注意力矩阵串联,结果乘以新的权重矩阵W,即可得到最终的注意力矩阵M;
import numpy as np
test_a = np.array([[1,2,3],[4,5,6],[4,5,6]], dtype=np.float32)
matrix = np.triu(np.ones(test_a.shape) * -np.inf, 1)  
test_a = test_a + matrix
test_a 
array([[  1., -inf, -inf],
       [  4.,   5., -inf],
       [  4.,   5.,   6.]])
def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0)

# 使用-inf掩盖的向量,在计算softmax时,不会分摊权重
test_a[0],softmax(test_a[0])
(array([  1., -inf, -inf]), array([1., 0., 0.]))

带掩码的多头注意力层输出的注意力矩阵M,送到解码器的下一个子层,这是一个多头注意力层;

多头注意力层:

我们之前提到过:编码器输出的特征值,将作为输入传给所有解码器,更准确的描述是:将作为输入传给所有解码器的多头注意力子层;即解码器中的多头注意力层有两个输入:一个来自带掩码的多头注意力层,另一个是编码器输出的特征值;

由于涉及编码器与解码器的交互,解码器的这一子层也被称为编码器-解码器注意力层

我们用R来表示编码器输出的特征值(每个词都对应一个特征向量,因此这里的R实际是一个矩阵),用M表示由带掩码的多头注意力层输出的注意力矩阵;我们知道多头注意力机制第1步就是创建Q K V三个矩阵(通过将输入矩阵乘以权重矩阵),但是R和M两个输入,究竟用谁?

答案是:我们使用M作为输入矩阵来创建查询矩阵Q,使用R作为输入矩阵创建K和V矩阵;

  • 这里查询矩阵Q是从M求得,所以本质上包含了目标句的特征;
  • 键矩阵和值矩阵用R计算,则包含了原句的特征;

细节的:

  • Q·K^T:其第一行是查询向量q1(<sos>)与所有键向量k1(I)、k2(am)、k3(good)的点积,因此第1行表示目标词<sos>与原句中所有词的相似度;最终得到的所有行对应 查询矩阵(目标句特征)与键矩阵(原句特征)的相似度;
  • 经过维度平方根的缩放,和softmax函数,得到分数矩阵,再乘以值矩阵V,即注意力矩阵Z,目标句的注意力矩阵Zi是通过分数加权的值向量之和计算的(每一个目标句词都对应了一个注意力向量),实际的可能是这样:Z2的注意力向量包含了0.98个值向量v1(I)、0.02个值向量v2(am)、0.00的值向量v3(good),这个结果可以帮助模型理解目标词我指代原词I;

计算h个注意力矩阵后,将它们串联起来,乘以一个新的权重矩阵,得到最终的注意力矩阵;将其输入解码器的下一个子层,即前馈网络层;

前馈网络层:

  • 其工作原理与解码器中一致;
  • 解码器的前馈网络层中的叠加和归一化组件同样连接子层的输入和输出,而且需要注意的是:解码器的三个子层都使用了叠加和归一化组件连接了子层的输入和输出;
  • 前馈网络层输出解码后的特征(最后一个解码器输出将是目标句的特征);

关于线性层和softmax层:

  • 解码器学习了目标句特征之后,需要将顶层(叠加的最后一个)解码器的输出送入线性层和softmax层;
  • 线性层将生成一个logit3(是一种概率分布)向量,其大小等于原句中的词汇量(这个应该是指词源量,而不是原句的词量,输出的词的索引值,也是要对应到总词汇表的);
  • 接下来,再使用softmax函数将logit向量转换成概率,然后将输出具有高概率值的词的索引值,即通过概率得到预测的词;

整合编码器和解码器

即Transformer架构;

  • 编码器学习原句特征并将其发送给解码器;
  • 解码器又会生成目标句;

训练Transformer

可以通过最小化损失函数来训练Transformer网络,解码器预测的是词汇的概率分布,并选择概率最高的词作为输出,因此损失函数的选择,需要让预测的概率分布和实际的概率分布之间的差异最小化,这样可以将损失函数定义为交叉熵损失函数,并使用Adam算法来优化训练过程;

需要注意的是,为了防止过拟合,可以将dropout方法应用于每个子层的输出,以及嵌入和位置编码的总和(这里说的可能是输入矩阵);

小结

了解了Transformer 编码器-解码器架构,了解使用的不同子层;我们了解到自注意力机制将一个词与句子中的所有词联系起来,以便更好的理解这个词;使用Q K V三个矩阵计算自注意力值;如何计算位置编码,以及如何用它来捕捉词序;

下一章,我们将学习Bert,以及它如何使用Transformer来对上下文嵌入进行学习。

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

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

相关文章

Tableau自学四部曲_Part4:BI仪表盘搭建

文章目录 一、数据可视化原则1. 区分用户2. 主次分明、详略得当3. 真实准确4. 符合大众认知和审美习惯5. 适度原则6. 五秒原则6. 恰到好处的说明7. 少即是多8. 可视化案例 二、BI仪表盘搭建1. 仪表盘搭建原则2. 明确仪表盘主题3. 仪表盘主题拆解4. 开发设计工作表5. 构思仪表盘…

LQR 控制器

LQR&#xff08;Linear Quadratic Regulator&#xff09;控制器 LQR&#xff08;Linear Quadratic Regulator&#xff09;是一种经典的线性控制器设计方法&#xff0c;用于设计线性时不变系统的状态反馈控制器&#xff0c;以最小化系统性能指标&#xff0c;通常是二次代价函数…

软件测试/测试开发丨ChatGPT:带你进入智能对话的新时代

简介 人工智能时代来临 我们正处于AI的iPhone时刻。——黄仁勋&#xff08;英伟达CEO&#xff09; ChatGPT 好得有点可怕了&#xff0c;我们距离危险的强人工智能不远了。——马斯克&#xff08;Tesla/SpaceX/Twitter CEO&#xff09; 以上的内容说明我们现在正处于一个技术大…

Docker镜像解析获取Dockerfile文件

01、概述 当涉及到容器镜像的安全时&#xff0c;特别是在出现镜像投毒引发的安全事件时&#xff0c;追溯镜像的来源和解析Dockerfile文件是应急事件处理的关键步骤。在这篇博客中&#xff0c;我们将探讨如何从镜像解析获取Dockerfile文件&#xff0c;这对容器安全至关重要。 02…

2023 年高教社杯全国大学生数学建模竞赛题D 题 圈养湖羊的空间利用率

2023 年全国大学生数学建模竞赛题D 题 圈养湖羊的空间利用率思路详解Python源码 昨天已经将E题第一二问的详解和思路源码都写了出来&#xff0c;大家如果想从E题下手的话推荐参考本人文章&#xff0c;个人认为E题在建模上是优于D题的&#xff0c;毕竟有给出数据而且有明确的建…

基于springboot+vue+mysql的新能源充电系统--前后端分离(内含源码+报告+部署教程)

新能源充电系统管理系统按照操作主体分为管理员和用户。管理员的功能包括反馈管理、客服聊天管理、充电桩管理、充电桩预约管理、字典管理、新能源公告管理、用户管理、管理员管理等&#xff0c;可以管理报修。用户的功能包括管理部门以及部门岗位信息&#xff0c;管理充电桩信…

2023年下半年高项考试学习计划

之前总结 2023年上半年的考试&#xff0c;对于我自己&#xff0c;就是虎头蛇尾&#xff0c;也谈不上太过自信&#xff0c;好好学习了一段时间之后&#xff0c;也就是不再发博文&#xff0c;截止到2022年11月的时候&#xff0c;自己就算是放弃了&#xff0c;没有再主动学习。 结…

华为云云耀云服务器L实例评测|老用户回归的初印象

华为云云耀云服务器L实例评测&#xff5c;老用户回归的初印象 前言一、新面孔1. 云耀云服务器2. 服务器特色 二、上手感官体验1. 性价比感受2. 推荐宝塔面板3. CloudShell登录4. 安全性 总结 前言 其实笔者接触华为云已经很久了&#xff0c;第一次使用的云服务器就是华为云。当…

【Linux成长史】Linux基本指令大全

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集 数据库专栏 初阶数据结构 &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如…

SpringMvc丨DispatcherServlet

​ ​ DispatcherServlet 是 Spring 框架中的一个核心组件&#xff0c;用于处理客户端请求并将请求分发到合适的处理程序&#xff08;Controller&#xff09;进行处理。它是 Spring MVC 框架的一部分&#xff0c;负责接收 HTTP 请求&#xff0c;将请求分发给控制器进行处理&a…

sed正则表达式

很多linux命令支持正则表达式&#xff0c;sed也不例外。 行开始 ( ^ ) 插入符^匹配一行的开始。比如说&#xff0c;匹配以103打头的行&#xff1a; sed -n /^103/p data.txt 注意&#xff0c;插入符只有在表达式的首位时&#xff0c;才表示行首匹配。 行尾( $) 美元符$匹…

怎样理解 Object 类中的 clone() 方法?

目录 1. clone() 方法说明 2. JVM 内存模型 3. 浅拷贝(浅克隆)与深拷贝(深克隆)的区别 4. 使用 clone() 克隆方法需要注意的事项 5. Object 类中的 clone() 方法为浅克隆 1. clone() 方法说明 clone() 方法是 Java.lang.Object 类中已经定义好的一个方法&#xff0c;该方…

文心一言、讯飞星火与GPT-4/3.5在回答中文历史问题的表现

最近&#xff0c;随着备受关注的文心一言正式免费向全社会开放&#xff0c;再次引起了社会层面对国产大模型的兴趣。 以文心一言为代表的国产大模型性能究竟如何&#xff1f;如果将它们相互比较&#xff0c;并且和GPT系列模型等国际前沿水平的LLM进行比较&#xff0c;会得到什么…

【系统设计系列】 应用层与微服务

系统设计系列初衷 System Design Primer&#xff1a; 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版&#xff1a; https://github.com/donnemart…

超全60000多字详解 14 种设计模式 (多图+代码+总结+Demo)

超全60000多字详解 14 种设计模式 (多图代码总结Demo) 之前读耗子叔文章时&#xff0c;看到过有句话没有实践&#xff0c;再多的理论都是扯淡&#xff0c;个人很赞同。你觉得自己学会了&#xff0c;但实践与学会之间有着很大差别。 单例模式 (Singleton Pattern) 定义或概念 …

水滴图 echarts lable失真显示很多9 水滴图 显示99999999

解决办法: 添加一个 seriesName lable用seriesName <template><div ref"EchartLiquidfill" class"EchartLiquidfill" :style"{ width: width }" /> </template><script> export default {name: "EchartLiquidfil…

第8章 驱动模块编译进内核实验(iTOP-RK3568开发板驱动开发指南 )

通过上一章的学习&#xff0c;我们学会了使用menuconfig图形化配置工具&#xff0c;以及了解了menuconfig相关的文件&#xff1a;Kconfig .config XXXdefconfig。本章节学习将helloworld驱动编译进内核。 输入“cd drivers/char”进入到 drivers/char 目录下&#xff0c;然后输…

2023工博会,正运动超高速PCIe实时运动控制卡应用预览(一)

展会倒计时&#xff1a;11天 本次的中国国际工业博览会正运动技术将携超高速PCIe实时运动控制卡亮相。 •为智能装备提供高速高精运动控制解决方案&#xff1b; •内部搭载运动控制实时内核MotionRT7; •提供多路高速IO输入输出&#xff0c;具备多种实时运动控制功能&#x…

Maven安装(超详解)

下载地址:Maven – Download Apache Maven 在提供的资料中,已经提供了下载好的安装包。如下 1、解压 apache-maven-3.9.4-bin.zip(解压即安装) bin目录 : 存放的是可执行命令。(mvn 命令重点关注) conf目录 :存放Maven的配置文件。(settings.xml配置文件后期需要修改)…

Unity中的场景加载

1、同步场景 2、异步加载 3、保留物体到下个场景中