transfomer模型——简介,代码实现,重要模块解读,源码,官方

一、什么是transfomer

Transformer是一种基于注意力机制(attention mechanism)的神经网络架构,最初由Vaswani等人在论文《Attention Is All You Need》中提出。它在自然语言处理(NLP)领域取得了巨大成功,特别是在机器翻译任务中。

传统的循环神经网络(RNNs)和长短时记忆网络(LSTM)在处理长距离依赖关系时存在一些问题,而Transformer引入了自注意力机制来解决这些问题。自注意力机制允许模型在处理序列数据时关注输入序列中的不同位置,而不仅仅是当前位置。这使得Transformer能够并行处理输入序列,加速训练。

Transformer的核心思想包括:

  1. 自注意力机制(Self-Attention): 模型能够同时考虑输入序列中的所有位置,而不是像传统的固定窗口大小的卷积或循环神经网络一样逐步处理。

  2. 位置编码(Positional Encoding): 由于Transformer没有显式的顺序信息,为了保留输入序列中元素的位置信息,需要添加位置编码。

  3. 多头注意力(Multi-Head Attention): 将自注意力机制应用多次,通过多个注意力头来捕捉不同的关系。

  4. 前馈神经网络(Feedforward Neural Network): 每个注意力子层后接一个前馈神经网络,用于学习非线性关系。

Transformer的成功不仅限于NLP领域,还在计算机视觉等领域取得了重要进展。由于其并行计算的优势,Transformer已成为深度学习中的经典模型之一,被广泛用于各种任务。

二、基本代码实现

Transformer的代码实现相对复杂,因为它涉及到自注意力机制、位置编码、多头注意力等多个关键概念。以下是一个简化的Transformer的PyTorch代码示例,用于机器翻译任务。这只是一个基本的实现,实际应用中可能需要根据任务和数据进行一些调整。

import torch
import torch.nn as nn

class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len=512):
        super(PositionalEncoding, self).__init__()
        self.encoding = torch.zeros(max_len, d_model)
        position = torch.arange(0, max_len).unsqueeze(1).float()
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * -(torch.log(torch.tensor(10000.0)) / d_model))
        self.encoding[:, 0::2] = torch.sin(position * div_term)
        self.encoding[:, 1::2] = torch.cos(position * div_term)
        self.encoding = self.encoding.unsqueeze(0)
        
    def forward(self, x):
        return x + self.encoding[:, :x.size(1)].detach()

class TransformerModel(nn.Module):
    def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers):
        super(TransformerModel, self).__init__()
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.positional_encoding = PositionalEncoding(d_model)
        self.transformer = nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers)
        self.fc = nn.Linear(d_model, vocab_size)
        
    def forward(self, src, tgt):
        src = self.embedding(src)
        src = self.positional_encoding(src)
        tgt = self.embedding(tgt)
        tgt = self.positional_encoding(tgt)
        output = self.transformer(src, tgt)
        output = self.fc(output)
        return output

# 定义模型
vocab_size = 10000  # 词汇表大小
d_model = 512  # 模型维度
nhead = 8  # 多头注意力的头数
num_encoder_layers = 6  # 编码器层数
num_decoder_layers = 6  # 解码器层数

model = TransformerModel(vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers)

# 定义输入
src = torch.randint(0, vocab_size, (10, 32))  # 10个序列,每个序列长度为32
tgt = torch.randint(0, vocab_size, (20, 32))  # 20个序列,每个序列长度为32

# 前向传播
output = model(src, tgt)

此代码仅为示例,实际中可能需要根据任务的不同进行调整。Transformer模型在实际应用中可能有更多的细节和优化。 PyTorch官方也提供了详细的Transformer模型文档。

三、详细解读自注意力机制

自注意力机制(Self-Attention Mechanism)是Transformer模型的核心组成部分之一,用于处理输入序列中各个位置之间的依赖关系。以下是对自注意力机制的详细解读:

  1. 注意力的概念:
    注意力机制模拟了人类视觉系统的工作原理,即在处理某个任务时,我们不是对所有信息一视同仁,而是在某个时刻关注一部分信息,而另一时刻可能关注其他信息。在自注意力机制中,模型通过学习到的权重分配给输入序列中的不同位置,以便在生成输出时更加关注相关的部分。

  2. 自注意力机制的基本原理:

    • Query(查询): 通过将输入序列与权重矩阵相乘,得到每个位置的查询向量。查询向量用于衡量每个位置与其他位置的相关性。
    • Key(键): 通过将输入序列与权重矩阵相乘,得到每个位置的键向量。键向量用于被查询向量衡量,从而计算注意力分布。
    • Value(值): 通过将输入序列与权重矩阵相乘,得到每个位置的值向量。值向量将根据注意力分布加权求和,形成最终的输出。
  3. 注意力分布计算:

    • 计算相似度: 通过查询向量和键向量的点积,计算每个位置的相似度得分。
    • 缩放: 为了避免相似度过大导致的梯度消失或梯度爆炸问题,一般会对相似度进行缩放,常用的缩放因子是输入维度的平方根。
    • Softmax: 对缩放后的相似度应用Softmax函数,得到注意力权重分布。Softmax确保所有权重的总和为1,使其成为有效的概率分布。
    • 注意力加权求和: 将值向量按照得到的注意力权重进行加权求和,得到最终的自注意力输出。
  4. 多头注意力(Multi-Head Attention):
    为了增强模型的表达能力,自注意力机制通常会使用多个独立的注意力头。每个头学习不同的查询、键、值权重矩阵,最后将多个头的输出拼接在一起并通过线性映射进行融合。

  5. 位置编码(Positional Encoding):
    自注意力机制没有直接考虑序列中元素的顺序,为了捕捉序列的位置信息,常常会在输入序列中添加位置编码。位置编码是一个与位置有关的可学习参数,使得模型能够更好地处理序列的顺序信息。

自注意力机制的引入有效地捕捉了序列中不同位置之间的关系,使得模型能够在输入序列中动态地分配注意力。这种机制的引入是Transformer模型成功的关键之一,尤其在处理长距离依赖关系时表现优异。

四、详细解读位置编码

位置编码(Positional Encoding)是Transformer模型中为了将序列中每个位置的信息注入到模型中而引入的一种机制。由于Transformer没有像循环神经网络(RNN)或卷积神经网络(CNN)那样显式的位置信息,因此引入位置编码来帮助模型理解输入序列中不同位置的相对关系。

在Transformer中,位置编码是通过将位置信息编码成一个与词嵌入(Word Embedding)具有相同维度的向量,并将其加和到输入的词嵌入上来实现的。这样,不同位置的词将拥有不同的词嵌入值,从而使模型能够区分它们。

位置编码的一种常用形式是使用正弦和余弦函数的组合。具体来说,位置编码的计算如下:

在这里插入图片描述

其中:

  • ( pos ) 是位置信息,表示序列中的每个位置;
  • ( i ) 是位置编码中的维度索引,取值范围为 ([0, d/2-1]),其中 ( d ) 是词嵌入的维度;
  • ( PE_{(pos, 2i)} ) 和 ( PE_{(pos, 2i+1)} ) 分别表示位置编码向量中的第 ( 2i ) 和 ( 2i+1 ) 维。

这样,每个位置 ( pos ) 都对应一个唯一的位置编码向量,将这个向量加和到词嵌入中,就能够考虑位置信息。

总体来说,位置编码在Transformer中是一个非常重要的组成部分,它帮助模型理解输入序列中词的位置关系,而不仅仅是词本身的内容。

五、详细解读多头注意力

多头注意力机制(Multi-Head Attention)是Transformer模型中的核心组件之一。它通过允许模型在不同的表示空间中分别关注输入序列的不同部分,从而提高了模型对不同特征的表达能力。以下是对多头注意力机制的详细解读:

1. 单头注意力机制回顾

首先,我们回顾一下单头注意力机制。对于给定的输入序列 (X = {x_1, x_2, …, x_n}),单头注意力机制的计算过程如下:

  1. 计算注意力分数(Attention Scores): 对于每个位置 (i),计算注意力分数 (e_{ij}),表示位置 (i) 对位置 (j) 的注意力贡献。
    [ e_{ij} = \frac{​{(Q_i \cdot K_j)}}{​{\sqrt{d_k}}} ]

    其中,(Q_i)、(K_j) 分别是位置 (i) 的查询(Query)和位置 (j) 的键(Key)表示,(d_k) 是注意力的维度。

  2. 计算注意力权重(Attention Weights): 使用 softmax 函数将注意力分数转换为注意力权重,表示每个位置对当前位置的贡献。
    [ \alpha_{ij} = \text{softmax}(e_{ij}) ]

  3. 加权求和(Weighted Sum): 利用注意力权重对值(Value)进行加权求和,得到当前位置的注意力输出。
    [ \text{Attention}(X) = \sum_{j=1}^{n} \alpha_{ij} \cdot V_j ]

其中,(V_j) 是位置 (j) 的值表示。

2. 多头注意力机制

多头注意力引入了多组查询、键和值的线性变换,以获得多个不同的注意力表示。假设有 (h) 个注意力头,对于第 (i) 个头,查询、键和值的变换分别为 (W_i^Q)、( (W_i^K) 和 (W_i^V)。多头注意力的计算过程如下:

  1. 多头线性变换: 对输入序列分别进行 (h) 组线性变换,得到多组查询、键和值。
    [ Q_i = XW_i^Q, \quad K_i = XW_i^K, \quad V_i = XW_i^V ]

  2. 多头注意力计算: 对每组注意力头分别计算注意力输出。
    [ \text{Head}_i = \text{Attention}(Q_i, K_i, V_i) ]

  3. 多头拼接: 将多个注意力头的输出拼接在一起。
    [ \text{MultiHead}(X) = \text{Concat}(\text{Head}_1, \text{Head}_2, ..., \text{Head}_h) ]

  4. 线性变换: 对拼接后的结果进行线性变换。
    [ \text{Output}(X) = \text{MultiHead}(X)W^O ]

其中,(W^O) 是输出的线性变换参数。

3. 多头注意力的优势

多头注意力机制的引入具有以下几个优势:

  • 多头并行计算: 不同注意力头可以并行计算,提高了计算效率。
  • 学习不同表示: 不同头关注输入序列的不同部分,有助于模型学习更丰富、更复杂的特征表示。
  • 提高模型泛化能力: 多头注意力可以使模型在处理不同类型的信息时更加灵活,提高了模型的泛化能力。

通过这种方式,多头注意力机制在Transformer模型中起到了至关重要的作用,使得模型能够更好地捕捉输入序列中的关系,提高了模型的表达能力。

六、详细解读前馈神经网络

前馈神经网络(Feedforward Neural Network)是一种最基本的神经网络结构,也被称为多层感知机(Multilayer Perceptron,MLP)。在深度学习中,前馈神经网络被广泛应用于各种任务,包括图像分类、语音识别、自然语言处理等。下面是对前馈神经网络的详细解读:

1. 基本结构

前馈神经网络由输入层、隐藏层和输出层组成。每一层都包含多个神经元(或称为节点),每个神经元与上一层的所有神经元都有连接,连接上带有权重。每个连接上都有一个权重,表示连接的强度。

  • 输入层(Input Layer): 接受输入特征的层,每个输入特征对应一个输入层神经元。

  • 隐藏层(Hidden Layer): 在输入层和输出层之间的一层或多层神经元,负责学习输入数据中的复杂模式。

  • 输出层(Output Layer): 提供网络的输出,输出的维度通常与任务的要求相匹配,例如,对于二分类任务,可以有一个输出神经元表示两个类别的概率。

2. 激活函数

每个神经元在接收到输入后,会通过激活函数进行非线性变换。常用的激活函数包括:

  • Sigmoid 函数: 将输入映射到范围 ((0, 1)),适用于二分类问题。

  • Hyperbolic Tangent(tanh)函数: 将输入映射到范围 ((-1, 1)),具有零中心性,有助于减少梯度消失问题。

  • Rectified Linear Unit(ReLU)函数: 对于正数输入,输出等于输入;对于负数输入,输出为零。ReLU 是目前最常用的激活函数之一。

  • Softmax 函数: 用于多分类问题的输出层,将输出转化为概率分布。

3. 前向传播

前馈神经网络的训练过程中,信息从输入层传播到输出层的过程称为前向传播。具体步骤如下:

  1. 输入层接收输入特征。

  2. 每个神经元接收来自上一层神经元的输入,计算加权和。

  3. 加权和经过激活函数进行非线性变换,得到每个神经元的输出。

  4. 输出传递到下一层作为输入,重复以上步骤。

  5. 最终,网络的输出被用于任务的预测。

4. 反向传播与训练

前馈神经网络通过反向传播算法进行训练。反向传播的基本思想是通过比较网络的输出与真实标签之间的差异,然后将误差反向传播到网络的每一层,调整权重以减小误差。

  1. 计算损失: 通过损失函数计算模型的输出与真实标签之间的误差。

  2. 反向传播: 从输出层到输入层,计算每个连接上的梯度,根据梯度更新权重。

  3. 优化: 使用优化算法(如梯度下降)更新网络参数,减小损失。

  4. 重复训练: 重复以上步骤,直到模型收敛或达到指定的训练轮数。

5. 应用领域

前馈神经网络广泛应用于图像分类、目标检测、语音识别、自然语言处理等领域。其简单而有效的结构使其成为深度学习的基石,同时也是更复杂神经网络结构的基础。

七、Transfomer模型知识简单化,知识性

Transformer 模型是一种基于自注意力机制的深度学习模型,最初由Vaswani等人于2017年提出,用于自然语言处理任务,但后来在其他领域也取得了很大成功。以下是对Transformer模型的简单化解释:

  1. 背景: Transformer的出现是为了解决序列数据处理中的问题,如机器翻译。传统的循环神经网络(RNN)和长短时记忆网络(LSTM)在处理长序列时存在一些限制,而Transformer采用了全新的结构。

  2. 自注意力机制: Transformer的核心是自注意力机制。传统的神经网络在处理序列数据时,对每个位置的信息处理是固定的,而自注意力机制允许模型在处理每个位置时关注输入序列的其他部分,从而更好地捕捉全局信息。

  3. 编码器-解码器结构: Transformer通常包含一个编码器和一个解码器。编码器负责将输入序列转换成抽象表示,解码器则基于这个表示生成输出序列。这使得模型适用于序列到序列的任务,如机器翻译。

  4. 位置编码: 由于Transformer没有内置处理序列中元素的顺序信息,位置编码被引入,以将元素的位置信息嵌入到输入数据中,使得模型能够考虑元素的相对位置。

  5. 多头注意力: 为了更好地捕捉不同特征尺度的信息,Transformer使用多头注意力机制。这允许模型同时关注输入序列的不同部分,从而提高了模型的表达能力。

  6. 前馈神经网络: 在编码器和解码器的每个位置上,都包含一个前馈神经网络。这个网络用于在不同位置上对抽象表示进行进一步的非线性变换。

Transformer模型通过引入自注意力机制和其他创新性的结构,成功地解决了处理序列数据时的一些限制,成为深度学习领域的重要模型之一。

八、编码器+解码器

编码器-解码器结构是深度学习中常用的一种网络架构,特别在图像分割和生成任务中得到广泛应用。以下是对编码器-解码器结构的详细解读:

编码器(Encoder):

  1. 特征提取: 编码器的主要作用是从输入数据中提取关键特征。对于图像任务,输入通常是图像,编码器通过一系列卷积层(Convolutional Layers)进行特征提取。这些卷积层可以捕捉图像中的低级别和高级别特征,例如边缘、纹理和对象形状。

  2. 降维: 随着网络深度的增加,编码器通常会进行降维操作,通过池化层(Pooling Layers)或步幅较大的卷积层减小特征图的尺寸。这有助于减少计算复杂性和内存需求,并提高网络对输入的抽象表示能力。

  3. 语义信息提取: 在编码器的高层级特征表示中,网络通常能够捕捉到更抽象的语义信息,例如图像中的物体类别、结构等。这些特征通常被称为“语义特征”。

解码器(Decoder):

  1. 上采样: 解码器负责将编码器提取的特征映射还原为输入数据的尺寸。这通常涉及到上采样操作,其中通过插值或反卷积操作将特征图的尺寸放大。

  2. 特征融合: 解码器通常需要与编码器的相应层进行特征融合,以保留从输入到编码器的层次结构中学到的语义信息。这可以通过连接编码器和解码器的相应层来实现,形成所谓的“跳跃连接”(Skip Connections)。

  3. 重建输出: 解码器的最终目标是生成与输入数据相匹配的输出。对于图像分割任务,输出通常是一个与输入图像尺寸相同的特征图,其中每个像素或区域对应一个类别的概率或标签。

应用领域:

  • 图像分割: 编码器-解码器结构在图像分割任务中广泛应用,其中编码器负责提取图像特征,而解码器负责还原像素级别的预测。

  • 图像生成: 在生成任务中,编码器-解码器结构可用于学习输入数据的潜在表示,并生成与输入类似的新样本。

  • 自动编码器: 编码器-解码器结构也是自动编码器(Autoencoder)的基础,其中网络被设计成学习输入数据的压缩表示和重建输入。

编码器-解码器结构的设计和优化取决于具体的任务和应用场景,而且随着深度学习的发展,许多变体和改进的结构也相继提出。

编码器-解码器的代码实现通常基于深度学习框架,如TensorFlow或PyTorch。下面是一个简化的例子,展示了一个基于卷积神经网络(CNN)的编码器-解码器结构,以用于图像分割任务:

import torch
import torch.nn as nn

class EncoderDecoder(nn.Module):
    def __init__(self):
        super(EncoderDecoder, self).__init__()
        
        # 编码器部分
        self.encoder = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            # 添加更多卷积层和池化层...
        )
        
        # 解码器部分
        self.decoder = nn.Sequential(
            # 添加上采样层和特征融合...
            nn.Conv2d(128, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),
            nn.Conv2d(64, 32, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),
            nn.Conv2d(32, 1, kernel_size=3, padding=1),
            nn.Sigmoid()  # 用于二分类任务时添加Sigmoid激活函数
        )

    def forward(self, x):
        # 编码器前向传播
        x = self.encoder(x)
        
        # 解码器前向传播
        x = self.decoder(x)
        
        return x

# 创建模型实例
model = EncoderDecoder()

# 打印模型结构
print(model)

编码器和解码器的结构可能会更加复杂,具体的设计取决于任务的要求和数据集的特点。上述代码中使用的是PyTorch的简单卷积层、池化层和上采样层,实际场景中可能需要更深的网络结构和更复杂的组件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机CentOS 8 重启后不能上网

情况说明:原本虚拟机是可以上网的,然后嘚一下,重启后,连接不上网络,完了,上网查找一堆质料,我的连接方式是桥接模式(复制物理网络连接状态)。 好,有人说是vmn…

Git基本概念和使用方式

Git 是一种版本控制系统,用于管理文件版本的变化。以下是其基本概念和使用方式: 仓库(repository):Git 存储代码的地方,可以理解为一个项目的文件夹。提交(commit):Git …

【Go入门】struct类型

【Go入门】struct类型 struct Go语言中,也和C或者其他语言一样,我们可以声明新的类型,作为其它类型的属性或字段的容器。例如,我们可以创建一个自定义类型person代表一个人的实体。这个实体拥有属性:姓名和年龄。这样…

前端开发引入element plus与windi css

背景 前端开发有很多流行框架,像React 、angular、vue等等,本文主要讲vue 给新手用的教程,其实官网已经写的很清楚,这里再啰嗦只是为了给新手提供一个更加简单明了的参考手册。 一、打开element plus官网选则如图所示模块安装命令…

c语言练习第11周(1~5)

数列 1 1 2 3 5 8 13 21 ... 被称为斐波纳数列。 输入若干个正整数N,输出这个序列的前 N 项的和。 题干数列 1 1 2 3 5 8 13 21 ... 被称为斐波纳数列。 输入若干个正整数N,输出这个序列的前 N 项的和。输入样例3 5 4 1输出样例…

【第七章】软件设计师 之 程序设计语言与语言程序处理程序基础

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 1、前言 正规式 2、编译过程 编译型&…

【操作系统】4.2 文件系统

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

如何有效的保护Windows登录 安当加密

为了有效保护Windows安全登录,以下是一些建议: 使用强密码:强密码是保护Windows登录安全的重要措施之一。确保密码包含大写字母、小写字母、数字和特殊字符,长度至少为8位,并且不要使用容易猜到的单词或短语。启用多因…

pointnetgpd复现

参考: Installation Instructions — Dex-Net 0.2.0 documentation Install git clone https://github.com/lianghongzhuo/PointNetGPD.git 添加环境变量 gedit ~/.bashrc #添加下面这一行 export PointNetGPD_FOLDER$HOME/code/PointNetGPD #然后source source…

SLAM从入门到精通(SLAM落地的难点)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在所有的slam算法中,基于反光柱的激光slam和基于二维码的视觉slam是落地最彻底的两种slam方法。和磁条、色带等传统导航方式相比较&…

