Skip to content

Instantly share code, notes, and snippets.

@georgehc
Last active April 22, 2022 06:26
Show Gist options
  • Save georgehc/92970a9470dbddd2086797691e6ce85a to your computer and use it in GitHub Desktop.
Save georgehc/92970a9470dbddd2086797691e6ce85a to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 94-775/95-865: Sentiment Analysis with IMDb Reviews\n",
"\n",
"Author: George H. Chen (georgechen [at symbol] cmu.edu)\n",
"\n",
"This demo shows how to train an LSTM model for sentiment analysis with IMDB reviews. This is a binary classification task: for each review, we classify it as having positive or negative sentiment."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import random\n",
"\n",
"# the next two lines are needed on my Intel-based MacBook Air to get the code to run; you likely don't need these two lines...\n",
"# (in fact I used to not need these two lines)\n",
"import os\n",
"os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'\n",
"\n",
"import torch\n",
"torch.use_deterministic_algorithms(True)\n",
"torch.backends.cudnn.benchmark = False\n",
"import torch.nn as nn\n",
"from torchsummaryX import summary\n",
"\n",
"from UDA_pytorch_utils import UDA_LSTMforSequential, UDA_pytorch_classifier_fit, \\\n",
" UDA_plot_train_val_accuracy_vs_epoch, UDA_pytorch_classifier_predict, \\\n",
" UDA_compute_accuracy\n",
"\n",
"np.random.seed(0)\n",
"torch.manual_seed(0)\n",
"random.seed(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load the dataset"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<torch._C.Generator at 0x7fcf16b70d70>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from torchnlp.datasets import imdb_dataset\n",
"torch.manual_seed(0)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"train_dataset = imdb_dataset(train=True)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"25000"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(train_dataset)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"proper_train_size = int(len(train_dataset) * 0.8)\n",
"val_size = len(train_dataset) - proper_train_size"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"proper_train_dataset, val_dataset = torch.utils.data.random_split(train_dataset,\n",
" [proper_train_size,\n",
" val_size])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'text': '\"Heartland\" is a wonderful depiction of what it was really like to live on the frontier. The hard work and individual strength that were needed to survive the hardships of the climate and the lack of medical care are blended with the camaraderie and the interdependence of the settlers. The drama was especially meaningful because the story is based on the diaries of real people whose descendants still live there. It was also nice to see the west inhabited by real people. No one was glamorous or looked as if they had just spent a session with the makeup or costume department. Conchatta Ferrell is just wonderful. She is an example of the strong, persevering people who came to Wyoming in the early 20th century and let no hardship stand in their way of a new life in a new land.',\n",
" 'sentiment': 'pos'}"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"proper_train_dataset[1]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"from torchnlp.encoders.text import SpacyEncoder"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"encoder = SpacyEncoder([data['text'] for data in proper_train_dataset])"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"proper_train_encoded = [encoder.encode(data['text']) for data in proper_train_dataset]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([ 5, 266, 5, 50, 14, 267, 268, 37, 22, 87, 88, 70, 269, 23,\n",
" 270, 33, 47, 271, 16, 6, 272, 273, 31, 274, 275, 109, 276, 277,\n",
" 23, 278, 47, 279, 37, 47, 280, 31, 47, 281, 37, 282, 283, 284,\n",
" 285, 85, 47, 286, 31, 47, 287, 37, 47, 288, 16, 6, 289, 88,\n",
" 290, 291, 130, 47, 292, 50, 32, 33, 47, 293, 37, 294, 295, 210,\n",
" 296, 297, 270, 206, 16, 298, 88, 299, 300, 23, 301, 47, 302, 303,\n",
" 27, 294, 295, 16, 304, 36, 88, 305, 306, 307, 13, 308, 185, 18,\n",
" 309, 310, 14, 311, 85, 47, 312, 306, 313, 314, 16, 315, 316, 50,\n",
" 309, 267, 16, 232, 50, 98, 317, 37, 47, 134, 30, 318, 295, 132,\n",
" 11, 23, 319, 12, 47, 320, 321, 322, 31, 323, 19, 324, 325, 12,\n",
" 223, 181, 37, 14, 326, 67, 12, 14, 326, 327, 16])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"proper_train_encoded[1]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['\"', 'Heartland', '\"', 'is', 'a', 'wonderful', 'depiction', 'of', 'what', 'it', 'was', 'really', 'like', 'to', 'live', 'on', 'the', 'frontier', '.', 'The', 'hard', 'work', 'and', 'individual', 'strength', 'that', 'were', 'needed', 'to', 'survive', 'the', 'hardships', 'of', 'the', 'climate', 'and', 'the', 'lack', 'of', 'medical', 'care', 'are', 'blended', 'with', 'the', 'camaraderie', 'and', 'the', 'interdependence', 'of', 'the', 'settlers', '.', 'The', 'drama', 'was', 'especially', 'meaningful', 'because', 'the', 'story', 'is', 'based', 'on', 'the', 'diaries', 'of', 'real', 'people', 'whose', 'descendants', 'still', 'live', 'there', '.', 'It', 'was', 'also', 'nice', 'to', 'see', 'the', 'west', 'inhabited', 'by', 'real', 'people', '.', 'No', 'one', 'was', 'glamorous', 'or', 'looked', 'as', 'if', 'they', 'had', 'just', 'spent', 'a', 'session', 'with', 'the', 'makeup', 'or', 'costume', 'department', '.', 'Conchatta', 'Ferrell', 'is', 'just', 'wonderful', '.', 'She', 'is', 'an', 'example', 'of', 'the', 'strong', ',', 'persevering', 'people', 'who', 'came', 'to', 'Wyoming', 'in', 'the', 'early', '20th', 'century', 'and', 'let', 'no', 'hardship', 'stand', 'in', 'their', 'way', 'of', 'a', 'new', 'life', 'in', 'a', 'new', 'land', '.']\n"
]
}
],
"source": [
"print([encoder.vocab[word_idx] for word_idx in proper_train_encoded[1]])"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"proper_train_labels = torch.tensor([int(data['sentiment'] == 'pos')\n",
" for data in proper_train_dataset])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"val_encoded = [encoder.encode(data['text']) for data in val_dataset]"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"val_labels = torch.tensor([int(data['sentiment'] == 'pos') for data in val_dataset])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"proper_train_dataset_encoded = list(zip(proper_train_encoded, proper_train_labels))\n",
"val_dataset_encoded = list(zip(val_encoded, val_labels))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setting up a recurrent neural net for sentiment analysis that uses pre-trained word embeddings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We first load in pre-trained GloVe embeddings only for tokens that we encountered in the proper training data."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"from torchnlp.word_to_vector import GloVe\n",
"pretrained_embedding = GloVe(name='6B', dim=100)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"torchnlp.word_to_vector.glove.GloVe"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(pretrained_embedding)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([ 0.2309, 0.2828, 0.6318, -0.5941, -0.5860, 0.6326, 0.2440, -0.1411,\n",
" 0.0608, -0.7898, -0.2910, 0.1429, 0.7227, 0.2043, 0.1407, 0.9876,\n",
" 0.5253, 0.0975, 0.8822, 0.5122, 0.4020, 0.2117, -0.0131, -0.7162,\n",
" 0.5539, 1.1452, -0.8804, -0.5022, -0.2281, 0.0239, 0.1072, 0.0837,\n",
" 0.5501, 0.5848, 0.7582, 0.4571, -0.2800, 0.2522, 0.6896, -0.6097,\n",
" 0.1958, 0.0442, -0.3114, -0.6883, -0.2272, 0.4618, -0.7716, 0.1021,\n",
" 0.5564, 0.0674, -0.5721, 0.2374, 0.4717, 0.8277, -0.2926, -1.3422,\n",
" -0.0993, 0.2814, 0.4160, 0.1058, 0.6220, 0.8950, -0.2345, 0.5135,\n",
" 0.9938, 1.1846, -0.1636, 0.2065, 0.7385, 0.2406, -0.9647, 0.1348,\n",
" -0.0072, 0.3302, -0.1236, 0.2719, -0.4095, 0.0219, -0.6069, 0.4076,\n",
" 0.1957, -0.4180, 0.1864, -0.0327, -0.7857, -0.1385, 0.0440, -0.0844,\n",
" 0.0491, 0.2410, 0.4527, -0.1868, 0.4618, 0.0891, -0.1819, -0.0152,\n",
" -0.7368, -0.1453, 0.1510, -0.7149])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pretrained_embedding['cat']"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"embedding_weights = torch.empty(encoder.vocab_size, pretrained_embedding.dim)\n",
"for i, token in enumerate(encoder.vocab):\n",
" embedding_weights[i] = pretrained_embedding[token]"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"simple_lstm_model = nn.Sequential(nn.Embedding.from_pretrained(embedding_weights),\n",
" UDA_LSTMforSequential(100, 64),\n",
" nn.Linear(64, 2))"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"==============================================================\n",
" Kernel Shape Output Shape Params Mult-Adds\n",
"Layer \n",
"0_0 [100, 108380] [1, 5, 100] - -\n",
"1_1.LSTM_model - [1, 5, 64] 42.496k 41.984k\n",
"2_2 [64, 2] [1, 2] 130.0 128.0\n",
"--------------------------------------------------------------\n",
" Totals\n",
"Total params 10.880626M\n",
"Trainable params 42.626k\n",
"Non-trainable params 10.838M\n",
"Mult-Adds 42.112k\n",
"==============================================================\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/georgehc/opt/anaconda3/lib/python3.9/site-packages/torchsummaryX/torchsummaryX.py:101: FutureWarning: Dropping of nuisance columns in DataFrame reductions (with 'numeric_only=None') is deprecated; in a future version this will raise TypeError. Select only valid columns before calling the reduction.\n",
" df_sum = df.sum()\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Kernel Shape</th>\n",
" <th>Output Shape</th>\n",
" <th>Params</th>\n",
" <th>Mult-Adds</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Layer</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0_0</th>\n",
" <td>[100, 108380]</td>\n",
" <td>[1, 5, 100]</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1_1.LSTM_model</th>\n",
" <td>-</td>\n",
" <td>[1, 5, 64]</td>\n",
" <td>42496.0</td>\n",
" <td>41984.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2_2</th>\n",
" <td>[64, 2]</td>\n",
" <td>[1, 2]</td>\n",
" <td>130.0</td>\n",
" <td>128.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Kernel Shape Output Shape Params Mult-Adds\n",
"Layer \n",
"0_0 [100, 108380] [1, 5, 100] NaN NaN\n",
"1_1.LSTM_model - [1, 5, 64] 42496.0 41984.0\n",
"2_2 [64, 2] [1, 2] 130.0 128.0"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"summary(simple_lstm_model, torch.zeros((1, 5), dtype=torch.long))"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"os.makedirs('./saved_model_checkpoints', exist_ok=True)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1 [==================================================] 20000/20000\n",
" Train accuracy: 0.7994\n",
" Validation accuracy: 0.7858\n",
"Epoch 2 [==================================================] 20000/20000\n",
" Train accuracy: 0.8462\n",
" Validation accuracy: 0.8366\n",
"Epoch 3 [==================================================] 20000/20000\n",
" Train accuracy: 0.7997\n",
" Validation accuracy: 0.8016\n",
"Epoch 4 [==================================================] 20000/20000\n",
" Train accuracy: 0.8569\n",
" Validation accuracy: 0.8384\n",
"Epoch 5 [==================================================] 20000/20000\n",
" Train accuracy: 0.8820\n",
" Validation accuracy: 0.8564\n",
"Epoch 6 [==================================================] 20000/20000\n",
" Train accuracy: 0.8926\n",
" Validation accuracy: 0.8630\n",
"Epoch 7 [==================================================] 20000/20000\n",
" Train accuracy: 0.9039\n",
" Validation accuracy: 0.8660\n",
"Epoch 8 [==================================================] 20000/20000\n",
" Train accuracy: 0.9005\n",
" Validation accuracy: 0.8550\n",
"Epoch 9 [==================================================] 20000/20000\n",
" Train accuracy: 0.9098\n",
" Validation accuracy: 0.8620\n",
"Epoch 10 [==================================================] 20000/20000\n",
" Train accuracy: 0.9137\n",
" Validation accuracy: 0.8582\n",
"Epoch 11 [==================================================] 20000/20000\n",
" Train accuracy: 0.9261\n",
" Validation accuracy: 0.8642\n",
"Epoch 12 [==================================================] 20000/20000\n",
" Train accuracy: 0.8894\n",
" Validation accuracy: 0.8336\n",
"Epoch 13 [==================================================] 20000/20000\n",
" Train accuracy: 0.8931\n",
" Validation accuracy: 0.8348\n",
"Epoch 14 [==================================================] 20000/20000\n",
" Train accuracy: 0.9063\n",
" Validation accuracy: 0.8432\n",
"Epoch 15 [==================================================] 20000/20000\n",
" Train accuracy: 0.9162\n",
" Validation accuracy: 0.8394\n",
"Epoch 16 [==================================================] 20000/20000\n",
" Train accuracy: 0.9360\n",
" Validation accuracy: 0.8518\n",
"Epoch 17 [==================================================] 20000/20000\n",
" Train accuracy: 0.9447\n",
" Validation accuracy: 0.8512\n",
"Epoch 18 [==================================================] 20000/20000\n",
" Train accuracy: 0.9563\n",
" Validation accuracy: 0.8556\n",
"Epoch 19 [==================================================] 20000/20000\n",
" Train accuracy: 0.9465\n",
" Validation accuracy: 0.8524\n",
"Epoch 20 [==================================================] 20000/20000\n",
" Train accuracy: 0.9460\n",
" Validation accuracy: 0.8528\n",
"Epoch 21 [==================================================] 20000/20000\n",
" Train accuracy: 0.9439\n",
" Validation accuracy: 0.8560\n",
"Epoch 22 [==================================================] 20000/20000\n",
" Train accuracy: 0.9558\n",
" Validation accuracy: 0.8544\n",
"Epoch 23 [==================================================] 20000/20000\n",
" Train accuracy: 0.9454\n",
" Validation accuracy: 0.8510\n",
"Epoch 24 [==================================================] 20000/20000\n",
" Train accuracy: 0.9471\n",
" Validation accuracy: 0.8504\n",
"Epoch 25 [==================================================] 20000/20000\n",
" Train accuracy: 0.9476\n",
" Validation accuracy: 0.8556\n",
"Epoch 26 [==================================================] 20000/20000\n",
" Train accuracy: 0.9560\n",
" Validation accuracy: 0.8582\n",
"Epoch 27 [==================================================] 20000/20000\n",
" Train accuracy: 0.9398\n",
" Validation accuracy: 0.8472\n",
"Epoch 28 [==================================================] 20000/20000\n",
" Train accuracy: 0.9518\n",
" Validation accuracy: 0.8534\n",
"Epoch 29 [==================================================] 20000/20000\n",
" Train accuracy: 0.9387\n",
" Validation accuracy: 0.8464\n",
"Epoch 30 [==================================================] 20000/20000\n",
" Train accuracy: 0.9544\n",
" Validation accuracy: 0.8534\n",
"Epoch 31 [==================================================] 20000/20000\n",
" Train accuracy: 0.9574\n",
" Validation accuracy: 0.8554\n",
"Epoch 32 [==================================================] 20000/20000\n",
" Train accuracy: 0.9596\n",
" Validation accuracy: 0.8554\n",
"Epoch 33 [==================================================] 20000/20000\n",
" Train accuracy: 0.9542\n",
" Validation accuracy: 0.8578\n",
"Epoch 34 [==================================================] 20000/20000\n",
" Train accuracy: 0.9518\n",
" Validation accuracy: 0.8508\n",
"Epoch 35 [==================================================] 20000/20000\n",
" Train accuracy: 0.8696\n",
" Validation accuracy: 0.8272\n",
"Epoch 36 [==================================================] 20000/20000\n",
" Train accuracy: 0.8936\n",
" Validation accuracy: 0.8430\n",
"Epoch 37 [==================================================] 20000/20000\n",
" Train accuracy: 0.9093\n",
" Validation accuracy: 0.8476\n",
"Epoch 38 [==================================================] 20000/20000\n",
" Train accuracy: 0.9222\n",
" Validation accuracy: 0.8458\n",
"Epoch 39 [==================================================] 20000/20000\n",
" Train accuracy: 0.9295\n",
" Validation accuracy: 0.8476\n",
"Epoch 40 [==================================================] 20000/20000\n",
" Train accuracy: 0.9372\n",
" Validation accuracy: 0.8506\n",
"Epoch 41 [==================================================] 20000/20000\n",
" Train accuracy: 0.7367\n",
" Validation accuracy: 0.6810\n",
"Epoch 42 [==================================================] 20000/20000\n",
" Train accuracy: 0.9170\n",
" Validation accuracy: 0.8328\n",
"Epoch 43 [==================================================] 20000/20000\n",
" Train accuracy: 0.9456\n",
" Validation accuracy: 0.8470\n",
"Epoch 44 [==================================================] 20000/20000\n",
" Train accuracy: 0.9530\n",
" Validation accuracy: 0.8470\n",
"Epoch 45 [==================================================] 20000/20000\n",
" Train accuracy: 0.9407\n",
" Validation accuracy: 0.8384\n",
"Epoch 46 [==================================================] 20000/20000\n",
" Train accuracy: 0.9494\n",
" Validation accuracy: 0.8460\n",
"Epoch 47 [==================================================] 20000/20000\n",
" Train accuracy: 0.9429\n",
" Validation accuracy: 0.8482\n",
"Epoch 48 [==================================================] 20000/20000\n",
" Train accuracy: 0.9415\n",
" Validation accuracy: 0.8514\n",
"Epoch 49 [==================================================] 20000/20000\n",
" Train accuracy: 0.9518\n",
" Validation accuracy: 0.8520\n",
"Epoch 50 [==================================================] 20000/20000\n",
" Train accuracy: 0.9278\n",
" Validation accuracy: 0.8412\n",
"Epoch 51 [==================================================] 20000/20000\n",
" Train accuracy: 0.9590\n",
" Validation accuracy: 0.8518\n",
"Epoch 52 [==================================================] 20000/20000\n",
" Train accuracy: 0.9423\n",
" Validation accuracy: 0.8502\n",
"Epoch 53 [==================================================] 20000/20000\n",
" Train accuracy: 0.9519\n",
" Validation accuracy: 0.8460\n",
"Epoch 54 [==================================================] 20000/20000\n",
" Train accuracy: 0.9586\n",
" Validation accuracy: 0.8506\n",
"Epoch 55 [==================================================] 20000/20000\n",
" Train accuracy: 0.9563\n",
" Validation accuracy: 0.8520\n",
"Epoch 56 [==================================================] 20000/20000\n",
" Train accuracy: 0.9650\n",
" Validation accuracy: 0.8550\n",
"Epoch 57 [==================================================] 20000/20000\n",
" Train accuracy: 0.8292\n",
" Validation accuracy: 0.8032\n",
"Epoch 58 [==================================================] 20000/20000\n",
" Train accuracy: 0.8671\n",
" Validation accuracy: 0.8268\n",
"Epoch 59 [==================================================] 20000/20000\n",
" Train accuracy: 0.8833\n",
" Validation accuracy: 0.8384\n",
"Epoch 60 [==================================================] 20000/20000\n",
" Train accuracy: 0.8973\n",
" Validation accuracy: 0.8440\n",
"Epoch 61 [==================================================] 20000/20000\n",
" Train accuracy: 0.9096\n",
" Validation accuracy: 0.8456\n",
"Epoch 62 [==================================================] 20000/20000\n",
" Train accuracy: 0.9206\n",
" Validation accuracy: 0.8430\n",
"Epoch 63 [==================================================] 20000/20000\n",
" Train accuracy: 0.5366\n",
" Validation accuracy: 0.5450\n",
"Epoch 64 [==================================================] 20000/20000\n",
" Train accuracy: 0.5177\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" Validation accuracy: 0.5242\n",
"Epoch 65 [==================================================] 20000/20000\n",
" Train accuracy: 0.7853\n",
" Validation accuracy: 0.7740\n",
"Epoch 66 [==================================================] 20000/20000\n",
" Train accuracy: 0.7916\n",
" Validation accuracy: 0.7798\n",
"Epoch 67 [==================================================] 20000/20000\n",
" Train accuracy: 0.6038\n",
" Validation accuracy: 0.6058\n",
"Epoch 68 [==================================================] 20000/20000\n",
" Train accuracy: 0.6278\n",
" Validation accuracy: 0.6210\n",
"Epoch 69 [==================================================] 20000/20000\n",
" Train accuracy: 0.6282\n",
" Validation accuracy: 0.6226\n",
"Epoch 70 [==================================================] 20000/20000\n",
" Train accuracy: 0.6432\n",
" Validation accuracy: 0.6380\n",
"Epoch 71 [==================================================] 20000/20000\n",
" Train accuracy: 0.6517\n",
" Validation accuracy: 0.6454\n",
"Epoch 72 [==================================================] 20000/20000\n",
" Train accuracy: 0.6606\n",
" Validation accuracy: 0.6588\n",
"Epoch 73 [==================================================] 20000/20000\n",
" Train accuracy: 0.6853\n",
" Validation accuracy: 0.6814\n",
"Epoch 74 [==================================================] 20000/20000\n",
" Train accuracy: 0.6931\n",
" Validation accuracy: 0.6976\n",
"Epoch 75 [==================================================] 20000/20000\n",
" Train accuracy: 0.6648\n",
" Validation accuracy: 0.6676\n",
"Epoch 76 [==================================================] 20000/20000\n",
" Train accuracy: 0.6708\n",
" Validation accuracy: 0.6724\n",
"Epoch 77 [==================================================] 20000/20000\n",
" Train accuracy: 0.6723\n",
" Validation accuracy: 0.6748\n",
"Epoch 78 [==================================================] 20000/20000\n",
" Train accuracy: 0.6737\n",
" Validation accuracy: 0.6738\n",
"Epoch 79 [==================================================] 20000/20000\n",
" Train accuracy: 0.6773\n",
" Validation accuracy: 0.6782\n",
"Epoch 80 [==================================================] 20000/20000\n",
" Train accuracy: 0.7423\n",
" Validation accuracy: 0.7400\n",
"Epoch 81 [==================================================] 20000/20000\n",
" Train accuracy: 0.6243\n",
" Validation accuracy: 0.6248\n",
"Epoch 82 [==================================================] 20000/20000\n",
" Train accuracy: 0.5303\n",
" Validation accuracy: 0.5370\n",
"Epoch 83 [==================================================] 20000/20000\n",
" Train accuracy: 0.5298\n",
" Validation accuracy: 0.5356\n",
"Epoch 84 [==================================================] 20000/20000\n",
" Train accuracy: 0.5288\n",
" Validation accuracy: 0.5366\n",
"Epoch 85 [==================================================] 20000/20000\n",
" Train accuracy: 0.5293\n",
" Validation accuracy: 0.5364\n",
"Epoch 86 [==================================================] 20000/20000\n",
" Train accuracy: 0.5314\n",
" Validation accuracy: 0.5394\n",
"Epoch 87 [==================================================] 20000/20000\n",
" Train accuracy: 0.5382\n",
" Validation accuracy: 0.5454\n",
"Epoch 88 [==================================================] 20000/20000\n",
" Train accuracy: 0.5468\n",
" Validation accuracy: 0.5506\n",
"Epoch 89 [==================================================] 20000/20000\n",
" Train accuracy: 0.5592\n",
" Validation accuracy: 0.5622\n",
"Epoch 90 [==================================================] 20000/20000\n",
" Train accuracy: 0.6414\n",
" Validation accuracy: 0.6362\n",
"Epoch 91 [==================================================] 20000/20000\n",
" Train accuracy: 0.7195\n",
" Validation accuracy: 0.7050\n",
"Epoch 92 [==================================================] 20000/20000\n",
" Train accuracy: 0.8198\n",
" Validation accuracy: 0.8044\n",
"Epoch 93 [==================================================] 20000/20000\n",
" Train accuracy: 0.8312\n",
" Validation accuracy: 0.8178\n",
"Epoch 94 [==================================================] 20000/20000\n",
" Train accuracy: 0.8362\n",
" Validation accuracy: 0.8210\n",
"Epoch 95 [==================================================] 20000/20000\n",
" Train accuracy: 0.8367\n",
" Validation accuracy: 0.8166\n",
"Epoch 96 [==================================================] 20000/20000\n",
" Train accuracy: 0.8436\n",
" Validation accuracy: 0.8236\n",
"Epoch 97 [==================================================] 20000/20000\n",
" Train accuracy: 0.8465\n",
" Validation accuracy: 0.8202\n",
"Epoch 98 [==================================================] 20000/20000\n",
" Train accuracy: 0.8445\n",
" Validation accuracy: 0.8180\n",
"Epoch 99 [==================================================] 20000/20000\n",
" Train accuracy: 0.8377\n",
" Validation accuracy: 0.8192\n",
"Epoch 100 [==================================================] 20000/20000\n",
" Train accuracy: 0.8393\n",
" Validation accuracy: 0.8182\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"num_epochs = 100 # during optimization, how many times we look at training data\n",
"batch_size = 64 # during optimization, how many training data to use at each step\n",
"learning_rate = 0.005 # during optimization, how much we nudge our solution at each step\n",
"\n",
"train_accuracies, val_accuracies = \\\n",
" UDA_pytorch_classifier_fit(simple_lstm_model,\n",
" torch.optim.Adam(simple_lstm_model.parameters(),\n",
" lr=learning_rate),\n",
" nn.CrossEntropyLoss(), # includes softmax\n",
" proper_train_dataset_encoded, val_dataset_encoded,\n",
" num_epochs, batch_size,\n",
" sequence=True,\n",
" save_epoch_checkpoint_prefix='./saved_model_checkpoints/imdb_lstm')\n",
"\n",
"UDA_plot_train_val_accuracy_vs_epoch(train_accuracies, val_accuracies)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The model at the end of epoch 7 achieved the highest validation accuracy: 0.866000\n"
]
},
{
"data": {
"text/plain": [
"<All keys matched successfully>"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"best_epoch_idx = np.argmax(val_accuracies)\n",
"print('The model at the end of epoch %d achieved the highest validation accuracy: %f'\n",
" % (best_epoch_idx + 1, val_accuracies[best_epoch_idx]))\n",
"simple_lstm_model.load_state_dict(torch.load('./saved_model_checkpoints/imdb_lstm_epoch%d.pt' % (best_epoch_idx + 1)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Finally evaluate on test data"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"test_dataset = imdb_dataset(train=False, test=True)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"test_encoded = [encoder.encode(data['text']) for data in test_dataset]"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"test_labels = torch.tensor([int(data['sentiment'] == 'pos') for data in test_dataset])"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"predicted_test_labels = UDA_pytorch_classifier_predict(simple_lstm_model,\n",
" test_encoded,\n",
" sequence=True)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test accuracy: 0.86952\n"
]
}
],
"source": [
"print('Test accuracy:', UDA_compute_accuracy(predicted_test_labels, test_labels))"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([1])"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"UDA_pytorch_classifier_predict(simple_lstm_model,\n",
" [encoder.encode('this movie rocks')],\n",
" sequence=True)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([0])"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"UDA_pytorch_classifier_predict(simple_lstm_model,\n",
" [encoder.encode('this movie sucks')],\n",
" sequence=True)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([0])"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"UDA_pytorch_classifier_predict(simple_lstm_model,\n",
" [encoder.encode('this sucks')],\n",
" sequence=True)"
]
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment