Sentiment Analysis with LSTM and Word2Vec Embeddings
import\u0020copy import\u0020torch from\u0020torch\u0020import\u0020nn from\u0020torch\u0020import\u0020optim import\u0020torchtext from\u0020torchtext\u0020import\u0020data from\u0020torchtext\u0020import\u0020datasets
TEXT\u0020=\u0020data.Field(sequential=True, batch_first=True, lower=True) LABEL\u0020=\u0020data.LabelField()
#\u0020load\u0020data\u0020splits train_data, val_data, test_data\u0020=\u0020datasets.SST.splits(TEXT, LABEL)
#\u0020build\u0020dictionary TEXT.build_vocab(train_data) LABEL.build_vocab(train_data)
#\u0020hyperparameters
vocab_size\u0020=\u0020len(TEXT.vocab)
label_size\u0020=\u0020len(LABEL.vocab)
padding_idx\u0020=\u0020TEXT.vocab.stoi['
#\u0020build\u0020iterators train_iter, val_iter, test_iter\u0020=\u0020data.BucketIterator.splits( (train_data, val_data, test_data),\u0020 batch_size=32) #\u0020your\u0020code\u0020here use_cuda\u0020=\u0020torch.cuda.is_available() device\u0020=\u0020torch.device("cuda"\u0020if\u0020use_cuda\u0020else\u0020"cpu")\u0020
#\u0020Training\u0020function\u0020 def\u0020train(model, train_loader, optimizer, criterion):\u0020 model.train()\u0020 total_loss\u0020=\u00200.0\u0020 total_correct\u0020=\u00200\u0020 for\u0020batch\u0020in\u0020train_loader:\u0020 #text\u0020=\u0020batch.text #labels\u0020=\u0020batch.label text, labels\u0020=\u0020batch.text.to(device), batch.label.to(device)\u0020 optimizer.zero_grad()\u0020 logits\u0020=\u0020model(text) loss\u0020=\u0020criterion(logits, labels)\u0020 ''' l2_reg\u0020=\u0020torch.tensor(0, dtype=torch.float) for\u0020param\u0020in\u0020model.parameters():\u0020 l2_reg\u0020+=\u0020torch.norm(param)\u0020 loss\u0020+=\u00200.01\u0020*\u0020l2_reg\u0020 '''
loss.backward()\u0020
optimizer.step()\u0020
#scheduler.step()\u0020
total_loss\u0020+=\u0020loss.item()\u0020*\u0020text.size(0)\u0020
preds\u0020=\u0020logits.argmax(dim=1)\u0020
total_correct\u0020+=\u0020(preds\u0020==\u0020labels).sum().item()\u0020
avg_loss\u0020=\u0020total_loss\u0020/\u0020len(train_loader.dataset)\u0020
accuracy\u0020=\u0020total_correct\u0020/\u0020len(train_loader.dataset)\u0020
return\u0020avg_loss, accuracy\u0020
def\u0020evaluate(model, iterator, criterion): epoch_loss\u0020=\u00200 epoch_acc\u0020=\u00200
model.eval()
with\u0020torch.no_grad():
for\u0020batch\u0020in\u0020iterator:
#text, text_lengths\u0020=\u0020batch.text
#text\u0020=\u0020batch.text
#labels\u0020=\u0020batch.label
text, labels\u0020=\u0020batch.text.to(device), batch.label.to(device)\u0020
predictions\u0020=\u0020model(text)
loss\u0020=\u0020criterion(predictions, batch.label)
acc\u0020=\u0020accuracy(predictions, batch.label)
epoch_loss\u0020+=\u0020loss.item()
epoch_acc\u0020+=\u0020acc.item()
return\u0020epoch_loss\u0020/\u0020len(iterator), epoch_acc\u0020/\u0020len(iterator)
def\u0020accuracy(predictions, labels): _, predicted_labels\u0020=\u0020torch.max(predictions, 1) correct\u0020=\u0020(predicted_labels\u0020==\u0020labels).float() accuracy\u0020=\u0020correct.sum()\u0020/\u0020len(correct) return\u0020accuracy
#\u0020Define\u0020evaluation\u0020function\u0020 def\u0020evaluate1(model, iterator, criterion):\u0020 epoch_loss\u0020=\u00200\u0020 epoch_acc\u0020=\u00200\u0020 model.eval()\u0020 with\u0020torch.no_grad():\u0020 for\u0020batch\u0020in\u0020iterator:\u0020 text, text_lengths\u0020=\u0020batch.text\u0020 predictions\u0020=\u0020model(text, text_lengths).squeeze(1)\u0020 loss\u0020=\u0020criterion(predictions, batch.label)\u0020 acc\u0020=\u0020(predictions.argmax(1)\u0020==\u0020batch.label).float().mean()\u0020 epoch_loss\u0020+=\u0020loss.item()\u0020 epoch_acc\u0020+=\u0020acc.item()\u0020 return\u0020epoch_loss\u0020/\u0020len(iterator), epoch_acc\u0020/\u0020len(iterator) class\u0020RNNClassifier(nn.Module):\u0020 def\u0020__init__(self, vocab_size, embedding_dim, hidden_dim, label_size, padding_idx):\u0020 super(RNNClassifier, self).init()\u0020 self.vocab_size\u0020=\u0020vocab_size\u0020 self.embedding_dim\u0020=\u0020embedding_dim\u0020 self.hidden_dim\u0020=\u0020hidden_dim\u0020 self.label_size\u0020=\u0020label_size\u0020 self.num_layers\u0020=\u00202\u0020#\u0020change\u0020the\u0020number\u0020of\u0020layers\u0020here\u0020 self.dropout_num\u0020=\u00200.5 self.dropout\u0020=\u0020nn.Dropout(0.5)\u0020#\u0020add\u0020dropout\u0020layer\u0020 self.bidirectional=False
#\u0020Embedding\u0020Layer\u0020
self.embedding\u0020=\u0020nn.Embedding(vocab_size, embedding_dim, padding_idx=padding_idx)\u0020
self.embedding_dropout\u0020=\u0020nn.Dropout(self.dropout_num)\u0020#\u0020add\u0020embedding\u0020dropout\u0020layer\u0020
#\u0020LSTM\u0020Layer\u0020
self.lstm\u0020=\u0020nn.LSTM(embedding_dim, hidden_dim, num_layers=self.num_layers, batch_first=True,bidirectional=self.bidirectional)\u0020
self.lstm_dropout\u0020=\u0020nn.Dropout(self.dropout_num)\u0020#\u0020add\u0020lstm\u0020dropout\u0020layer\u0020
#\u0020Fully\u0020Connected\u0020Layer\u0020
self.fc\u0020=\u0020nn.Linear(hidden_dim, label_size)\u0020
self.fc_dropout\u0020=\u0020nn.Dropout(self.dropout_num)\u0020#\u0020add\u0020fc\u0020dropout\u0020layer\u0020
self.softmax\u0020=\u0020nn.LogSoftmax(dim=1)
def\u0020zero_state(self, batch_size):\u0020
#hidden\u0020=\u0020torch.zeros(1, batch_size, self.hidden_dim) #\u0020change\u0020from\u00202-D\u0020to\u00203-D\u0020(num_layers=1\u0020here)\u0020
#cell\u0020=\u0020torch.zeros(1, batch_size, self.hidden_dim)\u0020
hidden\u0020=\u0020torch.zeros(self.num_layers, batch_size, self.hidden_dim)\u0020
cell\u0020=\u0020torch.zeros(self.num_layers, batch_size, self.hidden_dim)\u0020
return\u0020hidden, cell\u0020
def\u0020forward(self, text):\u0020
#\u0020text\u0020shape\u0020=\u0020[batch_size, seq_len]\u0020
#\u0020Embedding\u0020
emb\u0020=\u0020self.embedding(text)\u0020#\u0020shape\u0020=\u0020[batch_size, seq_len, embedding_dim]\u0020
emb\u0020=\u0020self.embedding_dropout(emb)\u0020#\u0020apply\u0020dropout\u0020on\u0020embedding\u0020
emb\u0020=\u0020torch.mean(emb, dim=1)\u0020#\u0020mean\u0020pooling\u0020over\u0020time\u0020step\u0020
#\u0020LSTM\u0020Layer\u0020
h0, c0\u0020=\u0020self.zero_state(text.size(0))\u0020#\u0020shape\u0020=\u0020[num_layers, batch_size, hidden_dim]\u0020
output, (hn, cn)\u0020=\u0020self.lstm(emb.unsqueeze(1), (h0, c0))\u0020#\u0020add\u0020unsqueeze\u0020to\u0020convert\u00202-D\u0020to\u00203-D\u0020
output\u0020=\u0020self.lstm_dropout(output)\u0020#\u0020apply\u0020dropout\u0020on\u0020output\u0020of\u0020lstm\u0020
#\u0020Fully\u0020Connected\u0020Layer\u0020
output\u0020=\u0020torch.mean(output, dim=1)\u0020#\u0020mean\u0020pooling\u0020over\u0020time\u0020step\u0020
output\u0020=\u0020self.fc(output)\u0020#\u0020pass\u0020through\u0020fully\u0020connected\u0020layer\u0020
output\u0020=\u0020self.fc_dropout(output)\u0020#\u0020apply\u0020dropout\u0020on\u0020output\u0020of\u0020fc\u0020layer\u0020
#output\u0020=\u0020self.softmax(output)
return\u0020output
model\u0020=\u0020RNNClassifier(vocab_size, embedding_dim, hidden_dim, label_size,padding_idx).to(device)\u0020 #optimizer\u0020=\u0020optim.SGD(model.parameters(), lr=0.01)\u0020#\u0020Use\u0020SGD\u0020optimizer\u0020for\u0020now\u0020 optimizer\u0020=\u0020optim.Adam(model.parameters(), lr=0.001)\u0020
scheduler\u0020=\u0020optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.8)\u0020
#criterion\u0020=\u0020nn.NLLLoss()\u0020 criterion\u0020=\u0020nn.CrossEntropyLoss() num_epochs\u0020=\u002010 #Define\u0020the\u0020loss\u0020value\u0020and\u0020precision\u0020value\u0020in\u0020the\u0020process\u0020of\u0020model\u0020training\u0020and\u0020verification, which\u0020is\u0020convenient\u0020to\u0020use\u0020Plot\u0020output\u0020later train_losses\u0020=\u0020[] val_losses\u0020=\u0020[] train_accs\u0020=\u0020[] val_accs\u0020=\u0020[] def\u0020model_running(model,train_iter, val_iter,optimizer, criterion): best_val_acc\u0020=\u00200.0\u0020 for\u0020epoch\u0020in\u0020range(1,num_epochs+1): train_acc\u0020=\u00200.0 train_loss\u0020=\u00200.0 val_acc\u0020=\u00200.0 val_loss\u0020=\u00200.0 test_acc\u0020=\u00200.0 test_loss\u0020=\u00200.0
#Call\u0020the\u0020training\u0020function,train\u0020the\u0020model, and\u0020return\u0020train_loss,train_acc
train_loss, train_acc\u0020=\u0020train(model, train_iter, optimizer, criterion)
val_loss, val_acc\u0020=\u0020evaluate(model, val_iter, criterion)
#\u0020Print\u0020progress
print('Epoch\u0020[{}/{}], Train Loss: {:.4f}, Val Loss: {:.4f}, Train Acc: {:.4f}, Val Acc: {:.4f}'\n .format(epoch, num_epochs, train_loss, val_loss, train_acc, val_acc))
#\u0020Save\u0020loss\u0020and\u0020accuracy\u0020to\u0020list
train_losses.append(train_loss)
val_losses.append(val_loss)
train_accs.append(train_acc)
val_accs.append(val_acc)
if\u0020val_acc\u0020>\u0020best_val_acc:\u0020
best_val_acc\u0020=\u0020val_acc\u0020
best_model\u0020=\u0020model.state_dict()\u0020
return\u0020best_model
best_model\u0020=\u0020model_running(model,train_iter, val_iter,optimizer, criterion) #\u0020Load\u0020the\u0020best\u0020model\u0020 model.load_state_dict(best_model)\u0020
#\u0020Test\u0020the\u0020model\u0020on\u0020the\u0020test\u0020set\u0020 test_loss, test_acc\u0020=\u0020evaluate(model, test_iter, criterion)\u0020 print(f"Test loss: {test_loss:.4f}, Test accuracy: {test_acc:.4f}") 基于以上模型,运行结果如下: Epoch\u0020[1/10], Train Loss: 1.0701, Val Loss: 1.0404, Train Acc: 0.4080, Val Acc: 0.4900 Epoch\u0020[2/10], Train Loss: 1.0525, Val Loss: 1.0063, Train Acc: 0.4533, Val Acc: 0.5110 Epoch\u0020[3/10], Train Loss: 1.0319, Val Loss: 0.9688, Train Acc: 0.4913, Val Acc: 0.5405 Epoch\u0020[4/10], Train Loss: 1.0115, Val Loss: 0.9493, Train Acc: 0.5191, Val Acc: 0.5609 Epoch\u0020[5/10], Train Loss: 0.9717, Val Loss: 0.9377, Train Acc: 0.5495, Val Acc: 0.5788 Epoch\u0020[6/10], Train Loss: 0.9407, Val Loss: 0.9144, Train Acc: 0.5676, Val Acc: 0.5931 Epoch\u0020[7/10], Train Loss: 0.9258, Val Loss: 0.9144, Train Acc: 0.5853, Val Acc: 0.5975 Epoch\u0020[8/10], Train Loss: 0.9043, Val Loss: 0.9213, Train Acc: 0.5923, Val Acc: 0.6020 Epoch\u0020[9/10], Train Loss: 0.8723, Val Loss: 0.9296, Train Acc: 0.6099, Val Acc: 0.6029 Epoch\u0020[10/10], Train Loss: 0.8502, Val Loss: 0.9231, Train Acc: 0.6210, Val Acc: 0.5979 Test loss: 0.8969, Test accuracy: 0.6121 基于以上代码和结果,请用Word2Vec训练词向量内容:To train word embeddings using Word2Vec, you can modify the code as follows:
1.\u0020Import\u0020the\u0020Word2Vec\u0020class\u0020from\u0020the\u0020gensim\u0020library:
from\u0020gensim.models\u0020import\u0020Word2Vec
2.\u0020Train\u0020the\u0020Word2Vec\u0020model\u0020on\u0020your\u0020text\u0020data:
sentences\u0020=\u0020[sentence.split()\u0020for\u0020sentence\u0020in\u0020train_data.text]
w2v_model\u0020=\u0020Word2Vec(sentences, size=embedding_dim, window=5, min_count=1, workers=4)
Here, sentences is a list of tokenized sentences from your training data. The size parameter specifies the dimensionality of the word embeddings. The window parameter determines the size of the context window for the word2vec model. The min_count parameter specifies the minimum frequency of a word to be included in the vocabulary. The workers parameter determines the number of parallel processes to use for training.
3.\u0020Initialize\u0020the\u0020embedding\u0020layer\u0020of\u0020your\u0020model\u0020with\u0020the\u0020pre-trained\u0020word\u0020embeddings:
pretrained_embeddings\u0020=\u0020w2v_model.wv.vectors
model.embedding.weight.data.copy_(torch.from_numpy(pretrained_embeddings))
Here, w2v_model.wv.vectors returns the pre-trained word embeddings as a numpy array, which is then converted to a PyTorch tensor and assigned to the embedding layer of your model.
4.\u0020Train\u0020your\u0020model\u0020as\u0020before:
best_model\u0020=\u0020model_running(model, train_iter, val_iter, optimizer, criterion)
Note that you may need to adjust the hyperparameters of the Word2Vec model, such as size, window, and min_count, to obtain better word embeddings.
Also, keep in mind that training word embeddings using Word2Vec can be computationally expensive, especially if you have a large vocabulary or a large training dataset. In such cases, you may consider using pre-trained word embeddings such as GloVe or FastText instead.
原文地址: https://www.cveoy.top/t/topic/peYv 著作权归作者所有。请勿转载和采集!