完全图解自然语言处理中的Transformer——BERT基础(入门长文)

2023-11-06

翻译自Jay Alammar Blog

在上一篇文章可视化Seq2Seq+attention中,我们介绍了现在深度学习中特别常用的Attention(注意力)机制。注意力可以提升机器翻译的效果。这篇文章介绍Transformer,一种使用注意力机制提升训练速度的模型。Transformer在一些任务中优于谷歌翻译模型。它最大的好处是可以并行(RNN基本不可能并行)。Google Cloud 也推荐人们在他们的 Cloud TPU 上使用Transformer。所以让我们把模型拆开然后看看它是怎么运作的。

Transformer出自于论文Attention is All You Need,Tensorflow实现的版本可以由Tensor2Tensor下载查看。Pytorch版本见guide annotating the paper with PyTorch implementation。本篇文章会试着简化概念并且一个一个介绍,以便于初学者理解。

总览

让我们从将模型视为一个模块开始。在机器翻译应用中,模块输入一种语言的句子(sentence 序列),输出目标语言的句子。
在这里插入图片描述

在擎天柱善良的背后,我们发现一个连接着的编码组件和解码组件。(Transformer有变压器,变形金刚的意思,所以这是个冷笑话=-=)。

在这里插入图片描述

编码组件是由编码器堆叠起来组成的(论文里是由6个编码器堆成,选择6这个数字没什么特别的原因,你当然可以试试其他方案。)。解码组件也是用同样数量的解码器组成。
在这里插入图片描述

每个编码器结构相同,但是不共享权重。每一个编码器由两个子层组成。
在这里插入图片描述

编码器输入首先经过一个自注意力层(self-attention layer),自注意力层可以帮助编码器在编码具体单词时查看句子中的其他单词。我们会在后面详细说明自注意力层。

自注意力层的输出会进入到一个前馈神经网络。完全相同的前馈神经网络独立作用于每个位置。

解码器也有同样的两个层,但是在自注意层和前馈网络层之间有一个注意力层,注意力层可以帮助解码器注意输入句子的其他部分(和seq2seq中注意力机制类似)

张量(Tensors)图像化

目前为止我们已经看到了模型的主要组成部分,现在让我们看看各个向量(张量)是怎么经过训练模型的这些部分,由输入变为输出的。

和一般的NLP应用一样,我们将通过词嵌入技术(embedding algrithm)将单词变为向量。
在这里插入图片描述
每个词都被嵌入到512大小的向量中,这里用简单的盒子代替表示一下。

嵌入(embedding)只会在编码器最底层使用。概括的说就是所有编码器都接收一个由很多512大小的向量组成的列表,在最底层的编码器接收的是词嵌入层的输出(就是词转为向量,接收向量),但是在其他层的编码器直接接收前一层的输出。这个列表长度(大小)是一个可以设置的超参数,一般是我们训练集中最长句子的长度

当我们句子中的词经过嵌入层变成向量后,它们都会经过编码器的两个层。
在这里插入图片描述

这里我们可以看到Transformer的一个关键性质——每个位置的词经过编码器时都有自己的路径。路径在自注意力层中相互依赖,但是在前馈层中没有依赖关系,因此各个路径通过前馈层时可以并行执行。

接下来我们会用一个短句作为例子,看看编码器的每个层里它发生了什么。

编码模块

像我们之前提到的,编码器接收一个输入的向量列表。它将这个列表经过自注意力层(self-attention layer)处理,然后输入到一个前馈神经网络层,最后输出给下一个编码器

在这里插入图片描述

自注意总览

别被我用“自注意力”这个词误导了,好像这个概念是我们每个人都熟悉的那个概念。我在阅读论文“Attention is All You Need”之前,我个人对它一无所知。让我们看看它的具体情况。

假设下面的句子是我们想要翻译的句子:

”The animal didn't cross the street because it was too tired”

这个句子里“it”是指什么?是指“street”还是指“animal”?这对人来说很简单,但是算法设计上很难(就是人很容易理解,但是机器很难)。

当模型处理“it”这个词的时候,自注意力机制可以让“it”和“animal”相关联。

当模型处理每个目标词时(输入句子(序列)的每个词(位置)),自注意力机制会查看其余词与目标词的关系,这有助于更好的编码目标词。

