基于transformer的Seq2Seq机器翻译模型训练、预测教程

这篇具有很好参考价值的文章主要介绍了基于transformer的Seq2Seq机器翻译模型训练、预测教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

机器翻译(Machine Translation, MT)是一类将某种语言(源语言,source language)的句子 x x x翻译成另一种语言(目标语言,target language)的句子 y y y 的任务。机器翻译的相关研究早在上世纪50年代美苏冷战时期就开始了,当时的机器翻译系统是基于规则的,利用两种语言的单词、短语对应关系将俄语翻译成英语。

在早期的机器翻译主要是依靠统计学模型,使用一种叫统计机器翻译(Statistical Machine Translation, SMT)的方法,在1990年至2010年间是较为主流的方法,也取得了不错的效果。统计机器翻译方法的核心思想是从数据中统计出概率模型。假设需要构建一个将法语翻译成英语的模型,我们可以将任务描述为给定法语句子 x x x ,找到最有可能是 x x x 的翻译的英语句子 y y y,即 a r g m a x y P ( y ∣ x ) = a r g m a x y P ( x ∣ y ) P ( y ) argmax_y P(y|x) = argmax_y P(x|y)P(y) argmaxyP(yx)=argmaxyP(xy)P(y)
上式中的贝叶斯公式可分为两部分,其中 P ( x ∣ y ) P(x|y) P(xy)可以看作翻译模型,保证翻译的正确性; P ( y ) P(y) P(y)则是语言模型,保证翻译结果语言流畅。在当时的技术条件下,这样拆分后两个任务相对独立,分开学习会更容易一些。

在2014年,机器翻译研究迎来了重大的突破——神经机器翻译(Neural Machine Translation, NMT)。最简单的NMT系统使用单个神经网络就可以完成机器翻译任务,这个神经网络结构就是Seq2Seq(sequence-to-sequence,序列到序列),它由两个RNN组成,其中一个作为Encoder(编码器),另一个则是Decoder(解码器),Encoder的输入为源语言的语句,经过RNN处理并在最后一步得到输出,这个输出就可以看作输入句子的向量编码。

本篇文章中用于机器翻译的网络结构仍然是Seq2Seq网络结构,但是与两个RNN或者RNN+attention方法不同,经过简单的修改的transformer会是这个序列模型的主要结构。

transformer这个模型,大家都比较熟悉了,由论文《Attention is All You Need》提出,主要是可以实现并行化的训练,网络结构主要由全连接层、注意力机制和normalization层组成。关于transformer的结构在这里就不详细介绍了,大家感兴趣的可以去看看别的博主的文章,这里主要介绍如何将transformer用于机器翻译的模型训练。

代码

数据处理

数据主要使用的是torchtext中含英语和德语句子对的知名数据集Multi30k dataset,其包含大约30,000个英语和德语的句子对(平均长度约为13)。下面代码是数据处理部分和相关依赖库导入:

import torch
import torch.nn as nn
import torch.optim as optim

import torchtext
from torchtext.datasets import  Multi30k
#from torchtext.legacy.data import Field, BucketIterator   # pytorch1.9+  torchtext==0.10.0
from torchtext.data  import Field, TabularDataset, BucketIterator, Iterator  ## torchtext==0.6.0 torch==1.7

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

import numpy as np

import random
import math
import time

SEED = 1234

random.seed(SEED)
np.random.seed(SEED)
torch.manual_seed(SEED)
torch.cuda.manual_seed(SEED)
torch.backends.cudnn.deterministic = True


def tokenize_de(text):
    """
    Tokenizes German text from a string into a list of strings
    """
    return [w for w in text.split() if w]

def tokenize_en(text):
    """
    Tokenizes English text from a string into a list of strings
    """
    return [w for w in text.split() if w]


SRC = Field(tokenize=tokenize_de,
            init_token='<sos>',
            eos_token='<eos>',
            lower=True,
            batch_first=True)

TRG = Field(tokenize=tokenize_en,
            init_token='<sos>',
            eos_token='<eos>',
            lower=True,
            batch_first=True)



#train_data, valid_data, test_data = Multi30k()   # pytorch1.9+  torchtext==0.10.0

