赞
踩
import torch import torchtext import torch.nn as nn import torch.nn.functional as F from torchtext.vocab import GloVe import numpy as np import pandas as pd import matplotlib.pyplot as plt import re from sklearn.model_selection import train_test_split import time start=time.time() device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") #读取文件 data = pd.read_csv('D:/pycharmworkspace/ISLR-master/Tweets.csv') #取指定的两列 data = data[['airline_sentiment','text']] #去掉重复值 data.drop_duplicates(inplace=True) #返回每一种类型的数量 data.airline_sentiment.value_counts() #print(data.airline_sentiment.value_counts()) #在数据后面新建名字为review的一列数据 #neutral编号为0 positive编号为1 negative编号为2 取前一部分 data['review'] = pd.factorize(data.airline_sentiment)[0] #删除airline_sentiment这一列数据 del data['airline_sentiment'] #保留规则 保留A-Z a-z 加号是按原来句子样式表达 token = re.compile('[A-Za-z]+|[!?,.()]') def reg_text(text): # 保留所有大写和小写字母 new_text = token.findall(text) # 将所有大写变成小写 new_text = [word.lower() for word in new_text] return new_text #对指定的text这列数据进行操作 data['text'] = data.text.apply(reg_text) #创建词表 词表就是每一个单词给它编码的数值 word_set = set() #x是列表的集合 t是每一条文本的列表 for text in data.text: # 对文本列表内继续迭代 for word in text: # 重复单词不添加进去 word_set.add(word) #需要额外加1个 max_word = len(word_set) + 1 #将()转换成列表[] word_list = list(word_set) #word_list.index(w)+1是找到单词w的位置并加1 #这样词表就创建好了 word_index是词表 word_index = dict((word, word_list.index(word) + 1) for word in word_list) #将文本转换成数值表示 #现在文本是x apply是应用函数 lambda是匿名函数 t代表文本的每一行元素 取不到则置为0 text = data.text.apply(lambda x: [word_index.get(word, 0) for word in x]) #每行文本长度不齐故获取最大长度的文本 maxlen = max(len(x) for x in text) #将每行文本用0进行填充 pad_text = [l + (maxlen-len(l))*[0] for l in text] #将列表转换成数组 pad_text = np.array(pad_text) #制作标签 labels = data.review.values #划分训练集合测试集 x_train, x_test, y_train, y_test = train_test_split(pad_text, labels) class Mydataset(torch.utils.data.Dataset): def __init__(self, text_list, label_list): self.text_list = text_list self.label_list = label_list # index是序号 因为要进行切片 def __getitem__(self, index): # 切片并装换成长类型 text = torch.LongTensor(self.text_list[index]) label = self.label_list[index] return text, label def __len__(self): return len(self.text_list) train_ds = Mydataset(x_train, y_train) test_ds = Mydataset(x_test, y_test) BTACH_SIZE = 16 train_dl = torch.utils.data.DataLoader( train_ds, batch_size=BTACH_SIZE, shuffle=True ) test_dl = torch.utils.data.DataLoader( test_ds, batch_size=BTACH_SIZE ) em_dim = 100 hidden_size = 200 class Net(nn.Module): def __init__(self): super(Net, self).__init__() # max_word是总共单词的数量 将这些单词映射到100的张量上 #batch*maxlen*em_dim self.em = nn.Embedding(max_word, em_dim) #em_dim是输入特征 200是隐藏单元数 batch在第一维故bacth_first为True self.lstm = nn.LSTM(em_dim, hidden_size, batch_first=True) self.fc1 = nn.Linear(hidden_size, 256) self.fc2 = nn.Linear(256, 3) def forward(self, x): x = self.em(x) #lstm有两个输出 第一个是当前状态输出 第二个是当前隐藏输出 不要第二个 x, _ = self.lstm(x) #取出最后一个的输出 经过lstm的x数据形式是 batch,time_step,output #第一个维度是batch 第二个维度是每一次时间步的输出 第三个维度是预测结果 #对于第一个维度全要 第二个维度只要最后一个 第三个维度全要 x = F.relu(self.fc1(x[:, -1, :])) x = self.fc2(x) return x model = Net() model = model.to(device) loss_fn = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) def fit(epoch, model, trainloader, testloader): correct = 0 total = 0 running_loss = 0 model.train() for x, y in trainloader: x, y = x.to(device), y.to(device) y_pred = model(x) loss = loss_fn(y_pred, y) optimizer.zero_grad() loss.backward() optimizer.step() with torch.no_grad(): y_pred = torch.argmax(y_pred, dim=1) correct += (y_pred == y).sum().item() total += y.size(0) running_loss += loss.item() # exp_lr_scheduler.step() epoch_loss = running_loss / len(trainloader.dataset) epoch_acc = correct / total test_correct = 0 test_total = 0 test_running_loss = 0 model.eval() with torch.no_grad(): for x, y in testloader: x, y = x.to(device), y.to(device) y_pred = model(x) loss = loss_fn(y_pred, y) y_pred = torch.argmax(y_pred, dim=1) test_correct += (y_pred == y).sum().item() test_total += y.size(0) test_running_loss += loss.item() epoch_test_loss = test_running_loss / len(testloader.dataset) epoch_test_acc = test_correct / test_total print('epoch: ', epoch, 'loss: ', round(epoch_loss, 3), 'accuracy:', round(epoch_acc, 3), 'test_loss: ', round(epoch_test_loss, 3), 'test_accuracy:', round(epoch_test_acc, 3) ) return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc epochs = 30 train_loss = [] train_acc = [] test_loss = [] test_acc = [] for epoch in range(epochs): epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch, model, train_dl, test_dl) train_loss.append(epoch_loss) train_acc.append(epoch_acc) test_loss.append(epoch_test_loss) test_acc.append(epoch_test_acc) end = time.time() print(end-start)
有略微改善 但过拟合仍然严重
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。