如果你熟悉RNN,想一想RNN是怎么保留隐藏状态来让当前处理的词包含之前的处理词的表达。“self-attention”就是Transformer用来将其他相关单词的“理解”融入当前处理单词的方法。
在这里插入图片描述
当我们对"it"进行编码的时候,自注意力机制将“it”与其他词的相关性传入“it”的编码中,并会给“The animal”更大的权重。

最好仔细研究一下Tensor2Tensor,运行并根据这张图理解其中的运行机制。

自注意力详解

首先让我们用向量来简单的看看自注意力是怎么计算的,然后再让我们看看我们实际用的矩阵是怎么计算的。

第一步,自注意力机制会将编码器输入向量(这个例子中,输入向量是每个词经过embedding后的向量)变为三个向量。所以对于每个词,我们会创建一个Query向量,一个Key向量,一个Value向量。这三个向量是由词嵌入的向量乘以我们训练得出的三个矩阵得到的。

注意,这些新向量维度小于词嵌入的向量。当嵌入层和编码器输入和输出的向量维度是512时,这些向量的维度是64。但是他们并非一定要比原向量更小,这是一种架构选择,它可以使多头注意力(multiheaded attention)(大多数的多头注意力)计算保持不变。
在这里插入图片描述
X1乘以WQ得到q1,X2乘以WQ得到q2,(WQ是我们训练出来得到的)以此类推,最后得到所有的Query,Key,Value.。

那究竟什么是“query”, “key”, and “value” 向量呢?

他们就是抽象出来方便理解和计算注意力的。看下文你就知道他们是什么意思了。

第二步,计算注意力的第二步是打分。假设我们计算例子中的第一个单词“Think”。我们需要根据这个单词给输入句子中的每一个词打分。当我们编码当前位置的单词的时候,分数决定了我们给其他位置的单词多少关注(权重)。

分数是通过点乘(dot) 当前位置单词的query 向量 和 需要打分位置单词的key 向量 得到的。所以如果我们在位置#1使用注意力给其他部分打分,第一个分数是(qi dot k1),第二个分数是(q1 dot k2)。

在这里插入图片描述

第三步和第四步,第三步和第四步是将维度除以8(key 向量维度的平方根,论文里key维度是64。目的是得到更稳定的梯度。当然可以是其他值,不过这个是默认的),然后将结果通过softmax处理。softmax标准化(softmax normalizes)可以将值映射(压缩、标准化)到0-1之间。

第五步,第五步是将每个 value 向量乘以 softmax处理后的得分(为相加做准备)。这一步的目的是保留重要的词(想要关注的词)的完整性,去除不相关的词。(如给不相干的词乘以一个极小的数-0.001)

第六步将权重值向量相加。结果就是自注意力层(self-attention layer)在这个位置的输出(本例子里是第一个词)

在这里插入图片描述

这就是自注意力的整个计算过程。计算后的结果我们会传递给前向反馈神经网络。然而在实际应用中,计算都是以矩阵形式而不是以向量,因为矩阵运算速度快。接下来让我们看一下单词级别矩阵计算的样子。

自注意力矩阵运算

第一步是计算Query,Key,和Value矩阵。他们是通过嵌入层(embedding)输入的矩阵X和我们训练出来的权重矩阵(WQ,WK,WV)相乘得到的
在这里插入图片描述
X矩阵中的每一行对应于输入句子中的一个单词。我们再次看到嵌入向量的大小差异(512,或图中的4个方框)和q / k / v向量(64,或图中的3个方框)

最后,处理矩阵时,我们可以将2-6步变为一步计算自注意力层的输出。
在这里插入图片描述

一只有许多头的野兽

论文通过一个叫“多头注意力”(multi-headed attention)的机制进一步提高了自注意力层的性能。多头注意力机制从两个方面提高注意力层的性能:
1.它提高了模型关注不同位置的能力。的确,上面的例子中,Z1包含了一些其他位置的编码信息,但是实际上它却是由实际的词本身决定。我们翻译一个句子像 “The animal didn’t cross the street because it was too tired”,我们想知道“it”指代的是什么词时,多头注意力很有用。(翻译这段的时候好多 it 一下子把我看晕了…)(就是说it用一个注意力只能关注到“animal”,但是其实“tired”也是和“it”有关的)

