Machine Translation Ipynb
Machine Translation Ipynb
Machine Translation Ipynb
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Machine_Translation.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "w3LV6bzWmCUN"
},
"source": [
"# Text Translation"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YJs3pIp0l-MW"
},
"source": [
"## Importing Library"
]
},
{
"cell_type": "code",
"metadata": {
"id": "RrgHQcjk11rW"
},
"source": [
"# get the data at: http://www.manythings.org/anki/"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "HOZDC22_16Br"
},
"source": [
"import os, sys\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from tensorflow.keras.preprocessing.text import Tokenizer\n",
"from tensorflow.keras.preprocessing.sequence import
pad_sequences\n",
"\n",
"from tensorflow.keras.utils import to_categorical\n",
"\n",
"from tensorflow.keras.layers import Input, LSTM, GRU, Dense,
Embedding\n",
"from tensorflow.keras.models import Model"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "mSBgMHajmHcl"
},
"source": [
"## Defining Configuration"
]
},
{
"cell_type": "code",
"metadata": {
"id": "6mT9RpoT2DWv"
},
"source": [
"# some config\n",
"BATCH_SIZE = 64 # Batch size for training.\n",
"EPOCHS = 100 # Number of epochs to train for.\n",
"LATENT_DIM = 256 # Latent dimensionality of the encoding
space.\n",
"NUM_SAMPLES = 10000 # Number of samples to train on.\n",
"MAX_SEQUENCE_LENGTH = 100\n",
"MAX_NUM_WORDS = 20000\n",
"EMBEDDING_DIM = 50"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "bDr83n2-mOaF"
},
"source": [
"## Loading Data and Data Preparation"
]
},
{
"cell_type": "code",
"metadata": {
"id": "jA-1qBVE3Z6g",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "3c239d9b-f728-45a2-a36e-5188eef6adac"
},
"source": [
"from google.colab import drive\n",
"drive.mount('/content/drive', force_remount=True)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Mounted at /content/drive\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "bNh0ouPi4Gkf",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "c161a2d2-e6f5-4066-898d-1d67fcd81d87"
},
"source": [
"!unzip '/content/drive/My Drive/data/spa-eng.zip'"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Archive: /content/drive/My Drive/data/spa-eng.zip\n",
" inflating: _about.txt \n",
" inflating: spa.txt \n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "LVCIYaxo5L7H",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "c0d9df44-e626-407a-9853-f3bc98542def"
},
"source": [
"!unzip '/content/drive/My Drive/glove/glove.6B.50d.txt.zip'"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Archive: /content/drive/My
Drive/glove/glove.6B.50d.txt.zip\n",
" inflating: glove.6B.50d.txt \n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "-2wNtqX1aTnN",
"outputId": "2b32cd4f-a43f-48a1-b012-ae8c12fe1a60"
},
"source": [
"!head -5 'spa.txt'"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Go.\tVe.\tCC-BY 2.0 (France) Attribution: tatoeba.org
#2877272 (CM) & #4986655 (cueyayotl)\n",
"Go.\tVete.\tCC-BY 2.0 (France) Attribution: tatoeba.org
#2877272 (CM) & #4986656 (cueyayotl)\n",
"Go.\tVaya.\tCC-BY 2.0 (France) Attribution: tatoeba.org
#2877272 (CM) & #4986657 (cueyayotl)\n",
"Go.\tV√°yase.\tCC-BY 2.0 (France) Attribution: tatoeba.org
#2877272 (CM) & #6586271 (arh)\n",
"Hi.\tHola.\tCC-BY 2.0 (France) Attribution: tatoeba.org
#538123 (CM) & #431975 (Leono)\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "z9TyUbu7_0Rj"
},
"source": [
"# Where we will store the data\n",
"input_texts = [] # sentence in source language\n",
"target_texts = [] # sentence in target language\n",
"target_texts_inputs = [] # sentence in target language offset by
1"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "4y8dq56Q224e"
},
"source": [
"t = 0\r\n",
"for line in open('spa.txt'):\r\n",
" # only keep a limited number of samples\r\n",
" t += 1\r\n",
" if t > NUM_SAMPLES: # Number of samples is kept less as at the
end of the document the length is big and with bigger length, we have to
do more padding.\r\n",
" break\r\n",
"\r\n",
" # input and target are separated by tab\r\n",
" if '\\t' not in line:\r\n",
" continue\r\n",
"\r\n",
" # split up the input and translation\r\n",
" input_text = line.rstrip().split('\\t')[0]\r\n",
" translation = line.rstrip().split('\\t')[1]\r\n",
"\r\n",
" # make the target input and output\r\n",
" # recall we'll be using teacher forcing\r\n",
" target_text = translation + ' <end>'\r\n",
" target_text_input = '<start> ' + translation\r\n",
"\r\n",
" input_texts.append(input_text)\r\n",
" target_texts.append(target_text)\r\n",
" target_texts_inputs.append(target_text_input)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "py8sFFmg2EQb",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "7ddabaed-9ab4-4d33-ddc7-165eb92610cd"
},
"source": [
"print(\"num samples:\", len(input_texts))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"num samples: 10000\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y3JvtKwVmVuN"
},
"source": [
"## Tokenization, conversion to integers and creating sequences"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xPh6wGB_mcvW"
},
"source": [
"### Encoder: Input"
]
},
{
"cell_type": "code",
"metadata": {
"id": "K0ZDtbcN2FMq"
},
"source": [
"# tokenize the inputs\n",
"tokenizer_inputs = Tokenizer(num_words=MAX_NUM_WORDS)\n",
"tokenizer_inputs.fit_on_texts(input_texts)\n",
"input_sequences =
tokenizer_inputs.texts_to_sequences(input_texts)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "t2Ei5XjX2IDU",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "540935a6-fdf9-4352-bdfc-b62af44fdb0a"
},
"source": [
"# get the word to index mapping for input language\n",
"word2idx_inputs = tokenizer_inputs.word_index\n",
"print('Found %s unique input tokens.' % len(word2idx_inputs))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Found 2337 unique input tokens.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "QFQrWLWx2Io3",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "ad93155c-4605-48e1-f982-332eca40a2a0"
},
"source": [
"# determine maximum length input sequence\n",
"max_len_input = max(len(s) for s in input_sequences)\n",
"max_len_input"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"5"
]
},
"metadata": {
"tags": []
},
"execution_count": 12
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FCHOUJOomgGQ"
},
"source": [
"### Decoder: Output"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Xk6GfIQ42JKs"
},
"source": [
"# tokenize the outputs\n",
"# don't filter out special characters\n",
"# otherwise <start> and <end> won't appear\n",
"\n",
"tokenizer_outputs = Tokenizer(num_words=MAX_NUM_WORDS,
filters='')\n",
"tokenizer_outputs.fit_on_texts(target_texts +
target_texts_inputs)\n",
"\n",
"target_sequences =
tokenizer_outputs.texts_to_sequences(target_texts)\n",
"target_sequences_inputs =
tokenizer_outputs.texts_to_sequences(target_texts_inputs)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "AJtfeBMD2Jtc",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "f9c622de-3857-4ef3-a256-ad750b0a5cd2"
},
"source": [
"# get the word to index mapping for output language\n",
"\n",
"word2idx_outputs = tokenizer_outputs.word_index\n",
"print('Found %s unique output tokens.' % len(word2idx_outputs))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Found 6316 unique output tokens.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "CygmZukK2KQ4",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "048f7eb2-7ab4-4c51-b6b2-ca330219181c"
},
"source": [
"# store number of output words for later\n",
"# remember to add 1 since indexing starts at 1\n",
"num_words_output = len(word2idx_outputs) + 1\n",
"\n",
"# determine maximum length output sequence\n",
"max_len_target = max(len(s) for s in target_sequences)\n",
"max_len_target"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"9"
]
},
"metadata": {
"tags": []
},
"execution_count": 15
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gvIhJpAvnif_"
},
"source": [
"### Padding Sequences"
]
},
{
"cell_type": "code",
"metadata": {
"id": "P_uGzoUc2Lg9",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "e4579950-1c53-4d86-fe69-6e590407f70e"
},
"source": [
"# pad the sequences\n",
"encoder_inputs = pad_sequences(input_sequences,
maxlen=max_len_input)\n",
"print(\"encoder_inputs.shape:\", encoder_inputs.shape)\n",
"print(\"encoder_inputs[0]:\", encoder_inputs[0])\n",
"\n",
"decoder_inputs = pad_sequences(target_sequences_inputs,
maxlen=max_len_target, padding='post')\n",
"print(\"decoder_inputs[0]:\", decoder_inputs[0])\n",
"print(\"decoder_inputs.shape:\", decoder_inputs.shape)\n",
"\n",
"decoder_targets = pad_sequences(target_sequences,
maxlen=max_len_target, padding='post')"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"encoder_inputs.shape: (10000, 5)\n",
"encoder_inputs[0]: [ 0 0 0 0 15]\n",
"decoder_inputs[0]: [ 2 1468 0 0 0 0 0 0
0]\n",
"decoder_inputs.shape: (10000, 9)\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gHuwp5uDnmL-"
},
"source": [
"## Embedding -- Pre-train"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ZZZVas1T2MjW",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "8f656f7b-2b94-48b1-f44a-0f19ed3d780a"
},
"source": [
"# store all the pre-trained word vectors\n",
"print('Loading word vectors...')\n",
"word2vec = {}\n",
"with open(os.path.join('glove.6B.%sd.txt' % EMBEDDING_DIM)) as
f:\n",
" # is just a space-separated text file in the format:\n",
" # word vec[0] vec[1] vec[2] ...\n",
" for line in f:\n",
" values = line.split()\n",
" word = values[0]\n",
" vec = np.asarray(values[1:], dtype='float32')\n",
" word2vec[word] = vec\n",
"print('Found %s word vectors.' % len(word2vec))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Loading word vectors...\n",
"Found 400000 word vectors.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yOT30Fe3nq1-"
},
"source": [
"### Embedding Matrix"
]
},
{
"cell_type": "code",
"metadata": {
"id": "AddETm9L2OKH",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "c4e81537-7891-4a18-869e-7e6950f48ece"
},
"source": [
"# prepare embedding matrix\n",
"print('Filling pre-trained embeddings...')\n",
"num_words = min(MAX_NUM_WORDS, len(word2idx_inputs) + 1)\n",
"embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))\n",
"for word, i in word2idx_inputs.items():\n",
" if i < MAX_NUM_WORDS:\n",
" embedding_vector = word2vec.get(word)\n",
" if embedding_vector is not None:\n",
" # words not found in embedding index will be all zeros.\
n",
" embedding_matrix[i] = embedding_vector"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Filling pre-trained embeddings...\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YMf9J8cQntMh"
},
"source": [
"### Embedding Layer"
]
},
{
"cell_type": "code",
"metadata": {
"id": "JzmHOaXe2PPx"
},
"source": [
"# create embedding layer\n",
"embedding_layer = Embedding(\n",
" num_words,\n",
" EMBEDDING_DIM,\n",
" weights=[embedding_matrix],\n",
" input_length=max_len_input\n",
")"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "0tvh4C9yqeqa"
},
"source": [
"## OHE Output"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Tko0ZG2R2P02"
},
"source": [
"# One-hot encoded version of the decoder target, as we have \n",
"# categorical cross entropy as the loss.\n",
"decoder_targets_one_hot = np.zeros((len(input_texts),
max_len_target, num_words_output), dtype='float32')\n",
"\n",
"# assign the values\n",
"for i, d in enumerate(decoder_targets):\n",
" for t, word in enumerate(d):\n",
" decoder_targets_one_hot[i, t, word] = 1"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "LGuZ2dyqn-Yn"
},
"source": [
"## Model Building"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "roLW7GBPoFnr"
},
"source": [
"### Encoder"
]
},
{
"cell_type": "code",
"metadata": {
"id": "RG_jAbxr2Qaq"
},
"source": [
"encoder_inputs_placeholder = Input(shape=(max_len_input,))\n",
"x = embedding_layer(encoder_inputs_placeholder)\n",
"\n",
"encoder = LSTM(\n",
" LATENT_DIM,\n",
" return_state=True,\n",
")\n",
"\n",
"encoder_outputs, h, c = encoder(x)\n",
"\n",
"# keep only the states to pass into decoder\n",
"encoder_states = [h, c]\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "JtCZZ4FZoKDk"
},
"source": [
"### Decoder"
]
},
{
"cell_type": "code",
"metadata": {
"id": "4x1_ORCU2RQl"
},
"source": [
"# Set up the decoder, using [h, c] as initial state.\n",
"decoder_inputs_placeholder = Input(shape=(max_len_target,))\n",
"\n",
"# this word embedding will not use pre-trained vectors\n",
"# although you could\n",
"decoder_embedding = Embedding(num_words_output, LATENT_DIM)\n",
"\n",
"decoder_inputs_x =
decoder_embedding(decoder_inputs_placeholder)\n",
"\n",
"# since the decoder is a \"to-many\" model we want to have\n",
"# return_sequences=True\n",
"decoder_lstm = LSTM(\n",
" LATENT_DIM,\n",
" return_sequences=True,\n",
" return_state=True,\n",
")\n",
"\n",
"decoder_outputs, _, _ = decoder_lstm(\n",
" decoder_inputs_x,\n",
" initial_state=encoder_states\n",
")\n",
"\n",
"# final dense layer for predictions\n",
"decoder_dense = Dense(num_words_output, activation='softmax')\
n",
"decoder_outputs = decoder_dense(decoder_outputs)\n",
"\n",
"# Create the model object\n",
"model = Model([encoder_inputs_placeholder,
decoder_inputs_placeholder], decoder_outputs)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "nuPfdD9wVcVx",
"outputId": "b166a9ad-8c2b-4156-a4f5-6e09f096f5b6"
},
"source": [
"model.summary()"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"________________________________________________________________________
__________________________\n",
"Layer (type) Output Shape Param #
Connected to \n",
"========================================================================
==========================\n",
"input_1 (InputLayer) [(None, 5)] 0
\n",
"________________________________________________________________________
__________________________\n",
"input_2 (InputLayer) [(None, 9)] 0
\n",
"________________________________________________________________________
__________________________\n",
"embedding (Embedding) (None, 5, 50) 116900
input_1[0][0] \n",
"________________________________________________________________________
__________________________\n",
"embedding_1 (Embedding) (None, 9, 256) 1617152
input_2[0][0] \n",
"________________________________________________________________________
__________________________\n",
"lstm (LSTM) [(None, 256), (None, 314368
embedding[0][0] \n",
"________________________________________________________________________
__________________________\n",
"lstm_1 (LSTM) [(None, 9, 256), (No 525312
embedding_1[0][0] \n",
"
lstm[0][1] \n",
"
lstm[0][2] \n",
"________________________________________________________________________
__________________________\n",
"dense (Dense) (None, 9, 6317) 1623469
lstm_1[0][0] \n",
"========================================================================
==========================\n",
"Total params: 4,197,201\n",
"Trainable params: 4,197,201\n",
"Non-trainable params: 0\n",
"________________________________________________________________________
__________________________\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sw420uIPoZnG"
},
"source": [
"## Model Compiling"
]
},
{
"cell_type": "code",
"metadata": {
"id": "tUQwiyZOAQjb"
},
"source": [
"# Compile the model and train it\n",
"model.compile(\n",
" optimizer='rmsprop',\n",
" loss='categorical_crossentropy',\n",
" metrics=['accuracy']\n",
")"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "HeTdTf17ock_"
},
"source": [
"## Model Fitting"
]
},
{
"cell_type": "code",
"metadata": {
"id": "j9oR7fA4ASw3",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "6d3fa079-6612-4a02-d685-79b22c3ec52a"
},
"source": [
"r = model.fit(\n",
" [encoder_inputs, decoder_inputs], decoder_targets_one_hot,\n",
" batch_size=BATCH_SIZE,\n",
" epochs=5, #EPOCHS,\n",
" validation_split=0.2,\n",
")"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Epoch 1/5\n",
"125/125 [==============================] - 13s 33ms/step -
loss: 3.4189 - accuracy: 0.6051 - val_loss: 2.5863 - val_accuracy:
0.6503\n",
"Epoch 2/5\n",
"125/125 [==============================] - 3s 26ms/step -
loss: 2.0379 - accuracy: 0.7127 - val_loss: 2.4423 - val_accuracy:
0.6698\n",
"Epoch 3/5\n",
"125/125 [==============================] - 3s 26ms/step -
loss: 1.8519 - accuracy: 0.7267 - val_loss: 2.2760 - val_accuracy:
0.6866\n",
"Epoch 4/5\n",
"125/125 [==============================] - 3s 26ms/step -
loss: 1.6913 - accuracy: 0.7443 - val_loss: 2.1812 - val_accuracy:
0.7003\n",
"Epoch 5/5\n",
"125/125 [==============================] - 3s 26ms/step -
loss: 1.5495 - accuracy: 0.7627 - val_loss: 2.1197 - val_accuracy:
0.7108\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Gz4Iiffiog33"
},
"source": [
"## Plot Diagnostics"
]
},
{
"cell_type": "code",
"metadata": {
"id": "5UK13HBjATk4",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 265
},
"outputId": "97d60608-fda8-4d68-cac9-be9d19765452"
},
"source": [
"# plot some data\n",
"plt.plot(r.history['loss'], label='loss')\n",
"plt.plot(r.history['val_loss'], label='val_loss')\n",
"plt.legend()\n",
"plt.show()"
],
"execution_count": null,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png":
"iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAALEgAACxIB0t1+/
AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG
90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deVxV1frH8c9iVsGJUSYRRVFEHDA1BSszrSzLsbk
s8zbaYN36Ndxu3bpD3bS6dfM2z6aZlmlZapaYpiKBojgrCCogKqKIDGf9/
tiHQAMEObDPOTzv1+u8Avbm7Ied58tmnbWerbTWCCGEcHwuZhcghBDCNiTQhRDCSUigCyGEk5
BAF0IIJyGBLoQQTsLNrAP7+fnpiIgIsw4vhBAOaePGjYe11v41bTMt0CMiIkhOTjbr8EII4ZC
UUpm1bZMhFyGEcBIS6EII4SQk0IUQwkmYNoYuhGiZysrKyM7OpqSkxOxS7JqXlxehoaG4u7vX
+3sk0IUQzSo7OxsfHx8iIiJQSpldjl3SWlNQUEB2djZdunSp9/
fJkIsQolmVlJTg6+srYV4HpRS+vr4N/itGAl0I0ewkzM/
tfM6RwwX6wcJTPPvNFsoqLGaXIoQQduWcga6UClNKrVRKbVVKbVFKPVDLfhcppVKt+/
xs+1INafsLef+XfbyxcldTHUII4eS8vb3NLqFJ1OcKvRyYobXuBQwG7lVK9aq+g1KqPfBf4Gq
tdQww0eaVWo3uHcTYvsG8/
uMu0nMKm+owQgjhcM4Z6Frrg1rrFOvHRUAGEHLWbjcAC7TWWdb98mxdaHXPXh1DxzYePDwvld
PlFU15KCGEE9Na8+ijj9K7d29iY2OZO3cuAAcPHiQxMZG+ffvSu3dvkpKSqKio4Lbbbvt931m
zZplc/R81aNqiUioC6AesO2tTd8BdKfUT4AO8qrX+qIbvnwZMAwgPD294tVbtW3vwz/
Gx3P5BMq8s38ljo6PP+7mEEOZ59pstbD1w3KbP2Su4Lc9cFVOvfRcsWEBqaippaWkcPnyYgQM
HkpiYyGeffcaoUaN48sknqaiooLi4mNTUVHJyckhPTwfg2LFjNq3bFur9pqhSyhv4EnhQa332
/wE3YABwJTAKeFop1f3s59Bav6W1jtdax/v719gs7NxKiyFvG5dEBzJxQCj/+3k3KVlHz+
+5hBAt2urVq7n++utxdXUlMDCQ4cOHs2HDBgYOHMj777/PX//6VzZv3oyPjw+RkZHs2bOH++
+/n6VLl9K2bVuzy/
+Del2hK6XcMcL8U631ghp2yQYKtNYngZNKqVVAHLDDZpVW2v4tfHkHBMbyt17j2OkTwiNfpPH
t9AS83F1tfjghRNOp75V0c0tMTGTVqlUsWbKE2267jYcffphbbrmFtLQ0vv/
+e2bPns28efN47733zC71DPWZ5aKAd4EMrfXMWnb7GhimlHJTSrUGBmGMtdtel+Ew+l/
g5onXymdZWPon/l74OMs/+RcUH2mSQwohnFNCQgJz586loqKC/
Px8Vq1axQUXXEBmZiaBgYHceeedTJ06lZSUFA4fPozFYmH8+PE8//
zzpKSkmF3+H9TnCn0ocDOwWSmVav3aE0A4gNZ6ttY6Qym1FNgEWIB3tNbpTVEw3v4w+C7jcWQ
PavN8uq75mMGZ/
8Ly75m4dLsU+kyE7peDR+smKUEI4RyuvfZa1q5dS1xcHEopXnzxRYKCgvjwww956aWXcHd3x9
vbm48++oicnBymTJmCxWKsgfnHP/5hcvV/
pLTWphw4Pj5e2+oGFydLypj+ykeMLP+ZSV7rcDlxCDy8IXoMxE6EyIvAVdrWCGEPMjIy6Nmzp
9llOISazpVSaqPWOr6m/
Z0i5dp4uTNt0jVc93YQW2Nm8Fzf47B5Hmz9GjZ9Dq39IOZa6DMJQgeCLDsWQjghh1v6X5tBkb
5MubALH63L5peKnnD1f+CRnXDdZxAxDH77GN4dCa/2gRXPQd42s0sWQgibcppAB/
jz6B5E+rXhz/
M3UVRSBm6eEH0lTPrQCPdrZoNvFKyeBf8dBG8Og9WvQGG22aULIUSjOVWge7m78u9JcRwsPMX
zi8+aZOPVFvpeDzcvgBnb4fIXjcBf/gzMioH3r4Dk92SmjBDCYTlVoAP0D+/AtMSuzE3ez4/
bcmveyTsABv0J7lwB03+Di5+Ck/
mw+CH4d3f47DrYPN9YxCSEEA7C6QId4KGRUXQP9ObxLzdzrLi07p07RsLwR+He9fCnVcZ0yIN
pxuKll7rBgmmwcxlUlDVP8UIIcZ6cMtA93Vx5eWJfCk6W8tdFW+r3TUpBpzi47Hl4KB1uXQyx
E2DHUvh0ArwcDUsegax1YNJUTyGEqItTBjpAbGg77ru4G1+lHmBp+qGGfbOLK3RJgKtfq5op0
yXBmCnz3mXVZso0zWJYIYT9qKt3+r59+
+jdu3czVlM3p5iHXpv7LunG8oxcnly4mYERHfD19mz4k1TOlIm+Ek4XQcZi2PyFMVMm6WUI7G
0sXuo9HtqH2f6HEEKIenLqQHd3deHlSXFc9Z/VPP11Om/
c0L9x9zL09DFmyvS9Hk7kwZaFRrgvf8Z4hF9otB3odQ207mi7H0QIZ/
Xd43Bos22fMygWLv9nrZsff/xxwsLCuPfeewH461//ipubGytXruTo0aOUlZXx/
PPPM3bs2AYdtqSkhLvvvpvk5GTc3NyYOXMmF198MVu2bGHKlCmUlpZisVj48ssvCQ4OZtKkSW
RnZ1NRUcHTTz/N5MmTG/VjgxMPuVSKDmrLg5d259vNh/
hm00HbPXHlTJmpy2F6qjFTpviwdaZMFHw22TpT5qTtjimEaLTJkyczb9683z+fN28et956Kws
XLiQlJYWVK1cyY8YMGtoW5Y033kApxebNm5kzZw633norJSUlzJ49mwceeIDU1FSSk5MJDQ1l
6dKlBAcHk5aWRnp6OqNHj7bJz+bUV+iV/pQYyQ9bc/nL1+kMjuxIgI+XbQ/
QsYsxUybxEeNqY/M82Pyl8YaqextjuKbPJGtPGXfbHlsIR1bHlXRT6devH3l5eRw4cID8/
Hw6dOhAUFAQDz30EKtWrcLFxYWcnBxyc3MJCgqq9/OuXr2a+++/
H4Do6Gg6d+7Mjh07GDJkCC+88ALZ2dmMGzeOqKgoYmNjmTFjBo899hhjxowhISHBJj+b01+hA
7i5uvDyxDhOlVbwxILNDf7NW29KQac+1pkyW+C2JcYQzM4frDNlesCSGTJTRgiTTZw4kfnz5z
N37lwmT57Mp59+Sn5+Phs3biQ1NZXAwEBKSkpscqwbbriBRYsW0apVK6644gp+/
PFHunfvTkpKCrGxsTz11FM899xzNjlWiwh0gG4B3jw6qgfLM/L4MiWn6Q/
o4mL0kLnqVXhkB1w3x+jl/tsnVTNllj8rM2WEMMHkyZP5/PPPmT9/
PhMnTqSwsJCAgADc3d1ZuXIlmZmZDX7OhIQEPv30UwB27NhBVlYWPXr0YM+ePURGRjJ9+nTGj
h3Lpk2bOHDgAK1bt+amm27i0UcftVlv9RYx5FJpytAufL/
lEM9+s4Wh3Xzp1K5V8xzYzROirzAep4tg2xLjzdRfXoXVM60zZSZA7wkyU0aIZhATE0NRUREh
ISF06tSJG2+8kauuuorY2Fji4+OJjm74fYrvuece7r77bmJjY3Fzc+ODDz7A09OTefPm8fHHH
+Pu7k5QUBBPPPEEGzZs4NFHH8XFxQV3d3fefPNNm/
xcTtEPvSEyC04y+pUk4iM68NHtFzRu1ktjnciDLV8Z4Z693vha+IVGuPe6Btr4mlebEE1E+qH
XX0P7obeYIZdKnX3b8H9XRJO08zCfrc8ytxjvABg0DaYuM2bKXPIUFBfAkofh5e4yU0YI0SAt
asil0k2DOrM0/
RAvLMkgMcqfsI52cKu6jl0g8VFIqJwp8wWknzVTJnYidL1YZsoI0cw2b97MzTfffMbXPD09Wb
dunUkV1azFDblUyj5azOhXkogJbsucOwfj4mKHdzGyWCBrjRHuW76CkmPQ2te4+1LsRAi9wHj
zVQgHkpGRQXR0tLnDnQ5Aa822bdtkyKU+Qju05ukxPVm39wgfrt1ndjk1O2OmzM5qM2U+hfdG
watxxkyZ3K1mVypEvXl5eVFQUNB004edgNaagoICvLwatmamxV6hg3HSbv9gA2v3FPDt9AQi/
WtvwmNXqs+U2b0SdAUExBhz3nuPh/
bhZlcoRK3KysrIzs622TxvZ+Xl5UVoaCju7mcOsdZ1hd6iAx0g93gJI2f+TLcAb76460Jc7XH
opS4n8qt6yvw+U2aIdabMtTJTRggnI0MudQhs68WzY2NIyTrGO0l7zC6n4bz9a5gpc8RYkfpy
d/
h0Emz6AspOmV2pEKKJtfgrdDCGXv708UZ+2pHPkvuHERXoY3ZJjaM15KbDpnnGTJnjOdCqA/
S9EQZMAb9uZlcohDhPMuRSD/
lFp7ls1s+EdWzNgrsvxM3VSf54sVhg3ypIfh+2LQZLufHGavztxlRImQIphEORIZd68Pfx5Pl
rYtmUXcibP+02uxzbcXExujxO+hAe2moMyRzZA1/cCrNiYMXf4Nh+s6sUQtiABHo1V/
bpxJg+nXjtx51sOVBodjm25xNoLF56IA1umAfB/
Yy7Lr3ax1iVuuN7sFSYXaUQ4jzJkMtZjp4sZeSsVfh5e7DovmF4uDn577xjWbDxQ0j5CE7mQb
twGHAr9LvZ+AUghLArjRpyUUqFKaVWKqW2KqW2KKUeqGPfgUqpcqXUhMYUbKYObTz4x7hYth0
q4rUVO80up+m1D4cRT8PDW2Hih0YLgh//
BrN6wbxbYe8q6d0uhIOoTy+XcmCG1jpFKeUDbFRKLdNan7E8USnlCvwL+KEJ6mxWI3sFMq5/
CG/
+vJuRvQKJC2tvdklNz9UdYq4xHod3wsYPjN7tW78C327Gm6hx18u9UoWwY+e8QtdaH9Rap1g/
LgIygJAadr0f+BLIs2mFJnnmqhj8vT2Z8UUaJWUtbFzZLwpGvQAztsE1s6FVR/
j+CZjZExbeDfs3yFW7EHaoQQPESqkIoB+w7qyvhwDXAnV2aVdKTVNKJSulkvPz8xtWaTNr18q
df03ow668E8xctsPscszh3gr6Xm8sWrprtTGPPWMRvHspzE6ADe8abQiEEHah3oGulPLGuAJ/
UGt9/KzNrwCPaa0tdT2H1votrXW81jre39+/4dU2s+Hd/
bn+gnDeTtpD8r4jZpdjrqBYGDPTuGofM8v42pKH4eVoWPyQ0fJXCGGqes1yUUq5A4uB77XWM2
vYvheobILiBxQD07TWX9X2nPY6y+VsJ06XM/
qVVbi5KL59IIHWHi2yhfwfaQ05G42r9C0LoLwEQgdC/
B3GOLx7M93eT4gWprGzXBTwLpBRU5gDaK27aK0jtNYRwHzgnrrC3JF4e7rx4oQ+7Cso5sWl28
0ux34oBaHxcO2b8HAGjPoHnDoGX91lXLUvfcJ4c1UI0WzqM+QyFLgZuEQplWp9XKGUukspdVc
T12cXLuzqx20XRvDBmn2s2X3Y7HLsT+uOMOQeuG8D3LrYuKvS+v/B6/
Hw4VVGN8jyUrOrFMLpycKieiouLeeKV5Mot2iWPpiIt6cMvdSpKBdSP4HkD6AwC9oEQP9bjEV
L0q9diPMmvVxsoLWHG/
+eGEfOsVO8sCTD7HLsn08gJMyAB1Lhhi8gZACsngmv9DFa+m5fKm0GhLAxCfQGiI/
oyJ0JkcxZn8XPO+x72qXdcHGF7pfBDZ/
DA5sg8RE4mApzJhu30Fv1knE1L4RoNBlyaaCSsgrG/Gc1J0rK+f6hRNq1kvazDVZRBtu/
heT3YM9P4OJmtPKNv91o7Ss3DxaiVjLkYkNe7q68PDGO/
BOnefabLWaX45hc3aHXWLjla7hvIwy6y+gZ89FY443UNa8bd10SQjSIBPp5iAtrz93Du7IgJY
dlW2W4oFH8uhltBh7eBte+Ba194YcnjamPC++C/
eulzYAQ9SRDLueptNzC1a+v5vCJUpY9lEiHNh5ml+Q8DqXDxvchbS6UFkFgb4ifAn0mg6eD3x
5QiEaSIZcm4OHmwsxJfSk8VcrTX6ebXY5zCeoNV75sbTPwijGmvmSGcdX+zYNwcJPZFQphlyT
QG6FXcFumXxLF4k0HWbLpoNnlOB9Pb+PK/E9JMPVH6HUNpM2B/
yXA2yMg9TMoO2V2lULYDRlyaaTyCgvj3lzD/iPF/
PDQcPx9PM0uybmdOgppnxszZA7vAK92RhfIAVPAv7vZ1QnR5GTIpQm5ubrw8sQ4TpZW8OTCzZ
j1C7LFaNUBBt8N966H25ZA1xGw/
m14YyB8MAbSF0ibAdFiSaDbQFSgDzNGdueHrbl8lZpjdjktg1IQMQwmvm/cPm/
EM3AsE+ZPMW6ft/xZOJppdpVCNCsZcrGRCotm0v/
WsjO3iB8eGk5QOy+zS2p5LBbYvcIYjtmx1JjuGDXSWLAUdZmxalUIBydDLs3A1UXx74lxlFZY
eHzBJhl6MYOLixHg18+BBzfD8D8bM2LmXGf0kPn5JSg6ZHaVQjQZCXQb6uLXhsdGR/
PT9nzmJe83u5yWrV0oXPwEPJQOkz427pO68nmYFQNzbzZaDljqvMGWEA5HhlxszGLR3PDOr6T
nHGfpgwmEdmhtdkmiUsFuY8HSb5/
CqSPQsasxLbLvjUZPdyEcgAy5NCMXF8VLE+LQWvPn+ZuwWGToxW74doXLnjfusDTubfAOgB+e
MhYsLZgGWeukzYBwaBLoTSCsY2ueuLIna3YX8Mk6mWlhd9y9oM8kuH0p3L3GuPHGtm/
hvcvgzaHGNMijmRLuwuHIkEsT0Vpzy3vrSd53lO8eSCDCr43ZJYm6nD4B6fONm14fsrYW8AmG
8EEQPgTCBhk9ZVzlTlXCXHUNuUigN6GDhae4bNYqooN8+HzaEFxdpM+33dMa8rZC5hrIWgtZv
8Jx69oCD2/jxthhgyF8sPGxNAsTzUwC3UTzN2bzyBdpPHVlT6YmRJpdjjgfx/bD/
nXWgF8HuemABuUCQbFVAR8+GNoGm12tcHIS6CbSWnPnR8ms2nmYb6cn0C3A2+ySRGOVFEL2Bu
PqPetXyNkIZcXGtvbhZwa8f09jfrwQNiKBbrK8ohIum7WKzr5t+PKuIbi5ygvcqVSUGePuWda
r+P3r4IT1xide7SD0gqqAD+4PHjKVVZw/CXQ7sCjtANPn/
Majo3pw78XdzC5HNCWt4ejeMwM+f5uxzcUNOvWtCviwweDtb269wqFIoNsBrTX3fpbCsq25fH
P/MKKD2ppdkmhOxUeM2+ntrxymSYGK08a2jl3PDHi/
KLlRtqiVBLqdKDhxmstmrSKonRcL7xmKh5sMvbRY5afhQGpVwGf9aqxeBWjV0Rru1imTwX3BT
frsC4MEuh1Zmn6Iuz7ZyPQRUTw8Um7IIKy0hoJdVTNpstbCkd3GNldPCOlfFfBhF0irghZMAt
3OPPj5b3yz6SBf3TOU2NB2Zpcj7NWJ/
DOv4A+mgaXM2OYfbQ1461BNhy4yTNNCSKDbmcLiMkbO+pn2rd355v5heLpJn25RD2WnjLH3yj
das9bB6UJjW5uAqnAPHwxBfcDV3dx6RZNoVKArpcKAj4BAQANvaa1fPWufG4HHAAUUAXdrrdP
qet6WHOgAK7flMeWDDdw1vCuPXx5tdjnCEVksxuyZ3wN+LRzLMra5t4aQAVUBHzrQmEIpHF5d
gV6fxhTlwAytdYpSygfYqJRaprXeWm2fvcBwrfVRpdTlwFvAoEZX7sQujg5gcnwYb63azWUxg
fQP72B2ScLRuLhAYC/
jMfAO42vHD545TJM0E3QFoIxeNOGDqhY+tQ8ztXxhew0eclFKfQ28rrVeVsv2DkC61jqkrudp
6VfoAEUlZYx+JQlPNxeWTE+glYcMvQgbO30CcpKrAj57A5SeMLa1DamaKhk+GAJj5DZ9DqCxV
+jVnygC6Aesq2O3O4DvGvK8LZWPlzsvTujDje+s46Xvt/
OXq3qZXZJwNp7eEHmR8QCoKIe8LVUzaTLXQvqXxjYPHwgbeGbzMQ/
pEupI6n2FrpTyBn4GXtBaL6hln4uB/
wLDtNYFNWyfBkwDCA8PH5CZKb3CAZ7+Kp1P1mXy+Z2DGRTpa3Y5oiXRGgr3n7mqNXcLRvMxV6
P5WPiQqqGatp3MrrjFa/QsF6WUO7AY+F5rPbOWffoAC4HLtdY7zvWcMuRS5eTpci5/
NQmNZukDibTxlJ7bwkSnjkF2ctVYfHYylJ8ytrXvXBXw4UPAr4c0H2tmjZ3looAPgSNa6wdr2
Scc+BG4RWu9pj5FSaCfaf3eI0x+ay03Dgrn+WtizS5HiCoVZXBwkzXgrQufTuYZ27zaGwudAm
PANwp8uxmtC2ThU5NpbKAPA5KAzUDlbdKfAMIBtNazlVLvAOOByjGU8toOWEkC/Y/
+tngr767eyyd3DGJYlJ/Z5QhRM63hyB7rVMlfjR41BbuqFj0BtOpQLeC7Gf/
1jYKOkcYtAMV5k4VFDqKkrIIrXkuipLSCpQ8l0tZLFoYIB1FRDscyjWAv2AWHd1Z9XHSw2o7K
mC5Z/Wret6vxedsQGb6pBwl0B/
Jb1lHGv7mG8f1DeWlinNnlCNF4p4ugYHfNYV85hRLArZU13Lv+MfBbyTqNSjabtiiaXr/
wDvxpeFfe/
Gk3o3sHMaJnoNklCdE4nj5Gx8jgvmd+XWvjRiDVA75gFxxKh4zF1gVRVq39zryarwz7DhHSib
IauUK3Q6fLK7j6P79wpLiUZQ8l0r61h9klCdG8ykuNIZzfw36ncZV/eGfVG7Jg3Ne1fec/
Dt/4djPu7+qEDctkyMUBpecUcs0bv3Bln068el0/
s8sRwn6UFFpD3hrwBTurPq+8tyuAextrwFeGfbeqh5fj3mBGhlwcUO+Qdtx3STdeWb6Ty3sHM
bq3LOgQAjCajIUMMB7VWSzGG7CVAX/
YOoRzIAW2fgXaUrWvd+CZAV8Z+B0iHLpLpQS6Hbv34m4sz8jlyYXpDIzoiK+3jBUKUSsXF2gX
YjwiLzpzW/lpOLL3j2G/
bTEUV1vU7uJmhHpNYe8daPdDODLkYue2Hyriqv+sZkTPAP57Y3+Unf+DEsLhFB+pNgtnp3UYZ
7dxx6jykqr9PHyMIZyzh298uxk9c5qJDLk4sB5BPjw4MooXl25nUdoBxvats4mlEKKhWnc0Hm
EDz/y6xQLHs6sCvvLqPmsdbJ6PcXsIK5/
gs8Le+gZt+87g2nwxK4HuAKYlRPLDllz+8vUWhkT6EtBWVtoJ0eRcXKB9uPHoNuLMbWWnjNWy
Z0+5TF8AJceqPYc7dOxSFfCVge8f3STtEWTIxUHszj/BFa8mMaybH+/
cGi9DL0LYI62tQzg7/xj2R/ZARamx35D7YNQL53UIGXJxAl39vXl0VA+eX5LB/
I3ZTIyXu80IYXeUgja+xiN88JnbLBXGLQILdhlz5JuANE5wILcP7cIFER157putHDh2yuxyhB
AN4eJqDL9EjTS6UzbFIZrkWUWTcHFRvDSxD+UWzWNfbsKs4TIhhH2SQHcwnX3b8MQV0STtPMy
n67LMLkcIYUck0B3QjYM6M7SbL3//
NoOsguJzf4MQokWQQHdALi6KFyfE4aIUj85Pw2KRoRchhAS6wwpp34q/
jOnFur1H+GDNPrPLEULYAQl0BzYxPpSLe/jz4vfb2JN/4tzfIIRwahLoDkwpxT/
H98HTzZVHvkijQoZehGjRJNAdXGBbL569OoaUrGO8nbTH7HKEECaSQHcCY/sGMyomkJk/
7GBHbpHZ5QghTCKB7gSUUrxwbSzeXm7MmJdGWYXl3N8khHA6EuhOws/bk+ev6c3mnELe/
Gm32eUIIUwgge5ErojtxFVxwby2YifpOYVmlyOEaGYS6E7muatj6NDGg0e+SON0eYXZ5Qghmp
EEupPp0MaDf1wby7ZDRby2YqfZ5QghmpEEuhO6tFcg4/
uH8uZPu0ndf+zc3yCEcAoS6E7qL1f1IsDHixnzUikpk6EXIVoCCXQn1a6VOy9O6MPu/JO8/
MN2s8sRQjSDcwa6UipMKbVSKbVVKbVFKfVADfsopdRrSqldSqlNSqn+TVOuaIjE7v7cMCicd1
bv5YmFm9kt/V6EcGr1uadoOTBDa52ilPIBNiqllmmtt1bb53IgyvoYBLxp/a8w2ZNX9ARg/
sZsPluXxaU9A5iaEMmgLh3lRtNCOJlzXqFrrQ9qrVOsHxcBGUDIWbuNBT7Shl+B9kqpTjavVj
RYG083/n5tLGsev4TpI6JIyTrGdW/
9ytg3fmFR2gHKZVWpEE6jQWPoSqkIoB+w7qxNIcD+ap9n88fQRyk1TSmVrJRKzs/
Pb1ilolH8vD15eGR31jx+CS9c25sTJeVMn/
Mbw1/6iXeS9lBUUmZ2iUKIRqp3oCulvIEvgQe11sfP52Ba67e01vFa63h/f//
zeQrRSF7urtw4qDPLHx7O27fEE9KhFc8vyeDCf/zI37/N4MCxU2aXKIQ4T/
UZQ0cp5Y4R5p9qrRfUsEsOEFbt81Dr14SdcnFRjOwVyMhegaTtN1rvvrt6L+
+t3suYPp2YmhBJ75B2ZpcphGiAcwa6Mt45exfI0FrPrGW3RcB9SqnPMd4MLdRaH7RdmaIpxYW
15/Ub+pN9tJj3f9nH5+uz+Cr1AEMifbkzsQsXdQ/
AxUXeQBXC3imt677LjVJqGJAEbAYq30F7AggH0FrPtob+68BooBiYorVOrut54+PjdXJynbsI
kxSeKuPz9Vm8/8s+Dh0voVuAN1OHdeGafiF4ubuaXZ4QLZpSaqPWOr7GbecK9KYigW7/
yiosLNl0kLeT9rDlwHH8vD24eXAENw/pTMc2HmaXJ0SLJIEuGkVrzdrdBbydtIeV2/
PxcndhfP9Q7hjWhUh/b7PLE6JFqSvQ6/
WmqGjZlFJc2M2PC7v5sTO3iHeS9vJFcjafrc9iRHQg0xIjGRjRQRYqCWEyuUIX5yW/
6DQfr93Hx79mcrS4jLjQdkxNiOTy3kG4uUqLICGaigy5iCZzqrSC+SnZvLd6L3sPnySkfStuH
9aFyQPD8PaUPwCFsDUJdNHkLBbN8oxc3knay/
p9R59oINYAAA9kSURBVPDxcuOGC8K5bWgEndq1Mrs8IZyGBLpoVqnWhUrfbT6Ii1JcFRfM1IQ
uxATLQiUhGksCXZhi/xFjodLcDVmcLK3gwq6+3JkYyUXd/eUNVCHOkwS6MFXhqTLmrM/
iA+tCpagAb6YmdGFsX1moJERDSaALu1BabmHxpgO8nbSXjIPGQqVbh0Rw0+DOdJCFSkLUiwS6
sCtaa9ZYFyr9ZF2oNGFAKHcMi6SLXxuzyxPCrsnCImFXlFIM7ebH0G5+7Mgt4p2kPczbkM2n6
7IY2TOQOxMjie8sC5WEaCi5Qhd2Ia+ohI/
XZvLxr5kcKy4jLqw9dyZ0YXSMLFQSojoZchEOo7i0nC83ZvPu6r3sKygmtEMrbh/
ahUmyUEkIQAJdOKAK60Klt1ftITnzKD5ebtw4qDO3XRhBUDsvs8sTwjQS6MKh/
ZZ1lHeS9vJdurFQ6eq4YKYmRNIruK3ZpQnR7CTQhVPYf6SYd1fvZV7yfopLKxjazZc7EyIZLg
uVRAsigS6cSmFxGZ+tz+KDNXvJPX6a7oHeTB0Wydh+wXi6yUIl4dwk0IVTKi238E3aAd5O2sO
2Q0X4+3hy65DO3DhIFioJ5yWBLpya1ppfdhkLlX7eYSxUmjggjDuGdSFCFioJJyMLi4RTU0ox
LMqPYVF+bD9kLFSau2E/
n6zL5LJegdyZEMkAWagkWgC5QhdOKe94CR+u3ccnv2ZReKqMvmHtmZYYyaiYIFxdJNiF45IhF
9FiFZeWM9+6UCmzoJiwjtaFSvFhtJGFSsIBSaCLFq/
Colm29RBvJ+1lY+ZR2nq5ceNgY6FSYFtZqCQchwS6ENWkZB3lnaQ9LE0/
hKuLcUelOxMi6dlJFioJ+yeBLkQNsgqKee+XqoVKCVF+TE2IJDHKT95AFXZLAl2IOhQWl/
Hp+kw+
+GUfeUWn6RHow3UXhHF1XDC+3p5mlyfEGSTQhaiH0nILi9IO8P4ve9ly4DhuLoqLevgzrn8ol
0QHyO3yhF2QQBeigbYdOs7ClBwW/
pZDXtFp2nq5MSYumPH9Q+gfLnPahXkaFehKqfeAMUCe1rp3DdvbAZ8A4RgLlf6ttX7/
XEVJoAtHUGHR/LLrMAt/y2Fp+iFOlVXQ2bc11/YLYVy/
UMJ9W5tdomhhGhvoicAJ4KNaAv0JoJ3W+jGllD+wHQjSWpfW9bwS6MLRnDhdztL0QyxIyWbtn
gK0hoERHRjXP5QrYjvRrpW72SWKFqBRS/+11quUUhF17QL4KONvUG/
gCFB+HnUKYde8Pd2YMCCUCQNCyTl2iq9+y2FBSjb/t2AzzyzawshegYzvH0JClD/
ucts8YYJ6jaFbA31xLVfoPsAiIBrwASZrrZfU8jzTgGkA4eHhAzIzM8+7cCHsgdaazTmFLEjJ
4evUHI4Wl+Hn7cFVccGM7x9KTHBbGW8XNtXoN0XPEegTgKHAw0BXYBkQp7U+XtdzypCLcDal5
RZ+3pHPgpRsVmTkUVphoXugN+P6h3JN3xC5dZ6wiabutjgF+Kc2fjPsUkrtxbhaX2+D5xbCYX
i4uTCyVyAjewVyrLiUxZsOsiAlm39+t41/Ld3GsG5+XNsvhFExQdJHRjQJW/
yrygJGAElKqUCgB7DHBs8rhMNq39qDmwZ35qbBndl7+CQLrePtD89Lo7VHOqN7BzG+fyiDI32
l+6OwmfrMcpkDXAT4AbnAM4A7gNZ6tlIqGPgA6AQojKv1T851YBlyES2NxaJJzjzKgpRslmw6
SNHpcjq18+KafiGM6xdCVKCP2SUKByALi4SwMyVlFSzPyGVBSg4/78inwqLpE9qOcf1CuEpaD
og6SKALYcfyi06zKO0AC1KypeWAOCcJdCEchLQcEOcigS6Eg5GWA6I2EuhCODBpOSCqk0AXwk
lUbzmwO//
k73PfpeVAyyGBLoSTqanlgG8bD67uKy0HnJ0EuhBOTFoOtCwS6EK0ENVbDqRkHUMpGNrVj3H9
peWAs5BAF6IFqt5yIPvoKVp7uErLAScggS5ECyYtB5yLBLoQAjBaDizbmsuClGxW7TxMhUUTG
9KOcf1DuFpaDjgECXQhxB9IywHHJIEuhKhTbS0HxvULYUBnaTlgTyTQhRD1Ii0H7J8EuhCiwa
TlgH2SQBdCNEptLQfG9Qshsbu0HGhOEuhCCJvQWrMpu5AFKdksSjvwe8uBy2ICubRnIEO7+cm
bqU1MAl0IYXOVLQe+
+i2Hn7bncbK0Ai93F4Z18+PSnoFcEh1AQFtpO2BrdQW6rAMWQpyXymGXkb0COV1ewbo9R1iRk
cvyjDyWZ+QBEBfajhE9jav3np18ZLZME5MrdCGETWmt2XaoiBUZuSzLyCNt/
zEAgtt5GeHeK5DBkR3xdJOhmfMhQy5CCNPkFZWwcptx1Z60M5+SMgttPFxJiPJnRM8ALokOkB
WqDSCBLoSwCyVlFazZfZjlGXmsyMgl9/
hplIL+4R0Y0TOAkT0D6RbgLUMzdZBAF0LYHa016TnHWZ6Ry4ptuaTnHAcgvGPr38N9YJeOMiX
yLBLoQgi7d7DwFCusV+6/7C6gtNyCj5cbw7v7c2nPQC7q4U/
71h5ml2k6CXQhhEMpLi0naedhVmTk8uO2PA6fKMXVRRHfuQOXWt9Y7eLXxuwyTSGBLoRwWBaL
JjX7mDElcmse23OLAIj0b8OlPQMZER3AgM4dcGshQzMS6EIIp7H/SDErMnJZsS2PX/
cUUFahad/
anYt7BDCiZwCJ3f1p6+W8fWYk0IUQTqmopIxVO6xDM9vzOFZchrurYlAXX0b0DODSnoGEdXSu
DpGNCnSl1HvAGCBPa927ln0uAl4B3IHDWuvh5ypKAl0IYUvlFRZSsqxDMxm57M4/
CUCPQB9G9AxgRM9A+oa1d/
h7qTY20BOBE8BHNQW6Uqo9sAYYrbXOUkoFaK3zzlWUBLoQointPXzy93DfsO8oFRaNn7eHdWg
mkIQoP9p4Ol73k0YPuSilIoDFtQT6PUCw1vqphhQlgS6EaC6FxWX8tMNYrfrT9jyKSsrxcHPh
wq6+1l4zAXRq18rsMuulqQO9cqglBvABXtVaf1TL80wDpgGEh4cPyMzMrOePIIQQtlFWYWHD3
iPGatVtuWQWFAMQE9z293DvHdwOFzsdmmnqQH8diAdGAK2AtcCVWusddT2nXKELIcymtWZX3o
nfWxGkZB3FoiGwrSeXRBvhbm893pu6fW42UKC1PgmcVEqtAuKAOgNdCCHMppQiKtCHqEAf7r6
oKwUnTrNyez4rMnJZlJrDnPVZ1h7v/lzaM4BLegYQ4GO/
Pd5tEehfA68rpdwAD2AQMMsGzyuEEM3K19uTCQNCmTAglNPlFfxq7fG+IiOP5Rm5AMSFtefSa
OONVXvr8V6fWS5zgIsAPyAXeAZjzByt9WzrPo8CUwAL8I7W+pVzHViGXIQQjqKyx/
vyrbks31bV4z2kfavfp0Q2V493WVgkhBA2VNnjfdnWPFbvqurxntjdnxE9A7m4h3+T9XiXQBd
CiCZS2eN92dY8ftxW1eN9QHiH32fN2LLHuwS6EEI0g+o93pdn5LLlQFWP90ut4d7YHu8S6EII
YYLKHu/
LM3JZU63H+wMjopiaEHlez9nU0xaFEELUoFO7Vtw0uDM3De7MydPlrN51mOVbcwlq1zRTHyXQ
hRCiGbTxdGNUTBCjYoKa7BgtoyO8EEK0ABLoQgjhJCTQhRDCSUigCyGEk5BAF0IIJyGBLoQQT
kICXQghnIQEuhBCOAnTlv4rpfKB870HnR9w2Ibl2Iq91gX2W5vU1TBSV8M4Y12dtdb+NW0wLd
AbQymVXFsvAzPZa11gv7VJXQ0jdTVMS6tLhlyEEMJJSKALIYSTcNRAf8vsAmphr3WB/
dYmdTWM1NUwLaouhxxDF0II8UeOeoUuhBDiLBLoQgjhJOw60JVSo5VS25VSu5RSj9ew3VMpNd
e6fZ1SKsJO6rpNKZWvlEq1PqY2U13vKaXylFLptWxXSqnXrHVvUkr1t5O6LlJKFVY7X39phpr
ClFIrlVJblVJblFIP1LBPs5+vetbV7OfLelwvpdR6pVSatbZna9in2V+T9azLrNekq1LqN6XU
4hq22f5caa3t8gG4AruBSMADSAN6nbXPPcBs68fXAXPtpK7bgNdNOGeJQH8gvZbtVwDfAQoYD
Kyzk7ouAhY387nqBPS3fuwD7Kjh/2Ozn6961tXs58t6XAV4Wz92B9YBg8/
ax4zXZH3qMus1+TDwWU3/
v5riXNnzFfoFwC6t9R6tdSnwOTD2rH3GAh9aP54PjFBKKTuoyxRa61XAkTp2GQt8pA2/
Au2VUp3soK5mp7U+qLVOsX5cBGQAIWft1uznq551mcJ6Hk5YP3W3Ps6eVdHsr8l61tXslFKhw
JXAO7XsYvNzZc+BHgLsr/Z5Nn/8h/37PlrrcqAQ8LWDugDGW/
9Mn6+UCmvimuqrvrWbYYj1T+bvlFIxzXlg65+6/
TCu7Koz9XzVUReYdL6sQwipQB6wTGtd6zlrxtdkfeqC5n9NvgL8GbDUst3m58qeA92RfQNEaK
37AMuo+i0sapaC0Z8iDvgP8FVzHVgp5Q18CTyotT7eXMc9l3PUZdr50lpXaK37AqHABUqp3s1
17LrUo65mfU0qpcYAeVrrjU15nLPZc6DnANV/
i4Zav1bjPkopN6AdUGB2XVrrAq31aeun7wADmrim+qrPOW12WuvjlX8ya62/
BdyVUn5NfVyllDtGaH6qtV5Qwy6mnK9z1WXW+TqrhmPASmD0WZvMeE2esy4TXpNDgauVUvswh
mUvUUp9ctY+Nj9X9hzoG4AopVQXpZQHxpsGi87aZxFwq/
XjCcCP2voOg5l1nTXOejXGOKg9WATcYp29MRgo1FofNLsopVRQ5dihUuoCjH+XTRoC1uO9C2R
orWfWsluzn6/61GXG+bIey18p1d76cStgJLDtrN2a/TVZn7qa+zWptf4/
rXWo1joCIyN+1FrfdNZuNj9Xbo355qaktS5XSt0HfI8xs+Q9rfUWpdRzQLLWehHGP/
yPlVK7MN50u85O6pqulLoaKLfWdVtT1wWglJqDMQPCTymVDTyD8QYRWuvZwLcYMzd2AcXAFDu
pawJwt1KqHDgFXNcMv5iHAjcDm61jrwBPAOHV6jLjfNWnLjPOFxgzcD5USrli/
BKZp7VebPZrsp51mfKaPFtTnytZ+i+EEE7CnodchBBCNIAEuhBCOAkJdCGEcBIS6EII4SQk0I
UQwklIoAshhJOQQBdCCCfx/6vqesAsdYQQAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "ZrCkUfCBAaXe",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 265
},
"outputId": "b4a20c38-320e-4fbd-bf8f-607a4cfddae9"
},
"source": [
"# accuracies\n",
"plt.plot(r.history['accuracy'], label='acc')\n",
"plt.plot(r.history['val_accuracy'], label='val_acc')\n",
"plt.legend()\n",
"plt.show()"
],
"execution_count": null,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png":
"iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAALEgAACxIB0t1+/
AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG
90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deXxUVZ7//9fJzhII2SBkIWFNgLAmbC6oiA2C4oK
C2iq2DW272z+nRx1HHHVm/PWj+9ttT/ulB5d2aRUUXGhQEQRFBSELe1hlS5GQBZJAIGvV5/
vHLSSmAwSt5NbyeT4ePEzde27qU9fUOzfnnjrHiAhKKaX8V5DdBSillGpbGvRKKeXnNOiVUsr
PadArpZSf06BXSik/
F2J3Ac3FxsZKamqq3WUopZRPycvLKxeRuJb2eV3Qp6amkpuba3cZSinlU4wxB8+2T7tulFLKz
2nQK6WUn9OgV0opP+d1ffQtaWhowOFwUFtba3cpXikiIoKkpCRCQ0PtLkUp5YV8IugdDgeRkZ
GkpqZijLG7HK8iIhw9ehSHw0FaWprd5SilvJBPdN3U1tYSExOjId8CYwwxMTH6145S6qx8Iug
BDflz0HOjlDoXn+i6UUopf1ZV08CKghLqG13cOjrF499fg14ppWxworaBz3eUsnRLEWt2l1Pv
dDE8JUqDXimlfNmp+kZW7ihl2ZYiVu8qo77RRY8uEdw+thdThyQwLDmqTZ5Xg/
4CXHfddRQWFlJbW8tDDz3EnDlz+PTTT3niiSdwOp3Exsby+eefU11dzQMPPEBubi7GGObOncu
NN95od/lKKRvU1Dv5YlcpS7cU8/nOEmobXMRFhnPrqBSmDklgREo3goLa9j6bzwX9f/
xjOwVFxz36PQf27MLcawadt92rr75KdHQ0NTU1ZGdnM23aNGbPns2aNWtIS0vj2LFjADz77LN
07dqVrVu3AlBRUeHRepVS3q22wcmXu8tYtqWYlTtKOFXvJKZTGNNHJjF1SE+yU6MJbuNwb6pV
QW+MmQS8AAQDL4vI8832/xG43P2wIxAvIlHufSnAy0AyIMDVInLAI9W3sz//
+c988MEHABQWFjJ//nwuvfTS78evR0dHA7By5UoWLFjw/XHdunVr/
2KVUu2qvtHFV3uscF9RUMKJuka6dQxl2rCeTB3Sk9Fp0YQE2zPQ8bxBb4wJBl4EJgIOIMcYs0
RECk63EZFHmrR/
ABje5Fu8AfyniKwwxnQGXD+l4NZcebeFL774gpUrV7Ju3To6duzIZZddxrBhw9i5c6ct9Sil7
NfgdPHN3nKWbSlm+fYjHK9tpEtECJMG92Dq0J6M6xNDqE3h3lRrruhHAXtFZB+AMWYBMA0oOE
v7W4C57rYDgRARWQEgItU/uWKbVFVV0a1bNzp27MjOnTv59ttvqa2tZc2aNezfv//
7rpvo6GgmTpzIiy++yJ/+9CfA6rrRq3ql/EOj08W3+46xdEsRn24/
QuWpBiLDQ5g4qDtThyRwcd84wkLsD/
emWhP0iUBhk8cOYHRLDY0xvYA0YJV7U3+g0hjzvnv7SuAxEXE2O24OMAcgJcXzQ4s8YdKkSfz
1r38lIyODAQMGMGbMGOLi4pg/
fz433HADLpeL+Ph4VqxYwZNPPsl9993H4MGDCQ4OZu7cudxwww12vwSl1I/
kdAkb9rvDfdsRjp6sp1NYMFcO7M6UzAQu7R9HRGiw3WWeladvxs4EFjUJ8hDgEqyunEPAQmAW
8ErTg0RkPjAfICsrSzxck0eEh4fzySeftLhv8uTJP3jcuXNnXn/
99fYoSynVRlwuIe9QBUs3F/
HxtiOUnaijQ2gwV2TEMzUzgcvT47063JtqTdAfxrqRelqSe1tLZgL3NXnsADY16fb5EBhDs6B
XSilvICJsLKxk6eZiPt5azJHjtYSHBHH5gHimDElgQkY8HcN8brBiq4I+B+hnjEnDCviZwK3N
Gxlj0oFuwLpmx0YZY+JEpAy4AtB1ApVSXkNE2Hq4iqVbilm2pZjDlTWEBQdxaf84Hr86nQkZ3
ekc7nvh3tR5qxeRRmPM/
cByrOGVr4rIdmPMM0CuiCxxN50JLBARaXKs0xjzKPC5sWbeygNe8virUEqpCyAiFBQf/
z7cDx07RUiQ4ZJ+sfxmYn+uHNidrh38Z32HVv2aEpGPgY+bbXuq2eOnz3LsCmDIj6xPKaU8Zt
eREyzdUsSyLcXsKz9JcJBhXJ8Y7r+8L1cN6k5UxzC7S2wTvv33iFJKncfe0urvw31PaTVBBsb
0juGXl/
Rm0uAeRHfyz3BvSoNeKeV3DpSfZOmWIpZuKWbnkRMYA9mp0Tw7bRCTBicQFxlud4ntSoNeKeU
XCo+dYumWYpZuKWK7ez6skb26MfeagVydmUD3LhE2V2gfDfo20rlzZ6qrffaDwEr5hMOVNXzs
DvfNjioAhiVH8eSUDK7OTKBnVAebK/QOGvRKKZ9ypKqWj7da4Z5/
qBKAzMSuPDY5nSmZCSRHd7S5Qu/je0H/yWNwZKtnv2ePTJj8/DmbPPbYYyQnJ3PffdbnwZ5+
+mlCQkJYvXo1FRUVNDQ08NxzzzFt2rTzPl11dTXTpk1r8bg33niD3//+9xhjGDJkCG++
+SYlJSXcc8897Nu3D4B58+Yxbty4n/iilfIdpSdq+XTbEZZuLibn4DFEICOhC//
yswFMyUwgNbaT3SV6Nd8LepvMmDGDhx9++Pugf/
fdd1m+fDkPPvggXbp0oby8nDFjxnDttdeed7HuiIgIPvjgg386rqCggOeee461a9cSGxv7/
fz2Dz74IOPHj+eDDz7A6XRql5AKCEer6/h0uxXu6/
cfxSXQv3tnHp7QnylDEugb39nuEn2G7wX9ea6828rw4cMpLS2lqKiIsrIyunXrRo8ePXjkkUd
Ys2YNQUFBHD58mJKSEnr06HHO7yUiPPHEE/
903KpVq7jpppuIjY0Fzsxvv2rVKt544w0AgoOD6dq1a9u+WKVsUnmqnuXbj7B0SzFrvzuK0yX
0ju3E/
Zf3ZerQnvTvHml3iT7J94LeRjfddBOLFi3iyJEjzJgxg7feeouysjLy8vIIDQ0lNTWV2tra83
6fH3ucUv6oqqaBFQUlLN1SxNd7yml0Cb1iOnLP+N5MyexJRkLkef9KVuemQX8BZsyYwezZsyk
vL+fLL7/k3XffJT4+ntDQUFavXs3Bgwdb9X2qqqpaPO6KK67g+uuv5ze/+Q0xMTHfz28/
YcIE5s2bx8MPP/
x9141e1StfdqK2gZU7Sli2pZg1u8upd7pIjOrA3ZekMTWzJ4MTu2i4e5AG/
QUYNGgQJ06cIDExkYSEBG677TauueYaMjMzycrKIj09vVXf52zHDRo0iH/7t39j/
PjxBAcHM3z4cF577TVeeOEF5syZwyuvvEJwcDDz5s1j7NixbflSlfK4U/
WNrNxRyrItRazeVUZ9o4uErhHcMbYXU4YkMCw5SsO9jZgmc5B5haysLMnN/
eEElzt27CAjI8OminyDniPljWrqnazeVcqyLcV8vrOE2gYX8ZHhXJ2ZwDVDExie3I2gdlwk25
8ZY/
JEJKulfXpFr5TyKKdLWPtdOYvzHHxWUMKpeiexncO4aWQyU4ckkJUaTbCGe7vSoG9DW7du5fb
bb//BtvDwcNavX29TRUq1ne/
Kqlmc5+CDjYcprqqlS0QI04b15JohPRmVFk2IFyySHah8JuhFxOf67zIzM9m0aVObP4+3db+p
wFFV08DSLUUsynOw8VAlQQbG94/
jySkDmZDhO0vt+TufCPqIiAiOHj1KTEyMz4V9WxMRjh49SkRE4E7YpNqX0yV8taeMRe6umfpG
F/27d+aJq9O5blgi8QE8eZi38omgT0pKwuFwUFZWZncpXikiIoKkpCS7y1B+bk/JCRblO/
gg/
zClJ+qI6hjKLdnJTB+ZrMMhvZxPBH1oaChpaWl2l6FUwKk8Vc+SzUUsznOw2VFFcJDh8gHxTB
+ZyOXp8YSHaNeML/CJoFdKtZ9Gp4svd5exON/
ByoJS6p0u0ntE8uSUDKYNSwy4RTv8gQa9UgqAnUeOsyjXwYebiiivriO6Uxg/
H9OLG0cmMqinfhLbl2nQKxXAjp2s56NNh1mU52B70XFCgw1XpMczfWQylw2II1SHRPoFDXqlA
kyD08XqnaUsynOwelcpDU5hcGIXnr5mINcOSwyIxbIDjQa9UgFie1EVi/
IcfLSpiGMn64ntHM6scancODKJ9B5d7C5PtSENeqX8WNmJuu+7ZnYeOUFYcBBXDoxn+sgkLu0
Xp59WDRAa9Er5mbpGJ6t2lLI438HqXWU4XcLQ5CienTaIa4b2JKqjds0EGg16pfyAiLD1sNU1
s2RzEZWnGoiPDGf2Jb2ZPjKRvvG6MlMga1XQG2MmAS8AwcDLIvJ8s/1/
BC53P+wIxItIVJP9XYAC4EMRud8ThSuloPR4LR9sPMzifAe7S6oJCwniZ4N6cOOIRC7uG6tdM
wpoRdAbY4KBF4GJgAPIMcYsEZGC021E5JEm7R8Ahjf7Ns8CazxSsVIBrrbBycodJSzKc7Bmdx
kugREpUfzX9ZlMGZJA1w6hdpeovExrruhHAXtFZB+AMWYBMA3rCr0ltwBzTz8wxowEugOfAi1
Oiq+UOjcRYVNhJYvyHPxjcxHHaxtJ6BrBry/
rww0jkugT19nuEpUXa03QJwKFTR47gNEtNTTG9ALSgFXux0HAH4CfA1ee7QmMMXOAOQApKSmt
qVupgHCkqpb3NzpYlOdgX9lJIkKDmDSoB9NHJjO2T4wu4KFaxdM3Y2cCi0TE6X58L/
CxiDjONbOdiMwH5oO1lKCHa1LKp9TUO/
ms4AiL8hx8vbccEchO7cavLu3N1ZkJREZo14y6MK0J+sNAcpPHSe5tLZkJ3Nfk8VjgEmPMvUB
nIMwYUy0ij/2YYpXyVyJC3sEKFuc7WLq5mBN1jSRGdeCBy/
tyw4gkUmM72V2i8mGtCfocoJ8xJg0r4GcCtzZvZIxJB7oB605vE5HbmuyfBWRpyCt1xuHKGt7
Pc7A438GBo6foEBrM5MweTB+ZxJi0GF04W3nEeYNeRBqNMfcDy7GGV74qItuNMc8AuSKyxN10
JrBAdF07pc7pVH0jn247wuJ8B2u/O4oIjOkdzX2X92VyZgKdw/
XjLcqzjLflclZWluTm5tpdhlIe5XIJOQeOsSjPwcdbizlZ7yQ5ugPTRyRzw4hEkqM72l2i8nH
GmDwRaXFko146KNWGCo+dYnG+1TVTeKyGTmHBTBmSwI0jkshOjdauGdUuNOiV8rCTdY18vLWY
RXkO1u8/
hjEwrk8Mv5nYn58N6kHHMH3bqfalP3FKeYDLJXy77yiL8h18svUINQ1OUmM68uhV/
bl+RBKJUR3sLlEFMA16pX6CA+UnWZzv4P38wxyurCEyPITrhvdk+sgkRqR041yfH1GqvWjQK3
WBTtQ2sGxLMYvzHeQcqMAYuKRfHL+dNICfDepBRGiw3SUq9QMa9Eq1gsslrP3uKIvyCvl0+xF
qG1z0ievEbycN4PrhiSR01a4Z5b006JU6h+KqGt7LdfBubiGOihq6RIQwfWQSN45IYlhylHbN
KJ+gQa9UMw1OF5/
vKGFhTiFfuqcBvqhvDL+dlM5VA7tr14zyORr0Srl9V1bNuzmFLM53UF5dT/
cu4dx3eV9uGplMSox+oEn5Lg16FdBq6p0s21rMuzmFbDhwjOAgw4T0eGaOStbFs5Xf0KBXAUd
E2Hb4OAtyDrFkUxEn6hpJi+3EY5PTuWFEIvGREXaXqJRHadCrgFF1qoEPNx1mQU4hO4qPEx4S
xJTMBGZkJzMqLVpvrCq/pUGv/
JqI8O2+YyzMOcTH245Q3+hicGIXnr1uMNcO7anrq6qAoEGv/
FLp8Vrey3PwXm4hB46eIjIihBlZyczITmZwYle7y1OqXWnQK7/
R6HTxxa4yFuQUsnpXKU6XMDotmoeu7MekQQl0CNNhkSowadArn3fw6EkW5hSyKM9B6Yk6YjuH
M/
uS3tyclUTvuM52l6eU7TTolU+qbXCyfPsRFmwoZN2+owQZuHxAPDdnJ3NFejyhOixSqe9p0Cu
fUlB0nIU5h/
hwUxFVNQ0kR3fg0av6M31kMj266rBIpVqiQa+83onaBpZsLmJhTiFbHFWEBQcxaXAPZmQnM7a
3LqCt1Plo0CuvJCLkHqxgwYZCPt5aTE2Dk/Qekcy9ZiDXDUukW6cwu0tUymdo0CuvUl5dx/
v5DhbkFLKv7CSdwoK5bngiM7OTGZLUVT/
UpNSPoEGvbOd0CWv2lLFwQyErd5TQ6BJG9urG76b3YUpmAp3C9cdUqZ9C30HKNoXHTn3/
oabiqlqiO4Vx10WpzMhOpm98pN3lKeU3NOhVu6prdLKiwJrr/eu95YC1DN+/
Tx3IlRndCQvRYZFKeZoGvWoXu0tOsDCnkPfzHVScaiAxqgMPTejH9JFJJHXTud6Vaksa9KrNn
KxrZOmWIhbkFLLxUCWhwYaJA7szIzuFi/vGEqzDIpVqF60KemPMJOAFIBh4WUSeb7b/
j8Dl7ocdgXgRiTLGDAPmAV0AJ/
CfIrLQU8Ur7yMibCys5N2cQv6xuYiT9U76xnfmySkZXD88kZjO4XaXqFTAOW/
QG2OCgReBiYADyDHGLBGRgtNtROSRJu0fAIa7H54C7hCRPcaYnkCeMWa5iFR68kUo+x07Wc8H
Gw+zMOcQu0uq6RAazNQhCcwclcyIlG46LFIpG7Xmin4UsFdE9gEYYxYA04CCs7S/
BZgLICK7T28UkSJjTCkQB2jQ+wGXS1j73VEW5Bzis+0l1DtdDE2O4r9vyGTqkAQiI3Sud6W8Q
WuCPhEobPLYAYxuqaExpheQBqxqYd8oIAz4roV9c4A5ACkpKa0oSdmpuKqG93IdvJtbiKOihq
4dQrl1dAozspPJSOhid3lKqWY8fTN2JrBIRJxNNxpjEoA3gTtFxNX8IBGZD8wHyMrKEg/
XpDygweni8x3WsMgvd5fhEriobwy/nZTOVQO7ExGqc70r5a1aE/
SHgeQmj5Pc21oyE7iv6QZjTBdgGfBvIvLtjylS2ee7smrezSlkcb6D8up6uncJ597L+nJzVjI
pMTosUilf0JqgzwH6GWPSsAJ+JnBr80bGmHSgG7CuybYw4APgDRFZ5JGKVZurqXeybGsx7+YU
suHAMYKDDBPS45k5KplL+8URonO9K+VTzhv0ItJojLkfWI41vPJVEdlujHkGyBWRJe6mM4EFI
tK06+Vm4FIgxhgzy71tlohs8tgrUB4hImw7fJwFOYdYsqmIE3WNpMZ05F8npXPjyETiI3Wud6
V8lflhLtsvKytLcnNz7S4jYFSdauCjzYdZsKGQguLjhIcEMSUzgRnZyYxKi9ZhkUr5CGNMnoh
ktbRPPxkboBqcLuYu2c7iPAd1jS4G9ezCs9MGce2wRLp20GGRSvkTDfoAJCI89dE23tlQyC2j
krltdC8GJ3a1uyylVBvRoA9AL3+1n3c2FHLvZX347aR0u8tRSrUxHT4RYJZvP8J/
fbKDKZkJPHrVALvLUUq1Aw36ALLVUcVDCzYyNCmKP9w8VBfVVipAaNAHiKLKGu5+PYeYTuG8d
EeWfpJVqQCiQR8Aqusa+cVrOdTUO/nbXdnERepUwUoFEr0Z6+canS4eeDufPaXVvDorm/
7ddS1WpQKNXtH7ueeW7WD1rjL+49pBjO8fZ3c5SqlzaaMPsOoVvR977Zv9vLb2AL+8OI2fj+l
ldzlKqeZqKqFwAxz8Bg6tg46xcMvbHn8aDXo/
tXpnKc8sLeDKjO48fnWG3eUopQBOlMChtXBwHRxcCyXbAIGgUOg5HHoOa5On1aD3QwVFx7n/
7XwyErrwwsxhugi3UnYQgYoD1pX6wW+scD/
mXncptCMkZcNlj0OvsZCYBWFtN+23Br2fKT1ey92v5xAZEcord2bTKVz/
FyvVLlwuKNt5phvm4Fo4UWzti4iCXuNg5CzodREkDIHg9ptTSlPAj5yqb+Tu13Opqmng3V+Np
UdXnVpYqTbjbIDizVagH1xrhXuteznsyJ5WsPcaBynjIC4dguwb+6JB7ydcLuGRhZvYXlTF/
NuzdJIypTyt/hQ4cs5crTtyoOGUtS+6D2Rccybco3qBF03xrUHvJ/7/
T3eyfHsJT00dyJUDu9tdjlK+r6YCDq133zxdC0WbwNUAGOgxGIbf7r5iHwuR3v2e06D3A+9sO
MT/rtnH7WN6cddFqXaXo5RvOnHkh90wJdv5fkRM4ggYd7/
VDZM8CjpE2V3tBdGg93Ff7ynnyQ+3Mb5/HHOvGagrQinVGiJQsd8d7O5RMRX7rX2hnawwv/
wJ62o9KQtCO9hb70+kQe/D9pSc4Ndv5dE3rjN/
uXW4Ltqt1Nm4XFBa8MOhjtVHrH0doq1Az77b6orp0b4jYtqDBr2PKq+u467XcggPCeaVWVlER
vjXD6ZSP0ljvXtEjHuo46F1UFtl7euSCKkXn7lxGjvA1hEx7UGD3gfVNjiZ/
UYu5dV1LJwzlqRubfdBC6V8Qv1JaxTM6W4YRy401lj7YvrCwGlW/
3qvcRCV4lUjYtqDBr2PcbmER9/
bzMZDlcy7bQRDk33rppBSHnHqGBSuP9MNU7wJXI1YI2IyYeSdZ0bEdI63u1rbadD7mD+u3M3S
LcX866R0Jmcm2F2OUu3jeNGZ0TAH11r97QDBYdBzBIx70Ar25FEQoZ8haU6D3ocsznPwP6v2M
iMrmXvG97a7HKXahggc29dkqONaa84YsEbEpIyGQTdYwZ44wudHxLQHDXofsX7fUR57fwvj+s
Tw7HWDdRil8h8up3WF3nQMe3WJta9DtBXo2bObjIjR2LpQrTpjxphJwAtAMPCyiDzfbP8fgcv
dDzsC8SIS5d53J/Cke99zIvK6JwoPJPvLT/Krv+eREt2RebeNJCzEv0cIKD/
XWA9FG89M13voW6g7PSImCdLGWzM6poyD2P5+PyKmPZw36I0xwcCLwETAAeQYY5aISMHpNiLy
SJP2DwDD3V9HA3OBLECAPPexFR59FX6s4mQ9v3gthyBjeHVWNl076jBK5WPqqt0jYtxX601Hx
MT2h0HXNZkjJsXeWv1Ua67oRwF7RWQfgDFmATANKDhL+1uwwh3gZ8AKETnmPnYFMAl456cUHS
jqGp386u95HK6o4e3Zo+kV08nukpQ6P5cLivJh51LYv8aaI0acYILcI2JmNRkRo8tbtofWBH0
iUNjksQMY3VJDY0wvIA1YdY5jEy+8zMAjIjz+/lY27D/GCzOHkZUabXdJSp1dYx3s/
8oK912fWJ86NcHWKJiLHz4zR0xEF7srDUievqsxE1gkIs4LOcgYMweYA5CSon+6Aby4ei/
v5x/mkSv7M22Y/m5UXqi2CvasgJ3LrP/
Wn7BGxfS7EgZMgf5XQYdudlepaF3QHwaSmzxOcm9ryUzgvmbHXtbs2C+aHyQi84H5AFlZWW2z
DLoP+cfmIn7/2W6uH57IgxP62l2OUmccL4ZdH1vhvn+NNW1vpzgYfD2kT7VupIbqgjfepjVBn
wP0M8akYQX3TODW5o2MMelAN2Bdk83Lgf8yxpz+tX4V8PhPqtjP5R2s4P97bzPZqd14/
sZMHUap7Fe22+qS2bkMDuda27qlwZh7rHBPyoagYHtrVOd03qAXkUZjzP1YoR0MvCoi240xzw
C5IrLE3XQmsEBEpMmxx4wxz2L9sgB45vSNWfXPCo+dYs4buSR0jeB/
b88iPETfPMoGLpcV6KfD/
ehea3vPEXDFk1a4x6UH3Hwxvsw0yWWvkJWVJbm5uXaX0e6qahq4cd5ayk7U8f694+gT19nukl
QgaayzumJ2LoWdH8PJUggKgdRLIH0KDLgauuq9Im9mjMkTkayW9ulHzLxAg9PFfW/
lc6D8JG/ePVpDXrWPmkrrJuqu0zdTqyGsM/
S90rpq7zfR51ZSUi3ToLeZiPDUR9v4em85v5s+hLF9YuwuSfmz40VWd8zOZXDgK2vGx07xkDn
dGimTdqneTPVDGvQ2e+mrfbyzoZB7L+vDzVnJ5z9AqQshAmW7zvS3F+Vb26P7wNj7rCv3xCyd
ZsDPadDb6NNtR/jvT3YyJTOBR68aYHc5yl+4nNY0A6fD/dh31vbEkTDhKSvcY/
vrzdQAokFvky2OSh5euJGhSVH84eahBAXpm079BA21sP9LK9h3fXLmZmrapTD2Xutmapeedle
pbKJBb4Oiyhrufj2XmE7hvHRHFhGhOoxS/Qg1Fe5Ppi6FPSuh4SSERVo3UdOnWP/
VRTgUGvTtrrqukV+8lkNtvZO37h1NXGS43SUpX1LlsK7Ydy6FA19bN1M7d4chN7s/
mXoJhOjPlPohDfp21Oh08cDb+ewprebVWdn07x5pd0nK24lA6Q53l8wyax53gJh+MPZ+983Uk
XozVZ2TBn07em7ZDlbvKuO56wYzvr9Oz6rOwuWEwg1nbqZW7Le2J2XDlU9bwyDj+ttZofIxGv
Tt5LVv9vPa2gP88uI0fj6ml93lKG/
TUAP7vjwzze+pcggKhd7j4aIHof9k6KKLwasfR4O+HazaWcIzSwu4MqM7j1+dYXc5ylvUVMDu
z6xw3/
u5dTM1vMuZm6l9J+r87cojNOjbWEHRcR54eyMZCV348y3DCNZhlIGtsvDMNL8HvrZWXurcA4b
OtMI99RIICbO7SuVnNOjbUOnxWu5+PYfIiFBeuTObjmF6ugOOCJQWuKcdWArFm63tsQPgooes
m6k9h+vNVNWmNHnayKn6Ru5+PZeqmgbeu2csPbrq/CEBw+WEwvVnwr3iAGDcN1P/
w7pyj+1nd5UqgGjQtwGXS3h4wSa2F1Xx0h1ZDOqpH1rxew018N1qK9x3fwKnjkJwGPS+DC56G
AZMhsgedlepApQGfRt4/tOdfFZQwlNTBzIho7vd5ai2cuoY7F5uXbV/
twoaTkF4V2ut1PQp1nS/4fpZCWU/
DXoPe3v9Ieav2cftY3px10WpdpejPK3ykLUwx86lcHCtdTM1sicMu9UK914X681U5XU06D3o6
z3l/
PtH2xjfP4651wzU9V79RU0FbF0Em94688nUuAy4+GEr3BP0Zqrybhr0HrKn5OtjxAwAABGkSU
RBVAS/fiuPvnGd+cutwwkJ1je+T3O5rNkgN/
4ddvwDnHXQPRMmPmONlInpY3eFSrWaBr0HlFfXcddrOYSHBPPKrCwiI0LtLkn9WBUHYdPb1r+
qQxARBSPvhOE/h4Shdlen1I+iQf8T1TY4mf1GLuXVdSycM5akbh3tLkldqIYaa7RM/
hvWVTwG+lwOE5+25pXRpfWUj9Og/
wlcLuHR9zaz8VAl824bwdBkXUjZZ4hA8Sara2bre1BbBVEpcNkTMOwW62ul/IQG/U/
wx5W7WbqlmH+dlM7kTJ1wyiecPApb37UCvmQbhERAxrVW10zqJXpTVfklDfofaXGeg/
9ZtZcZWcncM7633eWoc3E5rXHuG9+0hka6GqDnCJjyf2DwjdBB/xJT/k2D/kf4dt9RHnt/
C+P6xPDc9YN1GKW3OvqdNSRy0ztwogg6RMOo2dbVe/
dBdlenVLvRoL9A+8qq+dWbeaREd2TebSMJ1WGU3qX+JBQssa7eD34DJsj6hOrk56053fXDTCo
AtSrojTGTgBeAYOBlEXm+hTY3A08DAmwWkVvd238HTAGCgBXAQyIiHqm+nVWcrOcXr+UQHGR4
dVY2XTvqMEqvIAKOXCvct70P9ScgujdMeAqG3gJdetpdoVK2Om/
QG2OCgReBiYADyDHGLBGRgiZt+gGPAxeJSIUxJt69fRxwETDE3fRrYDzwhSdfRHuoa3Tyqzfz
KKqs5e3Zo+kV08nuklR1KWxeYN1YLd8FoR1h0PVW10zKWNAuNaWA1l3RjwL2isg+AGPMAmAaU
NCkzWzgRRGpABCRUvd2ASKAMMAAoUCJZ0pvPyLC4+9vZcOBY7wwcxhZqdF2lxS4nI2w5zMr3P
csB1cjJI+Ga//HCnmdREypf9KaoE8ECps8dgCjm7XpD2CM+Qare+dpEflURNYZY1YDxVhB/
xcR2dH8CYwxc4A5ACkp3jd++S+r9vJ+/mEeubI/
04Yl2l1OYCrbDZv+bl3BV5dAp3gYcy8Mv10XylbqPDx1MzYE6AdcBiQBa4wxmUAskOHeBrDCG
HOJiHzV9GARmQ/MB8jKyvKq/vslm4v4w4rdXD88kQcn9LW7nMBSdwK2f2BdvReuBxMM/
SdZXTP9JkKw3iNRqjVaE/SHgeQmj5Pc25pyAOtFpAHYb4zZzZng/
1ZEqgGMMZ8AY4Gv8AF5Byt49L3NZKd24/kbM3UYZXsQgUPrrHDf/
oE1x3tsf5j4LAyZAZE6v79SF6o1QZ8D9DPGpGEF/Ezg1mZtPgRuAf5mjInF6srZB/QGZhtj/
hur62Y88CcP1d6mDh09xZw3cknoGsH/
3p5FeEiw3SX5t+NFsPkdK+CP7YOwSMi8yeqaScrSG6tK/QTnDXoRaTTG3A8sx+p/
f1VEthtjngFyRWSJe99VxpgCwAn8i4gcNcYsAq4AtmLdmP1URP7RVi/
GU6pqGvjF6zk0uoRXZ2UT3UnHXreJxnpr2b2Nf4e9K0Fc0OsiuPRfYOA0CNORTUp5gvG2Ie1Z
WVmSm5tr2/
M3OF3c9bccvt13lDfvHs3YPjG21eK3SgqscN+ywFpbNTLBWqFp2G06z7tSP5IxJk9Eslrap5+
MbUJEeOqjbXy9t5zfTR+iIe9JNZWwbbEV8EX5EBQK6VdbXTN9roAg7RpTqq1o0Dfx0lf7eGdD
Ifde1oebs5LPf4A6N5cLDnzlXqVpCTTWQvwgmPQ8ZN4MnfQXqVLtQYPe7dNtR/
jvT3YyJTOBR68aYHc5vq2y8MyN1cqDEN7VGhI5/
OeQMExvrCrVzjTogS2OSh5euJGhSVH84eahBAVpEF2whlrYtcwK9+9WAwJp4+GKf4eMqRDawe
4KlQpYAR/0RZU13P16LjGdwnnpjiwiQrWv+IIUb3bfWH0XaiuhazKM/
1fr5mq3XnZXp5QiwIO+uq6RX7yWQ229k7fuHU1cZLjdJfmGU8es5fc2vglHtkJwOGRcY3XNpI
3XVZqU8jIBG/SNThf3v53PntJq/jYrm/
7ddTKsc3I5Yd9q6+p95zJw1kPCULj695A5HTp0s7tCpdRZBGzQP7dsB1/sKuM/rx/
Mpf3j7C7Hex3bD5vetv4dd1iBnvULa8x7wpDzH6+Usl1ABv1r3+zntbUH+OXFadw2WvuR/
0n9KdjxD6tr5sBXgIG+E+Bnz8GAqyFEu7iU8iUBF/
SrdpbwzNICrszozuNXZ9hdjvcQgcP57lWaFkPdceiWClc8aa3S1DXpvN9CKeWdAiroC4qO88D
bG8lI6MKfbxlGsA6jhJPlZ1ZpKtsBIR1g0HXuVZrG6Y1VpfxAwAR9yfFa7n49h8iIUF65M5uO
YQHz0v+ZCBz6Fr79v7DrY2uVpsQsuOYFa5WmiK52V6iU8qCASLtT9Y388vVcqmoaeO+esfToG
mF3SfZwNkDBR7DuRWu+mQ7dYPQ91tV7vHZjKeWv/
D7oXS7h4QWb2F5UxUt3ZDGoZwBerdZUQv4bsP5/rZEz0X1gyh+svnedClgpv+f3Qf/
8pzv5rKCEp6YOZEJGgK1OVHEAvv2rdYO1vhpSL4Epv4d+P9O+d6UCiF8H/dvrDzF/
zT5uH9OLuy5Ktbuc9iEChRtg3V9g51IwQTD4Rmsh7Z7D7K5OKWUDvw36r/aU8e8fbWN8/
zjmXjPQ/
9d7dTZaUwGvexEO51o3VC96CEbNgS497a5OKWUjvwz6PSUnuPfv+fSL78xfbh1OSLAfd1PUVk
H+m1b/e9UhiO5tTUsw9BYI72x3dUopL+B3QV9eXcddr+UQHhrMK7OyiYwItbuktlFx0Ar3/
Deg/oS11urk56H/JF2tSSn1A34V9LUNTma/
kUt5dR0L54wlMcoP50AvzLH633cssfrfB11v9b8njrC7MqWUl/
KboHe5hEff28zGQ5XMu20EQ5Oj7C7Jc5yN1o3VdS+CY4O1YtO4B6z+d52aQCl1Hn4T9PuPnuS
LXWU8NjmdyZkJdpfjGbXHrakJ1s+DykPW3DOTf2fNHKn970qpVvKboO8T15nPHrmUBH/
41GtlIaz/q9X/XnccUsbCz/
7LmjlS+9+VUhfIb4IeoKev98k78uDbF2H7h9bjQdfBmPsgaaS9dSmlfJpfBb1PcjmtFZvWvQi
F30J4Fxh7L4z6FUQl212dUsoPaNDbpe4EbHzL6n+vOABRKTDpeWuCsXBd1lAp5TmtCnpjzCTg
BSAYeFlEnm+hzc3A04AAm0XkVvf2FOBlINm972oROeCJ4n1SlcMa/573OtRVQfJomPgMpE/
V/
nelVJs4b9AbY4KBF4GJgAPIMcYsEZGCJm36AY8DF4lIhTEmvsm3eAP4TxFZYYzpDLg8+gp8xe
F8q3tm+weAwMBpVv97crbdlSml/
FxrruhHAXtFZB+AMWYBMA0oaNJmNvCiiFQAiEipu+1AIEREVri3V3uwdu/
ncsKuT6yAP7QWwiJhzK+t8e/
ddK1apVT7aE3QJwKFTR47gNHN2vQHMMZ8g9W987SIfOreXmmMeR9IA1YCj4mIs+nBxpg5wByA
lJSUH/EyvEz9Sdj0trWC07F90DXFGh45/HaI6GJ3dUqpAOOpm7EhQD/
gMiAJWGOMyXRvvwQYDhwCFgKzgFeaHiwi84H5AFlZWeKhmtrf8SLYMB9y/
wa1ldbyfDc9BenXQLDe91ZK2aM16XMY60bqaUnubU05gPUi0gDsN8bsxgp+B7CpSbfPh8AYmg
W9zyvaZF29b1sM4oKMa2Ds/ZA8yu7KlFKqVUGfA/
QzxqRhBfxM4NZmbT4EbgH+ZoyJxeqy2QdUAlHGmDgRKQOuAHI9VbytXC7Y/anV/
37wawjrbPW9j/6VNVWBUkp5ifMGvYg0GmPuB5Zj9b+/
KiLbjTHPALkissS97ypjTAHgBP5FRI4CGGMeBT431sofecBLbfRa2sf3/e/
z4Nh30CUJrnoORtxhLfahlFJexoh4V5d4VlaW5OZ64UX/
8WLIeQlyX4WaCug5AsbdDxnTtP9dKWU7Y0yeiGS1tE8T6nyKt1j971sXgasRMqa6+99Hg78vT
6iU8gsa9C1xuWDvCmuBj/1rILQTZN9t9b9H97a7OqWUuiAa9E3Vn4ItC2Dd/
4Wje6BLojU9wYg7oYMfLWSilAooGvQAJ0qs/
vecV6DmGCQMgxtfsaYpCPbTNWeVUgEjsIP+yDZ3//t74GyA9Ckw9j5roQ/
tf1dK+YnAC3qXC/audPe/
fwmhHWHkLBh9D8T0sbs6pZTyuMAJ+oYa2LLQ6n8v3wWRCXDl01b/
e8dou6tTSqk24/9BX10KOS9b/04dhR5D4IaXYOB1EBJmd3VKKdXm/
DfoSwqs9Ve3vGv1vw+YbPW/97pI+9+VUgHFv4JeBL773Jp/5rtVENLBmppg9K8htq/
d1SmllC38J+grDsLbN0PZTujcAyY8BSPv0v53pVTA85+g75JozRp58SMw6Abtf1dKKTf/
CfrgELh1od1VKKWU1wmyuwCllFJtS4NeKaX8nAa9Ukr5OQ16pZTycxr0Sinl5zTolVLKz2nQK
6WUn9OgV0opP2dExO4afsAYUwYc/AnfIhYo91A5nqR1XRit68JoXRfGH+vqJSJxLe3wuqD/
qYwxuSKSZXcdzWldF0brujBa14UJtLq060YppfycBr1SSvk5fwz6+XYXcBZa14XRui6M1nVhA
qouv+ujV0op9UP+eEWvlFKqCQ16pZTycz4Z9MaYScaYXcaYvcaYx1rYH26MWejev94Yk+oldc
0yxpQZYza5//2ynep61RhTaozZdpb9xhjzZ3fdW4wxI7ykrsuMMVVNztdT7VRXsjFmtTGmwBi
z3RjzUAtt2v2ctbKudj9nxpgIY8wGY8xmd13/0UKbdn9PtrIuW96T7ucONsZsNMYsbWGfZ8+X
iPjUPyAY+A7oDYQBm4GBzdrcC/zV/
fVMYKGX1DUL+IsN5+xSYASw7Sz7rwY+AQwwBljvJXVdBiy14XwlACPcX0cCu1v4f9nu56yVdb
X7OXOfg87ur0OB9cCYZm3seE+2pi5b3pPu5/4N8HZL/
788fb588Yp+FLBXRPaJSD2wAJjWrM004HX314uACcYY4wV12UJE1gDHztFkGvCGWL4FoowxCV
5Qly1EpFhE8t1fnwB2AInNmrX7OWtlXe3OfQ6q3Q9D3f+aj/Jo9/
dkK+uyhTEmCZgCvHyWJh49X74Y9IlAYZPHDv75h/37NiLSCFQBMV5QF8CN7j/
1Fxljktu4ptZqbe12GOv+0/sTY8yg9n5y95/Mw7GuBpuy9Zydoy6w4Zy5uyE2AaXAChE56/
lqx/dka+oCe96TfwJ+C7jOst+j58sXg96X/QNIFZEhwArO/MZWLcvHmr9jKPA/
wIft+eTGmM7AYuBhETnens99Luepy5ZzJiJOERkGJAGjjDGD2+N5z6cVdbX7e9IYMxUoFZG8t
n6u03wx6A8DTX/
rJrm3tdjGGBMCdAWO2l2XiBwVkTr3w5eBkW1cU2u15py2OxE5fvpPbxH5GAg1xsS2x3MbY0Kx
wvQtEXm/hSa2nLPz1WXnOXM/ZyWwGpjUbJcd78nz1mXTe/Ii4FpjzAGsLt4rjDF/
b9bGo+fLF4M+B+hnjEkzxoRh3ahY0qzNEuBO99fTgVXivqthZ13N+nCvxepj9QZLgDvcI0nGA
FUiUmx3UcaYHqf7JY0xo7B+Xts8HNzP+QqwQ0T+z1matfs5a01ddpwzY0ycMSbK/
XUHYCKws1mzdn9PtqYuO96TIvK4iCSJSCpWTqwSkZ83a+bR8xXyYw+0i4g0GmPuB5ZjjXR5VU
S2G2OeAXJFZAnWm+FNY8xerJt9M72krgeNMdcCje66ZrV1XQDGmHewRmPEGmMcwFysG1OIyF+
Bj7FGkewFTgF3eUld04FfG2MagRpgZjv8wgbriut2YKu7fxfgCSClSW12nLPW1GXHOUsAXjfG
BGP9YnlXRJba/
Z5sZV22vCdb0pbnS6dAUEopP+eLXTdKKaUugAa9Ukr5OQ16pZTycxr0Sinl5zTolVLKz2nQK6
WUn9OgV0opP/f/ADP4hvpUdJcLAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VHPNtth2AcqK"
},
"source": [
"## Prediction"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NdJFOMwqozjm"
},
"source": [
"### Encoder"
]
},
{
"cell_type": "code",
"metadata": {
"id": "xIOs3-ZqAb1a"
},
"source": [
"##### Make predictions #####\n",
"\n",
"# The encoder will be stand-alone\n",
"# From this we will get our initial decoder hidden state\n",
"encoder_model = Model(encoder_inputs_placeholder,
encoder_states)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "m6XJhUSfpF-o"
},
"source": [
"### Decoder"
]
},
{
"cell_type": "code",
"metadata": {
"id": "VQKeWWNRAkP8"
},
"source": [
"decoder_state_input_h = Input(shape=(LATENT_DIM,))\n",
"decoder_state_input_c = Input(shape=(LATENT_DIM,))\n",
"\n",
"decoder_states_inputs = [decoder_state_input_h,
decoder_state_input_c]\n",
"\n",
"decoder_inputs_single = Input(shape=(1,))\n",
"\n",
"decoder_inputs_single_x =
decoder_embedding(decoder_inputs_single)\n",
"\n",
"decoder_outputs, h, c = decoder_lstm(\n",
" decoder_inputs_single_x,\n",
" initial_state=decoder_states_inputs\n",
")\n",
"\n",
"decoder_states = [h, c]\n",
"\n",
"decoder_outputs = decoder_dense(decoder_outputs)\n",
"\n",
"# The sampling model\n",
"# inputs: y(t-1), h(t-1), c(t-1)\n",
"# outputs: y(t), h(t), c(t)\n",
"decoder_model = Model(\n",
" [decoder_inputs_single] + decoder_states_inputs, \n",
" [decoder_outputs] + decoder_states\n",
")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "WCjzDIwnAl6k"
},
"source": [
"# map indexes back into real words\n",
"# so we can view the results\n",
"idx2word_eng = {v:k for k, v in word2idx_inputs.items()}\n",
"idx2word_trans = {v:k for k, v in word2idx_outputs.items()}"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "bEXM5U6MAm_p"
},
"source": [
"def decode_sequence(input_seq):\n",
" # Encode the input as state vectors.\n",
" states_value = encoder_model.predict(input_seq)\n",
"\n",
" # Generate empty target sequence of length 1.\n",
" target_seq = np.zeros((1, 1))\n",
"\n",
" # Populate the first character of target sequence with the
start character.\n",
" # NOTE: tokenizer lower-cases all words\n",
" target_seq[0, 0] = word2idx_outputs['<start>']\n",
"\n",
" # if we get this we break\n",
" eos = word2idx_outputs['<end>']\n",
"\n",
" # Create the translation\n",
" output_sentence = []\n",
" for _ in range(max_len_target):\n",
" output_tokens, h, c = decoder_model.predict(\n",
" [target_seq] + states_value\n",
" )\n",
"\n",
" # Get next word\n",
" idx = np.argmax(output_tokens[0, 0, :]) \n",
"\n",
" # End sentence of EOS\n",
" if eos == idx:\n",
" break\n",
"\n",
" word = ''\n",
" if idx > 0:\n",
" word = idx2word_trans[idx]\n",
" output_sentence.append(word)\n",
"\n",
" # Update the decoder input\n",
" # which is just the word just generated\n",
" target_seq[0, 0] = idx\n",
"\n",
" # Update states\n",
" states_value = [h, c]\n",
"\n",
" return ' '.join(output_sentence)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "JDQ2NkEAAq6k",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 153
},
"outputId": "c832b5bf-8d7c-46e1-b861-b515e638b74f"
},
"source": [
"while True:\n",
" # Do some test translations\n",
" i = np.random.choice(len(input_texts))\n",
" input_seq = encoder_inputs[i:i+1]\n",
" translation = decode_sequence(input_seq)\n",
" print('-')\n",
" print('Input:', input_texts[i])\n",
" print('Translation:', translation)\n",
"\n",
" ans = input(\"Continue? [Y/n]\")\n",
" if ans and ans.lower().startswith('n'):\n",
" break"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"-\n",
"Input: Tom rocks.\n",
"Translation: tom se quedó está de tom años.\n",
"Continue? [Y/n]Y\n",
"-\n",
"Input: Just leave it.\n",
"Translation: ahora lo nuevo.\n",
"Continue? [Y/n]n\n"
],
"name": "stdout"
}
]
}
]
}