挑选出tensor中等于0的索引_在PyTorch中使用LSTM进行情感分析

如何使用递归神经网络分析文本。

自然语言处理(NLP)与深度学习相结合,已成为人工智能研究领域中最性感的主题之一。

有了正确的体系结构,就可以使用文本数据库(经过适当预处理)来训练神经网络,并从人类语言的语义中创建抽象,这对于提取见解和自动决策非常有用。

在本文中,我们将介绍递归神经网络(RNN)与自然语言处理(NLP)之间的关系。然后,使用Amazon Fine Food Reviews数据集,我们将训练使用PyTorch的LSTM将分析分类为积极还是消极。

最后,要检查一切是否顺利,让我们在测试数据集中的另一部分中查看该模型的准确性。

自然语言处理和递归神经网络

我们可以根据数据将文本定义为序列(单词的序列,或者在较低抽象级别的字符)。重要的是,为了在建模此数据集时提取尽可能多的信息,我们需要在模型中放置字符串的顺序。

这是递归神经网络出现的地方:在序列处理中,它们将部分输出保留为“状态”,以便随着时间的推移保留信息:

29fef42a55f4c2ca279b4a78a3514957.png

递归神经网络

为了对数据集进行建模,我们将使用特定的RNN体系结构LSTM。

数据集

我们的数据集是Amazon Fine Food Reviews,我们收到的文件是.csv文件,其中我们将使用“文本”和“分数”列,它们分别包含评论文本和分数,范围从1星到5星。

为了将其与我们的神经网络一起使用,我们将文本编码(即变换)为数字序列,其中每个数字都对应于词汇表中单词的索引,索引是一个设置的数据结构(组)包含数据集中存在的所有单词。

预处理

为了用文本数据训练神经网络,我们需要以某种方式将文本编码为数字。有几种方法可以做到这一点,在我们的分析中,我们将使用文本到序列。

在文本到序列方法中,文本编码分两个阶段进行:首先,创建词汇表:它是一个包含所有文本中存在的所有单词的集合,而无需重复。

此后,我们创建一个数据集,该数据集具有一个数字向量,该数字向量带有词汇表中每个单词的索引。最后,对于每个文本,我们的神经网络的输入如下所示:

cfaa33788cb0189460a14b19b78896fa.png

文本到序列

有一个名为TorchNLP的库,可以解决这个问题。而且,它还将解决在NLP中组装张量数据集时出现的另一个小问题,即字符串的大小:如果它们的大小不同,它们将无法成为张量并且无法最佳地通过我们的模型。

解决方案是填充:我们确定序列的最大。对于较小的那些,我们将0放在最后,直到它们达到大小为止;我们刚裁掉的最大的。

让我们转到预处理代码,我们将从导入库开始。

import torchimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optim#pip install pytorch-nlpfrom torchnlp.encoders.text import SpacyEncoder, pad_tensorfrom sklearn.model_selection import train_test_splitimport pandas as pdimport numpy as npimport seaborn as snsimport matplotlib.pyplot as plt%matplotlib inlinefrom tqdm.notebook import tqdm

然后,我们将导入数据框并从中删除所有非文本和标签的内容。因为分数是1到5星,所以我们将3和4除去:1和2星为消极,5星为积极。

我们还将通过肯定分析从文本中随机删除,直到数据集平衡为止。最后,我们借此机会在同一个框中将其转换为列表-这将有助于在后续步骤中对这些数据进行操作。

我们删除不需要的列,df.drop以不同的方式删除3至4,以显示可以用pandas完成的方式,然后将它们变成列表,以便对它们进行编码。

#importdf = pd.read_csv('D:/Jupyter/dataset/amazon-fine-food-reviews/reviews.csv')#drop useless datadf = df.drop(['Id', 'ProductId', 'UserId', 'ProfileName', 'HelpfulnessNumerator',       'HelpfulnessDenominator', 'Time', 'Summary',], axis=1)#remove ambiguous 3 and 4 stars for balancing#df = df[df['Score'] != 3]#create labels and preprocessdf['Score'] = df['Score'].apply(lambda i: 'positive' if i > 4 else 'negative')df['Text'] = df['Text'].apply(lambda x:x.lower())#set names for beautiful dfdf.columns = ['labels', 'text']

现在,我们将对数据进行编码。SpacyEncoder将遍历数据集并创建词汇表。

encoder = SpacyEncoder(text_as_list)encoded_texts = []for i in tqdm(range(len(text_as_list))):    encoded_texts.append(encoder.encode(text_as_list[i]))

还需要分析具有很长的文本(文本大小分布中的异常值)的可能性,如果出现这种情况,则将其消除。否则,填充数为0的文本将使预测和渐变倾斜。

我们还将绘制文本的分布图,看是否正确。

lengths = [len(i) for i in tqdm(encoded_texts)]length_as_series = pd.Series(lengths)plt.title("Probability Density Function for text lengths")sns.distplot(length_as_series)max_pad_length = length_as_series.quantile(0.9)
c683e223c67fc87db2b353b2725c7e7b.png

文本大小的概率密度函数

我们还看到该分布的第90个百分位数为191。我们将删除大小超过此值的文本,以确保我们的RNN以较少偏见的方式进行训练。

reviews = []labels = []for i in tqdm(range(len(encoded_texts))):    if len(encoded_texts[i]) < max_pad_length:        reviews.append(encoded_texts[i])        labels.append(1 if labels_as_list[i] == "positive" else 0)        assert len(reviews) == len(labels), "The labels and feature lists should have the same time"

最后,我们可以进行填充并创建数据集。让我们也划分训练和测试数据集:

padded_dataset = []for i in tqdm(range(len(reviews))):    padded_dataset.append(pad_tensor(reviews[i], int(max_pad_length)))#preparing the final dataset:X = torch.stack(padded_dataset)y = torch.tensor(labels)X_train, X_test, y_train, y_test = train_test_split(X,                                                    y,                                                    test_size=.25,                                                    random_state=42)X_train, y_train = torch.tensor(X_train), torch.tensor(y_train)X_test, y_test = torch.tensor(X_test), torch.tensor(y_test)

完成后,我们可以继续创建模型。

使用PyTorch创建模型

对于我们的模型,我们将使用layer nn.Embedding,它将对词汇索引序列进行矢量化nn.LSTM处理,然后再一层进行序列处理,再一层nn.Linear处理模型的复杂性。

class Net(nn.Module):    def __init__(self):        super().__init__()        self.embedding = nn.Embedding(len(encoder.vocab)+1, 32)        self.lstm = nn.LSTM(32, 32, batch_first=True)        self.fc1 = nn.Linear(32, 2)            def forward(self, x):        x_ = self.embedding(x)        x_, (h_n, c_n) = self.lstm(x_)        x_ = (x_[:, -1, :])        x_ = self.fc1(x_)        return x_

在通过LSTM之后,我们仅对每个序列进行线性层的最后预测。也就是说,我们可以实例化我们的对象(网络,优化器,DataLoader等),然后进入训练循环。

准备训练循环

我们将进入最后一步。在准备训练和测试循环时,我们将创建将在其中使用的对象。

此外 ,以网络,分类和损失的对象,我们将创建从一个的数据加载程序 torch.TensorDataset,它将由我们之前安装的X_train, y_train, X_test, y_test构建

ds_train = torch.utils.data.TensorDataset(X_train, y_train)train_loader = torch.utils.data.DataLoader(ds_train, batch_size=64, shuffle=True)ds_test = torch.utils.data.TensorDataset(X_test, y_test)test_loader = torch.utils.data.DataLoader(ds_test, batch_size=64, shuffle=True)classifier = Net()device = torch.device('cpu')optimizer = optim.Adam(classifier.parameters(), lr=.01)#0.002 dives 85% acccriterion = nn.CrossEntropyLoss()

我们终于可以进入训练循环了。看到我们使用tqdm获得更漂亮的输出和进度条。

以0.02(Adam优化器)的学习率,我们将训练网络10个周期,批大小为64。

epoch_bar = tqdm(range(10),                 desc="Training",                 position=0,                 total=2)acc = 0for epoch in epoch_bar:    batch_bar = tqdm(enumerate(train_loader),                     desc="Epoch: {}".format(str(epoch)),                     position=1,                     total=len(train_loader))        for i, (datapoints, labels) in batch_bar:                optimizer.zero_grad()                preds = classifier(datapoints.long())        loss = criterion(preds, labels)        loss.backward()        optimizer.step()            if (i + 1) % 500 == 0:                        preds = classifier(X_test)            acc = (preds.argmax(dim=1) == y_test).float().mean().cpu().item()        batch_bar.set_postfix(loss=loss.cpu().item(),                              accuracy="{:.2f}".format(acc),                              epoch=epoch)        batch_bar.update()            epoch_bar.set_postfix(loss=loss.cpu().item(),                          accuracy="{:.2f}".format(acc),                          epoch=epoch)    epoch_bar.update()

结果与结论

使用我们的体系结构和超参数,您应该达到接近85%的精度。

考虑到我们拥有庞大的词汇量和一些节点很少的复杂网络体系结构,可以说我们取得了很好的结果。

最后,作为以后的工作,基于预处理数据和模型的简单性,考虑如何部署数据并创建用于分析文本情感的API可能会很有趣。

好的,我会为您解答关于使用PyTorch进行线性回归的问题。 在PyTorch进行线性回归可以分为以下几个步骤: 1. 准备数据:首先,您需要准备数据,包括训练数据和验证数据。在本例,我们将使用一个简单的数据集,其包含一些房屋的面积和价格,以用于预测房价。 2. 定义模型:接下来,您需要定义一个模型。在本例,我们将使用一个简单的线性模型,它包含一个线性层,该层将输入的特征映射到输出的标签。 3. 定义损失函数:您需要定义一个损失函数,以便在训练模型时计算损失。在本例,我们将使用均方误差(MSE)损失函数。 4. 训练模型:接下来,您需要定义一个优化器,并使用训练数据对模型进行训练。在本例,我们将使用随机梯度下降(SGD)优化器,并迭代多次来更新模型的参数。 5. 验证模型:最后,您需要使用验证数据来评估模型的性能。在本例,我们将计算模型在验证数据上的损失,并将其与训练数据的损失进行比较,以确定模型是否过拟合。 以下是一个简单的代码示例,演示了如何使用PyTorch进行线性回归: ```python import torch import torch.nn as nn # 准备数据 x_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]]) y_train = torch.tensor([[2.0], [4.0], [6.0], [8.0]]) # 定义模型 model = nn.Linear(1, 1) # 定义损失函数 criterion = nn.MSELoss() # 定义优化器 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 训练模型 num_epochs = 1000 for epoch in range(num_epochs): # 向前传递 outputs = model(x_train) loss = criterion(outputs, y_train) # 向后传递和优化 optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) # 验证模型 x_val = torch.tensor([[5.0]]) y_val = model(x_val) print('预测的房价: {:.2f}'.format(y_val.item())) ``` 希望这可以帮助您理解如何使用PyTorch进行线性回归。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值