2.它给予注意力层多个“表示子空间”。正如我们接下来看到的那样,多头注意力可以让我们拥有多组Q/K/V矩阵(Transformer使用8个注意力头,所以最终我们的编码/解码器有8组)。每组都是随机初始化的。经过训练后,每组将嵌入层的输出(或者底层编码器/解码器的输出)投射到不同的表示子空间中。

在这里插入图片描述

如果我们做和之前提到的8头自注意力计算的话,只需要8次和8个不同的权重矩阵相乘,我们会得到8个不同的Z矩阵。(Query,Key,Value首先经过一个线性变换,然后输入到放缩点积attention,注意这里要做h次,其实也就是所谓的多头,每一次算一个头。而且每次Q,K,V进行线性变换的参数W是不一样的)

这就有个问题。前馈神经网络只接受一个矩阵,不接受多个矩阵。所以我们需要把这8个矩阵组合成1个矩阵。

怎么做呢?我们把8个矩阵连接起来,然后乘以一个额外的权重矩阵WO。

在这里插入图片描述

以上就是多头自注意力机制的所有内容了。但是我只是展示了实际计算中的一部分矩阵以便理解。让我们把多头注意力计算放到一张图上看看。

在这里插入图片描述

现在我们已经基本了解了多头注意力了,让我们看看例句中,当我们编码“it”的时候,不同头的注意力的注意机制是怎么样的。

在这里插入图片描述
当我们编码单词“it”的时候,一个注意力头更关注“the animal”,另一个更关注"tired"(假设是这样),那么模型用“animal”和“tired”一起表示“it”。

如果我们把所有的注意力头都放到一张图片里,看起来就会很复杂。

在这里插入图片描述

使用位置编码表示序列的顺序。

目前为止我们忽略了一件事,就是模型没有表示句子中单词的位置信息。

为了标记位置,transformer对每一个输入的嵌入层(embedding)都加了一个向量。这些向量遵循模型学习的特定模式(意思就是向量的维度和模型要的维度一样。)。这有助于决定每个单词的位置,或者句子中不同单词的距离。这里的逻辑是,将这些值添加到嵌入层,嵌入层向量会被投影到Q/K/V向量中,Q/K/V在注意力期间进行点积计算时,就有了位置信息。
To give the model a sense of the order of the words, we add positional encoding vectors -- the values of which follow a specific pattern

假设嵌入层是4维,那么实际位置编码长这个样子:
在这里插入图片描述

这玩意在实际模型中到底长啥样?

下面这个图每一行都对应位置信息编码成的向量。也就是说,第一行是我们要往嵌入层添加的输入句子中第一个词的位置向量。每一行由从-1到1之间的512个值构成,我给这些值做了颜色编码,看起来更直观一些。

在这里插入图片描述
一个真实的512大小嵌入层和20个词位置编码的例子。你可以看到它在中间很明显的分为两部分。这是因为左半部分的值是由一个函数生成(sin),右半部分是由另一个函数生成(cos)。然后组合 成为一个位置编码向量。

位置编码的具体公式在论文里有描述(3.5节),你可以从源码的get_timing_signal_1d().函数看到公式的代码具体实现。这并不是唯一的一种位置编码方式,只是这种方式可以处理未知长度的序列。(比如要求模型翻译的句子比训练集中所有句子都长)

残差(The Residuals)

我们之前提到过一个细节,每个编码模块的子层(自注意力层和前馈网络层)中间都有残差(residual)连接,然后紧跟着一个层标准化步骤。

在这里插入图片描述

如果我们将自注意力机制中向量和层标准化的运作方式如下图:

在这里插入图片描述

解码模块里自注意力子层的样子也差不多。如果整体看Transformer的编、解码模块(以两层为例),它长这样:
**加粗样式**

解码端

我们既然已经知道了编码模块的组成,那么解码模块也就知道了。所以解码端就不详细说了,还是让我们看看它们在一起工作的样子。

编码模块从处理输入的句子开始,由最顶端的编码器输出是由注意力向量K和V组成的集合。解码器会在每个“注意力编-解码层(encoder-decoder attention)”使用,它们能让解码器关注输入句子中恰当的地方。

在这里插入图片描述
编码阶段结束后就是解码阶段。解码阶段每一步会输出目标句子的一个元素。(比如翻译出来的句子中的一个词)

下面这些步骤会循环,直到解码器收到一个特殊的标记(EOS),这就代表解码结束。
解码模块每一步输出都会作为下一步的输入,解码模块内部动作和编码器一致,而且也会将每个词的位置嵌入并添加到输入向量中。

在这里插入图片描述

解码模块的自注意力层和编码模块的有点不一样。

在解码模块中(有些人将解码模块翻译为解码端),自注意力层只关注输入句子中之前位置的单词。这个操作是在自注意力计算中的softmax层之前,通过屏蔽未来的位置(将它们设置成 -inf)来实现的。

“编码-解码注意力”层的计算方式和多头自注意力是一样的。只不过它是从它下面的层创建Q矩阵,同时从编码模块的输出中获得K和V。

最后的Linear和Softmax层

解码模块输出的是一个向量或者小数,我们怎么把他们变成一个词呢?这就是最后的线性层和softmax层要做的工作。

线性层是个简单的全连接神经网络,它将解码模块输出的一堆向量投影成为一个炒鸡炒鸡大的向量,这个向量成为logits vector(对数向量)。

假设我们模型从训练集中获得10,000个不同的英文单词(就是字典中的单词),线性层会生成10,000个单元宽度的logits向量,每个单元代表一个词的分数。这就是为什么模型后面紧跟着线性层的原因。

softmax层会将这些分数转为概率(全为正,加起来和是1)。最高概率的单元会被选出来,这个单元代表的词就是这一步的输出。
在这里插入图片描述

训练回顾

现在我们已经了解了Transformer的整个前向训练过程。

训练期间,未经训练的模型会进行相同的前向训练,但是因为我们是有监督学习,所以是有标签可以对比训练输出的结果来判断正确与否。

为了方便理解,我们假设输出词典只有六个词(“a”, “am”, “i”, “thanks”, “student”, and “” ( ‘end of sentence’缩写)).

在这里插入图片描述

一旦我们定义了单词表(字典),我们就可以用同样宽度的向量表示每个词,这也叫作one-hot编码。比如,我们可以用下面的向量表示“am”

在这里插入图片描述

下一节我们会讨论损失函数(loss function)---- 在训练期间为了得到高准确率的模型,我们要优化的目标。

损失函数

假设我们在训练模型,而且是我们训练阶段的第一波。我们用个简单的例子训练-----把“merci”翻译成“thanks”。

什么意思呢?就是我们想让模型输出是“thanks”的概率分布,但是模型还没有开始训练,所以它还没能力输出。

在这里插入图片描述
模型的初始化参数(权重)是随机的,也就是会在每个单元(词)上产生一个随机的概率值。我们把初始的概率值和真正的概率比较,通过反向传播调整初始值,努力让模型输出的概率分布和真正的概率分布相同。

那么两个概率分布怎么比较呢?简单的方法就是一个减去另一个,更多的方法请看交叉熵损失-cross-entropy相对熵/KL散度(Kullback-Leibler divergence)

但是注意,上面的只是个超级简化的例子。更实际点,我们用一个句子代替一个词来举例。比如,输入“je suis étudiant”,然后期望输出“i am a student”。也就是说,我们想要我们的模型成功的输出如下要求的概率分布:

  • 每个概率分布都是单词表长度大小的向量(我们的例子中是6个,但是实际上单词表3000-10,000,向量也这么大)
  • 第一个概率分布中概率最高的单元应该是“i”的单元
  • 第二个概率分布的重概率最高的单元是“am”的单元
  • 以此类推,直到第五个输出了“‘<end of sentence>”符号,这个符号也是单词表(词典)里的。

目标输出

在这里插入图片描述
这是我们样本概率分布(目标的概率分布)。

在足够大的数据集上训练模型足够次数后,我们希望模型会生成如下概率分布。

在这里插入图片描述
这只是我们训练后期望的输出。当然这并不意味着短语是训练集的一部分(见cross-validation).。请注意每个单元都有一个很小的概率,即使它完全不可能是这个时间步的输出—这就是softmax的效果,这种方式有助于模型训练。

现在,因为模型一次产生一个输出,我们可以假设模型选择了概率分布中概率最高的词并且把其他词和概率丢弃了。这种选择方式称为贪婪解码(greedy decoding)。另一种选择方式是保留,比如,保留概率最高的两个单词(假设是“i”和“me”),然后下一步,模型运行两次:一次是假设第一个位置输出的是单词“i”,第二次假设第一个位置输出的单词是“me”,然后模型考虑位置#1和#2,保留错误更少的作为第一个位置(#1)的输出。重复这个步骤在位置#2和#3…等等。(束搜索可以看束搜索和贪婪搜索)。这种方式称为“束搜索”(beam search),我们的例子中,束搜索的大小(beam_size)是2(因为我们只比较了#1和#2两个位置),束搜索的数量(top_beams)也是2(“i”和"me",我们只比较了两个词)。这两个参数都是可以随你需要而设置的。

