文本分类项目

文本分类项目

在这一小节中,我们将通过实现一个简单的文本分类项目来深入了解如何使用 PyTorch 进行深度学习。我们将采用一个常用的数据集进行演示,并一步步实现模型的训练和测试。

1. 项目设置

首先,我们需要安装必要的库以及准备我们的数据集。在这个例子中,我们将使用 torch, torchtextpandas

1
pip install torch torchvision torchaudio torchtext pandas

在这里,我们将使用 torchtext 来处理文本数据,并使用 pandas 来进行数据操作。

2. 数据集准备

我们将使用一个非常简单的文本分类数据集。假设我们的数据存储在一个 CSV 文件中,包含两列:text(文本内容)和 label(分类标签)。数据集的格式如下:

1
2
3
4
5
text,label
"今天的天气非常好",0
"我喜欢这个电影",1
"这部电影太糟糕了",0
...

接下来,我们可以使用 pandas 来加载和预处理数据:

1
2
3
4
5
6
7
import pandas as pd

# 加载数据
df = pd.read_csv('data.csv')

# 查看数据
print(df.head())

3. 数据预处理

我们需要将文本数据转换为模型可以接受的格式。通常,我们使用 torchtext 提供的工具来处理文本。我们将进行以下步骤:

  • 文本分词
  • 创建词汇表
  • 将文本转换为张量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import torch
from torchtext import data, datasets

# 定义字段
TEXT = data.Field(tokenize='spacy', include_lengths=True)
LABEL = data.LabelField()

# 创建数据集
fields = [('text', TEXT), ('label', LABEL)]
examples = [data.Example.fromlist(row, fields) for row in df.values]

# 构建数据集
dataset = data.Dataset(examples, fields)

# 拆分数据集
train_data, test_data = dataset.split(split_ratio=0.8)

# 构建词汇表
TEXT.build_vocab(train_data, max_size=10000)
LABEL.build_vocab(train_data)

4. 创建数据加载器

通过 DataLoader 来方便地将数据分批加载。我们将使用 BucketIterator 来考虑不同文本长度:

1
2
3
4
5
6
7
8
from torchtext.data import BucketIterator

# 创建迭代器
train_iterator, test_iterator = BucketIterator.splits(
(train_data, test_data),
batch_size=32,
sort_within_batch=True,
device=torch.device('cuda' if torch.cuda.is_available() else 'cpu'))

5. 构建模型

接下来,我们构建我们的文本分类模型。我们可以使用 LSTM 或 GRU 网络进行处理。此处,我们使用 GRU:

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

class TextClassifier(nn.Module):
def __init__(self, vocab_size, embed_size, hidden_size, output_size):
super(TextClassifier, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_size)
self.gru = nn.GRU(embed_size, hidden_size)
self.fc = nn.Linear(hidden_size, output_size)
self.dropout = nn.Dropout(0.5)

def forward(self, text, text_lengths):
embedded = self.embedding(text)
packed_output = nn.utils.rnn.pack_padded_sequence(embedded, text_lengths)
packed_output, hidden = self.gru(packed_output)
return self.fc(hidden[-1])

6. 训练模型

我们需要定义损失函数和优化器,并进行训练:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import torch.optim as optim

# 超参数
EMBEDDING_SIZE = 100
HIDDEN_SIZE = 256
OUTPUT_SIZE = len(LABEL.vocab)

# 创建模型
model = TextClassifier(len(TEXT.vocab), EMBEDDING_SIZE, HIDDEN_SIZE, OUTPUT_SIZE)
model = model.to(device)

# 定义损失和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters())

# 训练模型
def train(model, iterator, optimizer, criterion):
model.train()
epoch_loss = 0
for batch in iterator:
text, text_lengths = batch.text
labels = batch.label

optimizer.zero_grad()
predictions = model(text, text_lengths).squeeze(1)

loss = criterion(predictions, labels)
loss.backward()
optimizer.step()

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

# 训练多个周期
for epoch in range(10):
train_loss = train(model, train_iterator, optimizer, criterion)
print(f'Epoch: {epoch+1}, Train Loss: {train_loss:.3f}')

7. 测试模型

训练完成后,我们可以在测试集上评估模型的性能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def evaluate(model, iterator, criterion):
model.eval()
epoch_loss = 0
with torch.no_grad():
for batch in iterator:
text, text_lengths = batch.text
labels = batch.label

predictions = model(text, text_lengths).squeeze(1)
loss = criterion(predictions, labels)
epoch_loss += loss.item()
return epoch_loss / len(iterator)

# 测试模型
test_loss = evaluate(model, test_iterator, criterion)
print(f'Test Loss: {test_loss:.3f}')

8. 总结

在这一小节中,我们实现了一个基础的文本分类项目,涵盖了数据加载、预处理、模型构建和训练测试的全过程。这些步骤为你理解如何从零开始使用 PyTorch 和深度学习处理文本分类任务奠定了基础。你可以在此基础上进一步拓展,尝试不同的网络结构和超参数调整。

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 模型
  • 数据增强和处理大规模数据集

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

24 从零到上手系统学习 PyTorch 详细教程

24 从零到上手系统学习 PyTorch 详细教程

1. 什么是 PyTorch?

PyTorch 是一个开源的深度学习框架,由 Facebook’s AI Research Lab 开发。它基于动态图机制,具有灵活性和易用性,广泛应用于计算机视觉、自然语言处理等领域。

2. 安装 PyTorch

在开始之前,我们需要先安装 PyTorch。可以使用以下命令在终端中安装:

1
pip install torch torchvision torchaudio

确认安装

安装完成后,可以通过执行以下代码验证安装是否成功:

1
2
import torch
print(torch.__version__)

3. PyTorch 基础

3.1 Tensor

Tensor 是 PyTorch 中的核心数据结构,类似于 NumPy 的数组,但支持 GPU 运算。

创建 Tensor

1
2
3
4
5
import torch

# 创建一个 2x3 的浮点 Tensor
x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print(x)

3.2 Tensor 运算

PyTorch 提供了丰富的数学运算,可以直接在 Tensor 上进行:

1
2
3
4
5
6
7
8
# Tensor 加法
y = torch.tensor([[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]])
z = x + y
print(z)

# 矩阵乘法
a = torch.matmul(x, y.T)
print(a)

3.3 转换 NumPy 数组

可以方便地在 PyTorch Tensor 和 NumPy 数组之间转换:

1
2
3
4
5
6
7
8
9
10
import numpy as np

# NumPy 数组转 Tensor
array = np.array([[1, 2, 3], [4, 5, 6]])
tensor = torch.from_numpy(array)
print(tensor)

# Tensor 转 NumPy 数组
array_back = tensor.numpy()
print(array_back)

4. 深度学习基础

4.1 神经网络

在 PyTorch 中可以使用 torch.nn 构建神经网络。

创建简单的神经网络

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

class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(3, 2) # 输入层到隐藏层
self.fc2 = nn.Linear(2, 1) # 隐藏层到输出层

def forward(self, x):
x = torch.relu(self.fc1(x)) # 激活函数
x = self.fc2(x)
return x

model = SimpleNN()
print(model)

4.2 训练模型

训练模型包括前向传播、计算损失、反向传播以及优化步骤。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 模拟数据
inputs = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
targets = torch.tensor([[1.0], [0.0]])

# 损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 训练过程
for epoch in range(100):
model.train() # 设置为训练模式
optimizer.zero_grad() # 清空梯度

outputs = model(inputs) # 前向传播
loss = criterion(outputs, targets) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数

if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')

5. 数据加载与预处理

5.1 使用 DataLoader

torch.utils.data 提供了用于处理数据集和批处理数据的工具。

示例代码

1
2
3
4
5
6
7
8
9
from torch.utils.data import DataLoader, TensorDataset

# 创建数据集
dataset = TensorDataset(inputs, targets)
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

# 遍历 DataLoader
for batch_inputs, batch_targets in dataloader:
print(batch_inputs, batch_targets)

6. 实战案例:手写数字识别

6.1 数据集准备

使用 torchvision 加载 MNIST 数据集。

1
2
3
4
5
6
7
8
9
10
import torchvision.transforms as transforms
from torchvision import datasets

transform = transforms.Compose([
transforms.ToTensor(), # 转换为 Tensor
transforms.Normalize((0.5,), (0.5,)) # 归一化
])

train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

6.2 构建并训练模型

基于前面的知识,可以构建一个更复杂的模型来处理 MNIST。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MNISTNN(nn.Module):
def __init__(self):
super(MNISTNN, self).__init__()
self.fc1 = nn.Linear(28*28, 128)
self.fc2 = nn.Linear(128, 10) # 10 类别

def forward(self, x):
x = x.view(-1, 28*28) # 展平
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x

# 实例化模型、定义损失和优化器
model = MNISTNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练模型
for epoch in range(5):
for images, labels in train_loader:
optimizer.zero_grad() # 清空梯度
outputs = model(images) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
print(f'Epoch [{epoch+1}/5], Loss: {loss.item():.4f}')

7. 总结

通过本教程,我们从基础到实战,系统学习了 PyTorch。我们了解了 Tensor 的创建与运算,神经网络的构建与训练,以及如何处理数据集并应用于实际的深度学习任务。希望能帮助你在深度学习的旅程上起到良好的助推作用!