可解释的 AI:在transformer中可视化注意力

news2024/12/23 17:35:59

 Visualizing Attention in Transformers | Generative AI (medium.com)

一、说明

        在本文中,我们将探讨可视化变压器架构核心区别特征的最流行的工具之一:注意力机制。继续阅读以了解有关BertViz的更多信息,以及如何将此注意力可视化工具整合到Comet的NLP和MLOps工作流程中。

        请随时按照此处的完整代码教程进行操作,或者,如果您迫不及待,请在此处查看最终项目。

二、系统介绍

        近年来,变压器被描述为NLP最重要的技术发展,但它们的工艺在很大程度上仍然不透明。这是一个问题,因为随着我们继续取得重大的机器学习进步,我们不能总是解释如何或为什么 - 这可能导致未检测到的模型偏差,模型崩溃以及其他道德和可重复性问题等问题。特别是随着模型更频繁地部署到医疗保健、法律、金融和安全等敏感领域,模型可解释性至关重要。

水平条形图显示不同职业的性别和种族预测,由 Word2Vec 模型(预变压器)预测

跨专业的性别和种族预测,由Word2Vec计算。这些习得的偏差可能会产生各种负面后果,具体取决于这种模型的应用。图片来自Simon Warchal的NLP嵌入中的偏见。

2.1 什么是BertViz?

        BertViz是一个开源工具,可以在多个尺度上可视化转换器模型的注意力机制,包括模型级、注意力头级和神经元级。但BertViz并不新鲜。事实上,BertViz的早期版本早在2017年就已经存在。

那么,为什么我们还在谈论BertViz呢?

        BertViz是一个领域的可解释性工具(NLP),否则它是众所周知的不透明的。而且,尽管它的名字,BertViz不仅在BERT上工作。BertViz API支持许多转换器语言模型,包括GPT系列模型,T5和大多数HuggingFace模型。

Comet UI 中两种不同类型的转换器模型的 BertViz 可视化:用于问答的纯编码器 distilbert 转换器和用于文本生成的纯解码器 gpt-2 转换器

        尽管它的名字,BertViz支持各种各样的模型。在左侧,我们使用仅编码器模型可视化问答任务,在右侧,我们使用仅解码器模型的文本生成任务。作者的动图。

        近年来,随着变压器架构越来越主导机器学习领域,它们也重新引发了关于人工智能可解释性和透明度的古老但重要的辩论。因此,虽然BertViz可能并不新鲜,但它作为人工智能领域的可解释性工具的应用现在比以往任何时候都更加重要。

2.2 但首先,变压器

        为了解释BertViz,它有助于对变压器和自我关注有一个基本的了解。如果您已经熟悉这些概念,请随时跳到我们开始编码的部分。

        我们不会在这里讨论变压器的细节,因为这有点超出本文的范围,但我们将介绍一些基础知识。我还鼓励您查看本文末尾的其他资源。

2.3 在开始(NLP的史前时代)

        那么,计算机究竟是如何“学习”自然语言的呢?简而言之,他们不能——至少不能直接。计算机只能理解和处理数值数据,因此NLP的第一步是将句子分解为“标记”,这些“标记”被分配了数值。驱动NLP的问题就变成了“我们如何才能准确地将语言和通信过程简化为计算?

        一些最早的NLP模型包括前馈神经网络,如多层感知器(MLP)甚至CNN,它们今天更普遍地用于计算机视觉。这些模型适用于一些简单的分类任务(如情感分析),但有一个主要缺点:它们的前馈性质意味着在每个时间点,网络只看到一个单词作为其输入。想象一下,试图预测句子中“the”后面的单词。有多少种可能性?

不“记住”任何上下文的序列模型的难度下一个单词句子预测的可视化

        如果没有太多上下文,下一个单词预测可能会变得非常困难。作者的图形。

        为了解决这个问题,递归神经网络(RNN)和长短期记忆网络(LSTMs,如Seq2Seq)允许反馈或周期。这意味着每个计算都由前一个计算通知,从而允许更多的上下文。

        然而,这种背景仍然有限。如果输入序列很长,则模型在到达序列末尾时往往会忘记序列的开头。此外,它们的顺序性质不允许并行化,使它们效率极低。众所周知,RNN也遭受了梯度爆炸的影响。