U-Mail邮件系统三大安全措施,防止信息泄露!

在当信息化高速发展的今天,国内很多企业业务流程对OA系统、CRM系统、ERP系统、邮件系统等办公应用依赖度越来越高。这些办公应用给企业带来便利的同时也伴随着越来越多的信息安全问题,而在日常的办公场景中,由于内部员工非法泄漏或黑客入侵导…

Flowable 外部表单

内置表单需要在每个节点中去配置,当如果多个节点使用同一套表单属性就要配置多次比较麻烦,修改的时候也要修改多次,外部表单可以定义一次,然后其它节点都去引用同一个表单属性。 外部表单需要定义一个.form后缀的文件。 外部表单…

运行pytest时,给出警告 PytestConfigWarning: Unknown config option: result_log

问题:在ini中配置了一些选项后运行pytest,会出现下面的警告信息 解决:在ini中增加配置:addopts -p no:warnings

【Git】的分支与版本

前言 Git 的分支是指将代码库从某一个特定的提交记录开始的一个独立的开发线,也可以理解为是一种代码开发的并行方式。分支在 Git 中的使用非常广泛,它可以让多人在同一个代码库中并行开发,同时也能够很方便地进行代码版本控制和管理。 Git …

Python 多进程多线程

多任务 并发:在一段时间内交替执行多个任务 并行:在一段时间内同事一起执行多个任务 进程 Process 进程:一个程序运行在系统之上, 便称这个程序喂一个运行进程,并分配进程ID方便系统管理。操作系统进行资源分配和调…

【多线程】

文章目录 概念一、线程的生命周期图二、线程的创建方式一方式二线程API线程优先级sleep阻塞守护线程多线程并发安全问题 总结 概念 线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。多线程:多个单一顺序执行的流程并发运行。造成"感官上…

JavaWeb Day10 案例 准备工作

目录 一、需求说明 二、环境搭建 (一)数据库 (二)后端 ①controller层 1.DeptController.java 2.EmpController.java ②mapper层 1.DeptMapper.java 2.EmpMapper.java ③pojo层 1.Dept.java 2.Emp.java 3.Result.ja…

Python之函数进阶-生成器函数

Python之函数进阶-生成器函数 生成器函数 Python中有2种方式构造生成器对象: 生成器表达式生成器函数 函数体代码中包含yield语句的函数与普通函数调用不同,生成器函数调用返回的是生成器对象 普通函数调用,函数会立即执行直到执行完毕。 生成器函数…

linux gdb 调试 常见调试命令介绍+总结

1.调试前准备 -g gcc arcg.c -g -oO -o app //必须添加-g 2.调试 gdb gdb app 3.常见调试命令 set args 1 2 3 4 5 6 //设置参数 show args //查看参数 3.1执行程序 1.start2. run gdb app set args 1 2 3 4 5 start //执行一行 c //继续执行 q…

【Git】Git分支与应用分支Git标签与应用标签

一,Git分支 1.1 理解Git分支 在 Git 中,分支是指一个独立的代码线,并且可以在这个分支上添加、修改和删除文件,同时作为另一个独立的代码线存在。一个仓库可以有多个分支,不同的分支可以独立开发不同的功能&#xff0…