train_data, valid_data, test_data = Multi30k.splits(exts = ('.de', '.en'),    ## torchtext==0.6.0 torch==1.7
                                                    fields = (SRC, TRG))

SRC.build_vocab(train_data, min_freq = 2)
TRG.build_vocab(train_data, min_freq = 2)


device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('device:', device)


BATCH_SIZE = 64

train_iterator, valid_iterator, test_iterator = BucketIterator.splits(
    (train_data, valid_data, test_data),
    batch_sizes=(BATCH_SIZE, BATCH_SIZE, BATCH_SIZE),
    device=device,
    sort_key=lambda x: len(x.src), # 根据源语句的长度
    sort_within_batch=False,   # 是否需要对批处理的内容进行排序
    repeat=False
)

特别说明一下,数据导入,是直接从torchtext.datasets import的,但是torchtext版本不一样,api接口会有所变化,详细看代码里面注释,笔者这里用的torchtext 0.6.0, torch 1.7。

如果由于网络的原因,下载数据失败,可以在手动下载该数据集并放到与代码同级的.data/目录下即可。

模型定义

class Encoder(nn.Module):
    def __init__(self, 
                 input_dim, 
                 hid_dim, 
                 n_layers, 
                 n_heads, 
                 pf_dim,
                 dropout, 
                 device,
                 max_length = 100):
        super().__init__()

        self.device = device
        
        self.tok_embedding = nn.Embedding(input_dim, hid_dim)
        self.pos_embedding = nn.Embedding(max_length, hid_dim)
        
        self.layers = nn.ModuleList([EncoderLayer(hid_dim, 
                                                  n_heads, 
                                                  pf_dim,
                                                  dropout, 
                                                  device) 
                                     for _ in range(n_layers)])
        
        self.dropout = nn.Dropout(dropout)
        
        self.scale = torch.sqrt(torch.FloatTensor([hid_dim])).to(device)
        
    def forward(self, src, src_mask):
        
        #src = [batch size, src len]
        #src_mask = [batch size, src len]
        
        batch_size = src.shape[0]
        src_len = src.shape[1]
        
        pos = torch.arange(0, src_len).unsqueeze(0).repeat(batch_size, 1).to(self.device)
        
        #pos = [batch size, src len]
        
        src = self.dropout((self.tok_embedding(src) * self.scale) + self.pos_embedding(pos))
        
        #src = [batch size, src len, hid dim]
        
        for layer in self.layers:
            src = layer(src, src_mask)
            
        #src = [batch size, src len, hid dim]
            
        return src



class EncoderLayer(nn.Module):
    def __init__(self, 
                 hid_dim, 
                 n_heads, 
                 pf_dim,  
                 dropout, 
                 device):
        super().__init__()
        
        self.layer_norm = nn.LayerNorm(hid_dim)
        self.self_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)
        self.positionwise_feedforward = PositionwiseFeedforwardLayer(hid_dim, 
                                                                     pf_dim, 
                                                                     dropout)
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, src, src_mask):
        
        #src = [batch size, src len, hid dim]
        #src_mask = [batch size, src len]
                
        #self attention
        _src, _ = self.self_attention(src, src, src, src_mask)
        
        #dropout, residual connection and layer norm
        src = self.layer_norm(src + self.dropout(_src))
        
        #src = [batch size, src len, hid dim]
        
        #positionwise feedforward
        _src = self.positionwise_feedforward(src)
        
        #dropout, residual and layer norm
        src = self.layer_norm(src + self.dropout(_src))
        
        #src = [batch size, src len, hid dim]
        
        return src


