riyageorge commited on
Commit
51649e7
·
1 Parent(s): a82bbda

Upload 3 files

Browse files
gru_movie_model.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2b0fa91a9f80f4388c147f3b4a638fbbb30a6f99834dec25060420fde323afac
3
+ size 43126776
gru_movie_model.ipynb ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "#### Movie sentiment model - GRU"
8
+ ]
9
+ },
10
+ {
11
+ "cell_type": "code",
12
+ "execution_count": 1,
13
+ "metadata": {},
14
+ "outputs": [],
15
+ "source": [
16
+ "import pandas as pd\n",
17
+ "import matplotlib.pyplot as plt\n",
18
+ "import seaborn as sns\n",
19
+ "from numpy import asarray\n",
20
+ "from numpy import zeros\n",
21
+ "import tensorflow as tf\n",
22
+ "from sklearn.model_selection import train_test_split\n",
23
+ "from sklearn.metrics import classification_report, confusion_matrix, accuracy_score\n",
24
+ "import pickle"
25
+ ]
26
+ },
27
+ {
28
+ "cell_type": "code",
29
+ "execution_count": 2,
30
+ "metadata": {},
31
+ "outputs": [],
32
+ "source": [
33
+ "def getGloveEmbeddings(glovefolderpath):\n",
34
+ " print(\"---------------------- Getting Glove Embeddings -------------------------\\n\")\n",
35
+ " embeddings_dictionary = dict()\n",
36
+ " glove_file = open(f\"{glovefolderpath}\", encoding=\"utf8\")\n",
37
+ " for line in glove_file:\n",
38
+ " records = line.split()\n",
39
+ " word = records[0]\n",
40
+ " vector_dimensions = asarray(records[1:], dtype='float32')\n",
41
+ " embeddings_dictionary [word] = vector_dimensions\n",
42
+ " glove_file.close()\n",
43
+ " print(\"---------------------- -------------------------\\n\")\n",
44
+ " return embeddings_dictionary\n",
45
+ "\n",
46
+ "\n",
47
+ "glove_folder=r'D:/STUDY/Sem3/deeplearning/glove.6B/glove.6B.100d.txt'"
48
+ ]
49
+ },
50
+ {
51
+ "cell_type": "code",
52
+ "execution_count": 3,
53
+ "metadata": {},
54
+ "outputs": [],
55
+ "source": [
56
+ "maxlen = 100"
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "execution_count": 4,
62
+ "metadata": {},
63
+ "outputs": [],
64
+ "source": [
65
+ "dataset = pd.read_csv('movie_data.csv')\n",
66
+ "\n",
67
+ "X = dataset['review'].values\n",
68
+ "y = dataset['sentiment'].values"
69
+ ]
70
+ },
71
+ {
72
+ "cell_type": "code",
73
+ "execution_count": 5,
74
+ "metadata": {},
75
+ "outputs": [],
76
+ "source": [
77
+ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)"
78
+ ]
79
+ },
80
+ {
81
+ "cell_type": "code",
82
+ "execution_count": 6,
83
+ "metadata": {},
84
+ "outputs": [],
85
+ "source": [
86
+ "tokeniser = tf.keras.preprocessing.text.Tokenizer()\n",
87
+ "tokeniser.fit_on_texts(X_train)\n",
88
+ "\n",
89
+ "\n",
90
+ "# Save the tokenizer using pickle\n",
91
+ "with open('tokenizer_movie_gru.pickle', 'wb') as handle:\n",
92
+ " pickle.dump(tokeniser, handle, protocol=pickle.HIGHEST_PROTOCOL)\n",
93
+ "\n",
94
+ "\n",
95
+ "X_train = tokeniser.texts_to_sequences(X_train)\n",
96
+ "X_test = tokeniser.texts_to_sequences(X_test)\n",
97
+ "vocab_size = len(tokeniser.word_index) + 1\n",
98
+ "\n",
99
+ "X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, padding='post', maxlen=maxlen)\n",
100
+ "X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, padding='post', maxlen=maxlen)"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "code",
105
+ "execution_count": 7,
106
+ "metadata": {},
107
+ "outputs": [
108
+ {
109
+ "name": "stdout",
110
+ "output_type": "stream",
111
+ "text": [
112
+ "---------------------- Getting Glove Embeddings -------------------------\n",
113
+ "\n",
114
+ "---------------------- -------------------------\n",
115
+ "\n"
116
+ ]
117
+ }
118
+ ],
119
+ "source": [
120
+ "embeddings_dictionary=getGloveEmbeddings(glove_folder)\n",
121
+ "embedding_matrix = zeros((vocab_size, maxlen))\n",
122
+ "for word, index in tokeniser.word_index.items():\n",
123
+ " embedding_vector = embeddings_dictionary.get(word)\n",
124
+ " if embedding_vector is not None:\n",
125
+ " embedding_matrix[index] = embedding_vector"
126
+ ]
127
+ },
128
+ {
129
+ "cell_type": "code",
130
+ "execution_count": 8,
131
+ "metadata": {},
132
+ "outputs": [
133
+ {
134
+ "name": "stdout",
135
+ "output_type": "stream",
136
+ "text": [
137
+ "Model: \"sequential\"\n",
138
+ "_________________________________________________________________\n",
139
+ " Layer (type) Output Shape Param # \n",
140
+ "=================================================================\n",
141
+ " embedding (Embedding) (None, 100, 100) 10591700 \n",
142
+ " \n",
143
+ " gru (GRU) (None, 100) 60600 \n",
144
+ " \n",
145
+ " dense (Dense) (None, 1) 101 \n",
146
+ " \n",
147
+ "=================================================================\n",
148
+ "Total params: 10652401 (40.64 MB)\n",
149
+ "Trainable params: 60701 (237.11 KB)\n",
150
+ "Non-trainable params: 10591700 (40.40 MB)\n",
151
+ "_________________________________________________________________\n",
152
+ "None\n"
153
+ ]
154
+ }
155
+ ],
156
+ "source": [
157
+ "model=tf.keras.models.Sequential([\n",
158
+ " tf.keras.layers.Embedding(input_dim=vocab_size,output_dim= maxlen, weights=[embedding_matrix], input_length=maxlen , trainable=False),\n",
159
+ " tf.keras.layers.GRU(maxlen),\n",
160
+ " tf.keras.layers.Dense(1, activation='sigmoid')\n",
161
+ " ]) \n",
162
+ " \n",
163
+ "print(model.summary())\n",
164
+ "\n",
165
+ "early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', mode='auto', patience=10)\n",
166
+ "\n",
167
+ "model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": 9,
173
+ "metadata": {},
174
+ "outputs": [
175
+ {
176
+ "name": "stdout",
177
+ "output_type": "stream",
178
+ "text": [
179
+ "Epoch 1/100\n",
180
+ "766/766 [==============================] - 41s 51ms/step - loss: 0.5112 - accuracy: 0.7408 - val_loss: 0.4424 - val_accuracy: 0.7906\n",
181
+ "Epoch 2/100\n",
182
+ "766/766 [==============================] - 39s 51ms/step - loss: 0.3865 - accuracy: 0.8234 - val_loss: 0.3741 - val_accuracy: 0.8330\n",
183
+ "Epoch 3/100\n",
184
+ "766/766 [==============================] - 38s 49ms/step - loss: 0.3418 - accuracy: 0.8473 - val_loss: 0.3578 - val_accuracy: 0.8444\n",
185
+ "Epoch 4/100\n",
186
+ "766/766 [==============================] - 39s 51ms/step - loss: 0.3104 - accuracy: 0.8653 - val_loss: 0.3519 - val_accuracy: 0.8446\n",
187
+ "Epoch 5/100\n",
188
+ "766/766 [==============================] - 40s 52ms/step - loss: 0.2721 - accuracy: 0.8819 - val_loss: 0.3361 - val_accuracy: 0.8510\n",
189
+ "Epoch 6/100\n",
190
+ "766/766 [==============================] - 40s 52ms/step - loss: 0.2412 - accuracy: 0.8972 - val_loss: 0.3429 - val_accuracy: 0.8540\n",
191
+ "Epoch 7/100\n",
192
+ "766/766 [==============================] - 41s 54ms/step - loss: 0.2082 - accuracy: 0.9143 - val_loss: 0.3459 - val_accuracy: 0.8570\n",
193
+ "Epoch 8/100\n",
194
+ "766/766 [==============================] - 61s 79ms/step - loss: 0.1683 - accuracy: 0.9329 - val_loss: 0.4076 - val_accuracy: 0.8528\n",
195
+ "Epoch 9/100\n",
196
+ "766/766 [==============================] - 59s 78ms/step - loss: 0.1338 - accuracy: 0.9495 - val_loss: 0.4233 - val_accuracy: 0.8490\n",
197
+ "Epoch 10/100\n",
198
+ "766/766 [==============================] - 56s 73ms/step - loss: 0.0984 - accuracy: 0.9636 - val_loss: 0.4878 - val_accuracy: 0.8514\n",
199
+ "Epoch 11/100\n",
200
+ "766/766 [==============================] - 56s 73ms/step - loss: 0.0725 - accuracy: 0.9753 - val_loss: 0.5296 - val_accuracy: 0.8413\n",
201
+ "Epoch 12/100\n",
202
+ "766/766 [==============================] - 56s 73ms/step - loss: 0.0513 - accuracy: 0.9831 - val_loss: 0.5957 - val_accuracy: 0.8437\n",
203
+ "Epoch 13/100\n",
204
+ "766/766 [==============================] - 56s 73ms/step - loss: 0.0390 - accuracy: 0.9879 - val_loss: 0.6976 - val_accuracy: 0.8336\n",
205
+ "Epoch 14/100\n",
206
+ "766/766 [==============================] - 61s 80ms/step - loss: 0.0334 - accuracy: 0.9895 - val_loss: 0.7144 - val_accuracy: 0.8468\n",
207
+ "Epoch 15/100\n",
208
+ "766/766 [==============================] - 63s 82ms/step - loss: 0.0264 - accuracy: 0.9913 - val_loss: 0.7993 - val_accuracy: 0.8417\n",
209
+ "Epoch 16/100\n",
210
+ "766/766 [==============================] - 61s 79ms/step - loss: 0.0285 - accuracy: 0.9907 - val_loss: 0.8220 - val_accuracy: 0.8445\n",
211
+ "Epoch 17/100\n",
212
+ "766/766 [==============================] - 57s 74ms/step - loss: 0.0257 - accuracy: 0.9915 - val_loss: 0.8161 - val_accuracy: 0.8396\n"
213
+ ]
214
+ }
215
+ ],
216
+ "source": [
217
+ "history=model.fit(x=X_train,\n",
218
+ " y=y_train,\n",
219
+ " epochs=100,\n",
220
+ " callbacks=[early_stop],\n",
221
+ " validation_split=0.3\n",
222
+ " )"
223
+ ]
224
+ },
225
+ {
226
+ "cell_type": "code",
227
+ "execution_count": 10,
228
+ "metadata": {},
229
+ "outputs": [],
230
+ "source": [
231
+ "def c_report(y_true, y_pred):\n",
232
+ " print(\"Classification Report\")\n",
233
+ " print(classification_report(y_true, y_pred))\n",
234
+ " acc_sc = accuracy_score(y_true, y_pred)\n",
235
+ " print(f\"Accuracy : {str(round(acc_sc,2)*100)}\")\n",
236
+ " return acc_sc\n",
237
+ "\n",
238
+ "def plot_confusion_matrix(y_true, y_pred):\n",
239
+ " mtx = confusion_matrix(y_true, y_pred)\n",
240
+ " sns.heatmap(mtx, annot=True, fmt='d', linewidths=.5, cmap=\"Blues\", cbar=False)\n",
241
+ " plt.ylabel('True label')\n",
242
+ " plt.xlabel('Predicted label')\n",
243
+ " plt.show()"
244
+ ]
245
+ },
246
+ {
247
+ "cell_type": "code",
248
+ "execution_count": 11,
249
+ "metadata": {},
250
+ "outputs": [
251
+ {
252
+ "name": "stdout",
253
+ "output_type": "stream",
254
+ "text": [
255
+ "469/469 [==============================] - 9s 18ms/step\n",
256
+ "Classification Report\n",
257
+ " precision recall f1-score support\n",
258
+ "\n",
259
+ " 0 0.82 0.87 0.85 7443\n",
260
+ " 1 0.86 0.81 0.84 7557\n",
261
+ "\n",
262
+ " accuracy 0.84 15000\n",
263
+ " macro avg 0.84 0.84 0.84 15000\n",
264
+ "weighted avg 0.84 0.84 0.84 15000\n",
265
+ "\n",
266
+ "Accuracy : 84.0\n"
267
+ ]
268
+ },
269
+ {
270
+ "data": {
271
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAGwCAYAAABhDIVPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAlxUlEQVR4nO3dd3RUdd7H8c8QkiGBEHoJhABG2ooQURCQtiCgLEVUdhXWUG00aQpqRECMgghGqiAEkLqiSLEsUpRmoSoagvSaKIZiAilk7vMHD7MOIWEGJgw/fL/OyTk799785nv3wPLeO3dmbJZlWQIAADBEPl8PAAAA4AniBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGCU/L4eIK8ERvbx9QgA8sD57ROVdsHXUwDICwXcrBKuvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCjECwAAMArxAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQL7gphJYM0czXntDRtW8qefPb+n7xi7qrRoUrHhv70r90fvtE9Xm8qcv2iAqltHj8kzqy5g0lrR+r1TMHqPHdt19xjWIhBbX381E6v32iQgoFevt0AOQiNTVFY2JGq3WLZqp71516ovO/tOvHH5z7o18cqlp/q+ry88yTPVzWiP/5Jz3Vs5vuu/duNW5QTyOHR+tcauqNPhX4CPECnysSHKg1cQOVecGhDn0mK/Lh0Rr69kc6dfZctmPbNbtTdWtW1PFfT2fb91Hs08rvl08PPBWrBp3H6Ic9x/RR7NMqXTw427FThz+uH385nhenA+AqXn3lZW3evEmj3xijDz9ervoNGuqpnt2UlJTkPKbhfY20et0G58+bY9927vv11yQ92aObwipU0AcLFmvytOnat/cXRb80zBenAx8gXuBzg7rdr6OJp/TUqx9oy0+HdOj471r9zW4dOHrS5bjQkiF6+4VH1e3FOGVeyHLZV7xIQd0eXkrjZq3Srl+Oa9/h3xQd+4kKBtpVIyLU5dhej96nkOAgTZizOs/PDYCrtLQ0rV71Xw0YNER17r5HFcLD9UzvvgqrEK7/LJzvPC4gIEAlSpZ0/hQOCXHu+3rdOuX3z68XXx6uipUq646ad+rl4SP05aovdPjQIV+cFm4w4gU+16ZJTW37+bDmjemuQ6tjtHnBC+r2UAOXY2w2m95/7QmNn71a8fsTs63x++lUJRxI1OP/qKugAgHy88unng/fp6Tfz2r7z4edx1WrXEbDej2gntFz5HBYeX5uAFxlZV1QVlaW7Ha7y3a73a7t27c5H2/5/js1bVRf7dq00msjh+v06VPOfRmZGfL391e+fPn+9PsFJEnbt23N4zPAzSC/L5/85MmTmjlzpjZv3qzExIv/IJUpU0YNGjRQ165dVbJkSV+OhxukUrkS6vVoI8V+sEZj3v+v6vwtXOOef0QZF7I0b/m3ki5enbmQ5dCkBetyXKfN0xO1aPyT+m3jW3I4LP12KkXte0/W6T/OS5IC/PNrdkxXvThhqY4knlLFciVuxOkB+JOCBQupVu1IvTd1sipVrqzixUvos09X6IedOxRW4eJ9bg3ua6TmLe5XufLldeTIEb074W09+1QvzZ2/SH5+fqpb716NG/OG4mbOUOcuT+j8+fN6Z/w4SdLJk7/58vRwg/jsysv333+vKlWqKDY2ViEhIWrcuLEaN26skJAQxcbGqlq1atqyZctV10lPT9fZs2ddftLT02/AGcBb8uWzacfuIxo+cbl2JhzVzI82atbHm9TrkfskSZHVw9T7saZ6cvgHua4zflgn/Zb8h1p0n6BG/x6rZWt3ask7T6lMicKSpFH92inhQJIWfvp9np8TgJyNjhkjy7J0f7PGuieypuZ/MFetH2zjvJLywINt1PTvzXV7lar6e/MWenfyNP2060dt+f47SVJExO0aNfoNzYmbpXp319bfmzRUufLlVLx4CdlsNl+eGm4Qn1156du3rx599FFNnTo12x82y7L09NNPq2/fvtq8eXOu68TExGjEiBEu24YPH+71eZF3Ek+ezfZS0O4DierQvLYkqWHkbSpVrJD2fDrSuT9/fj+9MbCj+nRupmpthqtp3Sp6sNEdKtvkef2RmiZJei5msZrfW01d2tbTW7NWqck9VXRHRKge+v7iupf+3B1d+4befP8LvTb107w/WQAKq1BBM2d/oHPnzik1NUUlS5bSkEHPqXz5sCseXz4sTEWLFtXhw4dU7976kqQH/9FWD/6jrX4/eVKBgYGSzaa5s+NUPuzKa+DW4rN42blzp+Li4q5YyTabTQMGDFBkZORV1xk2bJgGDhzoss1ut+vNTwZ5bVbkrc079qtKeCmXbbdXKKXDJ5IlSfNXfq813ya47F8+ubfmr/xOcz75RpIUVCBAkuRwOFyOczgs55+xxwbPUKDd37mvzt/C9d6ILmrRY4L2H+FSM3CjBQUFKSgoSGfPnNHmjRv03MAhVzwuKTFRp0+fVskS2W8lKF7i4su/H3/0oQLsdt1bv2Gezoybg8/ipUyZMvruu+9UrVq1K+7/7rvvVLp06auuY7fbs934BbO8+8EarY0bpCHdW2rJqm26528V1f3hhuozaoEkKflMqpLPuH5+Q+aFLCWdPKtfDv0qSfr2hwM6dfacZox6Qq+/95nOp2Wqe8cGqliuuD7f8JMkZXv3UvEihSRJu/cn6kzK+bw+TQD/b+OG9ZJlKbxSJR05fFjj3xqjipUqq/1DHXUuNVVTp0xUi/tbqXiJEjp65IjGjxursArhanBfI+caC+Z9oNqRkQoMCtI3mzZp/Lgx6jdgkAoXLuzDM8ON4rN4GTx4sJ588klt3bpVzZs3d4ZKUlKSVq9erenTp+utt97y1Xi4gbb+fFj/HDRdI/u204tPPqCDx37XkLFLtPCzq9/zdMnvp1PVvs9kvdq7rT6b1k/++fMpfn+iHh3wnn7ccywPpwfgqZSUPxQ74W0lJSYqJKSImt/fUn37D5C/v7+ysrK0J2GPln2yVH+c/UOlSpVS/QYN1btvfwUEBDjX2LXrB02Z9K7OnUtVpUqV9fLwEWrbroPvTgo3lM2yLJ+9X3TRokUaP368tm7dqqysi5/b4efnpzp16mjgwIHq1KnTNa8dGNnHW2MCuImc3z5RaRd8PQWAvFDAzUsqPo2XSzIzM3Xy5MVL+iVKlJC/v/9VfuPqiBfg1kS8ALcud+PFp5/zcom/v7/Kli3r6zEAAIAB+IRdAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABglvzsHLVu2zO0F27Vrd83DAAAAXI1b8dKhQwe3FrPZbMrKyrqeeQAAAHLlVrw4HI68ngMAAMAt13XPS1pamrfmAAAAcIvH8ZKVlaVRo0apXLlyKlSokPbv3y9Jio6O1vvvv+/1AQEAAP7M43gZPXq04uLiNGbMGAUEBDi333HHHZoxY4ZXhwMAALicx/EyZ84cvffee+rcubP8/Pyc22vVqqXdu3d7dTgAAIDLeRwvx44dU0RERLbtDodDmZmZXhkKAAAgJx7HS40aNbR+/fps2z/88ENFRkZ6ZSgAAICcuPVW6T975ZVXFBUVpWPHjsnhcOijjz5SQkKC5syZoxUrVuTFjAAAAE4eX3lp3769li9fri+//FIFCxbUK6+8ovj4eC1fvlz3339/XswIAADgZLMsy/L1EHkhMLKPr0cAkAfOb5+otAu+ngJAXijg5utBHr9sdMmWLVsUHx8v6eJ9MHXq1LnWpQAAANzmcbwcPXpUjz32mDZu3KgiRYpIkk6fPq0GDRpo4cKFKl++vLdnBAAAcPL4npeePXsqMzNT8fHxSk5OVnJysuLj4+VwONSzZ8+8mBEAAMDJ43teAgMDtWnTpmxvi966dasaNWqkc+fOeXXAa8U9L8CtiXtegFuXu/e8eHzlJSws7IofRpeVlaXQ0FBPlwMAAPCIx/EyduxY9e3bV1u2bHFu27Jli/r376+33nrLq8MBAABczq2XjYoWLSqbzeZ8nJqaqgsXLih//ovXdy7954IFCyo5OTnvpvUALxsBtyZeNgJuXV59q/SECROuYxQAAADvcSteoqKi8noOAAAAt1zzh9RJUlpamjIyMly2FS5c+LoGAgAAyI3HN+ympqaqT58+KlWqlAoWLKiiRYu6/AAAAOQlj+Pl+eef15o1azRlyhTZ7XbNmDFDI0aMUGhoqObMmZMXMwIAADh5/LLR8uXLNWfOHDVt2lTdunVTo0aNFBERofDwcM2bN0+dO3fOizkBAAAkXcOVl+TkZFWuXFnSxftbLr01+r777tPXX3/t3ekAAAAu43G8VK5cWQcOHJAkVatWTYsXL5Z08YrMpS9qBAAAyCsex0u3bt20c+dOSdLQoUM1adIkFShQQAMGDNCQIUO8PiAAAMCfefzFjJc7dOiQtm7dqoiICN15553emuu68Qm7wK2JT9gFbl1e/YTd3ISHhys8PPx6lwEAAHCLW/ESGxvr9oL9+vW75mEAAACuxq2XjSpVquTeYjab9u/ff91DAQAA5OS673m5WSWeyfT1CADyQJkQfwU2G+XrMQDkgfNro906zuN3GwEAAPgS8QIAAIxCvAAAAKMQLwAAwCjECwAAMMo1xcv69evVpUsX1a9fX8eOHZMkzZ07Vxs2bPDqcAAAAJfzOF6WLFmiVq1aKTAwUNu3b1d6erok6cyZM3r99de9PiAAAMCfeRwvr732mqZOnarp06fL39/fub1hw4batm2bV4cDAAC4nMfxkpCQoMaNG2fbHhISotOnT3tjJgAAgBx5HC9lypTR3r17s23fsGGDKleu7JWhAAAAcuJxvPTq1Uv9+/fXt99+K5vNpuPHj2vevHkaPHiwnnnmmbyYEQAAwMmtb5X+s6FDh8rhcKh58+Y6d+6cGjduLLvdrsGDB6tv3755MSMAAIDTNX8xY0ZGhvbu3auUlBTVqFFDhQoV8vZs14UvZgRuTXwxI3DrcveLGT2+8nJJQECAatSoca2/DgAAcE08jpdmzZrJZrPluH/NmjXXNRAAAEBuPI6X2rVruzzOzMzUjh07tGvXLkVFRXlrLgAAgCvyOF7Gjx9/xe2vvvqqUlJSrnsgAACA3Hjtixm7dOmimTNnems5AACAK/JavGzevFkFChTw1nIAAABX5PHLRh07dnR5bFmWTpw4oS1btig62r23OAEAAFwrj+MlJCTE5XG+fPlUtWpVjRw5Ui1btvTaYAAAAFfiUbxkZWWpW7duqlmzpooWLZpXMwEAAOTIo3te/Pz81LJlS749GgAA+IzHN+zecccd2r9/f17MAgAAcFUex8trr72mwYMHa8WKFTpx4oTOnj3r8gMAAJCX3L7nZeTIkRo0aJAefPBBSVK7du1cvibAsizZbDZlZWV5f0oAAID/5/a3Svv5+enEiROKj4/P9bgmTZp4ZbDrxbdKA7cmvlUauHV5/VulLzXOzRInAADgr8mje15y+zZpAACAG8Gjz3mpUqXKVQMmOTn5ugYCAADIjUfxMmLEiGyfsAsAAHAjeRQv//rXv1SqVKm8mgUAAOCq3L7nhftdAADAzcDteHHzHdUAAAB5yu2XjRwOR17OAQAA4BaPvx4AAADAl4gXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFPrdz2xYNHdhbHR9spiZ179D6datzPHZczAg1qXuH/rNgrsv2uTOn6dkendWy0d1q8/f6uT7fmdOn9cg/mqtJ3Tv0xx9nvXIOAHIWWiJYM1/soKNLByn586H6/v2ndFeVss797RtV0/Ixj+vo0kE6vzZad95WOtf1lr7xmM6vjVbbhlWd24oVDtQnbz6m/f95Tqe/GKZfFvXT+H6tFRwUkGfnBd8hXuBz59POK+L2qnpuyEu5Hvf12i/1864fVKJkqWz7Mi9kqmnzVmr/8D+v+nxjXntFlSOqXPO8ANxXpFABrXm3qzIvZKnD0AWK7DpVQ6es0qmUNOcxQQX8tWnXEb38Xs7/x+WSvo/Uk2VZ2bY7HJZWbNyjR15apDufmKxeby5TszqV9O7ANl49H9wc8vt6AODeBo10b4NGuR7z269Jih0Xo7HvTNPQgc9m29/9yT6SpM9WLM11naUfLlRKyllF9XhG325af80zA3DPoMca6OivZ/XUmOXObYcST7scs2DVj5KkCqVDcl3rzttKq3+ne9XwqRk6+NFAl32nU9I0fdlW5+PDSWf03idbNOCfuV+JhZmIF9z0HA6HRg8fpn916apKt0Vc8zoH9+/T7PenauqsBTp+7IgXJwSQkzYNqujL7/dp3vCHdV+tcB0/+Yfe+2SLZq3c7tE6gfb8inv5IT33zmdKOpV61ePLFi+k9o2qaf3Ow9c6Om5ixsdLenq60tPTXbbZ7XbxititY/6c9+WX308P/7PLNa+RkZGhkS8P0TP9Bql0mbLEC3CDVAotql7t71bsf77RmHkbVadaWY3r20oZF7I074sf3F5nTO+W+uano1qxcU+ux81++SH9o2FVBRXw14qNe/TM2OW5Hg8z3dT/wh85ckTdu3fP9ZiYmBiFhIS4/MTExNygCZHXEuJ/0pKFH2jYK6Nls9mueZ33Jk1QeKXKavlAWy9OB+Bq8tls2rHnhIbPWKudexM1c8V2zVq5Xb3a1nF7jTYNqqhpZEUNmfjFVY99ftJ/Vf/J6XrkpUWqXK6o3uzd8nrGx03qpr7ykpycrNmzZ2vmzJk5HjNs2DANHOj62qfdbteptBx+AUb5Ycc2nTqVrE7t7nduy8rK0uR3xurDhXO16JP/urXO9i3fav++X/TVmlqS5Lzhr33LRurSrZfznhkA3pX4+x+KP3TSZdvuQyfVoVE1t9doGllRlUOLKXHF8y7bF4x4RBt/PKxWA/737sOkU6lKOpWqPUd+16mz57X63a56Y856JSanXN+J4Kbi03hZtmxZrvv3799/1TXsdvv/v0x0mbTMax0LN5GWD7RVnbr3umwb0u8ptXygrR5o28HtdUa+Od7l5cXdP+/Sm6OiFTtttsqVD/PWuAAus/mno6oSVtxl2+3li+lw0hm313hr/sZs98hsnfW0np/8X63c9EuOv2fLd/FqbYC/nwcTwwQ+jZcOHTrIZrNd8W1vl1zPSwUww7lz53Ts6P9uqjtx/Jh+2bNbhQuHqHSZsgopUsTl+Pz586tY8RKqEF7JuS0p8YTOnj2jpMQTynJk6Zc9uyVJ5cpXUFBQkMqVr+CyxpnTpyRJ4ZUqKzi4cB6dGYB3//ON1k7spiGdG2rJ2p91T/Vy6v6Pu9Tn7ZXOY4oGF1BYqRCVLREsSapS4WLsJCWnOK+kXOkm3SNJZ53vXGpVL0KlihbU1t3HlXI+QzUqldTrT7XQph8PexRKMINP46Vs2bKaPHmy2rdvf8X9O3bsUJ067r8uCjMlxO/Sc8/8796mSRPGSJJat2mvYcNHu7XGzGkT9fnKT5yPe3Z5RJI0YcpMRdap68VpAXhia8IJ/TP6PxrZ6+968YnGOnjitIZM+q8WfrnLeUybBlU0fej//h2Y+8rDkqTX4r7S6Nlfu/U859Mz1b1NpMb0bim7v5+O/npWn6zfrbfmb/TuCeGmYLNyu+yRx9q1a6fatWtr5MiRV9y/c+dORUZGyuFweLx24hleNgJuRWVC/BXYbJSvxwCQB86vjXbrOJ9eeRkyZIhSU3N+v35ERITWrl17AycCAAA3O5/GS6NGuX+qasGCBdWkSZMbNA0AADDBTf05LwAAAJcjXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgBAABGIV4AAIBRiBcAAGAU4gUAABiFeAEAAEaxWZZl+XoI4Fqlp6crJiZGw4YNk91u9/U4ALyIv9/ICfECo509e1YhISE6c+aMChcu7OtxAHgRf7+RE142AgAARiFeAACAUYgXAABgFOIFRrPb7Ro+fDg38wG3IP5+IyfcsAsAAIzClRcAAGAU4gUAABiFeAEAAEYhXgAAgFGIFxht0qRJqlixogoUKKB69erpu+++8/VIAK7T119/rbZt2yo0NFQ2m01Lly719Ui4yRAvMNaiRYs0cOBADR8+XNu2bVOtWrXUqlUr/frrr74eDcB1SE1NVa1atTRp0iRfj4KbFG+VhrHq1aune+65RxMnTpQkORwOhYWFqW/fvho6dKiPpwPgDTabTR9//LE6dOjg61FwE+HKC4yUkZGhrVu3qkWLFs5t+fLlU4sWLbR582YfTgYAyGvEC4x08uRJZWVlqXTp0i7bS5curcTERB9NBQC4EYgXAABgFOIFRipRooT8/PyUlJTksj0pKUllypTx0VQAgBuBeIGRAgICVKdOHa1evdq5zeFwaPXq1apfv74PJwMA5LX8vh4AuFYDBw5UVFSU7r77btWtW1cTJkxQamqqunXr5uvRAFyHlJQU7d271/n4wIED2rFjh4oVK6YKFSr4cDLcLHirNIw2ceJEjR07VomJiapdu7ZiY2NVr149X48F4DqsW7dOzZo1y7Y9KipKcXFxN34g3HSIFwAAYBTueQEAAEYhXgAAgFGIFwAAYBTiBQAAGIV4AQAARiFeAACAUYgXAABgFOIFAAAYhXgB4HVdu3ZVhw4dnI+bNm2q55577obPsW7dOtlsNp0+fTrHY2w2m5YuXer2mq+++qpq1659XXMdPHhQNptNO3bsuK51gL8q4gX4i+jatatsNptsNpsCAgIUERGhkSNH6sKFC3n+3B999JFGjRrl1rHuBAeAvza+mBH4C2ndurVmzZql9PR0ffrpp+rdu7f8/f01bNiwbMdmZGQoICDAK89brFgxr6wDABJXXoC/FLvdrjJlyig8PFzPPPOMWrRooWXLlkn630s9o0ePVmhoqKpWrSpJOnLkiDp16qQiRYqoWLFiat++vQ4ePOhcMysrSwMHDlSRIkVUvHhxPf/887r8K9Muf9koPT1dL7zwgsLCwmS32xUREaH3339fBw8edH4hX9GiRWWz2dS1a1dJksPhUExMjCpVqqTAwEDVqlVLH374ocvzfPrpp6pSpYoCAwPVrFkzlznd9cILL6hKlSoKCgpS5cqVFR0drczMzGzHTZs2TWFhYQoKClKnTp105swZl/0zZsxQ9erVVaBAAVWrVk2TJ0/2eBYAV0a8AH9hgYGBysjIcD5evXq1EhIStGrVKq1YsUKZmZlq1aqVgoODtX79em3cuFGFChVS69atnb83btw4xcXFaebMmdqwYYOSk5P18ccf5/q8TzzxhBYsWKDY2FjFx8dr2rRpKlSokMLCwrRkyRJJUkJCgk6cOKF33nlHkhQTE6M5c+Zo6tSp+umnnzRgwAB16dJFX331laSLkdWxY0e1bdtWO3bsUM+ePTV06FCP/zsJDg5WXFycfv75Z73zzjuaPn26xo8f73LM3r17tXjxYi1fvlyff/65tm/frmeffda5f968eXrllVc0evRoxcfH6/XXX1d0dLRmz57t8TwArsAC8JcQFRVltW/f3rIsy3I4HNaqVassu91uDR482Lm/dOnSVnp6uvN35s6da1WtWtVyOBzObenp6VZgYKD1xRdfWJZlWWXLlrXGjBnj3J+ZmWmVL1/e+VyWZVlNmjSx+vfvb1mWZSUkJFiSrFWrVl1xzrVr11qSrFOnTjm3paWlWUFBQdamTZtcju3Ro4f12GOPWZZlWcOGDbNq1Kjhsv+FF17IttblJFkff/xxjvvHjh1r1alTx/l4+PDhlp+fn3X06FHnts8++8zKly+fdeLECcuyLOu2226z5s+f77LOqFGjrPr161uWZVkHDhywJFnbt2/P8XkB5Ix7XoC/kBUrVqhQoULKzMyUw+HQ448/rldffdW5v2bNmi73uezcuVN79+5VcHCwyzppaWnat2+fzpw5oxMnTqhevXrOffnz59fdd9+d7aWjS3bs2CE/Pz81adLE7bn37t2rc+fO6f7773fZnpGRocjISElSfHy8yxySVL9+fbef45JFixYpNjZW+/btU0pKii5cuKDChQu7HFOhQgWVK1fO5XkcDocSEhIUHBysffv2qUePHurVq5fzmAsXLigkJMTjeQBkR7wAfyHNmjXTlClTFBAQoNDQUOXP7/o/AQULFnR5nJKSojp16mjevHnZ1ipZsuQ1zRAYGOjx76SkpEiSVq5c6RIN0sX7eLxl8+bN6ty5s0aMGKFWrVopJCRECxcu1Lhx4zyedfr06dliys/Pz2uzAn9lxAvwF1KwYEFFRES4ffxdd92lRYsWqVSpUtmuPlxStmxZffvtt2rcuLGki1cYtm7dqrvuuuuKx9esWVMOh0NfffWVWrRokW3/pSs/WVlZzm01atSQ3W7X4cOHc7xiU716defNx5d88803Vz/JP9m0aZPCw8P10ksvObcdOnQo23GHDx/W8ePHFRoa6nyefPnyqWrVqipdurRCQ0O1f/9+de7c2aPnB+AebtgFkKPOnTurRIkSat++vdavX68DBw5o3bp16tevn44ePSpJ6t+/v9544w0tXbpUu3fv1rPPPpvrZ7RUrFhRUVFR6t69u5YuXepcc/HixZKk8PBw2Ww2rVixQr/99ptSUlIUHByswYMHa8CAAZo9e7b27dunbdu26d1333XeBPv000/rl19+0ZAhQ5SQkKD58+crLi7Oo/O9/fbbdfjwYS1cuFD79u1TbGzsFW8+LlCggKKiorRz506tX79e/fr1U6dOnVSmTBlJ0ogRIxQTE6PY2Fjt2bNHP/74o2bNmqW3337bo3kAXBnxAiBHQUFB+vrrr1WhQgV17NhR1atXV48ePZSWlua8EjNo0CD9+9//VlRUlOrXr6/g4GA99NBDua47ZcoUPfLII3r22WdVrVo19erVS6mpqZKkcuXKacSIERo6dKhKly6tPn36SJJGjRql6OhoxcTEqHr16mrdurVWrlypSpUqSbp4H8qSJUu0dOlS1apVS1OnTtXrr7/u0fm2a9dOAwYMUJ8+fVS7dm1t2rRJ0dHR2Y6LiIhQx44d9eCDD6ply5a68847Xd4K3bNnT82YMUOzZs1SzZo11aRJE8XFxTlnBXB9bFZOd9UBAADchLjyAgAAjEK8AAAAoxAvAADAKMQLAAAwCvECAACMQrwAAACjEC8AAMAoxAsAADAK8QIAAIxCvAAAAKMQLwAAwCj/B/Ut7r+e94ZGAAAAAElFTkSuQmCC",
272
+ "text/plain": [
273
+ "<Figure size 640x480 with 1 Axes>"
274
+ ]
275
+ },
276
+ "metadata": {},
277
+ "output_type": "display_data"
278
+ }
279
+ ],
280
+ "source": [
281
+ "preds = (model.predict(X_test) > 0.5).astype(\"int32\")\n",
282
+ "c_report(y_test, preds)\n",
283
+ "plot_confusion_matrix(y_test, preds)"
284
+ ]
285
+ },
286
+ {
287
+ "cell_type": "code",
288
+ "execution_count": 12,
289
+ "metadata": {},
290
+ "outputs": [
291
+ {
292
+ "name": "stderr",
293
+ "output_type": "stream",
294
+ "text": [
295
+ "d:\\STUDY\\Sem3\\deeplearning\\DLENV\\lib\\site-packages\\keras\\src\\engine\\training.py:3079: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.\n",
296
+ " saving_api.save_model(\n"
297
+ ]
298
+ }
299
+ ],
300
+ "source": [
301
+ "# Save the model\n",
302
+ "model.save(\"gru_movie_model.h5\")"
303
+ ]
304
+ },
305
+ {
306
+ "cell_type": "code",
307
+ "execution_count": 13,
308
+ "metadata": {},
309
+ "outputs": [],
310
+ "source": [
311
+ "# Load the saved model\n",
312
+ "gru_movie_model = tf.keras.models.load_model('gru_movie_model.h5')\n",
313
+ "\n",
314
+ "# Function to predict sentiment for a given review\n",
315
+ "def gru_predict_sentiment(review):\n",
316
+ " sequence = tokeniser.texts_to_sequences([review])\n",
317
+ " sequence = tf.keras.preprocessing.sequence.pad_sequences(sequence, padding='post', maxlen=maxlen)\n",
318
+ " prediction = gru_movie_model.predict(sequence)\n",
319
+ " if prediction > 0.5:\n",
320
+ " return \"Positive\"\n",
321
+ " else:\n",
322
+ " return \"Negative\""
323
+ ]
324
+ },
325
+ {
326
+ "cell_type": "code",
327
+ "execution_count": 14,
328
+ "metadata": {},
329
+ "outputs": [
330
+ {
331
+ "name": "stdout",
332
+ "output_type": "stream",
333
+ "text": [
334
+ "1/1 [==============================] - 1s 571ms/step\n",
335
+ "Review: This movie was fantastic! I loved every bit of it. \n",
336
+ "The sentiment is predicted as: Positive\n"
337
+ ]
338
+ }
339
+ ],
340
+ "source": [
341
+ "# Test the model prediction\n",
342
+ "example_review = \"This movie was fantastic! I loved every bit of it.\"\n",
343
+ "prediction_result = gru_predict_sentiment(example_review)\n",
344
+ "print(f\"Review: {example_review} \\nThe sentiment is predicted as: {prediction_result}\")"
345
+ ]
346
+ },
347
+ {
348
+ "cell_type": "code",
349
+ "execution_count": 15,
350
+ "metadata": {},
351
+ "outputs": [
352
+ {
353
+ "name": "stdout",
354
+ "output_type": "stream",
355
+ "text": [
356
+ "1/1 [==============================] - 0s 51ms/step\n",
357
+ "Review: This movie was very bad! I hated every bit of it. \n",
358
+ "The sentiment is predicted as: Negative\n"
359
+ ]
360
+ }
361
+ ],
362
+ "source": [
363
+ "# Test the model prediction\n",
364
+ "example_review = \"This movie was very bad! I hated every bit of it.\"\n",
365
+ "prediction_result = gru_predict_sentiment(example_review)\n",
366
+ "print(f\"Review: {example_review} \\nThe sentiment is predicted as: {prediction_result}\")"
367
+ ]
368
+ },
369
+ {
370
+ "cell_type": "code",
371
+ "execution_count": null,
372
+ "metadata": {},
373
+ "outputs": [],
374
+ "source": []
375
+ }
376
+ ],
377
+ "metadata": {
378
+ "kernelspec": {
379
+ "display_name": "DLENV",
380
+ "language": "python",
381
+ "name": "python3"
382
+ },
383
+ "language_info": {
384
+ "codemirror_mode": {
385
+ "name": "ipython",
386
+ "version": 3
387
+ },
388
+ "file_extension": ".py",
389
+ "mimetype": "text/x-python",
390
+ "name": "python",
391
+ "nbconvert_exporter": "python",
392
+ "pygments_lexer": "ipython3",
393
+ "version": "3.10.11"
394
+ }
395
+ },
396
+ "nbformat": 4,
397
+ "nbformat_minor": 2
398
+ }
tokenizer_movie_gru.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ce600da938552049e3985141044107bf41171365090270f3405d9f17c7d822f
3
+ size 4549072