三、变压器简介

        转换器是序列模型,它放弃了RNN和LSTM的顺序结构,并采用完全基于注意力的方法。转换器最初是为文本处理而开发的,是当今所有最先进的NLP神经网络的核心,但它们也可以用于图像,视频,音频或几乎任何其他顺序数据。

        变压器与以前的NLP模型的关键区别在于注意力机制,正如《注意力就是你需要的一切》论文中所普及的那样。这允许并行化,这意味着更快的训练和优化的性能。注意力还允许比重复更大的上下文,这意味着转换器可以制作更连贯、相关和更复杂的输出。

原始的变压器架构,如2017年使他们成名的论文所示,注意力是你所需要的。

        原始的变压器架构,如2017年使他们成名的论文所示,注意力是你所需要的。

        变压器由编码器和解码器组成,我们可以用它们执行的任务取决于我们是使用这些组件中的一个还是两个。NLP 的一些常见转换器任务包括文本分类、命名实体识别、问答、文本摘要、填空、下一个单词预测、翻译和文本生成。

显示三种不同类型的转换器的图表:仅编码器、仅解码器和编码器-解码器型号。图表还列出了特定于每种变压器类型的任务,以及示例和替代名称。

变压器由编码器和解码器组成,我们可以用它们执行的任务取决于我们是使用这些组件中的一个还是两个。请注意,还有一些不使用变压器的“序列到序列”模型。作者的图形。

四、变压器如何适应更大的NLP模型生态系统?

您可能听说过像ChatGPT或LLaMA这样的大型语言模型(LLM)。转换器架构是LLM的基本构建块,LLM对大量未标记的数据使用自我监督学习。这些模型有时也被称为“基础模型”,因为它们倾向于很好地推广到广泛的任务,并且在某些情况下也可用于更具体的微调。BERT是这类模型的一个例子。

显示转换器体系结构、基础模型和大型语言模型之间关系的图形。图形包括(作为示例):ViT,BLOOM,BERT,Falcon,LLaMA,ChatGPT和SAM(Segment Anything模型)。

并非所有LLM或基础模型都使用变压器,但它们通常都使用变压器。并非所有的基础模型都是LLM,但它们通常是LLM。并非所有变压器都是LLM或FM。重要的一点是,所有变压器型号都需要注意。作者的图形。

这是很多信息,但这里重要的一点是,变压器模型(以及所有基于变压器的基础LLM)的关键区别特征是自我注意的概念,我们将在下面讨论。

五、注意力机制

        一般来说,注意力描述了模型注意句子(或图像或任何其他顺序输入)的重要部分的能力。它通过根据输入要素的重要性及其在序列中的位置为其分配权重来实现此目的。

        请记住,注意力是通过并行化来提高以前的NLP模型(如RNN和LSTM)性能的概念。但注意力不仅仅是优化。它在拓宽语言模型在处理和生成语言时能够考虑的上下文方面也起着关键作用。这使模型能够以更长的顺序生成上下文适当且连贯的文本。

一张图片显示了BertViz对句子“动物没有过马路,因为它太害怕了”的表示。最后一个词,害怕,是由 GPT-2 模型预测的。该图显示 GPT-2 将“它”与动物相关联。

        在此示例中,GPT-2 以单词“害怕”结束输入序列。模型如何知道“它”是什么?通过检查注意力头,我们学习了将“它”与“动物”(而不是例如“街道”)相关联的模型。图片由作者提供。

        如果我们将变压器分解为“通信”阶段和“计算”阶段,注意力将代表“通信”阶段。在另一个类比中,注意力很像搜索检索问题,给定一个查询 q,我们希望找到与 q 最相似的集 k 并返回相应的 v

  • 查询:我在寻找什么?
  • 钥匙:我有什么东西?
  • 价值:我将传达哪些内容?

如何计算变压器注意力的可视化

注意力计算的可视化。图片来自Erik Storrs。

六、注意力的类型

        自我注意是指每个节点从该单个节点生成键、查询和值的事实。多头注意只是与不同的初始化权重并行多次应用的自我注意。交叉注意意味着查询仍从给定的解码器节点生成,但键和值作为编码器中节点的函数生成。

这是对变压器架构的过于简化的总结,我们已经掩盖了很多细节(如位置编码、段编码和注意力掩码)。有关更多信息,请查看下面的其他资源。

6.1 在 BertViz 之前可视化注意力

        转换器本质上不是可解释的,但已经有很多尝试为基于注意力的模型贡献事后可解释性工具。

以前可视化注意力的尝试通常过于复杂,并且不能很好地转化为非技术受众。它们也可能因项目和用例而异。

对以前一些非常混乱和复杂的可视化注意力尝试的补充

        以前可视化注意力的尝试没有标准化,而且经常过于混乱。图形由作者编译自基于注意力的神经机器翻译的交互式可视化和操作(2017)和序列到序列模型的可视化调试工具(2018)。

        一些解释注意力行为的成功尝试包括注意力矩阵热图和二分图表示,这两种方法今天仍在使用。但这些方法也有一些重大限制。

显示除 BertViz 之外的一些可视化转换器注意力的方法的图形

        注意力矩阵热图(左)向我们表明,该模型不是逐字翻译,而是考虑词序的更大上下文。但它缺少注意力机制的许多细节。

        BertViz最终因其能够说明自我注意的低级,细粒度细节而广受欢迎,同时仍然保持非常简单和直观的使用。

BertViz注意力头视图的GIF,稍后选择转换器和注意力格式类型,并选择特定的注意力头,如Comet ML中所示

        BertViz最终因其能够说明自我注意的低级,细粒度细节而广受欢迎,同时仍然保持非常简单和直观的使用。作者动图

        这是一个漂亮、干净的可视化。但是,我们实际上在看什么?

6.2 BertViz如何打破这一切

        BertViz在多个局部尺度上可视化注意力机制:神经元水平,注意力头部水平和模型水平。下面我们将分解这意味着什么,从最低、最精细的级别开始,然后向上发展。

显示使用 BertViz 的转换器模型的模型视图、注意力头视图和神经元视图的图形

        BertViz 在多个尺度上可视化注意力,包括模型级别、注意力头部级别和神经元层。作者的图形。

七、用彗星Comet可视化 BertViz 

        我们将BertViz图记录到实验跟踪工具Comet上,以便稍后比较我们的结果。要开始使用 Comet,请在此处创建一个免费帐户,获取您的 API 密钥,然后运行以下代码:

import comet_ml
comet_ml.init(api_key='<YOUR-API-KEY>')
experiment = comet_ml.Experiment()

        我们只需三行代码即可设置 Comet。

        在彗星中可视化注意力将有助于我们通过显示模型如何关注输入的不同部分来解释模型的决策。在本教程中,我们将使用这些可视化来比较和剖析几个预训练 LLM 的性能。但这些可视化也可以在微调期间用于调试目的。

        要将 BertViz 添加到您的仪表板,请导航到 Comet 的公共面板并选择“变压器模型查看器”或“变形金刚注意力头查看器”。

GIF显示如何将BertViz可视化的转换器模型视图添加到Comet UI仪表板。

        要将 BertViz 添加到您的 Comet 仪表板,请从公共面板中选择它并根据自己的喜好调整视图。作者的动图。

        我们将定义一些函数来解析我们的模型结果并将注意力信息记录到 Comet。请参阅 Colab 教程以获取使用的完整代码。然后,我们将运行以下命令开始将数据记录到 Comet:

7.1 文本生成示例

