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

泛读笔记:从Word2Vec到BERT

自然语言处理(NLP)模型的发展历史

1.统计方法时期:使用贝叶斯方法、隐马尔可夫模型、概率模型等传统统计方法
2.机器学习时期:支持向量机(SVM)、决策树模型、随机森林、朴素贝叶斯等传统机器学习方法
3.深度学习革命:各种新的深度学习模型,比如CNN、RNN(以及变体LSTM、GRU)
4.Transformer架构:提出的Self-Attention机制可以更好的捕捉长距离依赖问题,同时该架构允许并行处理元素,极大的提高了训练速度
5.预训练模型:随着Bert模型的发布,预训练成为了NLP的一个新标准。这些模型首先在一个大规模语料库上进行无监督预训练,然后针对具体任务进行微调,例如GPT系列

1 从NNLM到word2Vec

NNLM(Neural Network Language Model):最早尝试使用神经网络来预测序列中下一个词的概率的模型之一

  • 通过一个连续的词向量空间来表示词,使得相似的词在向量空间中距离较近。
  • 将前几个词的词向量作为输入,并通过一个隐藏层来预测下一个词。
  • 引入了softmax函数来计算每个词的概率分布。

Word2Vec:一种词嵌入技术,即把每个词映射到一个固定大小的向量空间中。

1.1 从向量表示到词嵌入

假设我们对求职人员进行人格测试,会给一个人的很多维度进行打分,内向/外向是其中之一,然后用0~100(内向→外向)来表示程度,假设有一个叫Jay的人得分为38/100,则可以用下图表示该得分:
在这里插入图片描述
为了更好的表达数据,我们将范围压缩至-1到1(类似归一化):
在这里插入图片描述
对于一个人,一个维度显然不足,我们再加一个得分作为第二维度:
在这里插入图片描述
我们就可以认为这个人的性格被这个向量表示出来了,假设我们想找的另一个和Jay性格相仿的人,则可使用该表示法进行比较。
在这里插入图片描述
由图可得,Person #1更合适,但如果是三维、四维或者更高维,则可以使用余弦相似度公式进行计算
在这里插入图片描述
以上述例子计算得
在这里插入图片描述
也可得出Person #1更合适,这就是将性格向量化,对于字词也是同样得,我们可以将词向量化,而生成词向量(Word Vectors) 的具体方法就是词嵌入(Word Embeddings) ,词嵌入是指将单词映射到一个稠密的向量空间中的过程,其中的每个维度都代表了某种语言特征。

这里以GloVe向量为例,它是一种用于生成词向量的方法,下面是的单词’king’的词嵌入:
[ 0.50451 , 0.68607 , -0.59517 , -0.022801, 0.60046 , -0.13498 , -0.08813 , 0.47377 , -0.61798 , -0.31012 , -0.076666, 1.493 , -0.034189, -0.98173 , 0.68229 , 0.81722 , -0.51874 , -0.31503 , -0.55809 , 0.66421 , 0.1961 , -0.13495 , -0.11476 , -0.30344 , 0.41177 , -2.223 , -1.0756 , -1.0783 , -0.34354 , 0.33505 , 1.9927 , -0.04234 , -0.64319 , 0.71125 , 0.49159 , 0.16754 , 0.34344 , -0.25663 , -0.8523 , 0.1661 , 0.40102 , 1.1685 , -1.0137 , -0.21585 , -0.15155 , 0.78321 , -0.91241 , -1.6106 , -0.64426 , -0.51042 ]

根据它们的值对单元格进行颜色编码(如果它们接近2则为红色,接近0则为白色,接近-2则为蓝色):
在这里插入图片描述

然后将’king’与其他单词进行比较
在这里插入图片描述
可以明显看到’Man’和’Woman’更相似,即该词嵌入很好的展示了单词的联系,下面再举一个例子:
在这里插入图片描述
大家可以根据色条的相似度,得出不同词之间的相似情况。

1.2 NNLM模型

NNLM的核心是一个多层感知机,它将词向量序列映射到一个固定长度的向量表示,然后将这个向量输入到一个softmax层中,计算出下一个词的概率分布,假设我们输入’Thou shalt’,然后该模型会按下面三个步骤进行预测:
在这里插入图片描述
最后’not’的得分最高,所以选择向用户推荐’not’。

其中Look up Embedding,由于模型在经过另外一个训练之后可以生成一个映射单词表所有单词的矩阵,也称词嵌入矩阵,从而在进行预测的时候,我们可以在这个词嵌入矩阵中查询输入的单词。

1.2.1 如何构建词嵌入矩阵

首先收集大量的文本数据,然后建立一个滑动窗口(滑动窗口的大小可以自定义),构建滑动窗口内+滑动窗口后一个单词的训练+预测样本,就可以得到一套用于训练用的数据集
在这里插入图片描述
下面是数据集,即不同的单词组合后面会出现的单词:
在这里插入图片描述

1.3 Word2Vec的两种架构:CBOW和Skipgram

CBOW: 为了更好的预测,不仅要考虑目标单词的前两个单词,还要考虑其后两个单词,这种通过“通过上下文词汇预测当前词”的架构就是连续词袋(CBOW)

Skipgram: 根据当前词推测当前单词的前后单词的架构就是Skipgram

1.4 Word2vec训练流程

  1. 首先创建两个矩阵:词嵌入Embedding矩阵(是网络Onehot层到Embedding层映射的网络参数矩阵,相当于一个初始化的Embedding矩阵)、上下文Context矩阵
  2. 前向传播:将上下文词的词向量求平均或相加,形成一个上下文向量,将上下文向量乘以一个权重矩阵(通常称为输出权重矩阵),并通过softmax函数计算每个词作为中心词的概率分布。
  3. 损失计算:计算预测的概率分布与真实标签(中心词的真实索引)之间的交叉熵损失。
  4. 反向传播:利用损失函数的梯度更新词向量矩阵和输出权重矩阵。
  5. 迭代重复

训练结束后,会得到一个全新的词嵌入Embedding矩阵,并用于之后的预测

2 从Seq2Seq到Seq2Seq with Attention

2.1 Seq2Seq(Sequence-to-sequence)

字面意思:输入一个序列,输出另一个序列

2.1.1 Encoder-Decoder模型

特别适用于序列到序列(seq2seq)的任务,如机器翻译、文本摘要、对话系统等。

  • 编码器(Encoder):编码器负责读取输入序列,并将其转换为一个固定长度的向量,这个向量被称为“上下文向量”或“编码向量”。编码器通常是一个递归神经网络(RNN),它可以逐个元素地处理输入序列,并生成一个状态向量,最终状态向量就是编码向量。

  • 解码器(Decoder):解码器接收编码器产生的上下文向量,并根据这个向量生成输出序列。解码器也是一个RNN,它通过逐个元素地生成输出序列中的元素,每次生成一个新元素时都会考虑到之前的状态和编码向量。

在这里插入图片描述

2.2 Attention机制

Encoder-Decoder模型有一个缺陷,序列较长时,所有语义完全转换为一个中间语义向量C来表示,可能会丢失许多信息,而Attention机制就让Eecoder 不再将整个输入序列编码为固定长度的「中间向量C」,而是编码成一个向量的序列(包含多个向量)。
在这里插入图片描述

Attention机制通过计算输入序列中各个部分与当前任务的相关性,从而为每个部分分配一个权重,这些权重反映了各个部分对当前任务的重要性
在这里插入图片描述

假设图书馆(source)里有很多书(value),为了方便查找,我们给书做了编号(key)。当我们想要了解漫威(query)的时候,我们就可以看看那些动漫、电影、甚至二战(美国队长)相关的书籍。
在这里插入图片描述
计算步骤

  1. 计算query和key的点积,得到权值
  2. 将权值归一化,即将原始计算分值整理成所有元素权重之和为1的概率分布,或者说通过SoftMax的内在机制更加突出重要元素的权重
  3. 将权重和 value 进行加权求和

最后便会得到一个Attention值,反应某元素对该任务的重要性。

2.2.1 举例说明Attention的计算步骤

假设输入为:The cat is sitting on the mat
我们想将该句子翻译为中文,步骤如下

  1. 将句子转化为词嵌入向量序列(Embedding Vectors)
  2. 输入到Encoder中,Encoder会计算每个输入词的隐藏状态 h i h_{i} hi i i i表示在输入序列中的位置
  3. 初始化解码器状态,假设要生成第一个词“这”(对应“The”),解码器会根据编码器的最后一个隐藏状态或所有隐藏状态的一个加权平均和来初始化解码器的状态,该初始状态包含了整个输入句子的信息
  4. attention机制,计算注意力得分、使用softmax函数将得分转化为注意力权重,这些权重决定了输入序列中的哪些位置最重要
  5. 计算上下文向量,使用注意力权重来加权求和所有Encoder隐藏状态
  6. 结合上下文向量和解码器的状态(通常是拼接),再输入到一个前馈神经网络,最后会得到一个输出词汇的概率分布表,选取概率最高的输入
  7. 重复该步骤,直到所有词汇翻译完毕

3 Transformer架构

3.1 Transformer编码

Transformer的提出即是为了更好的解决机器翻译问题,下面是一个简单步骤说明:
在这里插入图片描述

一个输入句子经过Transformer后,会被翻译成另一个句子,我们聚焦于中的模型:
在这里插入图片描述
其中:

  1. 编码组件部分由一堆Encoder构成(具体个数可以调)
  2. 解码组件部分也是由相同数量的Decoder组成

在这里插入图片描述
然后我们再聚焦于单个编码器和解码器:
在这里插入图片描述
步骤如下:

  1. 句子输入到编码器后,经过self-attention层,会帮助编码器在对每个单词编码时关注输入句子中的的其他单词,即可以捕捉到输入句子中词语之间的关系,而不仅仅是相邻的词。
  2. 然后传入前馈神经网络,进行特征提取
  3. 流入解码器,解码器也有self-attention层,但用于处理输出序列;编码-解码注意力层许解码器关注编码器的输出,帮助模型确定输入句子中最相关的部分,从而提高翻译的准确性;最后传入前馈神经网络,进行特征提取然后输出

3.1.2 举例说明

1.首先将每个输入词转化为词向量(这里的维度是演示作用,实际中可以自己调整)
在这里插入图片描述

2.输入到解码器中
在这里插入图片描述
便发现了Transformer的两个特点:

  1. 每个单词都是单独流入编码器,而不是排队进入
  2. 在前馈神经网络中,计算是独立的,即可以并行计算

3.2 Self-attention机制

假定现在要翻译下列句子:
“The animal didn’t cross the street because it was too tired”,那其中的it是指animal还是street呢?对人很容易,但对算法很难
但通过self-attention机制后,模型会得出itanimal更相关
在这里插入图片描述

3.3 self-attention计算方法

3.4 求和归一化

Transformer架构中,还需再提一下编码器中的一个细节:每个编码器中的每个子层都有一个残差连接,然后做了一个:层归一化(layer-normalization)
在这里插入图片描述
残差连接 (Residual Connection):残差连接引入了跳跃连接的思想,使得输入可以直接绕过一层或多层传递到后面的层。这种连接有助于缓解深层网络中的梯度消失/爆炸问题,并促进信息和梯度的流动。
层归一化 (Layer Normalization):层归一化是在神经网络层中对激活值进行归一化的技术,它可以帮助控制每一层的输出的统计特性(均值和方差),从而减少内部协变量移位(internal covariate shift),使得训练更加稳定。

3.5 解码器中的两个注意力层

我们观察解码器,会发现其中有两个注意力层
在这里插入图片描述

  1. 一个带masked的Multi-Head Attention,本质是Self-Attention,该自注意力层只允许关注已输出位置的信息,屏蔽了未输出的信息。
    例如在翻译“我是学生”为“I am a student”的过程中,当解码器开始生成“I”时,它只能看到自己之前生成的词(在这里是起始标记),而不能看到后续的任何词。

  2. 一个不带masked的Multi-Head Attention,即Encoder-Decoder Attention,这个注意力层允许解码器关注编码器产生的表示,以找到输入序列中与当前生成的输出最相关的部分。这有助于解码器在生成每个词时,能够利用到整个输入句子的信息。
    例如在翻译“我是学生”为“I am a student”的过程中,当解码器生成“I”时,它不仅会考虑之前生成的词,还会通过编码器-解码器注意力层去关注输入序列“我是学生”中的相关信息,从而更好地生成下一个词。

  3. List item

3.6 最后的线性层和softmax层

它们的作用是把Decoder输出的浮点型向量,变成一个

假设我们的模型词汇表是10000个英语单词,它们是从训练数据集中学习的。那logits向量维数也是10000,每一维对应一个单词的分数。然后,softmax层将这些分数转化为概率(全部为正值,加起来等于1.0),选择其中概率最大的位置的词汇作为当前时间步的输出。

4 BERT模型

4.1 从Word Embedding到ELMO

4.1.1 Word Embedding的缺陷

在第一部分中,介绍了word2vec技术,作为Word Embedding的一类,它也存在Word Embedding的一些缺陷,便是无法处理多义词问题

