网站开发完以后交付源代码,学电商,wordpress站点登陆,宁波外贸公司排名前五十目录
前言
一、前期准备
1.1 环境安装导入包
1.2 加载数据
1.3 构建词典
1.4 生成数据批次和迭代器
二、准备模型
2.1 定义模型
2.2 定义示例
2.3 定义训练函数与评估函数
三、训练模型
3.1 拆分数据集并运行模型
3.2 使用测试数据集评估模型
总结 前言 #x1…目录
前言
一、前期准备
1.1 环境安装导入包
1.2 加载数据
1.3 构建词典
1.4 生成数据批次和迭代器
二、准备模型
2.1 定义模型
2.2 定义示例
2.3 定义训练函数与评估函数
三、训练模型
3.1 拆分数据集并运行模型
3.2 使用测试数据集评估模型
总结 前言 本文为[365天深度学习训练营]中的学习记录博客 原作者[K同学啊] 说在前面
本周任务了解文本分类的基本流程、学习常用数据清洗方法、学习如何使用jieba实现英文分词、学习如何构建文本向量
我的环境Python3.8、Pycharm2020、torch1.12.1cu113
数据来源[K同学啊] 一、前期准备
1.1 环境安装导入包
本文是一个使用Pytorch实现的简单文本分类实战案例在本案例中我们将使用AG News数据集进行文本分类
需要确保已经安装了torchtext与poralocker库
PStorchtext库的安装需要与Pytorch、python的版本进行匹配具体可参考torchtext版本对应
import torch
import torch.nn as nn
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib,warnings
from torchtext.datasets import AG_NEWS
from torchtext.vocab import build_vocab_from_iterator
import torchtext.data.utils as utils
from torch.utils.data import DataLoader
from torch import nn
import timewarnings.filterwarnings(ignore)
device torch.device(cuda if torch.cuda.is_available() else cpu)
print(device)
1.2 加载数据
本文使用的数据集是AG NewsAGs News Topic Classification Dataset是一个广泛用于文本分分类任务的数据集尤其是在新闻领域该数据集是由AG’s Corpus of News Ariticles收集整理而来包含了四个主要的类别世界、体育、商业和科技 torchtext.datasets.AG_NEWS是一个用于加载AG News数据集的torchtext数据集类具体的参数如下 root数据集的根目录默认值是.datasplit数据集的拆分train、test**kwargs可选的关键字参数可传递给torchtext.datasets.TextClassificationDataset类构造的函数 该类加载的数据集是一个列表其中每个条目都是一个元祖包含以下两个元素 一条新闻文章的文本内容新闻文章所属的类别一个整数从1到4分别对应世界、科技、体育和商业 代码如下
train_iter AG_NEWS(splittrain)
1.3 构建词典 torchtext.data.ttils.get_tokenizer()是一个用于将文本数据分词的函数它返回一个分词器tokenizer函数可以将一个字符串转换成一个单词的列表 函数原型torchtext.data.ttils.get_tokenizer(tokenizer, language en) tokenizer参数是用于指定使用的分词器名称可以是一下之一 basic_english:用于基本英文文本的分词器moses:用于处理各种语言的分词器支持多种选项spacy:使用spaCy分词器需要安装spaCy库toktok用于各种语言的分词器速度较快 PS:分词器函数返回的单词列表中不包含任何标点符号或空格 代码如下
tokenizer utils.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]) #设置默认索引如果找不到单词则会选择默认索引print(vocab([here, is, an, example]))text_pipeline lambda x: vocab(tokenizer(x))
label_pipeline lambda x: int(x) - 1print(text_pipeline(here is an example))
print(label_pipeline(10)) 输出结果 [475, 21, 30, 5297] [475, 21, 30, 5297] 9 1.4 生成数据批次和迭代器
代码如下
def collate_batch(batch):label_list, text_list, offsets [],[],[0]for (_label, _text) in batch:# 标签列表label_list.append(label_pipeline(_label))# 文本列表processed_text torch.tensor(text_pipeline(_text),dtypetorch.int64)text_list.append(processed_text)#偏移量即语句的总词汇量offsets.append(processed_text.size(0))label_list torch.tensor(label_list, dtypetorch.int64)text_list torch.cat(text_list)offsets torch.tensor(offsets[:-1]).cumsum(dim0)return label_list.to(device),text_list.to(device), offsets.to(device)#数据集加载器
dataloader DataLoader(train_iter, batch_size8, shuffleFalse, collate_fncollate_batch)
二、准备模型
2.1 定义模型
首先对文本进行嵌入然后对句子嵌入之后的结果进行均值聚合 代码如下
#2.1 准备模型
class TextClassificationModel(nn.Module):def __init__(self,vocab_size,embed_dim,num_calss):super(TextClassificationModel, self).__init__()self.embedding nn.EmbeddingBag(vocab_size, embed_dim, sparseFalse)self.fc nn.Linear(embed_dim, num_calss)self.init_weights()def init_weights(self):initrange 0.5self.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)
self.embedding.weight.data.uniform_(-initrange, initrange)是在PyTorch框架下用于初始化神经网络的词嵌入层(embedding layer)权重的一种方法这里使用了均匀分布的随机值来初始化权重具体来说其作用如下
self.embedding这是神经网络的词嵌入层(embedding layer)其嵌入层的作用是将离散的单词表示通常为整数索引映射为固定大小的连续向量这些向量捕捉了单词之间的语义关系并作为网络的输入self.embedding.weight这是词嵌入层的权重矩阵它的形状为(vocab_size,embedding_dim)其中vocab_size是词汇表的大小embedding_dim是嵌入向量的维度self.embedding.weight.data这是权重矩阵的数据部分可以直接操作其底层的张量.uniform_(-initrange, initrange)这是一个原地操作用于将权重矩阵的值用一个均匀分布进行初始化均匀分布的范围为[-initrange,initrange]其中initrange是一个正数 这种方式初始化词嵌入层的权重可以使得模型在训练开始时具有一定的随机性有助于避免梯度消失或梯度爆炸等问题在训练过程中这些权重将通过优化算法不断更新以捕捉到更好的单词表示 2.2 定义示例
代码如下
#2.2定义实例
num_class len(set([label for (label,text) in train_iter]))
vocab_size len(vocab)
em_size 64
model TextClassificationModel(vocab_size, em_size, num_class).to(device)epochs 10
lr 5
batch_szie 64critertion torch.nn.CrossEntropyLoss()
optimizer torch.optim.SGD(model.parameters(), lrlr)
scheduler torch.optim.lr_scheduler.StepLR(optimizer,1.0,gamma0.1) 2.3 定义训练函数与评估函数
#2.3 定义训练函数与评估函数
def train(dataloader):model.train()total_acc, train_loss, total_count 0,0,0log_interval 500start_time time.time()for idx, (label, text, offsets) in enumerate(dataloader):predicted_label model(text, offsets)optimizer.zero_grad()loss critertion(predicted_label, label)loss.backward()optimizer.step()#记录acc和losstotal_acc (predicted_label.argmax(1) label).sum().item()train_loss loss.item()total_count label.size(0)if idx % log_interval 0 and idx0:elapsed time.time() - start_timeprint(| epoch{:1d} | {:4d}/{:4d} batchestrain_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, 0start_time time.time()def evaluate(dataloader):model.eval()total_acc, train_loss, total_count 0, 0 ,0with torch.no_grad():for idx, (label, text, offsets) in enumerate(dataloader):predicted_label model(text, offsets)loss critertion(predicted_label, label)# 记录acc和losstotal_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
三、训练模型
3.1 拆分数据集并运行模型 torchtext.data.functional.to_map_style_dataset函数的作用是将一个迭代式的数据集(Iterable-style dataset)转换为映射式的数据集Map-style dataset。这个转换使得我们可以通过索引更方便访问数据集中的元素 在PyTorch中数据集可以分为两种类型Iterable-style和Map-styleIterable-style数据集实现了__iter__()方法可以迭代访问数据集中的元素但不支持通过索引访问而Map-style数据集实现了__getitem__()和__len__()方法可以直接通过索引访问特定元素并能获取数据集的大小、 TorchText是Pytorch的一个扩展库专注于处理文本数据torchtext.data.functional中的to_map_style_dataset函数可以帮助我们将一个Iterable-style数据集转换为一个易于操作的Map-style数据集这样就可以通过索引直接访问数据集中的特定样本从而简化了训练、验证和测试过程中的数据处理。
代码如下
#3.1 拆分数据集并运行模型
from torch.utils.data.dataset import random_split
from torchtext.data.functional import to_map_style_datasettotal_accu Nonetrain_iter, test_iter AG_NEWS()
train_dataset to_map_style_dataset(train_iter)
test_dataset to_map_style_dataset(test_iter)
num_train int(len(train_dataset) * 0.95)
split_train_, split_valid_ random_split(train_dataset, [num_train, len(train_dataset)-num_train])train_dataloader DataLoader(split_train_, batch_sizebatch_szie, shuffleTrue, collate_fncollate_batch)
vaild_dataloader DataLoader(split_valid_, batch_sizebatch_szie, shuffleTrue, collate_fncollate_batch)
test_dataloader DataLoader(test_dataset, batch_sizebatch_szie, shuffleTrue, collate_fncollate_batch)for epoch in range(1, epochs1):epoch_start_time time.time()train(train_dataloader)val_acc, val_loss evaluate(vaild_dataloader)if total_accu is not None and total_accu val_acc:scheduler.step()else:total_accu val_accprint(- * 69)print(| epoch{:1d} | time: {:4.2f}s |vaild_acc {:4.3f} vaild_loss {:4.3f}.format(epoch,time.time()-epoch_start_time,val_acc, val_loss))print(- * 69) 输出结果 | epoch1 | 500/1782 batchestrain_acc 0.714 train_loss 0.01141 | epoch1 | 1000/1782 batchestrain_acc 0.864 train_loss 0.00623 | epoch1 | 1500/1782 batchestrain_acc 0.879 train_loss 0.00551 --------------------------------------------------------------------- | epoch1 | time: 7.21s |vaild_acc 0.810 vaild_loss 0.008 --------------------------------------------------------------------- | epoch2 | 500/1782 batchestrain_acc 0.905 train_loss 0.00445 | epoch2 | 1000/1782 batchestrain_acc 0.905 train_loss 0.00440 | epoch2 | 1500/1782 batchestrain_acc 0.906 train_loss 0.00442 --------------------------------------------------------------------- | epoch2 | time: 5.68s |vaild_acc 0.910 vaild_loss 0.004 --------------------------------------------------------------------- | epoch3 | 500/1782 batchestrain_acc 0.915 train_loss 0.00389 | epoch3 | 1000/1782 batchestrain_acc 0.918 train_loss 0.00381 | epoch3 | 1500/1782 batchestrain_acc 0.918 train_loss 0.00377 --------------------------------------------------------------------- | epoch3 | time: 6.04s |vaild_acc 0.910 vaild_loss 0.004 --------------------------------------------------------------------- | epoch4 | 500/1782 batchestrain_acc 0.929 train_loss 0.00331 | epoch4 | 1000/1782 batchestrain_acc 0.921 train_loss 0.00357 | epoch4 | 1500/1782 batchestrain_acc 0.926 train_loss 0.00341 --------------------------------------------------------------------- | epoch4 | time: 6.54s |vaild_acc 0.890 vaild_loss 0.005 --------------------------------------------------------------------- | epoch5 | 500/1782 batchestrain_acc 0.941 train_loss 0.00280 | epoch5 | 1000/1782 batchestrain_acc 0.945 train_loss 0.00266 | epoch5 | 1500/1782 batchestrain_acc 0.944 train_loss 0.00265 --------------------------------------------------------------------- | epoch5 | time: 6.76s |vaild_acc 0.917 vaild_loss 0.004 --------------------------------------------------------------------- | epoch6 | 500/1782 batchestrain_acc 0.948 train_loss 0.00255 | epoch6 | 1000/1782 batchestrain_acc 0.946 train_loss 0.00265 | epoch6 | 1500/1782 batchestrain_acc 0.946 train_loss 0.00260 --------------------------------------------------------------------- | epoch6 | time: 6.80s |vaild_acc 0.920 vaild_loss 0.004 --------------------------------------------------------------------- | epoch7 | 500/1782 batchestrain_acc 0.948 train_loss 0.00254 | epoch7 | 1000/1782 batchestrain_acc 0.945 train_loss 0.00266 | epoch7 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00248 --------------------------------------------------------------------- | epoch7 | time: 6.52s |vaild_acc 0.915 vaild_loss 0.004 --------------------------------------------------------------------- | epoch8 | 500/1782 batchestrain_acc 0.949 train_loss 0.00246 | epoch8 | 1000/1782 batchestrain_acc 0.949 train_loss 0.00246 | epoch8 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00252 --------------------------------------------------------------------- | epoch8 | time: 6.75s |vaild_acc 0.919 vaild_loss 0.004 --------------------------------------------------------------------- | epoch9 | 500/1782 batchestrain_acc 0.948 train_loss 0.00251 | epoch9 | 1000/1782 batchestrain_acc 0.949 train_loss 0.00247 | epoch9 | 1500/1782 batchestrain_acc 0.950 train_loss 0.00245 --------------------------------------------------------------------- | epoch9 | time: 6.87s |vaild_acc 0.919 vaild_loss 0.004 --------------------------------------------------------------------- | epoch10 | 500/1782 batchestrain_acc 0.951 train_loss 0.00244 | epoch10 | 1000/1782 batchestrain_acc 0.947 train_loss 0.00255 | epoch10 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00244 --------------------------------------------------------------------- | epoch10 | time: 6.64s |vaild_acc 0.919 vaild_loss 0.004 --------------------------------------------------------------------- 3.2 使用测试数据集评估模型
代码如下
print(Checking the results of test dataset.)
test_acc, test_loss evaluate(test_dataloader)
print(test accuracy {:8.3f}.format(test_acc))输出结果 总结
了解文本分类的基本流程、学习常用数据清洗方法、学习如何使用jieba实现英文分词、学习如何构建文本向量