textgen_model_version = "gpt2"
text_gen_prompts = [
    "The animal didn't cross the street because it was too",
    "The dog didn't play at the park becase it was too",
    "I went to the store. At the store I bought fresh",
    "At the store he bought flowers, candy, jewelry, and",
    "The dog ran up the street and barked too",
    "In 2016, the Young Mens' Christian Association (YMCA) was very",
    "The Doctor asked the Nurse a question. She",
    "The Doctor asked the Nurse a question. He",
]
text_generation_viz(
    text_gen_prompts,
    textgen_model_version,
)

7.2 问答示例

context = r"""A robot may not injure a human being or, through inaction, allow a human being to come to harm.
A robot must obey the orders given it by human beings except where such orders would conflict with the First Law.
A robot must protect its own existence as long as such protection does not conflict with the First or Second Laws.
"""
questions = [
    "Can a robot hurt a human?",
    "Can a robot injure a human?",
    "Should a robot obey orders from humans?",
    "Can a robot protect itself from a human?",
    "Can a robot love a human?"
]

qa_viz(context, questions, "distilbert-base-uncased-distilled-squad")

7.3 情绪分析示例

sa_prompts = [
    "Many people dislike Steve Jobs, while acknowledging his genius.",
    "The quick, brown fox jumps over the lazy dog.",
    "It was a beautiful day.",
    "It was a horrible day.",
    "I am confused.",
    "That movie was so sick but I wish it was longer.",
    "That movie was so awesome but I wish it was longer.",
    "That movie was so gross but I wish it was longer.",
    "That movie was so available but I wish it was longer.",
]
sa_model_version = "distilbert-base-uncased-finetuned-sst-2-english"

sentiment_viz(sa_prompts, sa_model_version)

八、神经元视图

        在最低级别,BertViz 可视化用于计算神经元中注意力的查询、键和值嵌入。给定选定的标记,此视图将跟踪从该令牌到序列中其他标记的注意力计算。

        在下面的 GIF 中,正值显示为蓝色,负值显示为橙色,颜色强度反映值的大小。连接线根据各个单词之间的注意力分数进行加权。

一个简短的 GIF,演示如何使用 BertViz 在注意力层的神经元级别上可视化计算,用于我们在 Comet ML 中的转换器实验。

神经元视图分解了用于预测每个令牌的计算,包括键和查询权重。

        以下两节中的视图将显示模型学习注意力模式,而此神经元视图显示了如何学习这些模式。神经元视图比我们在这个特定教程中需要的要精细一些,但为了更深入地研究,我们可以使用此视图将神经元与特定的注意力模式联系起来,更一般地说,将神经元与行为建模联系起来。

        重要的是要注意,注意力权重和模型输出之间存在什么关系并不完全清楚。有些人,如Jain等人在《注意力不是解释》中声称,标准注意力模块不应该被视为为预测提供了有意义的解释。然而,他们没有提出其他选择,BertViz仍然是当今最受欢迎的注意力可视化工具之一。

8.1 头视图

        注意力头视图通过揭示注意力头之间的模式,显示注意力如何在同一转换器层内的令牌之间流动。在此视图中,左侧的令牌关注右侧的令牌,注意力表示为连接每个令牌对的一条线。颜色对应于注意标题,线条粗细表示注意权重。

        在下拉菜单中,我们可以选择要可视化的实验,如果我们在实验中记录了多个资产,我们也可以选择我们的资产。然后,我们可以选择我们想要可视化的注意力层,或者,我们可以选择我们希望看到的注意力头的任意组合。请注意,连接标记的线条的颜色强度对应于标记之间的注意力权重。

BertViz 交互式可视化,如在 Comet UI 中绘制的那样。选择实验、资产、转换器模型图层和注意力格式。

        用户可以选择在 Comet UI 中指定实验、资产、图层和注意力格式。

        我们还可以指定希望如何格式化令牌。对于下面的问答示例,我们将选择“句子 A →句子 B”,以便我们可以检查问题和答案之间的注意力:

具有不同句子结构比较的注意力的BertViz可视化

        三种不同的方法来可视化BertViz的注意力输出。作者制图

