您的位置:首页 > 其它

NLP入门-情感分析系列教程-Faster Sentiment Analysis学习笔记

2020-07-24 21:25 691 查看

本系列来源Github自学使用翻译

在之前笔记中所使用的技术准确率达到84%左右,本文将使用一个训练速度更快,参数更少的模型。来自于论文Bag of Tricks for Efficient Text Classification

1 - 数据预处理

FastText论文核心观念之一是使用n-gram将其附加到句子的末尾:
例如

bi-gram
"how are you ?"
使用 bi-grams 为:
"how are", "are you" "you ?".

#一个bi-gram函数的演示
def generate_bigrams(x):
#zip()函数将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,返回由这些元组组成的列表。
#如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
#set() 函数创建一个无序不重复元素集
n_grams = set(zip(*[x[i:] for i in range(2)]))
for n_gram in n_grams:
#append() 方法用于在列表末尾添加新的对象
x.append(' '.join(n_gram))
return x
#查看函数调用结果
#print(generate_bigrams(['this','film','is','terrible']))
import torch
from torchtext import data
from torchtext import datasets
#--------------------------------------------1,处理数据----------------------------------
SEED = 1234

torch.manual_seed(SEED)
torch.backends.cudnn.deterministic = True

TEXT = data.Field(tokenize = 'spacy', preprocessing = generate_bigrams)
LABEL = data.LabelField(dtype = torch.float)
import random

train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)

train_data, valid_data = train_data.split(random_state = random.seed(SEED))
MAX_VOCAB_SIZE = 25_000

TEXT.build_vocab(train_data,
max_size = MAX_VOCAB_SIZE,
vectors = "glove.6B.100d",
unk_init = torch.Tensor.normal_)

LABEL.build_vocab(train_data)
BATCH_SIZE = 64

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
(train_data, valid_data, test_data),
batch_size = BATCH_SIZE,
device = device)

2 - 构建模型

  • 该模型只使用embedding层和linear层,首先传入每个句子的词向量,求取平均值后送入全连接层。
  • 纵向为词嵌入维度,使用filter依次计算每列平均值,最终得到一个[1x5]的张量
import torch.nn as nn
import torch.nn.functional as F

class FastText(nn.Module):
def __init__(self, vocab_size, embedding_dim, output_dim, pad_idx):
super().__init__()

self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=pad_idx)

self.fc = nn.Linear(embedding_dim, output_dim)

def forward(self, text):
# text = [sent len, batch size]
embedded = self.embedding(text)
# embedded = [sent len, batch size, emb dim]
# permute函数交换第一维和第二维
embedded = embedded.permute(1, 0, 2)
# embedded = [batch size, sent len, emb dim]
# avg_pool2d函数平均池化操作用于第一维
#squeeze()函数的功能是:从矩阵shape中,去掉维度为1的
# 在这里把batch这一列去掉了,平局池化函数坐拥用sent len(这个句子当中单词的个数),每个单词词向量对应列做平均池化
pooled = F.avg_pool2d(embedded, (embedded.shape[1], 1)).squeeze(1)
# pooled = [batch size, embedding_dim]
return self.fc(pooled)
  • 模型训练及评估同上篇
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: