0% found this document useful (0 votes)
19 views

Machine Translation Ipynb

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Machine Translation Ipynb

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

{

"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"
}
]
}
]
}

You might also like