>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/AtyZUu_j2k_ScNH6e732ow) 中的学习记录博客**
>- **🍖 原作者:[K同学啊 | 接辅导、项目定制](https://mtyjkh.blog.csdn.net/)**
>- **🚀 文章来源:[K同学的学习圈子](https://www.yuque.com/mingtian-fkmxf/zxwb45)**
使用AG News 数据集
AG News(AG's News Topic Classification Dataset)是一个广泛用于文本分类任务的数据集,尤其是在新闻领域。该数据集是由AG's Corpus of News Articles收集整理而来,包含了四个主要的类别:世界、体育、商业和科技。
加载数据 构建词典:
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
tokenizer = get_tokenizer('basic_english')
def yield_tokens(data_iter):
for _, text in data_iter:
yield tokenizer(text)
vocab = build_vocab_from_iterator(yield_tokens(train_iter),
specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"])
build_vocab_from_iterator
函数用于根据该yield_tokens
函数生成的标记构建词汇表。它采用标记化文本的迭代器 ( yield_tokens(train_iter)
)
如果在词汇表中找不到某个单词,它将由“ ”标记表示
模型定义:
from torch import nn
class TextClassificationModel(nn.Module):
def __init__(self, vocab_size, embed_dim, num_class):
super(TextClassificationModel, self).__init__()
self.embedding = nn.EmbeddingBag(vocab_size,
embed_dim,
sparse=False)
self.fc = nn.Linear(embed_dim, num_class)
self.init_weights()
def init_weights(self):
initrange = 0.5
self.embedding.weight.data.uniform_(-initrange, initrange)
self.fc.weight.data.uniform_(-initrange, initrange)
self.fc.bias.data.zero_()
def forward(self, text, offsets):
embedded = self.embedding(text, offsets)
return self.fc(embedded)
nn.EmbeddingBag
:该层用于有效地表示一包序列的嵌入。它类似于nn.Embedding
,但它允许不同长度的序列。vocab_size
:词汇量的大小。embed_dim
:词嵌入的维数。sparse=False
:表示嵌入不稀疏。nn.Linear
:将输入映射到输出的全连接(线性)层。embed_dim
:输入特征(词嵌入的维度)。num_class
:输出特征(分类的类数)。- 定义模型的前向传播。
- 采用
text
(标记索引) 和offsets
作为输入。 - 使用嵌入层嵌入输入。
- 将全连接层应用于嵌入输入。
模型训练:
def train(dataloader):
model.train() # Switch to training mode
total_acc, train_loss, total_count = 0, 0, 0
log_interval = 500
start_time = time.time()
for idx, (label, text, offsets) in enumerate(dataloader):
predicted_label = model(text, offsets)
optimizer.zero_grad() # Zero out gradients
loss = criterion(predicted_label, label) # Compute the loss between predicted and true labels
loss.backward() # Backward pass to compute gradients
optimizer.step() # Update weights based on the computed gradients
# Record accuracy and loss
total_acc += (predicted_label.argmax(1) == label).sum().item()
train_loss += loss.item()
total_count += label.size(0)
# Print training progress
if idx % log_interval == 0 and idx > 0:
elapsed = time.time() - start_time
print('| epoch {:1d} | {:4d}/{:4d} batches '
'| train_acc {:4.3f} train_loss {:4.5f}'.format(epoch, idx, len(dataloader),
total_acc / total_count, train_loss / total_count))
total_acc, train_loss, total_count = 0, 0, 0
start_time = time.time()
- 使用 将模型设置为训练模式
model.train()
。 - 迭代提供的批次
dataloader
。 - 计算预测、损失,并执行反向传播步骤来更新模型参数。
- 记录监测的准确性和损失。
- 按指定时间间隔打印训练进度。
def evaluate(dataloader):
model.eval() # Switch to evaluation mode
total_acc, train_loss, total_count = 0, 0, 0
with torch.no_grad():
for idx, (label, text, offsets) in enumerate(dataloader):
predicted_label = model(text, offsets)
loss = criterion(predicted_label, label) # Compute loss without backpropagation
# Record accuracy and loss for evaluation
total_acc += (predicted_label.argmax(1) == label).sum().item()
train_loss += loss.item()
total_count += label.size(0)
return total_acc / total_count, train_loss / total_count
- 使用 将模型设置为评估模式
model.eval()
。 - 迭代提供的批次
dataloader
。 - 计算预测和损失而不执行反向传播。
- 记录评估的准确性和损失。
可以在训练循环中重复调用train
训练数据,然后调用evaluate
验证或测试数据来监控模型的性能。
训练结果: