“AI”科普丨Transformer架构图解最强教程!

news2024/11/25 18:30:09

今天给大家分享一篇关于深度学习模型Transformer的文章。我愿称之为讲解Transformer模型最好的文章。

文章内容主要介绍 Transformer 模型的具体实现:

  1. Transformer整体架构
  2. Transformer概览
  3. 引入张量
  4. 自注意力机制Self-Attention
  5. 多头注意力机制Mutil-Head Attention
  6. 位置反馈网络(Position-wise Feed-Forward Networks)
  7. 残差连接和层归一化(Add & Normalize)
  8. 位置编码(Positional Encoding)
  9. 解码器Decoder
  10. 掩码Mask:Padding Mask + Sequence Mask
  11. 最后的线性层和Softmax层
  12. 嵌入层和最终的线性层
  13. 正则化操作

博客地址:https://blog.csdn.net/benzhujie1245com/article/details/117173090

英文地址:http://jalammar.github.io/illustrated-transformer/

文章有点长,建议收藏

1、Transformer模型架构

2017 年,Google 在论文 Attentions is All you need(论文地址:https://arxiv.org/abs/1706.03762) 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。

相比 RNN 网络结构,其最大的优点是可以并行计算。Transformer 的整体模型架构如图所示:

图片Transformer模型架构

2、Transformer 概览

首先,让我们先将 Transformer 模型视为一个黑盒,如图所示。在机器翻译任务中,将一种语言的一个句子作为输入,然后将其翻译成另一种语言的一个句子作为输出:

图片Transformer 模型(黑盒模式)

2.1 Encoder-Decoder

Transformer 本质上是一个 Encoder-Decoder 架构。因此中间部分的 Transformer 可以分为两个部分:编码组件和解码组件

图片Transformer 模型(Encoder-Decoder 架构模式)

其中,编码组件由多层编码器(Encoder)组成(在论文中作者使用了 6 层编码器,在实际使用过程中你可以尝试其他层数)。解码组件也是由相同层数的解码器(Decoder)组成(在论文也使用了 6 层)。

图片

编码器/解码器组成

每个编码器由两个子层组成:

  • Self-Attention层(自注意力层)
  • Position-wise Feed Forward Network(前馈网络,缩写为 FFN

如下图所示:每个编码器的结构都是相同的,但是它们使用不同的权重参数(6个编码器的架构相同,但是参数不同)

图片Encoder编码器组成

编码器的输入会先流入 Self-Attention 层。它可以让编码器在对特定词进行编码时使用输入句子中的其他词的信息(可以理解为:当我们翻译一个词时,不仅只关注当前的词,而且还会关注其他词的信息)。

注:关注词语的上下文环境,不仅仅是词语本身

后面我们将会详细介绍 Self-Attention 的内部结构。然后,Self-Attention 层的输出会流入前馈网络。

解码器也有编码器中这两层,但是它们之间还有一个注意力层(即 Encoder-Decoder Attention),其用来帮忙解码器关注输入句子的相关部分(类似于 seq2seq 模型中的注意力)

图片

编码器:self-attention层 + 前馈网络FFN(Position-wise Feed Forward Network)

解码器:self-attention层 + Encoder-Decoder Attention + 前馈网络FFN(Position-wise Feed Forward Network)

3、引入张量

现在我们已经了解了模型的主要组成部分,让我们开始研究各种向量/张量,以及他们在这些组成部分之间是如何流动的,从而将输入经过已训练的模型转换为输出。

3.1 引入词嵌入Embedding

和通常的 NLP 任务一样,首先,我们使用词嵌入算法(Embedding) 将每个词转换为一个词向量。

Transformer 论文中,词嵌入向量的维度是 512

图片

每个词被嵌入到大小为 512 的向量中。我们将用这些简单的框代表这些向量。

词嵌入仅发生在最底层的编码器中。所有编码器都会接收到一个大小为 512 的向量列表:

  • 底部编码器接收的是词嵌入向量
  • 其他编码器接收的是上一个编码器的输出。

这个列表大小是我们可以设置的超参数——基本上这个参数就是训练数据集中最长句子的长度

3.2 词嵌入后编码

对输入序列完成嵌入操作后,每个词都会流经编码器的两层。

在这里插入图片描述
词嵌入与编码

接下来,我们将换一个更短的句子作为示例,来说明在编码器的每个子层中发生了什么。

上面我们提到,编码器会接收一个向量作为输入。编码器首先将这些向量传递到 Self-Attention 层,然后传递到前馈网络,最后将输出传递到下一个编码器。

图片编码器揭秘

4、Self-Attention(自注意力)

4.1 Self-Attention概览

首先我们通过一个例子,来对 Self-Attention 有一个直观的认识。假如我们要翻译下面这个句子:

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

这个句子中的 it 指的是什么?是指 animal 还是 street ?对人来说,这是一个简单的问题,但是算法来说却不那么简单。

当模型在处理 it 时,Self-Attention 机制使其能够将 itanimal 关联起来。

当模型处理每个词(输入序列中的每个位置)时,Self-Attention 机制使得模型不仅能够关注当前位置的词,而且能够关注句子中其他位置的词,从而可以更好地编码这个词。

如果你熟悉 循环神经网络 RNN,想想如何维护隐状态,使 RNN 将已处理的先前词/向量的表示与当前正在处理的词/向量进行合并。Transformer 使用 Self-Attention 机制将其他词的理解融入到当前词中。

图片

图注:当我们在编码器 #5(堆栈中的顶部编码器)中对单词it进行编码时,有一部分注意力集中在The animal上,并将它们的部分信息融入到it的编码中。

4.2 Self-Attention机制

下面我们来看一下Self-Attention的具体机制。其基本结构如图所示:

图片Scaled Dot-Product Attention(缩放点积注意力)

对于 Self Attention 来讲,Q(Query),K(Key)和 V(Value) 三个矩阵均来自同一输入,并按照以下步骤计算:

在这里插入图片描述

  • 然后利用Softmax操作将其结果归一化为概率分布,再乘以矩阵 V 就得到权重求和的表示。

整个计算过程可以表示为:

图片

为了更好的理解 Self-Attention,下面我们通过具体的例子进行详细说明。

4.3 Self-Attention详解

下面通过一个例子,让我们看一下如何使用向量计算 Self-Attention。计算Self-Attention的步骤如下:

第 1 步:对编码器的每个输入向量(在本例中,即每个词的词向量)创建三个向量:

  • Query 向量
  • Key 向量
  • Value 向量

它们是通过词向量分别和3个矩阵相乘得到的,这3个矩阵通过训练获得。

请注意,这些向量的维数小于词向量的维数。新向量的维数为 64,而 embedding 和编码器输入/输出向量的维数为 512

新向量不一定非要更小,这是为了使多头注意力计算保持一致的结构性选择。

图片

在这里插入图片描述

最终会为输入句子中的每个词创建一个 Query,一个 Key 和一个 Value 向量

什么是 Query,Key 和 Value 向量?它们是一种抽象,对于注意力的计算和思考非常有用。继续阅读下面的注意力计算过程,你将了解这些向量所扮演的角色。

第 2 步:计算注意力分数

假设我们正在计算这个例子中第一个词 Thinking 的自注意力。我们需要根据 Thinking 这个词,对句子中的每个词都计算一个分数。这些分数决定了我们在编码 Thinking 这个词时,需要对句子中其他位置的每个词放置多少的注意力。

在这里插入图片描述

图片

在这里插入图片描述

目的是在反向传播时,求梯度更加稳定。实际上,你也可以除以其他数。

第 4 步:将这些分数进行 Softmax 操作Softmax 将分数进行归一化处理,使得它们都为正数并且和为1。

图片Softmax操作

这些 Softmax 分数决定了在编码当前位置的词时,对所有位置的词分别有多少的注意力。很明显,当前位置的词汇有最高的分数,但有时注意一下与当前位置的词相关的词是很有用的。

第 5 步:将每个 Softmax 分数分别与每个 Value 向量相乘。

这种做法背后的直觉理解是:对于分数高的位置,相乘后的值就越大,我们把更多的注意力放在它们身上;对于分数低的位置,相乘后的值就越小,这些位置的词可能是相关性不大,我们就可以忽略这些位置的词。

越大越重视

第 6 步:将加权 Value 向量(即上一步求得的向量)求和。这样就得到了自注意力层在这个位置的输出。

图片self-attention完整过程

这样就完成了自注意力的计算。生成的向量会输入到前馈网络中。但是在实际实现中,此计算是以矩阵形式进行,以便实现更快的处理速度。下面我们来看看如何使用矩阵计算。

4.4 使用矩阵计算 Self-Attention

第一步:计算Query、KeyValue矩阵。
在这里插入图片描述

图片计算QKV矩阵

  • 矩阵 X 中的每一行,表示输入句子中的每一个词的词向量(长度为 512,在图中为 4 个方框)
  • 矩阵Q、K和V 中的每一行,分别表示Query向量,Key向量和Value 向量(它们的长度都为64,在图中为3个方框)。

第2步:计算自注意力。由于这里使用了矩阵进行计算,可以将前面的第 2 步到第 6 步压缩为一步。

图片矩阵形式的自注意力计算

5、多头注意力机制(Multi-head Attention)

5.1 多头注意力机制架构

Transformer论文中,通过添加一种多头注意力机制,进一步完善了自注意力层。具体做法:

  1. 首先,通过个不同的线性变换对Query、KeyValue 进行映射;
  2. 然后,将不同的 Attention 拼接起来;
  3. 最后,再进行一次线性变换。

基本结构如图所示:

图片

每一组注意力用于将输入映射到不同的子表示空间,这使得模型可以在不同子表示空间中关注不同的位置。整个计算过程可表示为:

图片

在这里插入图片描述

图片

按照上面的方法,使用不同的权重矩阵进行 8 次自注意力计算,就可以得到 8 个不同的 Z 矩阵。

图片

接下来就有点麻烦了。因为前馈神经网络层接收的是 1 个矩阵(每个词的词向量),而不是上面的 8 个矩阵。因此,我们需要一种方法将这 8 个矩阵整合为一个矩阵。具体方法如下:

在这里插入图片描述

图片

5.2 Multi-head Attention总结

这差不多就是多头注意力的全部内容了。下面将所有内容放到一张图中,以便我们可以统一查看:

图片

现在让我们重新回顾一下前面的例子,看看在对示例句中的“it”进行编码时,不同的注意力头关注的位置分别在哪:

图片

当我们对it进行编码时,一个注意力头关注The animal,另一个注意力头关注tired。从某种意义上来说,模型对it的表示,融入了animaltired的部分表达。

Multi-head Attention 的本质是:在参数总量保持不变的情况下,将同样的Query,Key,Value 映射到原来的高维空间的不同子空间中进行Attention的计算,在最后一步再合并不同子空间中的Attention信息。

这样降低了计算每个 headAttention 时每个向量的维度,在某种意义上防止了过拟合

由于 Attention 在不同子空间中有不同的分布,Multi-head Attention 实际上是寻找了序列之间不同角度的关联关系,并在最后拼接这一步骤中,将不同子空间中捕获到的关联关系再综合起来。

6、位置前馈网络(Position-wise Feed-Forward Networks)

位置前馈网络就是一个全连接前馈网络,每个位置的词都单独经过这个完全相同的前馈神经网络。

其由两个线性变换组成,即两个全连接层组成,第一个全连接层的激活函数为 ReLU 激活函数。可以表示为:

在这里插入图片描述

7、残差连接和层归一化

编码器结构中有一个需要注意的细节:每个编码器的每个子层(Self-Attention 层和 FFN 层)都有一个残差连接,再执行一个层标准化操作,整个计算过程可以表示为:

在这里插入图片描述

将向量和自注意力层的层标准化操作可视化,如下图所示:

图片

上面的操作也适用于解码器的子层。假设一个 Transformer 是由 2 层编码器和 2 层解码器组成,其如下图所示:

图片

在这里插入图片描述

8、位置编码

到目前为止,我们所描述的模型中缺少一个东西:表示序列中词顺序的方法。为了解决这个问题,Transformer 模型为每个输入的词嵌入向量添加一个向量。

这些向量遵循模型学习的特定模式,有助于模型确定每个词的位置,或序列中不同词之间的距离。

图片

如果我们假设词嵌入向量的维度是 4,那么实际的位置编码如下:

图片

那么位置编码向量到底遵循什么模式?其具体的数学公式如下:

在这里插入图片描述

在下图中,我们将这些值进行可视化。每一行对应一个向量的位置编码。所以第一行对应于输入序列中第一个词的位置编码。每一行包含 64 个值,每个值的范围在 -1 和 1 之间

图片

需要注意的是,官方提供的示例代码(TensorFlow 1.x 版本中的 get_timing_signal_1d() 函数和 TensorFlow 2.x 版本 中的 call() 函数)与 Transformer 论文中的方法稍微存在一定差异:

  • Transformer 论文中,sine 函数和 cosine 函数产生的值交织在一起;
  • 而官方提供的代码中,左半部分的值全是由 sine 函数产生的,右半部分的值全是由 cosine 函数产生的,然后将它们拼接起来。

官方代码生成的位置编码值的可视化图如下:

图片

这不是唯一一种生成位置编码的方法。但这种方法的优点是:可以扩展到未知的序列长度。例如,当我们训练后的模型被要求翻译一个句子,而这个句子的长度大于训练集中所有句子的长度。

9、解码器Decoder

现在我们已经介绍了编码器的大部分概念,我们也了解了解码器的组件的原理。现在让我们看下编码器和解码器是如何协同工作的。

通过上面的介绍,我们已经了解第一个编码器的输入是一个序列,最后一个编码器的输出是一组注意力向量 KeyValue。这些向量将在每个解码器的 Encoder-Decoder Attention 层被使用,这有助于解码器把注意力集中在输入序列的合适位置。

图片

在完成了编码阶段后,我们开始解码阶段。解码阶段的每个时间步都输出一个元素

接下来会重复这个过程,直到输出一个结束符,表示 Transformer 解码器已完成其输出。每一步的输出都会在下一个时间步输入到下面的第一个解码器,解码器像编码器一样将解码结果显示出来。就像我们处理编码器输入一样,我们也为解码器的输入加上位置编码,来指示每个词的位置。

Encoder-Decoder Attention 层的工作原理和多头自注意力机制类似。不同之处是:Encoder-Decoder Attention 层使用前一层的输出构造 Query 矩阵,而 KeyValue 矩阵来自于编码器栈的输出。

10、掩码Mask

Mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 Padding MaskSequence Mask

  • Padding Mask 在所有的 scaled dot-product attention 里面都需要用到
  • Sequence Mask 只有在解码器 DecoderSelf-Attention 里面用到。

10.1 Padding Mask

什么是 Padding mask 呢?因为每个批次输入序列的长度是不一样的,所以我们要对输入序列进行对齐

具体来说:就是在较短的序列后面填充 0(但是如果输入的序列太长,则是截断,把多余的直接舍弃)。因为这些填充的位置,其实是没有什么意义的,所以我们的 Attention 机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。

具体的做法:把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过Softmax 后,这些位置的概率就会接近0。

10.2 Sequence Mask

Sequence Mask是为了使得 Decoder 不能看见未来的信息。也就是对于一个序列,在时刻,我们的解码输出应该只能依赖于时刻之前的输出,而不能依赖之后的输出。因为我们需要想一个办法,把之后的信息给隐藏起来。

具体的做法:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每个序列上,就可以达到我们的目的。

总结:对于DecoderSelf-Attention,里面使用到的scaled dot-product attention,同时需要Padding MaskSequence Mask,具体实现就是两个Mask相加。其他情况下,只需要Padding Mask

11、最后的线性层和 Softmax 层

解码器栈的输出是一个 float向量。我们怎么把这个向量转换为一个词呢?通过一个线性层再加上一个Softmax层实现。

11.1 线性层

线性层是一个简单的全连接神经网络,其将解码器栈的输出向量映射到一个更长的向量,这个向量被称为logits向量。

11.2 Softmax层

现在假设我们的模型有 10000 个英文单词(模型的输出词汇表)。因此 logits 向量有 10000 个数字,每个数表示一个单词的分数。

然后,Softmax 层会把这些分数转换为概率(把所有的分数转换为正数,并且加起来等于 1)。最后选择最高概率所对应的单词,作为这个时间步的输出。

图片

12、嵌入层和最后的线性层

Transformer 论文,提到一个细节:编码组件和解码组件中的嵌入层,以及最后的线性层共享权重矩阵

在这里插入图片描述

13、正则化操作

为了提高 Transformer 模型的性能,在训练过程中,使用了以下的正则化操作:

在这里插入图片描述

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

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

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

相关文章

【RabbitMQ】一篇文章带你理解消息分发的六种模式

RabbitMQ共有6种工作模式(消息分发模式),分别是简单模式、工作队列模式、发布订阅模式、路由模式、主题模式以及RPC模式。 简单模式是最基本的工作模式,也是最简单的消息传递模式。在简单模式中,一个生产者将消息发到…

银行存量客户运营与数字化转型

文章目录 银行运营的基础逻辑银行数字化的需求迷思 银行运营的基础逻辑 “运营”二字看似熟悉,但不同的人理解起来千差万别。商业银行不缺运营,缺少的是在数字化工具深度介入经营行为后各项配套要素的运营。明确运营的基础需求、必要性、目标、主要内容…

如何开发一套基于C#和.NET 6.0手术麻醉系统? 手术麻醉系统源码

如何开发一套基于C#和.NET 6.0手术麻醉系统? 手术麻醉系统源码 基于C#和.NET 6.0开发的手术麻醉系统是一个涉及多个层面的复杂项目。 以下是一个概述性的步骤,帮助你开始这个项目: 一、项目规划和需求分析 1、确定项目目标:明确…

微信小程序简易录音机

首先先创建一个项目&#xff08;想必大家都会啦那就直接开干&#xff09; 首先上html结构 <view class"wx-container"><view id"title">录音机</view><view id"time">{{hours}}:{{minute}}:{{second}}</view>&l…

Ubuntu 20.04安装显卡驱动、CUDA和cuDNN(2024.06最新)

一、安装显卡驱动 1.1 查看显卡型号 lspci | grep -i nvidia我们发现输出的信息中有Device 2230&#xff0c;可以根据这个信息查询显卡型号 查询网址&#xff1a;https://admin.pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci 输入后点击Jump查询 我们发现显卡型号为RTX …

【html】如何利用hbuilderX 开发一个自己的app并安装在手机上运行

引言&#xff1a; 相信大家都非常想开发一款自己的apk&#xff0c;手机应用程序&#xff0c;今天就教大家&#xff0c;如何用hbuilderX 开发一个自己的app并安装在手机上运行。 步骤讲解&#xff1a; 打开hbuilderX &#xff0c;选择新建项目 2.选择5app,想一个名字&#x…

聊聊最近比较火的AI产品做互联网算法备案

今年AI&#x1f525;了&#xff0c;而且是大火&#xff0c;导致监管部门相继出台相关政策&#xff0c;需要管控下&#xff0c;所以互联网算法备案就自然而然重新被提出来。其实这个互联网算法备案去年就已经开始实施了&#xff0c;去年只有几个大厂比如BAT等互联网巨头等会去弄…

学生管理系统更新(账号系统)

展示 头文件 #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//输入输出函数 #include<stdlib.h>//动态分配函数和随机函数 #include<windows.h>//控制台程序&#xff0c;用来实现cmd指令&#xff0c;title指令&#xff0c;cls指令等等 …

2024中国宁波-东南亚职业教育产教协同发展校企对接会举办

2024年6月16日&#xff0c;由东南亚教育部长组织技术教育发展中心&#xff08;SEAMEO TED&#xff09;、联合国教科文组织国际农村教育研究与培训中心&#xff08;UNESCO INRULED&#xff09;、中国教育国际交流协会&#xff08;CEAIE&#xff09;三方主办的“2024中国宁波-东南…

深入理解和实现Windows进程间通信(共享内存)

常见的进程间通信方法 常见的进程间通信方法有&#xff1a; 管道&#xff08;Pipe&#xff09;消息队列共享内存信号量套接字 下面&#xff0c;我们将详细介绍共享内存的原理以及具体实现。 什么是共享内存&#xff1f; Windows共享内存&#xff08;Shared Memory in Windo…

单商户社区团购卖菜卖水果商城自提点商城系统小程序源码

打造便捷团购新体验 &#x1f34e; 引言&#xff1a;社区团购的崛起 近年来&#xff0c;社区团购以其独特的优势&#xff0c;迅速崛起并受到广大消费者的喜爱。它不仅能够提供物美价廉的商品&#xff0c;还能让居民们享受到更加便捷的购物体验。而单商户社区团购系统小程序&am…

Airtest-Selenium实操小课④:微信读书上阅读书籍

1. 前言 上一课我们讲到用Airtest-Selenium爬取下载可爱的猫猫图片&#xff0c;还没看的同学可以戳这里看看~ 那么今天的推文&#xff0c;我们就来说说看&#xff0c;怎么实现模拟真人去打开微信读书网站&#xff0c;点击进入书本进行阅读。 2.需求分析和准备 整体的需求大…

告别繁琐录入,一键解锁OCR魅力:高效文字识别工具推荐

在日常工作中&#xff0c;我们常常会需要找一些模版&#xff0c;如果直接下载编辑某某文档&#xff0c;都是要花钱的。 比如领导让我找个法律文书&#xff0c;改成我们的内容&#xff0c;网上有很多的参考文档&#xff0c;但是不论哪个&#xff0c;下载都要钱&#xff0c;也不…

STM32 CAN总线通讯

使用STM32的CAN通讯&#xff0c;利用回环模式&#xff0c;按键控制发送CAN数据&#xff0c;中断接收CAN数据并通过串口助手打印出来。 7.2、配置引脚信息 由于每次新建工程都需要配置信息&#xff0c;比较麻烦&#xff0c;好在STM32CubeIDE提供了导入.ioc文件的功能&#xff…

阿里云PAI主机网页访问测试

笔者使用的阿里云平台PAI主机(首次使用免费三个月额度)&#xff0c;由于其默认不设置公网IP&#xff0c;所以在该主机上启动HTTP服务后无法访问测试。 这里使用ssh来作隧道穿透&#xff0c;首先需要配置ssh。 云主机配置ssh 1. 修改root账号密码 在云主机上执行 passwd ro…

图片转pdf,图片转pdf在线转换,在线图片转pdf

图片转PDF&#xff0c;听起来似乎是一个简单的操作&#xff0c;但实际上&#xff0c;它涉及到许多细节和技巧。有时候我们需要将图片转换为PDF格式&#xff0c;以便于分享、打印或保存。那么&#xff0c;如何将图片转换成PDF呢&#xff1f;接下来&#xff0c;我将为您详细介绍几…

电脑系统重装怎么操作?分享四个win10重装系统方法

“我遇到了一些笔记本电脑的问题&#xff0c;别人告诉我解决这个问题需要重新安装Win10电脑系统。但我不记得我把光盘放在哪里了&#xff0c;我能否在不丢失文件的情况下重新安装操作系统&#xff1f;电脑系统重装怎么操作&#xff1f;”虽然电脑自带系统中有多种方法可供选择&…

有哪些常用ORM框架

ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是一种编程技术&#xff0c;它允许开发者使用面向对象的编程语言来操作关系型数据库。ORM的主要目的是将数据库中的数据表映射到编程语言中的对象&#xff0c;从而使得开发者可以使用对象的方式来…

Docker之overlay2的迁移

原因 docker默认将文件及其容器放置在了系统盘的挂载区内&#xff0c;如果长期使用会发现系统挂载区被overlay2挤爆了,因此在一开始我们将其迁移在大容量外挂磁盘上,就可以避免系统盘被挤爆,放心使用. 具体操作 # 停止容器 systemctl stop docker# 修改容器配置&#xff0c…

Spring+SpringMVC介绍+bean实例化+依赖注入实战

Spring介绍 Spring是一个轻量级的Java 开发框架&#xff0c;核心是IOC&#xff08;控制反转&#xff09;和AOP&#xff08;面向切面编程&#xff09; Spring解决了业务层&#xff08;Service包&#xff09;与其他各层&#xff08;表现层&#xff0c;包括Model&#xff0c;Vie…