23 从零到上手系统学习 PyTorch 教程

23 从零到上手系统学习 PyTorch 教程

目次

  1. 序列到序列模型简介
  2. 数据准备
  3. 创建模型
    • 编码器
    • 解码器
  4. 训练模型
  5. 测试模型
  6. 总结与进阶

1. 序列到序列模型简介

序列到序列模型(Seq2Seq)是一种用于处理序列数据的深度学习模型,尤其多用于翻译、对话生成等任务。该模型通常包含两个主要部分:编码器(Encoder)解码器(Decoder)

  • 编码器: 输入序列并将其转换为一个上下文向量,表示输入的语义信息。
  • 解码器: 基于上下文向量逐步生成输出序列。

2. 数据准备

在进行序列到序列模型训练前,首先需要准备数据。这里以机器翻译任务为例,假设我们要将英语句子翻译成法语句子。

2.1 数据示例

1
2
源语言 (英语): "I am a student."
目标语言 (法语): "Je suis un étudiant."

2.2 数据预处理

我们需要对数据进行以下处理:

  • 分词(Tokenization)
  • 字典构建和索引映射
  • 填充(Padding)和截断(Truncation)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torch
from torch.nn.utils.rnn import pad_sequence

# 示例数据
source_sentences = ["I am a student.", "He is a teacher."]
target_sentences = ["Je suis un étudiant.", "Il est professeur."]

# 词汇表
source_vocab = {'<PAD>': 0, 'I': 1, 'am': 2, 'a': 3, 'student': 4, 'He': 5, 'is': 6, 'teacher': 7}
target_vocab = {'<PAD>': 0, 'Je': 1, 'suis': 2, 'un': 3, 'étudiant': 4, 'Il': 5, 'est': 6, 'professeur': 7}

# 数据转 indices
def sentence_to_indices(sentence, vocab):
return [vocab[word] for word in sentence.split()]

source_indices = [torch.tensor(sentence_to_indices(sent, source_vocab)) for sent in source_sentences]
target_indices = [torch.tensor(sentence_to_indices(sent, target_vocab)) for sent in target_sentences]

# 填充
source_padded = pad_sequence(source_indices, batch_first=True, padding_value=0)
target_padded = pad_sequence(target_indices, batch_first=True, padding_value=0)

3. 创建模型

3.1 编码器

编码器通常由多个LSTMGRU单元组成。下面是一个简单的编码器模型示例。

1
2
3
4
5
6
7
8
9
10
11
12
import torch.nn as nn

class Encoder(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(Encoder, self).__init__()
self.embedding = nn.Embedding(input_dim, hidden_dim)
self.rnn = nn.LSTM(hidden_dim, hidden_dim)

def forward(self, src):
embedded = self.embedding(src)
output, hidden = self.rnn(embedded)
return hidden

3.2 解码器

解码器的设计类同编码器,然而解码器需要接受上一时间步的输出和编码器的上下文向量。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Decoder(nn.Module):
def __init__(self, output_dim, hidden_dim):
super(Decoder, self).__init__()
self.embedding = nn.Embedding(output_dim, hidden_dim)
self.rnn = nn.LSTM(hidden_dim, hidden_dim)
self.fc_out = nn.Linear(hidden_dim, output_dim)

def forward(self, input, hidden):
input = input.unsqueeze(0) # 增加维度
embedded = self.embedding(input)
output, hidden = self.rnn(embedded, hidden)
prediction = self.fc_out(output.squeeze(0))
return prediction, hidden

4. 训练模型

在训练模型时,我们需要定义损失函数和优化器,并循环进行多次训练。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import torch.optim as optim

# 初始化模型
encoder = Encoder(input_dim=len(source_vocab), hidden_dim=256)
decoder = Decoder(output_dim=len(target_vocab), hidden_dim=256)

# 损失和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(list(encoder.parameters()) + list(decoder.parameters()))

# 训练过程
for epoch in range(num_epochs):
encoder.train()
decoder.train()
optimizer.zero_grad()

hidden = encoder(source_padded)
output, hidden = decoder(target_padded[:, 0], hidden)

loss = criterion(output, target_padded[:, 1:].view(-1))
loss.backward()
optimizer.step()

5. 测试模型

测试模型时,可以使用Greedy DecodingBeam Search等策略来生成输出序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def decode(encoder, decoder, src_sentence):
encoder.eval()
decoder.eval()

with torch.no_grad():
hidden = encoder(src_sentence)
input_token = torch.tensor([[1]]) # 假设1是目标语言的起始标记

output_sentence = []
for _ in range(max_length):
output, hidden = decoder(input_token, hidden)
top1 = output.argmax(1)[-1].item()
output_sentence.append(top1)
input_token = torch.tensor([[top1]])
if top1 == 0: # 假设0是填充标记
break

return output_sentence

6. 总结与进阶

在本节中,我们探索了序列到序列模型的构建过程,包括数据准备模型创建训练测试。这是一个基础但功能强大的模型,适用于多种序列生成任务。

进阶方向

  • 添加注意力机制
  • 使用 Transformer 模型
  • 数据增强和处理大规模数据集

通过进一步学习和实验,您可以提升模型的表现,应用到更复杂的任务,如对话系统和自动摘要生成等。

23 从零到上手系统学习 PyTorch 教程

https://zglg.work/pytorch-tutorial/23/

作者

AI教程网

发布于

2024-08-07

更新于

2024-08-10

许可协议