Sentiment Analysis with PyTorch RNN: A Comprehensive Tutorial
import\u0020torch\nimport\u0020torch.nn\u0020as\u0020nn\nimport\u0020torch.optim\u0020as\u0020optim\nfrom\u0020torchtext.datasets\u0020import\u0020SST\nfrom\u0020torchtext.data\u0020import\u0020Field,\u0020LabelField,\u0020BucketIterator\nfrom\u0020torchtext.vocab\u0020import\u0020GloVe\n\n#\u0020Step\u00201:\u0020Load\u0020Data\n#\u0020Define\u0020the\u0020fields\u0020for\u0020the\u0020dataset\ntext_field\u0020=\u0020Field(lower=True,\u0020include_lengths=True,\u0020batch_first=True)\nlabel_field\u0020=\u0020LabelField()\n\n#\u0020Download\u0020the\u0020SST\u0020dataset\u0020and\u0020split\u0020it\u0020into\u0020training/validation/test\u0020sets\ntrain_data,\u0020val_data,\u0020test_data\u0020=\u0020SST.splits(text_field,\u0020label_field)\n\n#\u0020Build\u0020the\u0020vocabulary\ntext_field.build_vocab(train_data,\u0020vectors=GloVe(name='6B',\u0020dim=300))\nlabel_field.build_vocab(train_data)\n\n#\u0020Define\u0020hyperparameters\nbatch_size\u0020=\u002064\nembedding_dim\u0020=\u0020300\nhidden_dim\u0020=\u0020128\nnum_layers\u0020=\u00201\nlabel_size\u0020=\u0020len(label_field.vocab)\n\n#\u0020Build\u0020iterators\u0020for\u0020the\u0020datasets\ntrain_iter,\u0020val_iter,\u0020test_iter\u0020=\u0020BucketIterator.splits(\n (train_data,\u0020val_data,\u0020test_data),\n batch_size=batch_size,\n sort_key=lambda\u0020x:\u0020len(x.text),\n sort_within_batch=True\n)\n\n#\u0020Step\u00202:\u0020Define\u0020the\u0020RNN\u0020Model\nclass\u0020RNNModel(nn.Module):\n def\u0020__init__(self,\u0020vocab_size,\u0020embedding_dim,\u0020hidden_dim,\u0020num_layers,\u0020label_size):\n super(RNNModel,\u0020self).init()\n self.embedding\u0020=\u0020nn.Embedding(vocab_size,\u0020embedding_dim)\n self.rnn\u0020=\u0020nn.RNN(embedding_dim,\u0020hidden_dim,\u0020num_layers,\u0020batch_first=True)\n self.fc\u0020=\u0020nn.Linear(hidden_dim,\u0020label_size)\n \n def\u0020forward(self,\u0020x,\u0020lengths):\n embedded\u0020=\u0020self.embedding(x)\n packed\u0020=\u0020nn.utils.rnn.pack_padded_sequence(embedded,\u0020lengths,\u0020batch_first=True)\n output,\u0020_\u0020=\u0020self.rnn(packed)\n output,\u0020_\u0020=\u0020nn.utils.rnn.pad_packed_sequence(output,\u0020batch_first=True)\n last_output\u0020=\u0020output[:,\u0020-1,\u0020:]\n out\u0020=\u0020self.fc(last_output)\n return\u0020out\n\n#\u0020Step\u00203:\u0020Training\u0020and\u0020Evaluation\u0020Functions\ndef\u0020train(model,\u0020iterator,\u0020optimizer,\u0020criterion):\n model.train()\n \n epoch_loss\u0020=\u00200\n epoch_acc\u0020=\u00200\n \n for\u0020batch\u0020in\u0020iterator:\n optimizer.zero_grad()\n \n text,\u0020text_lengths\u0020=\u0020batch.text\n predictions\u0020=\u0020model(text,\u0020text_lengths).squeeze(1)\n \n loss\u0020=\u0020criterion(predictions,\u0020batch.label)\n acc\u0020=\u0020calculate_accuracy(predictions,\u0020batch.label)\n \n loss.backward()\n optimizer.step()\n \n epoch_loss\u0020+=\u0020loss.item()\n epoch_acc\u0020+=\u0020acc.item()\n \n return\u0020epoch_loss\u0020/\u0020len(iterator),\u0020epoch_acc\u0020/\u0020len(iterator)\n\ndef\u0020evaluate(model,\u0020iterator,\u0020criterion):\n model.eval()\n \n epoch_loss\u0020=\u00200\n epoch_acc\u0020=\u00200\n \n with\u0020torch.no_grad():\n for\u0020batch\u0020in\u0020iterator:\n text,\u0020text_lengths\u0020=\u0020batch.text\n predictions\u0020=\u0020model(text,\u0020text_lengths).squeeze(1)\n \n loss\u0020=\u0020criterion(predictions,\u0020batch.label)\n acc\u0020=\u0020calculate_accuracy(predictions,\u0020batch.label)\n \n epoch_loss\u0020+=\u0020loss.item()\n epoch_acc\u0020+=\u0020acc.item()\n \n return\u0020epoch_loss\u0020/\u0020len(iterator),\u0020epoch_acc\u0020/\u0020len(iterator)\n\ndef\u0020calculate_accuracy(predictions,\u0020labels):\n rounded_preds\u0020=\u0020torch.round(torch.sigmoid(predictions))\n correct\u0020=\u0020(rounded_preds\u0020==\u0020labels).float()\n acc\u0020=\u0020correct.sum()\u0020/\u0020len(correct)\n return\u0020acc\n\n#\u0020Step\u00204:\u0020Train\u0020the\u0020Model\nmodel\u0020=\u0020RNNModel(len(text_field.vocab),\u0020embedding_dim,\u0020hidden_dim,\u0020num_layers,\u0020label_size)\noptimizer\u0020=\u0020optim.Adam(model.parameters())\ncriterion\u0020=\u0020nn.BCEWithLogitsLoss()\n\n#\u0020Training\u0020loop\nnum_epochs\u0020=\u002010\nbest_val_loss\u0020=\u0020float('inf')\n\nfor\u0020epoch\u0020in\u0020range(num_epochs):\n train_loss,\u0020train_acc\u0020=\u0020train(model,\u0020train_iter,\u0020optimizer,\u0020criterion)\n val_loss,\u0020val_acc\u0020=\u0020evaluate(model,\u0020val_iter,\u0020criterion)\n \n if\u0020val_loss\u0020<\u0020best_val_loss:\n best_val_loss\u0020=\u0020val_loss\n torch.save(model.state_dict(),\u0020'best_model.pt')\n \n print(f'Epoch:\u0020{epoch+1:02}')\n print(f' Train\u0020Loss:\u0020{train_loss:.3f}\u0020|\u0020Train\u0020Acc:\u0020{train_acc100:.2f}%')\n print(f' \u0020Val.\u0020Loss:\u0020{val_loss:.3f}\u0020|\u0020\u0020Val.\u0020Acc:\u0020{val_acc100:.2f}%')\n\n#\u0020Step\u00205:\u0020Train\u0020a\u0020Model\u0020with\u0020Better\u0020Accuracy\n#\u0020You\u0020can\u0020try\u0020different\u0020optimizers,\u0020learning\u0020rates,\u0020hidden\u0020layer\u0020dimensions,\u0020etc.\u0020to\u0020improve\u0020the\u0020accuracy\u0020of\u0020the\u0020model.
原文地址: https://www.cveoy.top/t/topic/o61f 著作权归作者所有。请勿转载和采集!