4.1.2 ELMo(Embedding from Language Models)

是一种创新的词嵌入方法,它通过语言模型来生成词向量,特别之处在于它能够提供上下文相关的词表示,有着以下特点:

  1. 上下文敏感性: 与传统的词嵌入方法(如Word2Vec或GloVe)不同,ELMo为每个词生成的向量不是固定的,而是取决于该词出现的上下文。这意味着同一个词在不同的句子中可能会有不同的向量表示,这更符合自然语言的真实使用情况。
  2. 双向语言模型: ELMo 使用了两个长短期记忆网络(LSTM)作为语言模型,一个正向LSTM(从左到右读取文本),一个反向LSTM(从右到左读取文本)。通过结合这两种方向的语言模型,ELMo能够捕捉到词在句子中的前后关系。
  3. 层次结构: ELMo的LSTM语言模型有多层,每一层都可以捕获不同粒度的语义信息。最终的词嵌入是这些层的加权平均,这使得ELMo能够综合考虑局部和全局的上下文信息。

一个句子通过ELMo之后会得到三个Embedding,如下图所示:
在这里插入图片描述
假设我们将“i am a student”翻译为“我是学生”

  1. 预训练阶段: ELMo 需要在大量未标注的文本数据上进行预训练,以生成上下文敏感的词向量。输入“i am a student”,会分别通过正向和反向LSTM,去获得每个词基于前面词/后面词的概率分布。
  2. 第一个Embedding,是单词的Word Embedding
  3. 第二个Embedding,是双层双向LSTM中第一层LSTM对应单词位置的Embedding,这层编码单词的句法信息更多一些
  4. 第三个Embedding,是双层双向LSTM中第二层LSTM对应单词位置的Embedding,这层编码单词的语义信息更多一些

通过ELMo生成的词向量,比传统的词嵌入技术(如 Word2Vec 或 GloVe)更具有动态性和语境适应性,因此在输入到分类/预测模型中之后,会有更好的效果。

4.2 微调(Fine-tuning)

把在源数据集上训练的源模型的能力迁移到新数据新模型上

迁移学习(Transfer learning) ,就是把已训练好的模型(预训练模型)参数迁移到新的模型来帮助新模型训练。现迁移学习有以下三种手段:

  1. Transfer Learning:冻结预训练模型的全部卷积层,只训练自己定制的全连接层
  2. Extract Feature Vector: 先计算出预训练模型的卷积层对所有训练和测试数据的特征向量,然后抛开预训练模型,只训练自己定制的简配版全连接网络
  3. Fine-tuning:冻结预训练模型的部分卷积层(通常是靠近输入的多数卷积层,因为这些层保留了大量底层信息)甚至不冻结任何网络层,训练剩下的卷积层(通常是靠近输出的部分卷积层)和全连接层

假设我们想从图像中识别出不同种类的椅子,然后将购买链接推荐给用户。一种可能的方法是:

先找出100种常见的椅子,为每种椅子拍摄1,000张不同角度的图像,便收集到的10万张图像数据集(目标数据集)

  1. 在源数据集(如ImageNet数据集)上预训练一个神经网络模型,即源模型
  2. 创建一个新的神经网络模型,即目标模型,它复制了源模型上除了输出层外的所有模型设计及其参数,我们假设这些模型参数包含了源数据集上学习到的知识,且这些知识同样适用于目标数据集,我们还假设源模型的输出层与源数据集的标签紧密相关,因此在目标模型中不予采用。
  3. 为目标模型添加一个输出大小为目标数据集类别个数的输出层,并随机初始化该层的模型参数
  4. 目标数据集上训练目标模型,我们将从头训练输出层,而其余层的参数都是基于源模型的参数微调得到的

在这里插入图片描述

4.3 生成式的预训练之GPT:预训练(单向Transformer) + Fine-tuning

ELMo方法使用的是LSTM去提取数据特征,但随着Transformer的出现,它的特征抽取能力要强于LSTM,所以特征提取自然就采用了Transformer,但它采用的是单向Transformer
在这里插入图片描述

4.3.1 为什么要采用单向transformer呢?

GPT使用的Transformer结构就是将Encoder中的Self-Attention替换成了Masked Self-Attention,即屏蔽了未输出的词,理由如下:

  1. 生成连贯的文本序列。
  2. 避免信息泄露,即模型不会提前知道它还没有生成的信息。