了解更多

了解更多…我就不贴链接了,直接到 https://jalammar.github.io/illustrated-transformer/ 原文最末端看一下。
主要是看看论文,比如 Attention is all you need,github还是哪个看看源码,比如tensor2tensor。实际使用,tensorformer确实比 Seq2Seq快。而且如果新手的话谷歌有tensor2tensor框架,可以直接调用一些现成的模型和参数。关于tensor2tensor框架的使用就不介绍了,源码的docs里介绍的很详细,自己参观…
当然本文只是一个很基础的内容。论文解读推荐https://yq.aliyun.com/articles/342508?utm_content=m_39938

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

完全图解自然语言处理中的Transformer——BERT基础(入门长文) 的相关文章

  • 创建向量空间

    我有一个问题 我有很多文档 每一行都是由某种模式构建的 当然 我有这一系列的图案 我想创建一些向量空间 然后通过某种规则来向量这个模式 我还不知道这个规则是什么 即使这个模式像我的向量空间的 质心 然后向量当前文档的每一行 再次按照此规则
  • 理解含义的算法[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想知道是否有任何特定的算法可以遵循
  • NLTK 中的 FreqDist 未对输出进行排序

    我是 Python 新手 我正在尝试自学语言处理 python 中的 NLTK 有一个名为 FreqDist 的函数 可以给出文本中单词的频率 但由于某种原因它无法正常工作 这是教程让我写的 fdist1 FreqDist text1 vo
  • AttributeError:使用 CRF 时“Tensor”对象没有属性“_keras_history”

    我知道关于这个问题有很多问题 我已经阅读了其中的一些问题 但没有一个对我有用 I am trying to build a model with the following architecture 代码如下 token inputs In
  • Spacy 中的自定义句子分割

    I want spaCy使用我提供的句子分割边界而不是它自己的处理 例如 get sentences Bob meets Alice SentBoundary They play together gt Bob meets Alice Th
  • 将 python NLTK 解析树保存到图像文件[重复]

    这个问题在这里已经有答案了 这可能会复制这个 stackoverflowquestion https stackoverflow com questions 23429117 saving nltk drawn parse tree to
  • python中的语音识别持续时间设置问题

    我有一个 Wav 格式的音频文件 我想转录 我的代码是 import speech recognition as sr harvard sr AudioFile speech file wav with harvard as source
  • 将复数名词转换为单数名词

    如何使用 R 将复数名词转换为单数名词 我使用 tagPOS 函数来标记每个文本 然后提取所有标记为 NNS 的复数名词 但是如果我想将这些复数名词转换为单数该怎么办 library openNLP library tm acq o lt
  • 使用正则表达式标记化进行 NLP 词干提取和词形还原

    定义一个函数 名为performStemAndLemma 它需要一个参数 第一个参数 textcontent 是一个字符串 编辑器中给出了函数定义代码存根 执行以下指定任务 1 对给出的所有单词进行分词textcontent 该单词应包含字
  • NLTK 中的 wordnet lemmatizer 不适用于副词 [重复]

    这个问题在这里已经有答案了 from nltk stem import WordNetLemmatizer x WordNetLemmatizer x lemmatize angrily pos r Out 41 angrily 这是 nl
  • 缩短文本并仅保留重要句子

    德国网站 nandoo net 提供了缩短新闻文章的可能性 如果使用滑块更改百分比值 文本会发生变化并且某些句子会被遗漏 您可以在这里看到它的实际效果 http www nandoo net read article 299925 http
  • 如何提取句子中的主语及其各自的从属短语?

    我正在尝试在句子中进行主题提取 以便我能够根据主题获得情感 我在用nltk在 python2 7 中用于此目的 以下面的句子为例 Donald Trump is the worst president of USA but Hillary
  • 如何在R中使用OpenNLP获取POS标签?

    这是 R 代码 library NLP library openNLP tagPOS lt function x s lt as String x word token annotator lt Maxent Word Token Anno
  • 旧版本的 spaCy 在尝试安装模型时抛出“KeyError: 'package'”错误

    我在 Ubuntu 14 04 4 LTS x64 上使用 spaCy 1 6 0 和 python3 5 为了安装 spaCy 的英文版本 我尝试运行 这给了我错误消息 ubun ner 3 NeuroNER master src pyt
  • 如何将标记化中的多单词名称保留在一起?

    我想使用 TF IDF 特征对文档进行分类 一种方法是 from sklearn feature extraction text import TfidfVectorizer import string import re import n
  • 使用 NLP 进行地址分割

    我目前正在开发一个项目 该项目应识别地址的每个部分 例如来自 str Jack London 121 Corvallis ARAD ap 1603 973130 输出应如下所示 street name Jack London no 121
  • Python模块可以访问英语词典,包括单词的定义[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 python 模块 它可以帮助我从英语词典中获取单词的定义 当然有enchant 这可以帮助我检查该单词是否存在于英语中
  • 给定文档,选择相关片段

    当我在这里提出问题时 自动搜索返回的问题的工具提示给出了问题的前一点 但其中相当一部分没有给出任何比理解问题更有用的文本 标题 有谁知道如何制作一个过滤器来删除问题中无用的部分 我的第一个想法是修剪仅包含某个列表中的单词的任何前导句子 例如
  • Lucene 标准分析器与 Snowball

    刚刚开始使用 Lucene Net 我使用标准分析器索引了 100 000 行 运行了一些测试查询 并注意到如果原始术语是单数 则复数查询不会返回结果 我知道雪球分析器增加了词干支持 这听起来不错 不过 我想知道 超过标准的雪球锣是否有任何
  • 从 Penn Treebank 格式的文本中提取子句

    说我有一句话 After he had eaten the cheese Bill went to the grocery 在我的程序中 我得到以下输出 PARSE TREE ROOT S SBAR IN After S NP PRP he

随机推荐

  • Maven中dependencyManagement作用说明

    备注 今天有好些实习的同事问到Maven中关于dependencyManagement和普通dependencies的区别 说多了 麻烦 记录一下 在Maven多模块的时候 管理依赖关系是非常重要的 各种依赖包冲突 查询问题起来非常复杂 于
  • python网络爬虫有那些实例_python爬虫经典例子有哪些

    python爬虫例子 首先导入爬虫的库 生成一个response对象 然后设置编码格式 并打印状态码 最后输出爬取的信息 代码为 print response text python爬虫例子 1 爬取强大的BD页面 打印页面信息 第一个爬虫
  • 毕业设计-基于机器视觉的焊缝图像处理研究- OpenCV

    目录 前言 课题背景和意义 实现技术思路 一 焊缝识别系统设计 二 焊缝图像预处理 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要
  • 设置读取plc时间_Visual Studio 2010-C#跟西门子1200(Sharp7)窗体控制④-循环读取

    Visual Studio 2010 C 跟西门子1200 Sharp7 窗体控制 循环读取 上期回顾 上期主要是对单个按钮 按下后能够同时置位PLC的多个位 本期做一个读取PLC的OK NOK的统计数据的C 标签 先创建一个标签 在设定一
  • SpringBoot:@Schedule定时任务

    一 Schedule SpringBoot内置了Sping Schedule定时框架 通过注解驱动方式添加所注解方法到定时任务 根据配置定时信息定时执行 二 定时任务实现 1 开启定时任务 package com gupao springb
  • 使用VBA在工作表中快速插入行

    在工作表中插入行 有需要用到代码吗 是不是杀鸡用牛刀的感觉 其实不是这样的 在很多复杂的应用场景中 插入行不再是简单的单击鼠标右键就可以即刻完成的 比如需要隔行插入空行 如果有一万行数据 是不是搞到手抽筋了 再比如插入空行的数量不是固定的
  • 自动记录数据录入时间不懂得VBA的朋友可以看看

    在日常工作中 经常会遇到需要实时记录数据录入的时间问题 有朋友会说了 用快捷键啊 按Ctrl 分号 可以返回当前的系统日期 按Ctrl Shift 分号 可以返回当前的系统时间 但是如果需要同时返回日期和时间又该怎么处理呢 对于懂得VBA的
  • 关于对Vue中slot插槽理解

    关于slot插槽理解 1 何时需要使用插槽 在开发中 我们需要将共性内容抽取到组件中 将不同的暴露为插槽 插槽的益处便是 一旦预留了插槽 使用者便可以根据自己的需求来决定插槽中插入的的内容 2 slot的基本使用 div div
  • 软件测试之网络协议基础

    软件测试之网络协议基础 前言 我会在此账号上持续更新 软件测试的文章 包括网络部分 前端代码部分 数据库部分 软件测试部分 互联网协议 osi 7层协议 tcp ip 5层协议 网络协议的存在是为了两者中间根据一定的协议沟通交流 每层运行常
  • 光线跟踪(RayTracing)原理及c++实现

    Chapt1 Why to write a RayTracing Render 提到Computer Graphics 众所周知的是如OpenGL Direct3D这样非常流行的光栅化渲染器 事实上 这些大部分应用于游戏制作的API主要为实
  • Flutter控件——布局控件:层叠

    Stack 层叠布局 Android 中的 Frame 布局是相似的 子组件可以根据距父容器四个角的位置来确定自身的位置 层叠布局允许子组件按照代码中声明的顺序堆叠起来 Flutter中使用Stack和Positioned这两个组件来配合实
  • 怎么关闭win10虚拟机服务器,win10系统彻底关闭退出vmware虚拟机的步骤

    有关win10系统彻底关闭退出vmware虚拟机的操作方法想必大家有所耳闻 但是能够对win10系统彻底关闭退出vmware虚拟机进行实际操作的人却不多 其实解决win10系统彻底关闭退出vmware虚拟机的问题也不是难事 小编这里提示两点
  • 数十万条以上的大量数据如何快速插入数据库中

    引言 这几天工作这边同事遇到了一个问题 对十五万条数据进行计算 插入数据库的时候耗时很严重 使用了批量插入对十五万条数据插入仍然耗费了30秒 前面计算也耗费了二十多秒 系统流畅度因此很难堪 经过我的排查发现主要是两个点需要优化 1 计算的算
  • 关于STM32在线升级文件大或者跳转后中断有问题的解决方法(IAR环境)

    首先 大家都知道是跳转到每个程序的复位中断地址 一开始我的IAR环境的启动文件是没有复位中断地址的 可以去IAR官网随便下载一个重新覆盖掉启动文件 当然还得看你的外设中断有没有包含 或者有多的要去掉 DCD Handler类型的 如果遇到I
  • 怎样在 Markdown 中使程序代码带上行号

    在图灵社区使用 Markdown 写文章时 如果在一段文字的每行开头加上四个空格 或者一个制表符 Tab 这段文字就会被视为程序代码 这样 就会自动识别所用的编程语言 进行代码染色 语法高亮显示 但是 如果这段程序很长的话 就有两个小问题
  • 假设检验,显著性,置信水平,p值,点估计

    1 为什么需要假设检验 以下图激光器项目为例子 抽样30个 改善前720mw 改善后723mw 有一点提升 提升小 可能是正常的波动 所以不一定真的提升了 所以到底是正常波动还是真的改善了 需要结合功率标准差进行分析 标准差决定了波动的情况
  • 医疗管理系统-图形报表、POI报表

    目录 1 套餐预约占比饼形图 1 1 需求分析 1 2 完善页面 1 2 1 导入ECharts库 1 2 2 参照官方实例导入饼形图 1 3 后台代码 1 3 1 Controller 1 3 2 服务接口 1 3 3 服务实现类 1 3
  • STM8 学习笔记 5:时钟

    1 概述 时钟是单片机的脉搏 是单片机的驱动源 使用任何一个外设都必须打开相应的时钟 这样的好处是 如果不使用一个外设的时候 就把它的时钟关掉 从而可以降低系统的功耗 达到节能 实现低功耗的效果 每个时钟tick 系统都会处理一步数据 这样
  • 图数据库-Neo4j:linux centOS7安装

    1 下载 下载地址 社区版免费 https neo4j com download other releases releases 2 解压 tar axvf neo4j community 3 4 5 unix tar gz 3 修改配置文
  • 完全图解自然语言处理中的Transformer——BERT基础(入门长文)

    翻译自Jay Alammar Blog 在上一篇文章可视化Seq2Seq attention中 我们介绍了现在深度学习中特别常用的Attention 注意力 机制 注意力可以提升机器翻译的效果 这篇文章介绍Transformer 一种使用注