class MultiHeadAttentionLayer(nn.Module):
    def __init__(self, hid_dim, n_heads, dropout, device):
        super().__init__()
        
        assert hid_dim % n_heads == 0
        
        self.hid_dim = hid_dim
        self.n_heads = n_heads
        self.head_dim = hid_dim // n_heads
        
        self.fc_q = nn.Linear(hid_dim, hid_dim)
        self.fc_k = nn.Linear(hid_dim, hid_dim)
        self.fc_v = nn.Linear(hid_dim, hid_dim)
        
        self.fc_o = nn.Linear(hid_dim, hid_dim)
        
        self.dropout = nn.Dropout(dropout)
        
        self.scale = torch.sqrt(torch.FloatTensor([self.head_dim])).to(device)
        
    def forward(self, query, key, value, mask = None):
        
        batch_size = query.shape[0]
        
        #query = [batch size, query len, hid dim]
        #key = [batch size, key len, hid dim]
        #value = [batch size, value len, hid dim]
                
        Q = self.fc_q(query)
        K = self.fc_k(key)
        V = self.fc_v(value)
        
        #Q = [batch size, query len, hid dim]
        #K = [batch size, key len, hid dim]
        #V = [batch size, value len, hid dim]
                
        Q = Q.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)
        K = K.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)
        V = V.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)
        
        #Q = [batch size, n heads, query len, head dim]
        #K = [batch size, n heads, key len, head dim]
        #V = [batch size, n heads, value len, head dim]
                
        energy = torch.matmul(Q, K.permute(0, 1, 3, 2)) / self.scale
        
        #energy = [batch size, n heads, query len, key len]
        
        if mask is not None:
            energy = energy.masked_fill(mask == 0, -1e10)
        
        attention = torch.softmax(energy, dim = -1)
                
        #attention = [batch size, n heads, query len, key len]
                
        x = torch.matmul(self.dropout(attention), V)
        
        #x = [batch size, n heads, query len, head dim]
        
        x = x.permute(0, 2, 1, 3).contiguous()
        
        #x = [batch size, query len, n heads, head dim]
        
        x = x.view(batch_size, -1, self.hid_dim)
        
        #x = [batch size, query len, hid dim]
        
        x = self.fc_o(x)
        
        #x = [batch size, query len, hid dim]
        
        return x, attention

class PositionwiseFeedforwardLayer(nn.Module):
    def __init__(self, hid_dim, pf_dim, dropout):
        super().__init__()
        
        self.fc_1 = nn.Linear(hid_dim, pf_dim)
        self.fc_2 = nn.Linear(pf_dim, hid_dim)
        
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, x):
        
        #x = [batch size, seq len, hid dim]
        
        x = self.dropout(torch.relu(self.fc_1(x)))
        
        #x = [batch size, seq len, pf dim]
        
        x = self.fc_2(x)
        
        #x = [batch size, seq len, hid dim]
        
        return x


class Decoder(nn.Module):
    def __init__(self, 
                 output_dim, 
                 hid_dim, 
                 n_layers, 
                 n_heads, 
                 pf_dim, 
                 dropout, 
                 device,
                 max_length = 100):
        super().__init__()
        
        self.device = device
        
        self.tok_embedding = nn.Embedding(output_dim, hid_dim)
        self.pos_embedding = nn.Embedding(max_length, hid_dim)
        
        self.layers = nn.ModuleList([DecoderLayer(hid_dim, 
                                                  n_heads, 
                                                  pf_dim, 
                                                  dropout, 
                                                  device)
                                     for _ in range(n_layers)])
        
        self.fc_out = nn.Linear(hid_dim, output_dim)
        
        self.dropout = nn.Dropout(dropout)
        
        self.scale = torch.sqrt(torch.FloatTensor([hid_dim])).to(device)
        
    def forward(self, trg, enc_src, trg_mask, src_mask):
        
        #trg = [batch size, trg len]
        #enc_src = [batch size, src len, hid dim]
        #trg_mask = [batch size, trg len]
        #src_mask = [batch size, src len]
                
        batch_size = trg.shape[0]
        trg_len = trg.shape[1]
        
        pos = torch.arange(0, trg_len).unsqueeze(0).repeat(batch_size, 1).to(self.device)
                            
        #pos = [batch size, trg len]
            
        trg = self.dropout((self.tok_embedding(trg) * self.scale) + self.pos_embedding(pos))
                
        #trg = [batch size, trg len, hid dim]
        
        for layer in self.layers:
            trg, attention = layer(trg, enc_src, trg_mask, src_mask)
        
        #trg = [batch size, trg len, hid dim]
        #attention = [batch size, n heads, trg len, src len]
        
        output = self.fc_out(trg)
        
        #output = [batch size, trg len, output dim]
            
        return output, attention


class DecoderLayer(nn.Module):
    def __init__(self, 
                 hid_dim, 
                 n_heads, 
                 pf_dim, 
                 dropout, 
                 device):
        super().__init__()
        
        self.layer_norm = nn.LayerNorm(hid_dim)
        self.self_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)
        self.encoder_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)
        self.positionwise_feedforward = PositionwiseFeedforwardLayer(hid_dim, 
                                                                     pf_dim, 
                                                                     dropout)
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, trg, enc_src, trg_mask, src_mask):
        
        #trg = [batch size, trg len, hid dim]
        #enc_src = [batch size, src len, hid dim]
        #trg_mask = [batch size, trg len]
        #src_mask = [batch size, src len]
        
        #self attention
        _trg, _ = self.self_attention(trg, trg, trg, trg_mask)
        
        #dropout, residual connection and layer norm
        trg = self.layer_norm(trg + self.dropout(_trg))
            
        #trg = [batch size, trg len, hid dim]
            
        #encoder attention
        _trg, attention = self.encoder_attention(trg, enc_src, enc_src, src_mask)
        
        #dropout, residual connection and layer norm
        trg = self.layer_norm(trg + self.dropout(_trg))
                    
        #trg = [batch size, trg len, hid dim]
        
        #positionwise feedforward
        _trg = self.positionwise_feedforward(trg)
        
        #dropout, residual and layer norm
        trg = self.layer_norm(trg + self.dropout(_trg))
        
        #trg = [batch size, trg len, hid dim]
        #attention = [batch size, n heads, trg len, src len]
        
        return trg, attention


class Seq2Seq(nn.Module):
    def __init__(self, 
                 encoder, 
                 decoder, 
                 src_pad_idx, 
                 trg_pad_idx, 
                 device):
        super().__init__()
        
        self.encoder = encoder
        self.decoder = decoder
        self.src_pad_idx = src_pad_idx
        self.trg_pad_idx = trg_pad_idx
        self.device = device
        
    def make_src_mask(self, src):
        
        #src = [batch size, src len]
        
        src_mask = (src != self.src_pad_idx).unsqueeze(1).unsqueeze(2)

        #src_mask = [batch size, 1, 1, src len]

        return src_mask
    
    def make_trg_mask(self, trg):
        
        #trg = [batch size, trg len]
        
        trg_pad_mask = (trg != self.trg_pad_idx).unsqueeze(1).unsqueeze(2)
        
        #trg_pad_mask = [batch size, 1, 1, trg len]
        
        trg_len = trg.shape[1]
        
        trg_sub_mask = torch.tril(torch.ones((trg_len, trg_len), device = self.device)).bool()
        
        #trg_sub_mask = [trg len, trg len]
            
        trg_mask = trg_pad_mask & trg_sub_mask
        
        #trg_mask = [batch size, 1, trg len, trg len]
        
        return trg_mask

    def forward(self, src, trg):
        
        #src = [batch size, src len]
        #trg = [batch size, trg len]
                
        src_mask = self.make_src_mask(src)
        trg_mask = self.make_trg_mask(trg)
        
        #src_mask = [batch size, 1, 1, src len]
        #trg_mask = [batch size, 1, trg len, trg len]
        
        enc_src = self.encoder(src, src_mask)
        
        #enc_src = [batch size, src len, hid dim]
                
        output, attention = self.decoder(trg, enc_src, trg_mask, src_mask)
        
        #output = [batch size, trg len, output dim]
        #attention = [batch size, n heads, trg len, src len]
        
        return output, attention

模型训练

INPUT_DIM = len(SRC.vocab)
OUTPUT_DIM = len(TRG.vocab)
HID_DIM = 256
ENC_LAYERS = 3
DEC_LAYERS = 3
ENC_HEADS = 8
DEC_HEADS = 8
ENC_PF_DIM = 512
DEC_PF_DIM = 512
ENC_DROPOUT = 0.1
DEC_DROPOUT = 0.1

enc = Encoder(INPUT_DIM, 
              HID_DIM, 
              ENC_LAYERS, 
              ENC_HEADS, 
              ENC_PF_DIM, 
              ENC_DROPOUT, 
              device)

dec = Decoder(OUTPUT_DIM, 
              HID_DIM, 
              DEC_LAYERS, 
              DEC_HEADS, 
              DEC_PF_DIM, 
              DEC_DROPOUT, 
              device)

SRC_PAD_IDX = SRC.vocab.stoi[SRC.pad_token]
TRG_PAD_IDX = TRG.vocab.stoi[TRG.pad_token]

model = Seq2Seq(enc, dec, SRC_PAD_IDX, TRG_PAD_IDX, device).to(device)

def count_parameters(model):
    return sum(p.numel() for p in model.parameters() if p.requires_grad)

print(f'The model has {count_parameters(model):,} trainable parameters')

def initialize_weights(m):
    if hasattr(m, 'weight') and m.weight.dim() > 1:
        nn.init.xavier_uniform_(m.weight.data)

model.apply(initialize_weights)

LEARNING_RATE = 0.0005

optimizer = torch.optim.Adam(model.parameters(), lr = LEARNING_RATE)

criterion = nn.CrossEntropyLoss(ignore_index = TRG_PAD_IDX)


def train(model, iterator, optimizer, criterion, clip):
    
    model.train()
    
    epoch_loss = 0
    
    for i, batch in enumerate(iterator):
        
        src = batch.src
        trg = batch.trg
        
        optimizer.zero_grad()
        
        output, _ = model(src, trg[:,:-1])
                
        #output = [batch size, trg len - 1, output dim]
        #trg = [batch size, trg len]
            
        output_dim = output.shape[-1]
            
        output = output.contiguous().view(-1, output_dim)
        trg = trg[:,1:].contiguous().view(-1)
                
        #output = [batch size * trg len - 1, output dim]
        #trg = [batch size * trg len - 1]
            
        loss = criterion(output, trg)
        
        loss.backward()
        
        torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
        
        optimizer.step()
        
        epoch_loss += loss.item()
        
    return epoch_loss / len(iterator)

def evaluate(model, iterator, criterion):
    
    model.eval()
    
    epoch_loss = 0
    
    with torch.no_grad():
    
        for i, batch in enumerate(iterator):

            src = batch.src
            trg = batch.trg

            output, _ = model(src, trg[:,:-1])
            
            #output = [batch size, trg len - 1, output dim]
            #trg = [batch size, trg len]
            
            output_dim = output.shape[-1]
            
            output = output.contiguous().view(-1, output_dim)
            trg = trg[:,1:].contiguous().view(-1)
            
            #output = [batch size * trg len - 1, output dim]
            #trg = [batch size * trg len - 1]
            
            loss = criterion(output, trg)

            epoch_loss += loss.item()
        
    return epoch_loss / len(iterator)


def epoch_time(start_time, end_time):
    elapsed_time = end_time - start_time
    elapsed_mins = int(elapsed_time / 60)
    elapsed_secs = int(elapsed_time - (elapsed_mins * 60))
    return elapsed_mins, elapsed_secs

N_EPOCHS = 10
CLIP = 1

best_valid_loss = float('inf')

for epoch in range(N_EPOCHS):
    
    start_time = time.time()
    
    train_loss = train(model, train_iterator, optimizer, criterion, CLIP)
    valid_loss = evaluate(model, valid_iterator, criterion)
    
    end_time = time.time()
    
    epoch_mins, epoch_secs = epoch_time(start_time, end_time)
    
    if valid_loss < best_valid_loss:
        best_valid_loss = valid_loss
        torch.save(model.state_dict(), 'tut6-model.pt')
    
    print(f'Epoch: {epoch+1:02} | Time: {epoch_mins}m {epoch_secs}s')
    print(f'\tTrain Loss: {train_loss:.3f} | Train PPL: {math.exp(train_loss):7.3f}')
    print(f'\t Val. Loss: {valid_loss:.3f} |  Val. PPL: {math.exp(valid_loss):7.3f}')

最后训练输出:
基于transformer的Seq2Seq机器翻译模型训练、预测教程文章来源地址https://www.toymoban.com/news/detail-437297.html