4.4 BERT:双向Transformer版的GPT

4.4.1 BERT模型的架构:预训练(双向Transformer) + Fine-Tuning

即BERT模型综合了ELMo的双向优势和Transformer的特征提取优势

下图是BERT、GPT、ELMo的结构图对比:
在这里插入图片描述

4.4.2 BERT对输入、输出部分的处理

为了适配多任务下的迁移学习,BERT设计了更通用的输入层和输出层。

BERT的输入部分是个线性序列,两个句子之间通过分隔符「SEP」分割,最前面是起始标识「CLS」,每个单词有三个embedding:

  1. 单词embedding,有的单词会拆分成一组有限的公共子词单元,例如下图示例中‘playing’被拆分成了‘play’和‘ing’
  2. 句子embedding,用于区分两个句子,例如B是否是A的下文(对话场景,问答场景等)
  3. 位置信息embedding,句子有前后顺序

在这里插入图片描述

把单词对应的三个embedding相加,就形成了BERT的输入。

BERT在预训练的输出部分如参考下图:
在这里插入图片描述

4.4.3 BERT的创新点

  1. 掩码语言模型(Masked Language Model, MLM):在训练过程中,输入的一段文本会被随机地遮盖一部分词汇(通常大约15%的词汇会被遮盖)。这些被遮盖的词汇将被特殊标记(如[MASK])替换,能更好地捕捉到词汇的多义性和上下文依赖性。
  2. 下一句预测(Next Sentence Prediction, NSP):即判断句子B是否是句子A的下文,这个关系保存在BERT输入表示图中的[CLS]符号中,通过NSP任务,BERT模型可以学到句子级别的上下文关系

参考文献

ransformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

相关文章:

泛读笔记:从Word2Vec到BERT

自然语言处理(NLP)模型的发展历史 1.统计方法时期:使用贝叶斯方法、隐马尔可夫模型、概率模型等传统统计方法 2.机器学习时期:支持向量机(SVM)、决策树模型、随机森林、朴素贝叶斯等传统机器学习方法 3.深度学习革命:各种新的深度学习模型&am…...

redis实现分布式锁详细教程,可续锁(看门狗)、可重入

前言 本文将讨论的做一个高并发场景下避不开的话题,即redis分布式锁。比如在淘宝 的秒杀场景、热点新闻和热搜排行榜等。可见分布式锁是一个程序员面向高级的一门必修课,下面请跟着本篇文章好好学习。 redis分布式锁有哪些面试题 1.Redis做分布式的时…...

代码随想录打卡Day32

