动手学深度学习(十三) NLP机器翻译(下)

简介: 动手学深度学习(十三) NLP机器翻译(下)

Sequence to Sequence模型


模型:

训练


29.png

Image Name


预测


28.png

Image Name

具体结构:


27.png

Image Name


Encoder

class Seq2SeqEncoder(d2l.Encoder):
    def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
                 dropout=0, **kwargs):
        super(Seq2SeqEncoder, self).__init__(**kwargs)
        self.num_hiddens=num_hiddens
        self.num_layers=num_layers
        self.embedding = nn.Embedding(vocab_size, embed_size)
        self.rnn = nn.LSTM(embed_size,num_hiddens, num_layers, dropout=dropout)
    def begin_state(self, batch_size, device):
        return [torch.zeros(size=(self.num_layers, batch_size, self.num_hiddens),  device=device),
                torch.zeros(size=(self.num_layers, batch_size, self.num_hiddens),  device=device)]
    def forward(self, X, *args):
        X = self.embedding(X) # X shape: (batch_size, seq_len, embed_size)
        X = X.transpose(0, 1)  # RNN needs first axes to be time
        # state = self.begin_state(X.shape[1], device=X.device)
        out, state = self.rnn(X)
        # The shape of out is (seq_len, batch_size, num_hiddens).
        # state contains the hidden state and the memory cell
        # of the last time step, the shape is (num_layers, batch_size, num_hiddens)
        return out, state

encoder = Seq2SeqEncoder(vocab_size=10, embed_size=8,num_hiddens=16, num_layers=2)
X = torch.zeros((4, 7),dtype=torch.long)
output, state = encoder(X)
output.shape, len(state), state[0].shape, state[1].shape

(torch.Size([7, 4, 16]), 2, torch.Size([2, 4, 16]), torch.Size([2, 4, 16]))


Decoder


class Seq2SeqDecoder(d2l.Decoder):
    def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
                 dropout=0, **kwargs):
        super(Seq2SeqDecoder, self).__init__(**kwargs)
        self.embedding = nn.Embedding(vocab_size, embed_size)
        self.rnn = nn.LSTM(embed_size,num_hiddens, num_layers, dropout=dropout)
        self.dense = nn.Linear(num_hiddens,vocab_size)
    def init_state(self, enc_outputs, *args):
        return enc_outputs[1]
    def forward(self, X, state):
        X = self.embedding(X).transpose(0, 1)
        out, state = self.rnn(X, state)
        # Make the batch to be the first dimension to simplify loss computation.
        out = self.dense(out).transpose(0, 1)
        return out, state

decoder = Seq2SeqDecoder(vocab_size=10, embed_size=8,num_hiddens=16, num_layers=2)
state = decoder.init_state(encoder(X))
out, state = decoder(X, state)
out.shape, len(state), state[0].shape, state[1].shape

(torch.Size([4, 7, 10]), 2, torch.Size([2, 4, 16]), torch.Size([2, 4, 16]))


损失函数

def SequenceMask(X, X_len,value=0):
    maxlen = X.size(1)
    mask = torch.arange(maxlen)[None, :].to(X_len.device) < X_len[:, None]   
    X[~mask]=value
    return X

X = torch.tensor([[1,2,3], [4,5,6]])
SequenceMask(X,torch.tensor([1,2]))

tensor([[1, 0, 0],
        [4, 5, 0]])

X = torch.ones((2,3, 4))
SequenceMask(X, torch.tensor([1,2]),value=-1)

tensor([[[ 1.,  1.,  1.,  1.],
         [-1., -1., -1., -1.],
         [-1., -1., -1., -1.]],
        [[ 1.,  1.,  1.,  1.],
         [ 1.,  1.,  1.,  1.],
         [-1., -1., -1., -1.]]])

class MaskedSoftmaxCELoss(nn.CrossEntropyLoss):
    # pred shape: (batch_size, seq_len, vocab_size)
    # label shape: (batch_size, seq_len)
    # valid_length shape: (batch_size, )
    def forward(self, pred, label, valid_length):
        # the sample weights shape should be (batch_size, seq_len)
        weights = torch.ones_like(label)
        weights = SequenceMask(weights, valid_length).float()
        self.reduction='none'
        output=super(MaskedSoftmaxCELoss, self).forward(pred.transpose(1,2), label)
        return (output*weights).mean(dim=1)

loss = MaskedSoftmaxCELoss()
loss(torch.ones((3, 4, 10)), torch.ones((3,4),dtype=torch.long), torch.tensor([4,3,0]))

tensor([2.3026, 1.7269, 0.0000])


训练

def train_ch7(model, data_iter, lr, num_epochs, device):  # Saved in d2l
    model.to(device)
    optimizer = optim.Adam(model.parameters(), lr=lr)
    loss = MaskedSoftmaxCELoss()
    tic = time.time()
    for epoch in range(1, num_epochs+1):
        l_sum, num_tokens_sum = 0.0, 0.0
        for batch in data_iter:
            optimizer.zero_grad()
            X, X_vlen, Y, Y_vlen = [x.to(device) for x in batch]
            Y_input, Y_label, Y_vlen = Y[:,:-1], Y[:,1:], Y_vlen-1
            Y_hat, _ = model(X, Y_input, X_vlen, Y_vlen)
            l = loss(Y_hat, Y_label, Y_vlen).sum()
            l.backward()
            with torch.no_grad():
                d2l.grad_clipping_nn(model, 5, device)
            num_tokens = Y_vlen.sum().item()
            optimizer.step()
            l_sum += l.sum().item()
            num_tokens_sum += num_tokens
        if epoch % 50 == 0:
            print("epoch {0:4d},loss {1:.3f}, time {2:.1f} sec".format( 
                  epoch, (l_sum/num_tokens_sum), time.time()-tic))
            tic = time.time()

embed_size, num_hiddens, num_layers, dropout = 32, 32, 2, 0.0
batch_size, num_examples, max_len = 64, 1e3, 10
lr, num_epochs, ctx = 0.005, 300, d2l.try_gpu()
src_vocab, tgt_vocab, train_iter = d2l.load_data_nmt(
    batch_size, max_len,num_examples)
encoder = Seq2SeqEncoder(
    len(src_vocab), embed_size, num_hiddens, num_layers, dropout)
decoder = Seq2SeqDecoder(
    len(tgt_vocab), embed_size, num_hiddens, num_layers, dropout)
model = d2l.EncoderDecoder(encoder, decoder)
train_ch7(model, train_iter, lr, num_epochs, ctx)

epoch   50,loss 0.093, time 38.2 sec
epoch  100,loss 0.046, time 37.9 sec
epoch  150,loss 0.032, time 36.8 sec
epoch  200,loss 0.027, time 37.5 sec
epoch  250,loss 0.026, time 37.8 sec
epoch  300,loss 0.025, time 37.3 sec


测试

def translate_ch7(model, src_sentence, src_vocab, tgt_vocab, max_len, device):
    src_tokens = src_vocab[src_sentence.lower().split(' ')]
    src_len = len(src_tokens)
    if src_len < max_len:
        src_tokens += [src_vocab.pad] * (max_len - src_len)
    enc_X = torch.tensor(src_tokens, device=device)
    enc_valid_length = torch.tensor([src_len], device=device)
    # use expand_dim to add the batch_size dimension.
    enc_outputs = model.encoder(enc_X.unsqueeze(dim=0), enc_valid_length)
    dec_state = model.decoder.init_state(enc_outputs, enc_valid_length)
    dec_X = torch.tensor([tgt_vocab.bos], device=device).unsqueeze(dim=0)
    predict_tokens = []
    for _ in range(max_len):
        Y, dec_state = model.decoder(dec_X, dec_state)
        # The token with highest score is used as the next time step input.
        dec_X = Y.argmax(dim=2)
        py = dec_X.squeeze(dim=0).int().item()
        if py == tgt_vocab.eos:
            break
        predict_tokens.append(py)
    return ' '.join(tgt_vocab.to_tokens(predict_tokens))

for sentence in ['Go .', 'Wow !', "I'm OK .", 'I won !']:
    print(sentence + ' => ' + translate_ch7(
        model, sentence, src_vocab, tgt_vocab, max_len, ctx))

Go . => va !
Wow ! => <unk> !
I'm OK . => ça va .
I won ! => j'ai gagné !


Beam Search


简单greedy search:


26.png

Image Name


维特比算法:选择整体分数最高的句子(搜索空间太大)


集束搜索:


25.png

Image Name

相关文章
|
1月前
|
机器学习/深度学习 自然语言处理 监控
利用深度学习技术实现自然语言处理中的情感分析
本文将深入探讨如何利用深度学习技术,特别是神经网络模型,来实现自然语言处理领域中的情感分析任务。通过结合深度学习算法和大规模文本数据集,可以实现更准确和高效的情感分析,为情感识别和情感推断提供更好的解决方案。
|
3月前
|
机器学习/深度学习 自然语言处理 TensorFlow
在Python中进行自然语言处理(NLP)的深度学习
在Python中进行自然语言处理(NLP)的深度学习
34 3
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用与挑战
【2月更文挑战第10天】 随着人工智能技术的不断发展,深度学习在自然语言处理领域的应用日益广泛。本文将探讨深度学习在自然语言处理中的重要性、现状和未来挑战,以及我个人对于该领域的一些思考和见解。
17 1
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用与挑战
【2月更文挑战第4天】随着人工智能技术的不断发展,深度学习在自然语言处理领域扮演着越来越重要的角色。本文将探讨深度学习在自然语言处理中的应用现状及面临的挑战,从技术角度分析其发展趋势和解决方向。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用
【2月更文挑战第3天】随着人工智能技术的不断发展,自然语言处理成为了人工智能领域中的一个重要分支。深度学习作为一种有效的机器学习方法,在自然语言处理领域中也有着广泛的应用。本文将从深度学习在自然语言处理中的应用出发,探讨深度学习技术在自然语言处理中的优势和挑战,并介绍一些常见的深度学习模型及其应用。
21 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习技术在自然语言处理中的应用与思考
【2月更文挑战第3天】 传统的自然语言处理技术在处理复杂语义和语法问题时存在诸多限制,而深度学习技术的崛起为解决这一难题提供了新的可能性。本文将探讨深度学习技术在自然语言处理领域的应用现状及未来发展趋势,以及对技术发展的思考和展望。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用与挑战
【2月更文挑战第3天】 自然语言处理(NLP)是人工智能领域的热门研究方向,而深度学习技术的迅猛发展为NLP的发展带来了新的机遇和挑战。本文将探讨深度学习在自然语言处理中的应用现状,分析技术发展趋势,并就其中的挑战进行讨论,旨在为读者提供对NLP领域的深入了解和思考。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用与挑战
【2月更文挑战第3天】在当今信息爆炸的时代,自然语言处理技术的发展日新月异。本文将探讨深度学习在自然语言处理领域中的应用现状和面临的挑战,以及作者对未来发展的一些思考。
23 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用
【2月更文挑战第3天】深度学习技术因其强大的模式识别和分类能力,成为自然语言处理领域的热门技术之一。本文将介绍深度学习在自然语言处理中的应用,包括文本分类、情感分析、机器翻译等方面。我们将从基础概念入手,详细阐述深度学习在自然语言处理中的实现方法以及优势与不足之处。
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习的前沿技术和应用:从自然语言处理到机器视觉
深度学习作为人工智能的核心技术,近年来得到了广泛的关注和应用。除了在语音识别、自然语言处理等领域有不俗表现外,深度学习在机器视觉方面也取得了很多进展。本文将介绍深度学习的前沿技术和应用,包括自然语言处理、图像识别和目标检测等。