Transformer详解(附代码实现及翻译任务实现)

news2024/10/5 17:20:43

一:了解背景和动机

  1. 阅读Transformer论文:

    阅读原始的Transformer论文:“Attention is All You Need”,由Vaswani等人于2017年提出,是Transformer模型的开创性工作。
    在这里插入图片描述

二:理解基本构建块

  1. 注意力机制:

    Transformer的核心在于自注意力机制。它允许模型在处理每个词时考虑句子中的所有其他词,从而有效捕获长距离依赖关系。这是通过计算查询(Q)、键(K)和值(V)之间的关系实现的,其中注意力分数是通过以下公式计算得出的:
    Attention(Q, K, V) = softmax ( QK T d k ) V \text{Attention(Q, K, V)} = \text{softmax}\left(\frac{\text{QK}^T}{\sqrt{d_k}}\right)\text{V} Attention(Q, K, V)=softmax(dk QKT)V
    在这里插入图片描述

  2. 位置编码:

    在Transformer模型中,由于自注意力机制并不关注输入序列中元素的顺序,为了使模型能够处理序列数据的顺序信息,引入了位置编码(Positional Encoding)。

    位置编码的主要目的是为模型提供一些关于输入序列中元素相对位置的信息。由于Transformer没有内置的对序列顺序的理解,位置编码的添加有助于模型区分不同位置的词或输入。位置编码通常是通过在输入嵌入向量中添加一个与位置相关的向量来实现的。这个向量的设计通常遵循一些规律,以便模型能够通过学习位置编码来理解输入序列的顺序。一种常见的方式是使用正弦和余弦函数:

    位置 p o s pos pos 和嵌入维度 i i i 之间的位置编码 P E ( p o s , 2 i ) PE(pos, 2i) PE(pos,2i) P E ( p o s , 2 i + 1 ) PE(pos, 2i+1) PE(pos,2i+1) 分别计算如下:

    P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i / d ) P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i / d ) PE(pos, 2i) = \sin\left(\frac{{pos}}{{10000^{2i/d}}}\right) \\ PE(pos, 2i+1) = \cos\left(\frac{{pos}}{{10000^{2i/d}}}\right) PE(pos,2i)=sin(100002i/dpos)PE(pos,2i+1)=cos(100002i/dpos)
    其中,(pos) 是位置,(i) 是维度的索引,(d) 是嵌入的维度。这样设计的位置编码能够使得不同位置之间的编码有一些规律性的差异,以便模型学习到序列的顺序信息。

    在实际实现中,这个位置编码会被直接添加到输入嵌入向量中。这样,通过学习嵌入向量和位置编码之间的权重,模型就可以同时利用嵌入向量的语义信息和位置编码的顺序信息。以下是一个简化的Python代码示例,演示了如何生成位置编码:

    import torch
    import torch.nn as nn
    import math
    
    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() * -(math.log(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()
    
    # Example usage
    d_model = 512
    max_len = 100
    positional_encoding = PositionalEncoding(d_model, max_len)
    
    # Assuming input is a tensor of shape (batch_size, sequence_length, d_model)
    input_sequence = torch.rand((32, 50, d_model))
    output_sequence = positional_encoding(input_sequence)
    

    这个示例中,PositionalEncoding 模块可以添加到Transformer的输入嵌入中。你可以根据实际任务和模型的需要调整嵌入维度和序列的最大长度。

三:学习Transformer模型的结构

  1. Encoder和Decoder结构:

    • 理解Transformer模型的整体结构,包括Encoder和Decoder。了解Encoder中多头注意力(Multi-Head Attention)和前馈神经网络(Feedforward Network)的作用,以及Decoder中的掩码多头注意力。
    Encoder结构:
    1. 多层自注意力机制(Multi-Head Self Attention):
      • 每个注意力头学习不同的注意力表示,从而捕捉输入序列中不同位置的信息。
      • 每个注意力头的输出通过线性层进行变换和组合。
    2. 前馈神经网络(Feedforward Neural Network):
      • 每个注意力头的输出通过一个全连接前馈神经网络进行非线性映射。
    3. 层归一化(Layer Normalization)和残差连接(Residual Connection):
      • 在每个子层(自注意力和前馈神经网络)的输出后都应用层归一化和残差连接。
      • 这有助于梯度的流动和训练稳定性。

    Decoder结构:

    1. 多层自注意力机制(Multi-Head Self Attention):
      • 类似于Encoder,但在Decoder中,自注意力机制要注意到输入序列和输出序列的不同位置。
    2. 多层编码-解码注意力机制(Multi-Head Encoder-Decoder Attention):
      • 将Encoder的输出用作Query,将Decoder的自注意力输出用作Key和Value。这允许Decoder关注输入序列的不同部分。
    3. 前馈神经网络(Feedforward Neural Network):
      • 与Encoder中的结构类似,用于处理解码器的注意力输出。
    4. 层归一化(Layer Normalization)和残差连接(Residual Connection):
      • 同样,在每个子层后应用层归一化和残差连接。
  2. Layer Normalization 和残差连接:

    • 学习如何在Transformer的层中使用Layer Normalization和残差连接。

    1. Layer Normalization(层归一化):

    层归一化是一种用于神经网络中的归一化技术,其目的是减少内部协变量转移(Internal Covariate Shift)。在每个训练小批量上,层归一化对每个特征进行归一化,使其均值为零,标准差为一。

    在Transformer中,Layer Normalization通常在每个子层的输出上应用,例如自注意力层或前馈神经网络层。其数学表达式如下:
    L a y e r N o r m ( x ) = γ ( ( x − μ ) / σ ) + β LayerNorm(x)=γ((x−μ)/σ)+β LayerNorm(x)=γ((xμ)/σ)+β
    其中,x 是输入张量,μσ 分别是其均值和标准差,γβ 是可学习的缩放和平移参数。

    2. 残差连接(Residual Connection):

    残差连接是一种通过将输入直接添加到输出上的机制,用于解决梯度消失问题。在Transformer的每个子层的输出后都使用了残差连接。其数学表达式如下:
    O u t p u t = I n p u t + S u b l a y e r ( I n p u t ) Output=Input+Sublayer(Input) Output=Input+Sublayer(Input)
    其中,Sublayer(⋅) 是子层的变换,可以是自注意力、编码-解码注意力或前馈神经网络等。

四:使用现有的实现进行实践

  1. PyTorch或TensorFlow实现:

    • 使用PyTorch或TensorFlow,了解如何实现一个简单的Transformer模型。可以参考开源实现或教程。
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    class MultiHeadAttention(nn.Module):
        def __init__(self, d_model, num_heads):
            super(MultiHeadAttention, self).__init__()
            self.d_model = d_model
            self.num_heads = num_heads
    
            self.Q = nn.Linear(d_model, d_model)
            self.K = nn.Linear(d_model, d_model)
            self.V = nn.Linear(d_model, d_model)
            self.fc_out = nn.Linear(d_model, d_model)
    
        def forward(self, Q, K, V, mask):
            # Q, K, V: (batch_size, seq_len, d_model)
            Q = self.Q(Q)
            K = self.K(K)
            V = self.V(V)
    
            Q = self.split_heads(Q)
            K = self.split_heads(K)
            V = self.split_heads(V)
    
            scores = torch.matmul(Q, K.transpose(-1, -2)) / torch.sqrt(torch.tensor(self.d_model, dtype=torch.float32))
            if mask is not None:
                scores = scores.masked_fill(mask == 0, float("-inf"))
    
            attention = F.softmax(scores, dim=-1)
            x = torch.matmul(attention, V)
            x = self.combine_heads(x)
            x = self.fc_out(x)
            return x
    
        def split_heads(self, x):
            return x.view(x.size(0), -1, self.num_heads, self.d_model // self.num_heads).transpose(1, 2)
    
        def combine_heads(self, x):
            return x.transpose(1, 2).contiguous().view(x.size(0), -1, self.num_heads * (self.d_model // self.num_heads))
    
    class PositionwiseFeedforward(nn.Module):
        def __init__(self, d_model, d_ff, dropout=0.1):
            super(PositionwiseFeedforward, self).__init__()
            self.linear1 = nn.Linear(d_model, d_ff)
            self.dropout = nn.Dropout(dropout)
            self.linear2 = nn.Linear(d_ff, d_model)
    
        def forward(self, x):
            x = F.relu(self.linear1(x))
            x = self.dropout(x)
            x = self.linear2(x)
            return x
    
    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() * -(math.log(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 TransformerEncoderLayer(nn.Module):
        def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
            super(TransformerEncoderLayer, self).__init__()
            self.self_attention = MultiHeadAttention(d_model, num_heads)
            self.feedforward = PositionwiseFeedforward(d_model, d_ff, dropout)
            self.layer_norm1 = nn.LayerNorm(d_model)
            self.layer_norm2 = nn.LayerNorm(d_model)
            self.dropout = nn.Dropout(dropout)
    
        def forward(self, x, mask):
            attention_output = self.self_attention(x, x, x, mask)
            x = x + self.dropout(attention_output)
            x = self.layer_norm1(x)
            
            feedforward_output = self.feedforward(x)
            x = x + self.dropout(feedforward_output)
            x = self.layer_norm2(x)
            return x
    
    class TransformerEncoder(nn.Module):
        def __init__(self, vocab_size, d_model, num_heads, d_ff, num_layers, max_len=512, dropout=0.1):
            super(TransformerEncoder, self).__init__()
            self.embedding = nn.Embedding(vocab_size, d_model)
            self.positional_encoding = PositionalEncoding(d_model, max_len)
            self.layers = nn.ModuleList([
                TransformerEncoderLayer(d_model, num_heads, d_ff, dropout) for _ in range(num_layers)
            ])
    
        def forward(self, x, mask):
            x = self.embedding(x)
            x = self.positional_encoding(x)
            for layer in self.layers:
                x = layer(x, mask)
            return x
    
    class TransformerDecoderLayer(nn.Module):
        def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
            super(TransformerDecoderLayer, self).__init__()
            self.self_attention = MultiHeadAttention(d_model, num_heads)
            self.encoder_decoder_attention = MultiHeadAttention(d_model, num_heads)
            self.feedforward = PositionwiseFeedforward(d_model, d_ff, dropout)
            self.layer_norm1 = nn.LayerNorm(d_model)
            self.layer_norm2 = nn.LayerNorm(d_model)
            self.layer_norm3 = nn.LayerNorm(d_model)
            self.dropout = nn.Dropout(dropout)
    
        def forward(self, x, encoder_output, src_mask, tgt_mask):
            attention_output = self.self_attention(x, x, x, tgt_mask)
            x = x + self.dropout(attention_output)
            x = self.layer_norm1(x)
    
            encoder_attention_output = self.encoder_decoder_attention(x, encoder_output, encoder_output, src_mask)
            x = x + self.dropout(encoder_attention_output)
            x = self.layer_norm2(x)
    
            feedforward_output = self.feedforward(x)
            x = x + self.dropout(feedforward_output)
            x = self.layer_norm3(x)
    
            return x
    
    class TransformerDecoder(nn.Module):
        def __init__(self, vocab_size, d_model, num_heads, d_ff, num_layers, max_len=512, dropout=0.1):
            super(TransformerDecoder, self).__init__()
            self.embedding = nn.Embedding(vocab_size, d_model)
            self.positional_encoding = PositionalEncoding(d_model, max_len)
            self.layers = nn.ModuleList([
                TransformerDecoderLayer(d_model, num_heads, d_ff, dropout) for _ in range(num_layers)
            ])
            self.fc_out = nn.Linear(d_model, vocab_size)
    
        def forward(self, x, encoder_output, src_mask, tgt_mask):
            x = self.embedding(x)
            x = self.positional_encoding(x)
            for layer in self.layers:
                x = layer(x, encoder_output, src_mask, tgt_mask)
            x = self.fc_out(x)
            return x
    
    class Transformer(nn.Module):
        def __init__(self, src_vocab_size, tgt_vocab_size, d_model, num_heads, d_ff, num_layers, max_len=512, dropout=0.1):
            super(Transformer, self).__init__()
            self.encoder = TransformerEncoder(src_vocab_size, d_model, num_heads, d_ff, num_layers, max_len, dropout)
            self.decoder = TransformerDecoder(tgt_vocab_size, d_model, num_heads, d_ff, num_layers, max_len, dropout)
    
        def forward(self, src_input, tgt_input, src_mask, tgt_mask):
            encoder_output = self.encoder(src_input, src_mask)
            decoder_output = self.decoder(tgt_input, encoder_output, src_mask, tgt_mask)
            return decoder_output
    
    # Example usage:
    src_vocab_size = 1000
    tgt_vocab_size = 1000
    d_model = 512
    num_heads = 8
    d_ff = 2048
    num_layers = 6
    max_len = 100
    dropout = 0.1
    
    model = Transformer(src_vocab_size, tgt_vocab_size, d_model, num_heads, d_ff, num_layers, max_len, dropout)
    

五:深入细节

  1. 超参数调整:

    • 学习调整Transformer模型的超参数,包括学习率、层数、隐藏单元数等。
  2. 更深入的理解多头注意力:

    • 了解多头注意力是如何工作的,以及它如何在不同的子空间上学到不同的表示。

    多头注意力机制的工作原理:

    考虑一个输入序列 X X X,通过线性变换分别生成 Q u e r y ( Q ) Query(Q) QueryQ K e y ( K ) Key(K) KeyK V a l u e ( V ) Value(V) ValueV的表示。对于每个注意力头 i i i,通过计算注意力分数并对Value进行加权,得到头 i i i 的输出 O i O_i Oi

    多头注意力的输出 O O O 是所有注意力头输出的拼接:
    O = C o n c a t ( O 1 , O 2 , . . . , O h ) O=Concat(O_1,O_2,...,O_h) O=Concat(O1,O2,...,Oh)
    其中, h ℎ h 是注意力头的数量。

    学习不同表示的子空间:

    每个注意力头都有独立的权重矩阵 ( W i Q , W i K , W i V ) (W_i^Q,W_i^K,W_i^V) (WiQ,WiK,WiV),这意味着每个头可以学到不同的表示。这种独立性使得每个头都能够关注输入序列的不同部分,捕捉不同方面的信息。

    举例来说,考虑一个翻译任务,输入是一个包含动词的句子。不同的注意力头可以分别关注主语、宾语、谓语等不同的语法成分,从而更好地捕捉句子的语法结构。

六:应用到实际任务

  1. 语言建模或翻译任务:

    • 尝试将学到的Transformer模型应用于语言建模或翻译任务。使用开源的语料库和模型预训练,然后微调模型以适应你的任务。
    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torchtext.data import Field, BucketIterator
    from torchtext.datasets import Multi30k
    from torch.nn import Transformer
    
    # 设置随机种子以保证可重复性
    torch.manual_seed(42)
    
    # 定义Field对象
    SRC = Field(tokenize='spacy', tokenizer_language='en', init_token='<sos>', eos_token='<eos>', lower=True)
    TRG = Field(tokenize='spacy', tokenizer_language='fr', init_token='<sos>', eos_token='<eos>', lower=True)
    
    # 加载Multi30k数据集
    train_data, valid_data, test_data = Multi30k.splits(exts=('.en', '.fr'), fields=(SRC, TRG))
    
    # 构建词汇表
    SRC.build_vocab(train_data, min_freq=2)
    TRG.build_vocab(train_data, min_freq=2)
    
    # 定义Transformer模型
    class TransformerModel(nn.Module):
        def __init__(self, src_vocab_size, trg_vocab_size, d_model=512, nhead=8, num_encoder_layers=6, num_decoder_layers=6):
            super(TransformerModel, self).__init__()
            self.embedding = nn.Embedding(src_vocab_size, d_model)
            self.transformer = Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers)
            self.fc = nn.Linear(d_model, trg_vocab_size)
    
        def forward(self, src, trg):
            src = self.embedding(src)
            trg = self.embedding(trg)
            output = self.transformer(src, trg)
            output = self.fc(output)
            return output
    
    # 初始化模型和优化器
    model = TransformerModel(len(SRC.vocab), len(TRG.vocab))
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    criterion = nn.CrossEntropyLoss()
    
    # 定义训练函数
    def train(model, iterator, optimizer, criterion):
        model.train()
        for batch in iterator:
            src = batch.src
            trg = batch.trg
            optimizer.zero_grad()
            output = model(src, trg)
            output = output.view(-1, output.shape[-1])
            trg = trg.view(-1)
            loss = criterion(output, trg)
            loss.backward()
            optimizer.step()
    
    # 构建BucketIterator
    BATCH_SIZE = 32
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    train_iterator, valid_iterator, test_iterator = BucketIterator.splits(
        (train_data, valid_data, test_data), 
        batch_size=BATCH_SIZE, 
        device=device)
    
    # 训练模型
    for epoch in range(10):
        train(model, train_iterator, optimizer, criterion)
    
    # 在测试集上评估模型(简化,实际应用中需要更详细的评估过程)
    def evaluate(model, iterator, criterion):
        model.eval()
        total_loss = 0
        with torch.no_grad():
            for batch in iterator:
                src = batch.src
                trg = batch.trg
                output = model(src, trg)
                output = output.view(-1, output.shape[-1])
                trg = trg.view(-1)
                loss = criterion(output, trg)
                total_loss += loss.item()
        return total_loss / len(iterator)
    
    test_loss = evaluate(model, test_iterator, criterion)
    print(f'Test Loss: {test_loss:.3f}')
    

七:关注最新研究

  1. 阅读最新的Transformer相关论文:

    • 随着研究的不断进展,关注最新的Transformer相关的研究论文,了解模型的演进和新的应用。

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

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

相关文章

软件研发过程中,项目管理工具应该如何选择?

本文作者&#xff1a;极狐GitLab 资深解决方案架构师 尹学峰 许多企业依旧在用老旧的方式&#xff0c;如Excel离线表格进行项目管理。表格无法简介的呈现出项目的任务分解、完成进度、任务类别等多种项目管理过程中必备的要求&#xff0c;更无法实现与企业员工的日常即时通信系…

MATLAB - 加载预定义的机器人模型

系列文章目录 前言 一、 要快速访问常见的机器人模型&#xff0c;可使用 loadrobot 功能&#xff0c;该功能可加载市售的机器人模型&#xff0c;如 Universal Robots™ UR10 cobot、Boston Dynamics™ Atlas 人形机器人和 KINOVA™ Gen 3 机械手。探索如何生成关节配置并与机器…

day02_计算机常识丶第一个程序丶注释丶关键字丶标识符

计算机常识 计算机如何存储数据 计算机世界中只有二进制。那么在计算机中存储和运算的所有数据都要转为二进制。包括数字、字符、图片、声音、视频等。 进制 进制也就是进位计数制&#xff0c;是人为定义的带进位的计数方法 实例&#xff1a; // 在java 中 可以使用不同…

蓝桥杯备赛day02 -- 算法训练题 拿金币Java

目录 题目&#xff1a; 问题描述 输入格式 输出格式 解题过程 第一步 定义dp数组 第二步 确定 dp 数组递推公式 第三步 dp数组的初始化 第四步 dp数组的遍历顺序 第五步 举例说明 报错&#xff1a;内存超限 用dp数组去存储位置上的金币 dp数组从二维降为一维 收获&a…

如何在CentOS 7 中搭建Python 3.0 环境

1、下载 通过https://www.python.org/ftp/python/下载Python安装包&#xff0c;这里下载Python-3.10.9.tgz&#xff1b; 2、上传 借助MobaXterm等工具将Python安装包上传至/opt目录&#xff1b; 3、解压 将JDK压缩文件解压至/opt目录&#xff1a;tar -xvf /opt/Python-3.1…

idea设置编辑器背景颜色

文章目录 一、Ided常用工具栏显示二、更改idea主题设置三、设置代码编辑器背景颜色为豆沙绿四、设置新项目 默认Jdk配置、maven配置1、settings for new projects2、structre for new projects 五、修改代码中注释的字体颜色六、设置编辑器字体大小七、文件编码的设置(可以设置…

【网络安全】【密码学】【北京航空航天大学】实验一、数论基础(上)【C语言和Java实现】

实验一、数论基础&#xff08;上&#xff09; 一、实验目的 1、通过本次实验&#xff0c;熟悉相关的编程环境&#xff0c;为后续的实验做好铺垫&#xff1b; 2、回顾数论学科中的重要基本算法&#xff0c;并加深对其的理解&#xff0c;为本学期密码学理论及实验课程打下良好…

Python - 深夜数据结构与算法之 DP 串讲

目录 一.引言 二.DP 知识点回顾 1.递归 2.分治 3.动态规划 三.DP 经典题目回顾 1.Climb-Stairs [70] 2.Unique-Paths [62] 3.House-Robber [198] 4.Min-Path-Sum [64] 5.Best-Time-Sell-Stock [121] 6.Min-Cost-Climb [746] 7.Edit-Distance [72] 8.Longest-Sub-…

Android PendingIntent 闪退

先来给大家推荐一个我日常会使用到的图片高清处理在线工具&#xff0c;主要是免费&#xff0c;直接白嫖 。 有时候我看到一张图片感觉很不错&#xff0c;但是图片清晰度不合我意&#xff0c;就想有没有什么工具可以处理让其更清晰&#xff0c; 网上随便搜下就能找到&#xff…

C++设计模式(李建忠)笔记1

C设计模式&#xff08;李建忠&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT&#xff1a;https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 文章目录 C设计模…

编译原理1.1习题 语言处理器

图源&#xff1a;文心一言 编译原理习题整理~&#x1f95d;&#x1f95d; 作为初学者的我&#xff0c;这些习题主要用于自我巩固。由于是自学&#xff0c;答案难免有误&#xff0c;非常欢迎各位小伙伴指正与讨论&#xff01;&#x1f44f;&#x1f4a1; 第1版&#xff1a;自…

目标检测-One Stage-YOLOv7

文章目录 前言一、YOLOv7的不同版本二、YOLOv7的网络结构二、YOLOv7的创新点三、创新点的详细解读ELAN和E-ELANBoF训练技巧计划型重参化卷积辅助训练模块标签分配Lead head guided label assignerCoarse-to-fine lead head guided label assigner 基于级联模型的复合缩放方法 总…

开发知识点-JAVA-springboot

springboot springbootConfiguration注解的底层核心原理Bean注解的底层核心原理 springboot Configuration注解的底层核心原理 https://www.bilibili.com/video/BV1rq4y1E7gK/?spm_id_from333.999.0.0&vd_sourcef21773b7086456ae21a58a6cc59023be spring.io 全家桶 24…

【Emgu CV教程】5.4、几何变换之图像翻转

今天讲解的两个函数&#xff0c;可以实现以下样式的翻转。 水平翻转&#xff1a;将图像沿Y轴(图像最左侧垂直边缘)翻转的操作。原始图像中位于左侧的内容将移动到目标图像的右侧&#xff0c;原始图像中位于右侧的内容将移动到目标图像的左侧。垂直翻转&#xff1a;将图像沿X轴…

智能小程序小部件(Widget)导航、地图、画布等组件,以及开放能力、原生组件说明

智能小程序小部件(Widget)导航、地图、画布等组件&#xff0c;以及开放能力、原生组件说明。 导航组件 navigator 页面链接&#xff0c;控制小程序的跳转。navigator 子节点的背景色应为透明色。 属性说明 属性名类型默认值必填说明urlstring是跳转地址deltanumber1否当 …

用Spark在大数据平台DataBricks轻松处理数据

Apache Spark是一个强大的开源分布式计算系统&#xff0c;专为大规模数据处理而设计。而DataBricks则提供了一个基于云的环境&#xff0c;使得在Spark上处理数据变得更加高效和便捷。本文将介绍如何在DataBricks平台上使用Spark轻松处理大数据。DataBricks是一个基于云的大数据…

8.临床预测模型验证——交叉验证/Bootstrap法

基本概念 交叉验证&#xff1a; 将一定比例的数据挑选出来作为训练集&#xff0c;将其余未选中的样本作为测试集&#xff0c;先在训练集中构建模型&#xff0c;再在测试集中做预测。 内部验证&#xff1a;手动将样本随机分为训练集和测试集&#xff0c;先在训练集中构建模型…

MySQL面试题 | 11.精选MySQL面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

vue2 pdfjs-2.8.335-dist pdf文件在线预览功能

1、首先先将 pdfjs-2.8.335-dist 文件夹从网上搜索下载&#xff0c;复制到public文件夹下. 2、在components下新建组件PdfViewer.vue文件 3、在el-upload 中调用 pdf-viewer 组件 4、在el-upload 中的 on-preview方法中加上对应的src路径 internalPreview(file) { //判断需要…

【Python】箱型图和热图绘制详解和示例

箱型图&#xff08;Box Plot&#xff09;和热图&#xff08;Heatmap&#xff09;是两种常用的数据可视化工具&#xff0c;它们各自有着不同的特点和用途。在写总结和文献时对数据的表达更加直观&#xff0c;本文对这两种图像的绘制进行详解和示例。 箱型图由一组数据的最小值、…