8.2 注意头部模式

        注意力头不共享参数,因此每个头都会学习独特的注意力机制。在下图中,给定一个输入,将跨同一模型的各层检查注意力头。我们可以看到,不同的注意力似乎集中在非常独特的模式上。

        在左上角,相同单词之间的注意力最强(请注意“the”的两个实例相交的交叉)。在顶部中心,重点是句子中的下一个单词。在右上角和左下角,注意力头集中在每个分隔符上(分别为 [SEP] 和 [CLS])。底部中心强调逗号。右下角几乎是一个词袋图案。

BertViz表明,转换器注意力捕捉语言中的各种模式,包括位置模式,分隔符模式和词袋。

        BertViz表明,注意力可以捕捉语言中的各种模式,包括位置模式、分隔符模式和词袋。图片由作者提供。

        注意力头还可以捕获词汇模式。在下图中,我们可以看到专注于列表项(左)、动词(中心)和首字母缩略词(右侧)的注意力头示例。

BertViz显示转换器注意力头捕获词汇模式,如列表项,动词和首字母缩略词。

        BertViz显示注意力头捕获词汇模式,如列表项,动词和首字母缩略词。图片由作者提供。

8.3 注意力偏向

        头视图的一个应用是检测模型偏差。如果我们为我们的模型(在本例中为 GPT-2)提供两个除了最终代词之外相同的输入,我们会得到非常不同的生成输出:

BertViz可以帮助捕获变压器注意力机制中的模型偏差

        在左边,模型假设“她”是护士。在右边,它假设“他”是问问题的医生。一旦我们检测到模型偏差,我们如何增加我们的训练数据来抵消它?图片由作者提供。

        该模型假设“他”指的是医生,“她”指的是护士,这可能表明共同参考机制正在编码性别偏见。我们希望通过识别偏见的来源,我们可以潜在地努力抵消它(也许通过额外的训练数据)。

九、模型视图

        模型视图是跨所有层和头部的注意力的鸟瞰视角。在这里,我们可能会注意到跨层的注意力模式,说明了注意力模式从输入到输出的演变。每行数字代表一个注意力层,每列代表单独的注意力头。要放大任何特定头部的数字,我们只需单击它即可。请注意,您可以在模型视图中找到与头视图中相同的线型图案。

显示如何使用模型视图在 Comet UI 中放大注意力头视图的 GIF。

        要在模型视图中放大注意力头,只需单击它。注意注意力模式是如何跨层演变的。图片由作者提供。

9.1 模型视图应用程序

        那么,我们如何使用模型视图呢?首先,由于每一层都使用单独的独立权重进行初始化,因此专注于一个句子的特定模式的层可能专注于另一个句子的不同模式。因此,我们不一定会在实验运行中查看相同模式的相同注意力头。通过模型视图,我们可以更普遍地确定哪些层可能专注于给定句子的感兴趣区域。请注意,这是一门非常不精确的科学,正如许多人所提到的,“如果你寻找它,你就会找到它。尽管如此,这种观点确实为我们提供了一些有趣的见解,即该模型可能关注的内容。

        在下图中,我们使用本教程前面的相同示例(左)。在右边,句子的版本略有不同。在这两种情况下,GPT-2 都生成了句子中的最后一个单词。起初,认为狗有太多去公园的计划似乎很愚蠢。但检查注意力的头部表明,该模型可能将“公园”称为“太忙”。

BertViz帮助解开变压器如何理解语言。

在左边,GPT-2 在用“害怕”结束句子时可能指的是“动物”。在右边,当它以“忙碌”结束句子时,它可能指的是“公园”。图片由作者提供。

十、AI 中的可解释性

显示亚马逊招聘实践中性别差异的水平条形图

2018年,亚马逊取消了他们花了四年时间建立的求职者推荐系统,因为该系统意识到该模型表现出明显的性别偏见。该模式了解到招聘做法中现有的性别差异,并学会了使这些差异永久化。图片来自路透社。

随着人工智能变得越来越先进,模型计算几乎不可能解释,即使是创建它们的工程师和研究人员也是如此。这可能导致一系列意想不到的后果,包括但不限于:偏见和刻板印象的延续,对组织决策的不信任,甚至法律后果。可解释人工智能 (XAI) 是一组用于描述模型预期影响和潜在偏差的过程。对 XAI 的承诺有助于:

  • 组织采用负责任的 AI 开发方法
  • 开发人员确保模型按预期工作并满足法规要求
  • 研究人员表征决策的准确性、公平性和透明度
  • 组织建立信任和信心

那么,当当今最流行的ML架构(变压器)是出了名的不透明时,从业者如何将XAI实践整合到他们的工作流程中呢?这个问题的答案并不简单,必须从许多不同的角度来解释可解释性。但我们希望本教程通过帮助您可视化转换器中的注意力,为您的 XAI 工具箱中提供另一个工具。

结论

感谢您一直走到最后,我们希望您喜欢这篇文章。请随时在我们的社区 Slack 频道上与我们联系,提出任何问题、意见或建议!

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

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

相关文章

B074-详情富文本 服务上下架 高级查询 分页 查看详情

目录 服务详情修改优化ProductServiceImplProduct.vue 详情数据-富文本-vue-quill-editor使用步骤测试图片的访问方式富文本集成fastDfs 后台服务上下架&#xff08;批量&#xff09;前端开始后端完成ProductControllerProductServiceImplProductMapper 前台展示上架前端开始后…

【雕爷学编程】Arduino动手做(171)---micro:bit 开发板3

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#xff0c;这…

Jmeter 如何并发执行 Python 脚本

目录 1. 前言 2. Python 实现文件上传 3. Jmeter 并发执行 4. 最后 1. 前言 JMeter 是一个开源性能测试工具&#xff0c;它可以帮助我们更轻松地执行性能测试&#xff0c;并使测试结果更加可靠。Python 是一种广泛使用的编程语言&#xff0c;它可以用于开发各种软件和应用…

ResultMap结果集映射

为了解决属性名和字段名不相同的问题 example&#xff1a;MyBatis-CRUD: Mybatis做增删改查 使用resultmap前查询password时为空&#xff0c;因为属性名与字段名不相同 做结果集映射&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!…

自己动手写一个编译器

一、概述 本文将参考《自己动手写编译器这本书》&#xff0c;自己写一个编译器&#xff0c;但是因为本人水平有限。文章中比较晦涩的内容&#xff0c;自己也没弄明白。因此&#xff0c;本文仅在实践层跑一遍流程。具体的原理还需要大家自行探索。 TinyC 编译器可将 TinyC 源程序…

JavaScript 判断先后两个数组增加和减少的元素

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

错误解决:Failed to create Spark client for Spark session

错误解决&#xff1a;Failed to create Spark client for Spark session "Failed to create Spark client for Spark session"的错误通常表示无法为Spark会话创建Spark客户端。这可能是由于以下一些常见问题导致的&#xff1a; Spark配置错误&#xff1a;请检查Spar…

SAMStable-Diffusion集成进化!分割、生成一切!AI绘画新玩法

自SAM「分割一切」模型推出之后&#xff0c;二创潮就开始了&#xff0c;有想法有行动&#xff01;飞桨AI Studio开发者会唱歌的炼丹师就创作出SAM进化版&#xff0c;将SAM、Stable Diffusion集成&#xff0c;实现「分割」、「生成」能力二合一&#xff0c;并部署为应用&#xf…

vue项目入口和个文件之间的关系

vue项目入口和个文件之间的关系 1、代码的执行顺序和引入关系 1、代码的执行顺序和引入关系

新星计划打卡学习:VUE3引入element-plus

目录 1、安装element-plus 2、安装按需导入插件 3、修改配置文件 4、添加页面内容 5、保存并重启项目 1、安装element-plus 官网说要想使用element-plus需要先进行安装&#xff0c;并给出了三种安装方式&#xff0c;我选择了第三种。 报错了&#xff1a; 解决的办法&…

PostgreSQL 设置时区,时间/日期函数汇总

文章目录 前言查看时区修改时区时间/日期操作符和函数时间/日期操作符日期/时间函数&#xff1a;extract&#xff0c;date_part函数支持的field 数据类型格式化函数用于日期/时间格式化的模式&#xff1a; 扩展 前言 本文基于 PostgreSQL 12.6 版本&#xff0c;不同版本的函数…

人才公寓水电表改造解决方案

随着社会经济的不断发展&#xff0c;人才公寓作为吸引和留住人才的重要配套设施&#xff0c;其水电表改造问题越来越受到人们的关注。本文将从以下几个方面探讨人才公寓水电表改造解决方案。 一、现状分析 目前&#xff0c;人才公寓的水电表普遍存在以下几个问题&#xff1a; …

Jenkins从配置到实战(二) - Jenkins如何在多台机器上自动化构建

前言 jenkins除了支持在本机上进行项目构建&#xff0c;还可以将构建任务分发到其他远程服务器上去执行&#xff0c;可以实现在不同平台和架构的机器上来完成项目的自动化构建任务&#xff0c;也能减轻jenkins服务器的压力。本文章就主要介绍下此流程。 准备工作 准备两台机…

2.02 分类功能实现后台实现

三级分类效果图&#xff1a; 一 实现一级分类查询 步骤1&#xff1a;使用逆向工程生成创建实体类和对应的mapper 实体类&#xff1a;Categorymapper: CategoryMapper和CategoryMapper.xml步骤2&#xff1a; import com.one.pojo.Category; import java.util.List; public int…

视频讲解Codeforces Round 887 (Div. 2)(A--C)

文章目录 A. Desorting1、板书2、代码 B. Fibonaccharsis1、板书2、代码 C. Ntarsis Set1、板书2、代码 视频讲解Codeforces Round 887 (Div. 2)&#xff08;A–C&#xff09; A. Desorting 1、板书 2、代码 #include<bits/stdc.h> #define endl \n #define INF 0x3f…

Linux6.13 Docker LNMP项目搭建

文章目录 计算机系统5G云计算第四章 LINUX Docker LNMP项目搭建一、项目环境1.环境描述2.容器ip地址规划3.任务需求 二、部署过程1.部署构建 nginx 镜像2.部署构建 mysql 镜像3.部署构建 php 镜像4.验证测试 计算机系统 5G云计算 第四章 LINUX Docker LNMP项目搭建 一、项目…

功能测试也可以发现数据库相关的性能问题

很多同学认为功能测试和性能测试是严格分开的&#xff0c;功能测试人员无法发现性能问题。其实不是这样的&#xff0c;功能测试人员在验证功能时也可以发现性能问题&#xff1b;一些功能反而在功能测试环境不好验证&#xff0c;需要在性能环境上测试。 今天咱们就说一下测试涉及…

Spring Security 身份验证的基本类/架构

目录 1、SecurityContextHolder 核心类 2、SecurityContext 接口 3、Authentication 用户认证信息接口 4、GrantedAuthority 拥有权限接口 5、AuthenticationManager 身份认证管理器接口 6、ProviderManager 身份认证管理器的实现 7、AuthenticationProvider 特定类型的…

西北乱跑娃 -- CSS动态旋转果冻效果

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>旋转果冻</title> <style> #myDIV {margin: 250px;width: 250px;height: 250px;background: orange;position: relative;font-size: 20px;animation: anima…

【前缀和】LeetCode 560. 和为k的字数组

文章目录 题目描述方法1 暴力方法2 暴力优化方法3 前缀和方法4 前缀和优化 题目描述 力扣560题&#xff0c;链接&#xff1a;https://leetcode.cn/problems/subarray-sum-equals-k 方法1 暴力 暴力法&#xff0c;三重for循环&#xff0c;时间复杂度 O ( N 3 ) O(N^3) O(N3)&a…