到了这里,关于基于transformer的Seq2Seq机器翻译模型训练、预测教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

    请看vcr:https://transformers.run/back/transformer/

    2024年02月08日
    浏览(42)
  • 深度学习笔记之Seq2seq(二)基于Seq2seq注意力机制的动机

    上一节介绍了 Seq2seq text{Seq2seq} Seq2seq 网络常用的基本结构以及在 机器翻译 任务中,关于 目标函数 与 预测概率 的描述。本节依然以 机器翻译 任务为例,对 Seq2seq text{Seq2seq} Seq2seq 中的 注意力机制 ( Attention ) (text{Attention}) ( Attention ) 进行描述。 关于 机器翻译 任务的 Seq2

    2024年02月09日
    浏览(48)
  • 李宏毅-hw5-translation-有关transformer、seq2seq的探索

    一、ppt研读: 1.关于这个 input Embedding 的内容: 2.关于Positional Encoding: 二、慢慢积累,一点点阅读代码: 虽然这次的模块挺多的,但是,这样也就意味着,把这个内化为自己的,就可以获得更大的进步了 1.关于使用git命令获取到源代码: 2.Fix Random Seed部分都是相同的,就是为

    2024年02月09日
    浏览(40)
  • Transformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

    我在写上一篇博客《22下半年》时,有读者在文章下面评论道:“july大神,请问BERT的通俗理解还做吗?”,我当时给他发了张俊林老师的BERT文章,所以没太在意。 直到今天早上,刷到CSDN上一篇讲BERT的文章,号称一文读懂,我读下来之后,假定我是初学者,读不懂。 关于

    2024年02月02日
    浏览(34)
  • 构建seq2seq模型的常见问题

    1. seq2seq模型,输入是一个词向量,而不是词向量列表,对吧? 是的,对于seq2seq模型,输入和输出都需要被转换成词向量形式。 对于输入来说,通常会将一个句子转换成一个词向量序列。具体地,对于每个单词或者字符,都会将其对应成一个词向量,然后将所有词向量按照它

    2024年02月06日
    浏览(38)
  • 【文本摘要(2)】pytorch之Seq2Seq

    改废了两个代码后,又找到了一个文本摘要代码 终于跑起来了 改废的两个代码: 一个是机器翻译改文本摘要,结果没跑起来。。。 一个是英文文本摘要改中文文本摘要,预测的摘要全是,,,这种 代码参考: https://github.com/jasoncao11/nlp-notebook/tree/master/4-2.Seq2seq_Att 跪谢大佬

    2024年02月03日
    浏览(45)
  • Seq2Seq在安全领域的应用实践

    非常感谢您委托我撰写这篇专业的技术博客文章。作为一位世界级人工智能专家、程序员、软件架构师,我会遵循您提供的目标和约束条件,以专业的技术语言,结合深入的研究和准确的信息,为您呈现一篇内容丰富、结构清晰、实用价值高的技术博客文章。 下面我将开始正文的

    2024年04月28日
    浏览(34)
  • 自然语言处理: 第四章Seq2Seq

    开始之前,首先提出一个问题,电脑是怎么识别人类的命令的,首先人们通过输入代码(编码) ,带入输入给计算机然后再经过处理(解码)得到最终的命令。所以可以看到这其实是一个编码 + 解码的过程。可以看到首先我们将初始的信息通过编码,得到涵盖全局的信息的特征然

    2024年02月12日
    浏览(53)
  • 从零实现深度学习框架——Seq2Seq模型尝试优化

    本着“ 凡我不能创造的,我就不能理解 ”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 💡系列文章完整目录: 👉点此👈 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽

    2024年02月12日
    浏览(39)
  • 【深度学习-注意力机制attention 在seq2seq中应用】

    这是一个普通的seq2seq结构,用以实现机器对话,Encoder需要把一个输入的一个句子转化为一个最终的输出,上下文context vector,然后在Decoder中使用,但这里有些问题: 如果句子很长,这个向量很难包含sequence中最早输入的哪些词的信息,那么decoder的处理必然也缺失了这一部分

    2024年02月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包