今天有点事,先做一题,剩下的明天补。 509. 斐波那契数 这道题目太简单了,递归几行代码就结束了,用动态规划做也可以,主要是学习一下动态规划五部曲。 这是递归的代码 class Solution { public:int fib(int n) {//确…...

数学学习记录

目录 学习资源: 9月14日 1.映射:​编辑 2.函数: 9月15日 3.反函数: 4.收敛数列的性质 5.反三角函数: 9月16日 6.函数的极限: 7.无穷小和无穷大 极限运算法则: 学习资源: 3Blue1…...

R语言统计分析——散点图1(常规图)

参考资料:R语言实战【第2版】 R语言中创建散点图的基础函数是plot(x,y),其中,x和y是数值型向量,代表着图形中的(x,y)坐标点。 attach(mtcars) plot(wt,mpg,main"Basic Scatter plot of MPG vs. Weigh…...

蓝桥杯—STM32G431RBT6按键的多方式使用(包含软件消抖方法精讲)从原理层面到实际应用(一)

新建工程教程见http://t.csdnimg.cn/JySLg 点亮LED教程见http://t.csdnimg.cn/Urlj5 末尾含所有代码 目录 按键原理图 一、按键使用需要解决的问题 1.抖动 1.什么是抖动 2.抖动类型 3.如何去消除抖动 FIRST.延时函数消抖(缺点:浪费CPU资源&#xff…...

基于STM32的温度、电流、电压检测proteus仿真系统(OLED、DHT11、继电器、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32F103C8T6 采用DHT11读取温度、滑动变阻器模拟读取电流、电压。 通过OLED屏幕显示,设置电流阈值为80,电流小阈值为50,电压阈值为60,温度阈值…...

Linux - iptables防火墙

目录 一、iptables概述 二、规则表与规则链结构(四表五链) 1.简述 2.四表(规则表) 3.五链(规则链) 三、数据链过滤的匹配流程 四、iptables命令行配置方法 1.命令格式 2.基本匹配条件 3.隐含匹配 …...

【C语言零基础入门篇 - 3】:格式化输入输出、字符操作和sizeof运算符揭秘

文章目录 格式化输入与输出格式化输入输出演示基本格式化输入输出 字符的输入输出sizeof运算符 格式化输入与输出 什么是数据的输出? 计算机向输出设备输出数据 什么是数据的输入? 从输入设备向计算机输入数据 #include<stdio.h>&#xff1a;标准的输入输出库&#…...

JVM字节码与局部变量表

文章目录 局部变量表javap字节码指令分类 指令指令数据类型前缀加载和存储指令加载常量算术指令其他指令 字节码示例说明 局部变量表 每个线程的帧栈是独立的&#xff0c;每个线程中的方法调用会产生栈帧&#xff0c;栈帧中保存着方法执行的信息&#xff0c;例如局部变量表。 …...

Java许可政策再变,Oracle JDK 17 免费期将结束!

原文地址&#xff1a;https://www.infoworld.com/article/3478122/get-ready-for-more-java-licensing-changes.html Oracle JDK 17的许可协议将于9月变更回Oracle Technology Network License Agreement&#xff0c;这将迫使用户重新评估他们的使用策略。 有句老话说&#xf…...

网页交互模拟:模拟用户输入、点击、选择、滚动等交互操作

目录 一、理论基础 1.1 网页交互模拟的重要性 1.2 网页交互的基本原理 二、常用工具介绍 2.1 Selenium 2.2 Puppeteer 2.3 Cypress 2.4 TestCafe 三、实战案例 3.1 模拟用户输入 3.2 模拟用户点击 3.3 模拟用户选择 3.4 模拟滚动操作 四、最佳实践与优化 4.1 代…...

C sharp 学习 笔记

介绍 这篇文章是我学习C#语言的笔记 学的是哔哩哔哩刘铁锰老师2014年的课程 在学习C#之前已经学习过C语言了。看的是哔哩哔哩比特鹏哥的课程。他们讲的都很不错 正在更新&#xff0c; 大家可以在我的gitee仓库中下载笔记源文件、项目资料等 笔记源文件可以在Notion中导入…...

文章资讯职场话题网站源码整站资源自带2000+数据

介绍&#xff1a; 数据有点多&#xff0c;数据资源包比较大&#xff0c;压缩后还有250m左右。值钱的是数据&#xff0c;网站上传后直接可用&#xff0c;爽飞了 环境&#xff1a;NGINX1.18 mysql5.6 php7.2 代码下载...

c++ templates常用函数

说明 c templates学习中会遇到大量的模版常用函数&#xff0c;书上不会详细介绍&#xff0c;查看一个之后要永久记录一段时间之后再看看&#xff0c;这里总结一下。 undeclared(); undeclared();//若undeclared();未定义&#xff0c;则在第一阶段编译时报错 undeclared(t);…...

【重学 MySQL】三十一、字符串函数

【重学 MySQL】三十一、字符串函数 函数名称用法描述ASCII(S)返回字符串S中的第一个字符的ASCII码值CHAR_LENGTH(s)返回字符串s的字符数&#xff0c;与CHARACTER_LENGTH(s)相同LENGTH(s)返回字符串s的字节数&#xff0c;和字符集有关CONCAT(s1,s2,…,sn)连接s1,s2,…,sn为一个字…...

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统 1. 部署环境说明2. 部署基础环境2.1. 操作系统基本配置2.2. 部署Nginx2.3. 部署MySQL2.4. 部署PHP 3. 部署GLPI资产管理系统 1. 部署环境说明 本次环境选择使用华为云Flexus云服务器X实例&#xff0c;因为其具有高…...

深入理解Go语言的面向对象编程、Git与GitHub的使用

Go语言以其简洁、高效和并发支持而广受欢迎。虽然Go不是一种传统的面向对象编程(OOP)语言,但它提供了一些特性,使我们能够模拟OOP的某些概念。在本文中,我们将深入探讨Go语言中的面向对象编程技巧,以及如何使用Git和GitHub进行版本控制。通过丰富的代码示例和详细的解释,…...

redis底层—通信协议RESP

...

JVM 调优篇6 可视化性能监控工具-JVisual VM

一 Visual VM 1.1 概述 Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具。 它集成了多个JDK命令行工具&#xff0c;使用Visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo)&#xff0c;监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...