{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Node classification with Personalised Propagation of Neural Predictions (PPNP) and Approximate PPNP (APPNP)" ] }, { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden", "tags": [ "CloudRunner" ] }, "source": [ "
Run the latest release of this notebook:
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import NetworkX and stellargraph:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "nbsphinx": "hidden", "tags": [ "CloudRunner" ] }, "outputs": [], "source": [ "# install StellarGraph if running on Google Colab\n", "import sys\n", "if 'google.colab' in sys.modules:\n", " %pip install -q stellargraph[demos]==1.2.1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "nbsphinx": "hidden", "tags": [ "VersionCheck" ] }, "outputs": [], "source": [ "# verify that we're using the correct version of StellarGraph for this notebook\n", "import stellargraph as sg\n", "\n", "try:\n", " sg.utils.validate_notebook_version(\"1.2.1\")\n", "except AttributeError:\n", " raise ValueError(\n", " f\"This notebook requires StellarGraph version 1.2.1, but a different version {sg.__version__} is installed. Please see .\"\n", " ) from None" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import networkx as nx\n", "import pandas as pd\n", "import numpy as np\n", "import os\n", "from tensorflow import keras\n", "from tensorflow.keras import backend as K\n", "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n", "\n", "import stellargraph as sg\n", "from stellargraph.mapper import FullBatchNodeGenerator\n", "from stellargraph.layer.ppnp import PPNP\n", "from stellargraph.layer.appnp import APPNP\n", "\n", "from tensorflow.keras import layers, optimizers, losses, metrics, Model\n", "from sklearn import preprocessing, feature_extraction, model_selection\n", "from stellargraph import datasets\n", "from IPython.display import display, HTML\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading the CORA network" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "DataLoadingLinks" ] }, "source": [ "(See [the \"Loading from Pandas\" demo](../basics/loading-pandas.ipynb) for details on how data can be loaded.)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [ "DataLoading" ] }, "outputs": [ { "data": { "text/html": [ "The Cora dataset consists of 2708 scientific publications classified into one of seven classes. The citation network consists of 5429 links. Each publication in the dataset is described by a 0/1-valued word vector indicating the absence/presence of the corresponding word from the dictionary. The dictionary consists of 1433 unique words." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "dataset = datasets.Cora()\n", "display(HTML(dataset.description))\n", "G, node_subjects = dataset.load()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "StellarGraph: Undirected multigraph\n", " Nodes: 2708, Edges: 5429\n", "\n", " Node types:\n", " paper: [2708]\n", " Features: float32 vector, length 1433\n", " Edge types: paper-cites->paper\n", "\n", " Edge types:\n", " paper-cites->paper: [5429]\n" ] } ], "source": [ "print(G.info())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We aim to train a graph-ML model that will predict the \"subject\" attribute on the nodes. These subjects are one of 7 categories:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
subject
Neural_Networks818
Probabilistic_Methods426
Genetic_Algorithms418
Theory351
Case_Based298
Reinforcement_Learning217
Rule_Learning180
\n", "
" ], "text/plain": [ " subject\n", "Neural_Networks 818\n", "Probabilistic_Methods 426\n", "Genetic_Algorithms 418\n", "Theory 351\n", "Case_Based 298\n", "Reinforcement_Learning 217\n", "Rule_Learning 180" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "node_subjects.value_counts().to_frame()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Splitting the data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For machine learning we want to take a subset of the nodes for training, and use the rest for validation and testing. We'll use scikit-learn again to do this.\n", "\n", "Here we're taking 140 node labels for training, 500 for validation, and the rest for testing." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "train_subjects, test_subjects = model_selection.train_test_split(\n", " node_subjects, train_size=140, test_size=None, stratify=node_subjects\n", ")\n", "val_subjects, test_subjects = model_selection.train_test_split(\n", " test_subjects, train_size=500, test_size=None, stratify=test_subjects\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note using stratified sampling gives the following counts:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
subject
Neural_Networks42
Genetic_Algorithms22
Probabilistic_Methods22
Theory18
Case_Based16
Reinforcement_Learning11
Rule_Learning9
\n", "
" ], "text/plain": [ " subject\n", "Neural_Networks 42\n", "Genetic_Algorithms 22\n", "Probabilistic_Methods 22\n", "Theory 18\n", "Case_Based 16\n", "Reinforcement_Learning 11\n", "Rule_Learning 9" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train_subjects.value_counts().to_frame()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The training set has class imbalance that might need to be compensated, e.g., via using a weighted cross-entropy loss in model training, with class weights inversely proportional to class support. However, we will ignore the class imbalance in this example, for simplicity." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Converting to numeric arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For our categorical target, we will use one-hot vectors that will be compared against the model's soft-max output." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "target_encoding = preprocessing.LabelBinarizer()\n", "\n", "train_targets = target_encoding.fit_transform(train_subjects)\n", "val_targets = target_encoding.transform(val_subjects)\n", "test_targets = target_encoding.transform(test_subjects)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating the PPNP model in Keras" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now create a StellarGraph object from the NetworkX graph and the node features and targets. It is StellarGraph objects that we use in this library to perform machine learning tasks on." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To feed data from the graph to the Keras model we need a generator. Since PPNP is a full-batch model, we use the `FullBatchNodeGenerator` class to feed node features and the normalized graph Laplacian matrix to the model.\n", "\n", "Specifying the `method='ppnp'` argument to the `FullBatchNodeGenerator` will preprocess the adjacency matrix and supply the personalized page rank matrix necessary for PPNP. The personalized page rank matrix is a dense matrix and so `sparse=False` must be passed to `FullBatchNodeGenerator`. `teleport_probability=0.1` specifies the probability of returning to the starting node in the propagation step as described in the paper (alpha in the paper). " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "generator = FullBatchNodeGenerator(\n", " G, method=\"ppnp\", sparse=False, teleport_probability=0.1\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For training we map only the training nodes returned from our splitter and the target values." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "train_gen = generator.flow(train_subjects.index, train_targets)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can specify our machine learning model, we need a few more parameters for this:\n", "\n", " * the `layer_sizes` is a list of hidden feature sizes of each full fully connected layer in the model. In this example we use three fully connected layers with 64,64, and 7 hidden node features at each layer. \n", " * `activations` is a list of activations applied to each layer's output\n", " * `dropout=0.5` specifies a 50% dropout at each layer. \n", " * `kernel_regularizer=keras.regularizers.l2(0.001)` specifies a penalty that prevents the model weights from become too large and helps limit overfitting\n", " \n", "**Note that the size of the final fully connected layer must be equal to the number of classes you are trying to predict.**\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We create a PPNP model as follows:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "ppnp = PPNP(\n", " layer_sizes=[64, 64, train_targets.shape[-1]],\n", " activations=[\"relu\", \"relu\", \"relu\"],\n", " generator=generator,\n", " dropout=0.5,\n", " kernel_regularizer=keras.regularizers.l2(0.001),\n", ")\n", "\n", "x_inp, x_out = ppnp.in_out_tensors()\n", "predictions = keras.layers.Softmax()(x_out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Training the model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's create the actual Keras model with the input tensors `x_inp` and output tensors being the predictions `predictions` from the final dense layer" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "ppnp_model = Model(inputs=x_inp, outputs=predictions)\n", "ppnp_model.compile(\n", " optimizer=optimizers.Adam(lr=0.01),\n", " loss=losses.categorical_crossentropy,\n", " metrics=[\"acc\"],\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Train the model, keeping track of its loss and accuracy on the training set, and its generalisation performance on the validation set (we need to create another generator over the validation data for this)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "val_gen = generator.flow(val_subjects.index, val_targets)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create callbacks for early stopping (if validation accuracy stops improving) and best model checkpoint saving:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "if not os.path.isdir(\"logs\"):\n", " os.makedirs(\"logs\")" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "es_callback = EarlyStopping(\n", " monitor=\"val_acc\", patience=50\n", ") # patience is the number of epochs to wait before early stopping in case of no further improvement\n", "\n", "mc_callback = ModelCheckpoint(\n", " \"logs/best_ppnp_model.h5\",\n", " monitor=\"val_acc\",\n", " save_best_only=True,\n", " save_weights_only=True,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Train the model" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ['...']\n", " ['...']\n", "Train for 1 steps, validate for 1 steps\n", "Epoch 1/80\n", "1/1 - 1s - loss: 2.1556 - acc: 0.1571 - val_loss: 2.0886 - val_acc: 0.3340\n", "Epoch 2/80\n", "1/1 - 0s - loss: 2.0775 - acc: 0.2643 - val_loss: 2.0250 - val_acc: 0.3020\n", "Epoch 3/80\n", "1/1 - 0s - loss: 2.0350 - acc: 0.3357 - val_loss: 1.9640 - val_acc: 0.3020\n", "Epoch 4/80\n", "1/1 - 0s - loss: 1.9686 - acc: 0.3500 - val_loss: 1.9072 - val_acc: 0.3020\n", "Epoch 5/80\n", "1/1 - 0s - loss: 1.9118 - acc: 0.3286 - val_loss: 1.8519 - val_acc: 0.3020\n", "Epoch 6/80\n", "1/1 - 0s - loss: 1.8614 - acc: 0.3286 - val_loss: 1.7883 - val_acc: 0.3300\n", "Epoch 7/80\n", "1/1 - 0s - loss: 1.8051 - acc: 0.3286 - val_loss: 1.7203 - val_acc: 0.3480\n", "Epoch 8/80\n", "1/1 - 0s - loss: 1.7383 - acc: 0.3786 - val_loss: 1.6565 - val_acc: 0.4700\n", "Epoch 9/80\n", "1/1 - 0s - loss: 1.7872 - acc: 0.3571 - val_loss: 1.6091 - val_acc: 0.6800\n", "Epoch 10/80\n", "1/1 - 0s - loss: 1.6437 - acc: 0.4929 - val_loss: 1.5580 - val_acc: 0.7120\n", "Epoch 11/80\n", "1/1 - 0s - loss: 1.5356 - acc: 0.6286 - val_loss: 1.4868 - val_acc: 0.7180\n", "Epoch 12/80\n", "1/1 - 0s - loss: 1.4670 - acc: 0.6429 - val_loss: 1.4052 - val_acc: 0.7120\n", "Epoch 13/80\n", "1/1 - 0s - loss: 1.4368 - acc: 0.6500 - val_loss: 1.3339 - val_acc: 0.6980\n", "Epoch 14/80\n", "1/1 - 0s - loss: 1.4221 - acc: 0.6357 - val_loss: 1.2761 - val_acc: 0.6920\n", "Epoch 15/80\n", "1/1 - 0s - loss: 1.3478 - acc: 0.6571 - val_loss: 1.2250 - val_acc: 0.6980\n", "Epoch 16/80\n", "1/1 - 0s - loss: 1.2365 - acc: 0.6714 - val_loss: 1.1672 - val_acc: 0.7160\n", "Epoch 17/80\n", "1/1 - 0s - loss: 1.1550 - acc: 0.7214 - val_loss: 1.1331 - val_acc: 0.7140\n", "Epoch 18/80\n", "1/1 - 0s - loss: 1.2100 - acc: 0.7000 - val_loss: 1.1136 - val_acc: 0.7120\n", "Epoch 19/80\n", "1/1 - 0s - loss: 1.1084 - acc: 0.7000 - val_loss: 1.1051 - val_acc: 0.7180\n", "Epoch 20/80\n", "1/1 - 0s - loss: 1.0961 - acc: 0.7143 - val_loss: 1.1169 - val_acc: 0.7140\n", "Epoch 21/80\n", "1/1 - 0s - loss: 1.1314 - acc: 0.7143 - val_loss: 1.1359 - val_acc: 0.7140\n", "Epoch 22/80\n", "1/1 - 0s - loss: 1.1363 - acc: 0.7143 - val_loss: 1.1387 - val_acc: 0.7280\n", "Epoch 23/80\n", "1/1 - 0s - loss: 1.0875 - acc: 0.7429 - val_loss: 1.1233 - val_acc: 0.7500\n", "Epoch 24/80\n", "1/1 - 0s - loss: 1.0232 - acc: 0.7429 - val_loss: 1.0945 - val_acc: 0.7540\n", "Epoch 25/80\n", "1/1 - 0s - loss: 1.0564 - acc: 0.7214 - val_loss: 1.0719 - val_acc: 0.7460\n", "Epoch 26/80\n", "1/1 - 0s - loss: 0.9832 - acc: 0.8143 - val_loss: 1.0603 - val_acc: 0.7540\n", "Epoch 27/80\n", "1/1 - 0s - loss: 0.9897 - acc: 0.7286 - val_loss: 1.0585 - val_acc: 0.7820\n", "Epoch 28/80\n", "1/1 - 0s - loss: 1.0085 - acc: 0.7500 - val_loss: 1.0713 - val_acc: 0.7640\n", "Epoch 29/80\n", "1/1 - 0s - loss: 0.9292 - acc: 0.7500 - val_loss: 1.0938 - val_acc: 0.7440\n", "Epoch 30/80\n", "1/1 - 0s - loss: 0.9356 - acc: 0.7571 - val_loss: 1.1067 - val_acc: 0.7300\n", "Epoch 31/80\n", "1/1 - 0s - loss: 0.8826 - acc: 0.7857 - val_loss: 1.1116 - val_acc: 0.7260\n", "Epoch 32/80\n", "1/1 - 0s - loss: 0.9411 - acc: 0.7643 - val_loss: 1.0897 - val_acc: 0.7380\n", "Epoch 33/80\n", "1/1 - 0s - loss: 0.9439 - acc: 0.7857 - val_loss: 1.0754 - val_acc: 0.7420\n", "Epoch 34/80\n", "1/1 - 0s - loss: 0.8490 - acc: 0.8143 - val_loss: 1.0711 - val_acc: 0.7500\n", "Epoch 35/80\n", "1/1 - 0s - loss: 0.8453 - acc: 0.7857 - val_loss: 1.0632 - val_acc: 0.7500\n", "Epoch 36/80\n", "1/1 - 0s - loss: 0.9247 - acc: 0.8143 - val_loss: 1.0490 - val_acc: 0.7620\n", "Epoch 37/80\n", "1/1 - 0s - loss: 0.8107 - acc: 0.8214 - val_loss: 1.0372 - val_acc: 0.7720\n", "Epoch 38/80\n", "1/1 - 0s - loss: 0.8992 - acc: 0.7714 - val_loss: 1.0296 - val_acc: 0.7840\n", "Epoch 39/80\n", "1/1 - 0s - loss: 0.7891 - acc: 0.8286 - val_loss: 1.0220 - val_acc: 0.7820\n", "Epoch 40/80\n", "1/1 - 0s - loss: 0.9525 - acc: 0.7857 - val_loss: 1.0094 - val_acc: 0.8060\n", "Epoch 41/80\n", "1/1 - 0s - loss: 0.8830 - acc: 0.8286 - val_loss: 1.0159 - val_acc: 0.8120\n", "Epoch 42/80\n", "1/1 - 0s - loss: 0.8916 - acc: 0.8143 - val_loss: 1.0131 - val_acc: 0.8080\n", "Epoch 43/80\n", "1/1 - 0s - loss: 0.8381 - acc: 0.8286 - val_loss: 1.0018 - val_acc: 0.8040\n", "Epoch 44/80\n", "1/1 - 0s - loss: 0.8140 - acc: 0.8143 - val_loss: 0.9910 - val_acc: 0.8080\n", "Epoch 45/80\n", "1/1 - 0s - loss: 0.8264 - acc: 0.8143 - val_loss: 0.9893 - val_acc: 0.8020\n", "Epoch 46/80\n", "1/1 - 0s - loss: 0.8354 - acc: 0.8429 - val_loss: 0.9942 - val_acc: 0.8000\n", "Epoch 47/80\n", "1/1 - 0s - loss: 0.8170 - acc: 0.8429 - val_loss: 0.9960 - val_acc: 0.8040\n", "Epoch 48/80\n", "1/1 - 0s - loss: 0.7662 - acc: 0.8500 - val_loss: 0.9941 - val_acc: 0.8080\n", "Epoch 49/80\n", "1/1 - 0s - loss: 0.8325 - acc: 0.8429 - val_loss: 0.9952 - val_acc: 0.8040\n", "Epoch 50/80\n", "1/1 - 0s - loss: 0.8063 - acc: 0.8643 - val_loss: 0.9960 - val_acc: 0.8020\n", "Epoch 51/80\n", "1/1 - 0s - loss: 0.7980 - acc: 0.8643 - val_loss: 0.9937 - val_acc: 0.8020\n", "Epoch 52/80\n", "1/1 - 0s - loss: 0.7730 - acc: 0.8571 - val_loss: 0.9832 - val_acc: 0.8040\n", "Epoch 53/80\n", "1/1 - 0s - loss: 0.8485 - acc: 0.8500 - val_loss: 0.9706 - val_acc: 0.8100\n", "Epoch 54/80\n", "1/1 - 0s - loss: 0.7297 - acc: 0.8714 - val_loss: 0.9555 - val_acc: 0.8160\n", "Epoch 55/80\n", "1/1 - 0s - loss: 0.8148 - acc: 0.8643 - val_loss: 0.9450 - val_acc: 0.8180\n", "Epoch 56/80\n", "1/1 - 0s - loss: 0.7451 - acc: 0.8857 - val_loss: 0.9424 - val_acc: 0.8140\n", "Epoch 57/80\n", "1/1 - 0s - loss: 0.7683 - acc: 0.8643 - val_loss: 0.9456 - val_acc: 0.8200\n", "Epoch 58/80\n", "1/1 - 0s - loss: 0.7997 - acc: 0.8500 - val_loss: 0.9535 - val_acc: 0.8160\n", "Epoch 59/80\n", "1/1 - 0s - loss: 0.7472 - acc: 0.8714 - val_loss: 0.9661 - val_acc: 0.8080\n", "Epoch 60/80\n", "1/1 - 0s - loss: 0.7238 - acc: 0.8714 - val_loss: 0.9792 - val_acc: 0.8060\n", "Epoch 61/80\n", "1/1 - 0s - loss: 0.7303 - acc: 0.8929 - val_loss: 0.9898 - val_acc: 0.8040\n", "Epoch 62/80\n", "1/1 - 0s - loss: 0.7680 - acc: 0.8714 - val_loss: 0.9973 - val_acc: 0.8060\n", "Epoch 63/80\n", "1/1 - 0s - loss: 0.8879 - acc: 0.8071 - val_loss: 1.0074 - val_acc: 0.8060\n", "Epoch 64/80\n", "1/1 - 0s - loss: 0.7826 - acc: 0.8714 - val_loss: 1.0149 - val_acc: 0.8040\n", "Epoch 65/80\n", "1/1 - 0s - loss: 0.6799 - acc: 0.8786 - val_loss: 1.0084 - val_acc: 0.8040\n", "Epoch 66/80\n", "1/1 - 0s - loss: 0.7639 - acc: 0.8500 - val_loss: 0.9935 - val_acc: 0.8040\n", "Epoch 67/80\n", "1/1 - 0s - loss: 0.7458 - acc: 0.8786 - val_loss: 0.9711 - val_acc: 0.8140\n", "Epoch 68/80\n", "1/1 - 0s - loss: 0.6320 - acc: 0.9000 - val_loss: 0.9564 - val_acc: 0.8180\n", "Epoch 69/80\n", "1/1 - 0s - loss: 0.7241 - acc: 0.8857 - val_loss: 0.9506 - val_acc: 0.8100\n", "Epoch 70/80\n", "1/1 - 0s - loss: 0.7390 - acc: 0.8286 - val_loss: 0.9448 - val_acc: 0.8220\n", "Epoch 71/80\n", "1/1 - 0s - loss: 0.6677 - acc: 0.8643 - val_loss: 0.9432 - val_acc: 0.8260\n", "Epoch 72/80\n", "1/1 - 0s - loss: 0.7128 - acc: 0.8929 - val_loss: 0.9440 - val_acc: 0.8260\n", "Epoch 73/80\n", "1/1 - 0s - loss: 0.6855 - acc: 0.9071 - val_loss: 0.9466 - val_acc: 0.8240\n", "Epoch 74/80\n", "1/1 - 0s - loss: 0.5749 - acc: 0.9071 - val_loss: 0.9514 - val_acc: 0.8160\n", "Epoch 75/80\n", "1/1 - 0s - loss: 0.7657 - acc: 0.8643 - val_loss: 0.9716 - val_acc: 0.8100\n", "Epoch 76/80\n", "1/1 - 0s - loss: 0.6559 - acc: 0.9143 - val_loss: 0.9918 - val_acc: 0.8140\n", "Epoch 77/80\n", "1/1 - 0s - loss: 0.6620 - acc: 0.8929 - val_loss: 1.0184 - val_acc: 0.8100\n", "Epoch 78/80\n", "1/1 - 0s - loss: 0.6626 - acc: 0.8929 - val_loss: 1.0408 - val_acc: 0.8100\n", "Epoch 79/80\n", "1/1 - 0s - loss: 0.6625 - acc: 0.8929 - val_loss: 1.0550 - val_acc: 0.8100\n", "Epoch 80/80\n", "1/1 - 0s - loss: 0.7359 - acc: 0.9000 - val_loss: 1.0519 - val_acc: 0.8140\n" ] } ], "source": [ "history = ppnp_model.fit(\n", " train_gen,\n", " epochs=80,\n", " validation_data=val_gen,\n", " verbose=2,\n", " shuffle=False, # this should be False, since shuffling data means shuffling the whole graph\n", " callbacks=[es_callback, mc_callback],\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the training history:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfAAAAI4CAYAAACV/7uiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd3hU1dbA4d9OD2mUFCCFhE6A0DuIKCoIgpUionhVUFG5tmtX9CpiFxX8EAsiKIKioiJwEZCOJICUEHqAFNIL6WX298dJQnomECZtvc8zTzLn7Dmzk8Css9vaSmuNEEIIIeoXq9qugBBCCCGqTwK4EEIIUQ9JABdCCCHqIQngQgghRD0kAVwIIYSoh2xquwKXy93dXfv7+9d2NYQQQogrIiQkJF5r7VH6eL0P4P7+/gQHB9d2NYQQQogrQil1przj0oUuhBBC1EMSwIUQQoh6SAK4EEIIUQ9JABdCCCHqIQngQgghRD0kAVwIIYSoh+r9MrLKmEwm4uPjSU5OJj8/v7arI64Aa2trmjZtiru7O1ZWcj8qhGg8GnQAj4iIQCmFv78/tra2KKVqu0qiBmmtyc3NJSYmhoiICPz8/Gq7SkIIYTENusmSnp6Ot7c3dnZ2ErwbIKUUdnZ2eHt7k56eXtvVEUIIi2rQARyQbtVGQP7GQohL8b/QGKYvCSY9O6+2q3JJ5JNPCCFEozR/0wnWh8bwzI8H0FrXdnWqzaJj4EqpUcA8wBr4XGs9t9T5NsCXgAeQCNyltY6wZB2FEELUDyaT5tO/ThIcnljm3NAOHtw3NKDC155LzGD/uWQ6ebnw24Foevk1q7R8XWSxFrhSyhqYD4wGAoHJSqnAUsXeBZZorYOA14A3LVW/hm7x4sXY2DToOYtCiEYkMyefh5aF8M66o0QlZ5GQnlP0OBaTxlt/hJGUnlPh6/84FA3AZ3f34YauXsxZc4S/T5e9EajLLNmF3h84obU+pbXOAZYD40uVCQQ2Fny/qZzzjcrIkSOZNm1ajVxr4sSJREZG1si1hBCiKtl5+Xy1/TQxqVk1fu3Y1CwmfraT9aExvDQ2kLX/HsbqR4YWPT6/py85+SZ+2lfxZ97vB6Lp7u1GmxZOvHNHD9o0b8LMb/cSexn1PRZzgRd/PkhCWvYlX6M6LBnAvYFzxZ5HFBwr7h/g1oLvbwFclFItSl9IKTVdKRWslAqOi4u7IpWtL3JyKr7DLM7R0REvL68rXBshhDDMXh3Kq7+GMv6T7RyKTKmx6x6JTuXm+ds5EZvGoql9uW9oQJlVRl1audLDx43v95wrd2z7XGIG/0SkMCaoFQCuDrb839Q+pGXl8fCyveTmm8yuT75Js/bQeSZ/tovrP9jCyuAI9p9Lvrwf0kx1bRLbU8BwpdQ+YDgQCZTJwKK1/kxr3Vdr3dfDo8we5w3CtGnT+PPPP/n6669RSqGUYvHixSilWLZsGTfeeCNOTk689NJLaK154IEHaNeuHY6OjrRt25bnn3+e7OyLd4Glu9ALn2/fvp3evXvTpEkT+vTpw549e2rjxxVC1ICzCRmcjEur7WqwYs85vvv7LLf19sFKwYSFO9kQGnPZ1918NJbbP91BvtasmDGIkYEVN0om9vPjaMyFcoPpmoNG9/mY7q2KjnX0cuGt24MIPpPEf344wMrgc1U+Ptl4nKve3sSDS0M4k5DOM6M6s+u5a7m2i2UaS5YcFI0EfIs99yk4VkRrHUVBC1wp5QzcprWu0VuZV389TGhUak1e0iyBrV155aauZpefN28ep06dolWrVsybNw+A1FSj3s888wxvvfUW8+fPB4yEJp6ennz77bd4eXlx4MABZsyYga2tLa+++mqF72EymXjuueeYN28eHh4ePP7440yYMIHjx4/LeLkQ9UxUcia3LNhOTr6JXx8Zir+7U63U41BkCi/+coih7d15+/YgEtKyuX9JMA98E8yLYwL51xD/S8rLEZuaxcxle/Fr4cRX0/rR0s2h0vI39WjFf38L5fs95+jl16zEud8PRtPDxw3f5k1KHB/XozWHIlP4bMupSrvfixvYtjkvje3CyC5e2Fhbtk1syU/pPUAHpVQARuCeBNxZvIBSyh1I1FqbgOcwZqQ3Sm5ubtjZ2eHo6EjLli0ByMoyxmZmzJjBlClTSpR/4403ir739/fn5MmTLFiwoNIArrXmww8/pHfv3gDMnj2bgQMHcvLkSTp16lTTP5IQjVrshSw8nO2vSFKp7Lx8Hl62l+w8EzbWigeXhvDTw0NwtLOu8feqTFJ6Dg8uDcHdyY55k3pibaXwdHXg++mDePz7/fz3t1BOx6cx+6au1Q52c9eGkZuv+XRK7yqDN4CLgy039WjF6n+ieHFsIM72Rrg7m5DBgYgUnhvdudzXPX9jF/41JMCsbnR7Wys8Xaquy5VisQCutc5TSj0CrMNYRval1vqwUuo1IFhrvRq4GnhTKaWBLcDMmq5HdVrBdVX//v3LHFu0aBGff/454eHhpKenk5eXh8lU+T9ApRQ9evQoet66dWsAYmJiJIALUYM2hMbwwDfB3DckgBfHll58c/n++1so+88l83939cbRzoZpX/3Nc6sO8MHEnhbLQplv0sz6fj+xqdmseHAQLZzti8452lmzYEpv3loXxsK/TtHJy4Wpg/zNvnbImSRW7Y3k4avbVatnYWI/P1YER/D7gSgm9jNSLa8pmH1+Y7Hu89LMuUGoCyza3tdar9Fad9Rat9Nav1Fw7OWC4I3W+getdYeCMvdrrS0zla+ecXIq+Q945cqVzJw5k4kTJ7JmzRr27dvHyy+/TG5ubqXXsbKywtr64h164X/0qgK/EMJ84fHpPL5iPw421ny+7TS/HYiq0ev/EBLB0l1nmTG8LaO6tWJ4Rw+eGNmRn/dHsWTnmcu+vrkJTub9eZwtx+KYPa4rPX2bljlvZaV4bnQX2nk4sb4a4+Emk2b26sO0dHVg5oj2Zr8OoLdfUzp4OrN8z8X5078fiKaHb9My3ef1UV2bxCaKsbOzM2sXtS1bttCrVy+eeOIJ+vTpQ4cOHQgPD7/yFRRCVCozJ58Hl4ZgbaVYM2sYvf2a8p8fDnA85kKNXP9QZAov/HSQQW1b8PT1F3vNZo5oz8gunvz3t1BCzlR/bXNevok1B6OZsHAnPV/7H+cSMyotv+tUAh/9eZwJfX2Y3N+30rLXdPZk96lEs9OXrgw5x8HIFJ67sTNO9tXrNFZKMbGfL/vOJnP0/AXOJKRzMDKFsZW0vusTCeB1WEBAACEhIZw8eZL4+PgKW9SdOnXi4MGD/PLLL5w8eZJ58+axatUqC9dWCFGc1prnfzrI0ZgLzJvUiwB3JxZM6UMTO2tmLA3hQlblPWRVSc7I4aFlITR3suPjO3uVGFO2slK8N6En3s0ceXjZXmIvmLe2OTE9h/mbTnDV25t4eNleopIzyckz8frvoRW+Ji/fxOzVh/Fu6sir47pV2WU/orMnOfkmtp2Ir7I+KZm5vL32KP38mzGuR2uzfobSbu3tg6214vs95/i9YPb56O4tL+ladY0E8DrsySefxN3dnR49euDh4cH27dvLLTdjxgymTp3KvffeS69evdi9ezezZ8+2bGWFaIT2n0tm7MdbeX/90TIJS77ZdYaf9kXyxMiODO9oLHdt6ebAJ3f25kxCBk+vNC//dk6eiYeXhTBk7sYSj6vf3cz5lCwWTOmNe7Hx5kJujrb83119SMnM5ZkfDlT5PpuOxjLwzT95Z91RAjyc+GxqH/56egSPXNOedYdj2Hq8/Jwb3/59lrDzF3hpbBezJs3182+Oi70Nm8Jiqyw7b8NxkjJymD2u6yWP5Td3suP6ri1ZtS+C1fuj6OnbFJ9m9b/7HEDVxwTuxfXt21cHBweXe+7IkSN06dLFwjUStUH+1sLS4tOyGfvRNtKz80jLycNaKUZ1a8m0wf4oBRMX7mJ4Rw8W3d0XK6uSwefzrad4/fcjPDe6MzOGt6v0fV7+5RBLdp5hbFArHGxLBsgbu7fkms6Vrzl+Z10Yn24+yf5XrsfVwbbCcg9+E8K+c0ksvW8AHbxcio5n5eZz/QdbsLOx4o9Zw7At1tJPTM9hxLub6ebtytL7BpgdZB9eFkLImSR2PXdtha85HnOBUfO2MqmfL2/c0t2s61Zk6/E4pn7xNwAvjunC/cPaXtb1LE0pFaK17lv6uCz2FUI0Gv8LjeHb3Wco3Wxp7mTHpH5+9PNvZlYQyss38ei3+0jKyGHVw4Nxtrdhyc4zrAg+x28HorGxUng3c+T9iT3LBG+A+4YGsO9sMm+tDaOthzPXVZCQZNXeCJbsPMMDwwJ4YcylzV4f1sGD+ZtOsvtUYoXvk2/S7DyVwPWBXiWCN4CDrTUvjQ3kgSXBLNl5psSGH++tP0padh6v3FS9FvKITp6sOXiew1GpdPN2K7fMa7+F4mxvw5PXX/6KmCHt3PFu6khkciajG8j4N0gXuhCikTgYkcLMb/dy9PwFktJzSjw2hMYwYeFObvxoG9/vOUtWbuWTR99Zf5SdpxKYc0t3urY28mm/NDaQ3c9fyxu3dGNoB3cWTu2Dm2P5LV6lFG/dHkTX1m7M+CaYr3eElykTGpXK8z8dZEBAc54ZVf6aZXP08muKg60V2ysZcw6NSiUlM5ch7d3LPT+yiydXdfTgw/8dI74gz/ehyBS+/fss9wzyp2OpoF+Vqzt5AlTYjR5yJpGtx+N59Jr2NHeyq9a1y2NlpXhmdGemX9UW76aOl329ukJa4EKIBq94gpFfHx1aYo0yGLPFf94fydc7wnnmx4O8+UcYE/v5MnVgmzLjpX8cjGbhX6e4a6Aft/XxKXGuiZ0NUwa0YcqANlXWydnehuXTBzJr+X5eWX2Y0/HpvDQ2EGsrRUpGLg8uDcHN0ZZP7ux9WRm+7G2s6effnB0nKw7ghecGtyuz9QRg3HC8clMgN3ywhXfWHmXubd159dfDNG9ix6yRHapdJw8Xe3r4uLHxaCyPXlv29Z9uPkWzJrbcOcCv2teuyLgerS95IlxdJS1wIUSDVphgJO5CNgvu6lMmeIORaGRyfz/+mDWM5dMHMqhtCz7fepqr3t7E9CXB7DgZj9aaE7FpPLXyH3r6NuWlGkjI4mRvw8Kpfbh/aACLd4TzwJJgUrNyeWLFfqJTMlkwpQ8eLmXrW12D27lzLCaNuAvlp9bYfjKB9p7OeLpWnMCknYcz/xoawIqQc8xZc4Q94Un8Z1SnCnsZqjKisyf7zyWX2bnr6PkLbDgSw7TBATSxkzZmZeS3I4So17TW7DuXjAJ6+jYtMxY7b8MxthyLY84t3ctNMFKcUoqBbVswsG0LopIzWbrrDN/9fZb1oTF08nIhOy8fB1trPr2rN/Y2NZOm1NpK8eLYQPzdnXhl9WGGv72JpIxcXhvflT5tmlV9ATMMaW+0rHecjGd8z5KbQObkmdhzOpEJfX3Ke2kJj17TnlV7I1m09TRBPm7c0afyNd+VuaazJx9uOM7mo3ElejIW/nWSJnbW3D2o6l6Mxk5a4EKIeikrN5/v95zlxo+2ceuCHdyyYAdjPtrGij3nisaw/zwSw0cbT5iVYKS01k0d+c+ozux87lreuT0IG2tFZHImH0/uRSu3mh9HvWtgG76a1o88k+b2Pj5MHVhzAaxrazdcHWzYcSKhzLn955LJzM1ncAXj38W5ONjy0tguONlZM3tc13In6JmrW2s33J3t2Xj04jh4RFIGv/wTxeT+fjSrgbHvhk5a4EKIOisxPYczCekljuWbNP87EsP3e86RnJFL55YuvHlrd7SGr3eE858fD/DmH0e4rbcP3wefo5u3K6+NrzrBSEUcbK25o68vt/fxIT0nv2hTjCvhqo4e7HlhJPY2VjWaw9zayuhZ2F7OOPj2E/FYKRgYUP74d2nje3ozqlvLy+6BsLJSjOjkwdrD58nNN2FrbcXnW09jpeD+YQFVX0BIABdC1E0JadmMfP8vkjLKZiyztlJcH+jFPYP9GRDQvCjYTe7vy65TiXy9I5wvt5/GxcGWT6f0KbN++lIopa5o8C5UE3Utz5D27qwPjeFcYkaJPOA7TsbTzdsNtybmj2XX1PDBtV08WRkSQciZpIKc5We5uaf3FenhaIgkgAsh6qR31x/jQlYe8yb1xLXURKnOLV3K/ZBXSjGoXQsGtWtBdEomJk2DWjZ0OQrHwbefiGdSf2N2d0ZOHvvOJtdaYpOhHTywtVZsCotlx4l4svNMzBhev5Ks1CYZA2/AFi9ejI3NxXu0zZs3o5QiIiKi0tcppVi6dOllv/+0adMYOXLkZV9HND6HIlNYvucs0wb7M76nNyM6eZZ4mNNCa+XmKMG7mHYezni62LP95MVx8L9PJ5Jn0kXB3dKc7W3oH9CcdYfP8/XOM1wf6EV7z+qtKW/MJIA3IoMHDyY6Orpo3++asnTp0nLH6+bNm8fKlStr9L1Ew6e15pXVh2nhZMdjl7DGWJRPKcXgdi3YWbAkDmDHyQTsrK3o26Z5rdVrRCdPwhMySMnM5cEq0sqKkiSANyJ2dna0bNkSKyvL/Nnd3Nxo1qxmlsEIy9h0NJapX+wmO6/yTGTHYi5w26c72H2q7Kzm4vaeTWL8/O38sj/S7Dr8vD+SkDNJ/GdU50pzd4vqG9zenfi0HI7FpAHG+Hcvv6ZmbUJypVzT2cjKNqhtC3r5Ffu8yL4AqVFlHznpFVyp8ZEAXkctWrQINzc3srJK7nD01ltv4efnR35+Pg888ADt2rXD0dGRtm3b8vzzz5OdXX6iBii/C33Tpk0EBQXh4OBAUFAQmzZtKvO6F154gS5dutCkSRN8fX158MEHSUlJKbrm1KlTAeMOXynFtGnTgLJd6Fpr3n33Xdq2bYudnR3t2rXjww8/LPFe/v7+vPzyy8yaNYvmzZvj5eXF448/Tl6eeXsHi8vz7e6zbD0ez4bQyneK+nzrKULOJHHXF7v5MaT8IZlf/4li0me7CI1KYdby/Xy44ViVu2+lZefx5powevi4cXvvqtcli+opzLS2/UQ8yRk5HI5KrTB9qqW09XDm+Rs78/pIdzi0CtY8DZ8OhTd94f0uZR9zWsNbAbDwKlg+Bf54FkJ/AVPlN50NkUxiq6MmTJjAY489xi+//MLEiROLji9ZsoS77roLpRSenp58++23eHl5ceDAAWbMmIGtrS2vvvqqWe8RFRXF2LFjmTBhAsuXLycyMpJZs2aVKefo6Mhnn32Gr68vJ0+eZObMmTz22GN8/fXXDB48mE8++YRHHnmE6OjoovLlWbBgAS+99BLz5s1jxIgR/Pnnn/z73//GxcWF++67r6jcxx9/zDPPPMPu3bvZt28fU6ZMoVu3biXKCPNFJWfy7e6zONnb8NDVFXdRZuXmF+XLXr7nLGOCyt/04UJWLr/+E82YoFYkpefw5Mp/CE9I5/GRHbGyUmitmb/pBO+uP0Y//2Z8cmdv3l57lA83HOd0fDpv3RZU4UzrTzaeIPZCNgun9rmsNcb1gikfovaBsyc0rbmUoZXxadaENi2asONkPK3cHNC64vSpFhO5l+mhj8HGg8ZzWyfw7QdXPwsupfbt1hoykyDlHKREQMJJOLUZdn8KLdrD0MchaCJYN46em8YXwP94Fs4ftPz7tuwOo+eaXdzNzY3x48ezZMmSogAeHBxMaGgoq1atwsrKijfeeKOovL+/PydPnmTBggVmB/AFCxbg7u7OokWLsLGxITAwkDlz5nDTTTeVKPfiiy+WeJ8333yTSZMm8dVXX2FnZ4ebm7GbUMuWpf6zlTJ37lweffRRpk+fDkCHDh04evQob7zxRongPGzYMJ599tmiMl999RUbNmyQAF4NWmv+Pp3I4h3hrA+NId+ksVIwoa9PualEAXafTiQjJ59efk3ZdiK+zHKjQr/+E01mbj73Dw2ga2s3Xvz5IB9vPMHp+HTm3Nqd2asPs2pvJLf08mbubd2xt7Hm3TuCaOvhxDvrjhKZlMnCqWVTmp6OT+eLbae4vY9Pya7Uui4jEZLCjYBSGFjSYsGzC7QZDK17g21BilKtIeYQHPgeDv4AF4ybXlx9oM0g8BsEbYaARyeowXXgxQ1u585v/0Th4eKAk501ParITldt+Xlw/h84sxNiQ6HjDdD5Jig9dGcywY6PYON/wdkLrn/d+H21DKpeADblw5FfYet78MtM2DwXBj8GvaeCbcOexNj4Ang9cs899zBu3DhiY2Px9PRkyZIl9O/fn06djO31Fi1axOeff054eDjp6enk5eVhMpnMvn5oaCj9+/cvMVN96NChZcqtWrWKDz/8kBMnTpCamorJZCInJ4fz58+bPSEuNTWViIgIrrrqqhLHhw8fzrx588jIyKBJEyNY9OzZs0SZ1q1bc/r0abN/rktxLjGDPeGJ3FqHu23XHz5P66aOFW6/WGjr8Tje+P0IYecv4OZoy/3DAujXpjn3Lwlm7eHzFW60sSksFgdbK969owcj3/+LlSERPHFdxzLlvt9zls4tXYrSlr51WxAB7s68tTaMTWGxpOfk8/jIjjx2bfuiyY1KKWaOaE+bFk14csU/3LJgB9eX2tpy9+lEHGysL2vnLYtJj4fDP8GBFRDxd8lztk7QpDkc+sF4bm0H3n2MwBS+1QhqVjbQ4Xro+prRojyzA05vgYMFkz69usGwJyDwZrCq2fHpIe1b8N3fZ/lpXwSD2rYosb/3JctIhOAvIHwbnNsDuQXj1HYusH8ZuHeEoU9A99uN4JwaBT/NMH7mwPEw9kPjd3YprKyh683GdU5sgC3vwh9Pw8bXoet4o0XuN7jsDURaHJzdCRnx4NMPPAMv73edmwmRIcaNS6+7wPXKb1va+AJ4NVrBte3666/H3d2db7/9lpkzZ7J8+XJmz54NwMqVK5k5cyZz585l+PDhuLq6snLlSl544YUarcPu3bu54447eO6553jnnXdo1qwZu3bt4p577iEnJ6dG36uQnV3JFIpKqWrdmFyKL7adZvGOcEZ08qyTKRyPRKfy4NIQPF0c2PjU8Ao3eUhMz2Hmsr00d7Jj7q3dGd/TG0c7a7TWtPVw4vcD0eUGcK01G8NiGdzOnXYezlzVwYOVweeYdW0HrIt1ZYdGpqAiQ3i/fShq4fPg2RXVZjAPdRuMf/NezF13lDnXdSyTb7vQ2KDWtG7qyBPf7+e7v8+WOGdtpXjppsAa2bzjisjJgKNrjCB7YgOY8owP/WteBI8u0NQX3HzBsZnRes5INALEmR3G1+AvjUA+5j0IvAWcinVdD5hhtM4TTxV0Cf8f/PAvaP7GxW5hm5r5dzmorfG+WbkmBre7zPFvUz7sXQJ/FtyIeHWFnncW9CYMNoYHQn+Gre/Dzw/CpjkQdIfxu8jLhnEfQ6+pNdPboBR0uM54nNlh1Ovgj8ZXVx/j5sGjE5zdZZxPOF7y9fZu4DfA6AVp1cO8XoDsNOMG7sxOiNoL+QWfiV6B4Drm8n+mKlg0gCulRgHzAGvgc6313FLn/YCvgaYFZZ7VWq+xZB3rEmtra6ZMmcI333xD27ZtSUlJYdKkSQBs2bKFXr168cQTTxSVDw8Pr9b1AwMD+eabb8jPz8fa2rjz3L59e4ky27Ztw93dnddff73o2A8//FCiTGHALX6d0lxdXfHx8WHLli2MHTu26Phff/1FQEBAUeu7thyJTgXgcFQqQzvU7qSe0rTWzF59mCZ2NpxPzWLBppM8dUOncsu+u/4o6Tn5/PBQ3xJ7NCulGNu9FZ9sOkF8WjbupbqvT8alczYxgweuMpJoTOrny0PL9rLleBwjOnkaY40HVuC1ayk/20ego+zBt78RyA4sB2C0kwej/QZC5mCIGgRe3cG62EeM1pBwgt5xO9jcZb/RIg0cf+ktL4D0BCM4nt1pPG8z2PgAvpxrFmfKN1qJB1bAkdWQkwYurWHgw0ZQbdmt4tc2aQ6dxxgPMH7+ygKVUtCinfHocy+E/Wq0Jlc/ApvfhE6jjRuEwhsFN1+j67mqVSUmE+RdnAzbwg56eNlyOCaTwZez/jsiBNY8aYzj+w2GMe8aAby0brdB11vh+Hrj59n6HrTqCbd9Ae7tL/39K9NmsPEY8x4c/cMYstjxMeh8cHAD34HQa8rFm4xzf8PZHUZgP76+eu9lZWP8PANmGNfzG1hz//6qYLEArpSyBuYD1wERwB6l1GqtdWixYi8CK7TWnyqlAoE1gL+l6lgX3X333bz33nu88sorjB07lubNjX8YnTp14osvvuCXX36hW7du/Pbbb6xatapa137ooYd4//33mT59Ok899RRRUVFlWvCdOnUiLi6OL774ghEjRrBt2zYWLFhQokxAgJG3ePXq1QwdOhRHR0ecnZ3LvN9zzz3Hk08+SYcOHbj66qvZuHEjn376KfPnz69WvWua1pqw8xcAOBSVUucC+O8Ho9l9OpE5t3RnT3gin205xR19fWjTwqlEuUORKXz3t5H8pHjwLnRjUCs+2niCtYfOc1epjTI2hRmzzguX9FzbxYsWTnZ8//c5RqT9Ab8+hkZxgq6sbTmFKdNmGh+EBUG5qJV5ZrsxHglG96lvP+PDLeG40fJJjzPO2ToZrbA1TxtjpEEToMMNF8eKK5J81mjtnN1hfI0/ahy3Lrgh2fmJ8dWjsxHIW/cqFvB8Kh8TNeVDWgwknzPGsqP2GePUaefB3tXopu0+AfyHXlpXa3VamVZWxs1Nl3Fw4k/YMc9o+WellCpnC27eFwN6U19QVgU/w9mCcfmIiy3DAr8AJgeF+q6V8XtpWvD7cfYyXl+V84eMrnFnT7h1EXS/o+qbk443GMMGyWfBtbVlJprZORkt7+63G8Me6XHg3qnsTU/zAOhRMFk4PR7ijgKVr5gAjOERr67G+9QCS7bA+wMntNanAJRSy4HxQPEArgHXgu/dgCgL1q9OCgoKomfPnuzfv7+o+xxgxowZHDx4kHvvvZe8vDzGjh3L7NmzefTRR82+tre3N7/++iv//ve/6dmzJx06dOCjjz7i2muvLSozduxYXnjhBZ5//nnS0tIYPnw477zzDnfeeWdRmX79+jFr1ixmzJhBXFwc99xzD4sXLy7zfg899BDp6enMmTOHh5khn2YAACAASURBVB9+GF9fX+bOnVvrk9POp2aRkmnk2z4UmVJFacvKyMljzu9H6NralYn9fLm2iyfrDp/n9d+PsOjuvkXlClvpzZvY8e+RZcetATp5udCuoBu9dADfGBZLJy+XosxldjZW3NbHh03btqPPvIgKuIr1HWcz45fzfDtygBG8wfhgdu9gPPrcYxxLiSzZdXzyfWOWdbtrja7VNkOMGcPnDxgt24MrIew3owuzVZARSAqDkWvri0H7zA5ILViyZu8KvgOMD902Q4xArbURdAuD+6EfIeSrkr+EJu7g5A6UCja56ca4rKnYckUrWyPgBE2AjqOqvrm4EpSCDiONB0BW6sWgnHK2IFAXTJ47tfnipDiXlsbvsVVP6Dy2oEV48Wc2adDZaVilRRm/38gQCF0NprJ558tlZQODZsLwZ8DBteryxX+eZrW0TahT4d++hsrVAaqqdZk19kZK3Q6M0lrfX/B8KjBAa/1IsTKtgPVAM8AJGKm1Dqnsun379tXBwcHlnjty5AhdunSpoZ9A1GWX87feFBbLvYv34Olij5O9DZueurpmK3cZ3lt/lI83nuCHBwfR19/offl080neWhvG1//qz/COHgD8sj+SWcv389Zt3ZnYr+IlSe//7xifbDzOruevxdPFCEipWbn0fu1/3D+sLc+OvjiB7ER0EumfXkMnuwQcHtvN5OVniEzOZPNTV1dviVdeNthUMq5d2E19eBXEHTOC0YVo0MXmPTh7FczQLugi9+padSvYlA+pkcWCXEGLNCOxbFkb+4s3DoU3D039aq1ldcnycgBd+e+7IiYTZJt5A2ttD3a1O+zVmCilQrTWfUsfr2uT2CYDi7XW7ymlBgHfKKW6aa1LzGBSSk0HpgP4+Vlm/aRouEILxr9v6eXNwi2nuJCVi0sdyAB2NiGDhVtOcXPP1kXBG+BfQ/35fs9ZXv31MGtnXUVuvok5a44Q5OPGHX0q3/N6bFArPvrzOOsOnWfqIH8Ath2PJ8+ki7rPC7UP+xSsTjHb5j/ck+PKzlMJPH1Dp+qvz64qmFhZQ7sRxqNQfm5B5q1II3g3b1v9iU5W1kYQttAa6zrhcia6WVkZE/BEvWHJTGyRQPFPF5+CY8XdB6wA0FrvBByAMn0ZWuvPtNZ9tdZ9PTw8rlB1RWMRdv4CPs0cGViQ0CI0KrWWa2R4/fdQbKwUz44u2bNgb2PNyzcFciouna93hDN/0wliUrN55aauVQbXjl4udPB05veD0UXHNobF4uZoS2+/YuuBz+2BLe8S7jOOxck9efbHA1gpuL2PhZbZWdsaXa1tBhuTuq7Qmmgh6jNLBvA9QAelVIBSyg6YBKwuVeYscC2AUqoLRgCPs2AdRSMUFp1K55audGttjOseqgMBfMuxONaHxvDINe1p6VZ27PWazl6M6OTBhxuO8fnW09za25s+bcxrPY0JasXu04nEXsjCZNJsPhrLVR09sClcD5ydBqseAFdvPCfMw8Xeht2nE7mmsyderrUwDiyEKJfFArjWOg94BFgHHMGYbX5YKfWaUmpcQbEngQeUUv8A3wHTtKUG6UWjlJWbz6n4dLq0csHDxR4vV3sOX6GJbAlp2Uz+bBcbQmMqLZeRk8fsXw/TpkUT7hsaUGG5l2/qSk6+CTsbK56tRvKTMd1boTX8FXyAM9u+wy/9EDe20cYYKMC6543MYrcupIlrc8b1NJL1VDa2LoSwPIuOgRes6V5T6tjLxb4PBYbU8HuWu9WlaDgu5x7vRGwa+SZNl1bGTNpurd04FFUQwCND4O9FcMOcGlnX+e76o+w8lcDByBR+njmE9p5ll9pprXn2x4OEx6fzzX0DsLepeKJWgLsTH0/ujZO9NZ7VaBl38HLhvub/MHrLfJx1GqvsMaaObrA1skcln4Uh/za6r4FHrmmPl6sDIzrJcJUQdUldm8RWo2xtbcnMzKz1JCHiysrMzMTW9tImnRUmcOnc0lg33dXbjU1HY8nMzMTxpwch/pjxuHs12JcNuOY6GJHC8j3nuLlna7Ycj+fBpSH8MnMITvYl/wsu3hHO6n+iePqGTmbtEjWqW+X558vIToO1z/BSxlL+MbXlc8fn8HLI48WhzsYM7eRzxnrsEc8XvaSVmyOPXSv7cgtR1zToAO7p6UlkZCTe3t44OjpKS7yB0VqTmZlJZGQkXl5eVb+gHGHnL+Bga1WUFKVba1dMGhI2zsMn/hgMeAj+/gyW3wl3rriktcBaa15ZfYgWTna8dnM3DkakMPWL3fznxwN8MrlX0b/LPeGJvPH7Ea4L9OKh4RXvGnbJIvfCj/dD4ikSez/KbTv6kZdjw1MDOkI/CdBC1DcNOoC7uhrdolFRUeTmmpmgQNQrtra2eHl5Ff2tqyvsfCqdvFyK8n1383bDi0S89n5oJO8YPRda9zQ2XvjxPrjj65LpQc3w8/5I9p5N5u3bg3B1sGVIe3eevqEzb60No5dvU+4f1pbY1CweXrYXn2aOvDehR81upZmbBdvnwZa3jSVZ9/xK84BhtD+1hbDzFxhRavmYEKJ+aNABHIwgfqkf7qJh01pzJPoC13W52Hpv5ebAq47fGUlARhWk6u8xCTKTYe0z8OtjMO6TqvNPF0jLzuPNNWH08HHj9mI7nT04vC37zyXx5h9hdGnlyrwNx0nLyuOb+/rjWpNr0I+tgz+egaTTRk7qG98tGs+/d4g/q/+JIrCV/P8Qoj5q8AFciIrEpWWTmJ5D51bFNv0I38oovZ1lDpOZ0rzYDPCBDxq7Lf01Fxyawg1vmLU2+eONx4m9kM3CqX1KtKqVUrxzRw9u/mQ7d3/5N/kmzbxJPencsoaCaeJpWPssHFtrbOU49eeSiVIwZpXLzHIh6i9LrgMXok4JizY2MCmcgU5+Lqx5mmT71sxJHUV2Xn7JF1z9LPSfAbvmG9s9VuFUXBpfbjvN7X186OVXdo22q4Mt/ze1D0521jwwLKDCLTirxZQPW96B+QPg9Fa47jV4cHuZ4C2EqP+kBS4ardIz0Nm9EOLCOD5wAembbTl2Po3uPm4XX6CU0a2eGmmslW7R3th7uBxaa177LRR7G2v+M6r8rT/ByIwW/OJ12NnUwL108llYNd3YQCTwZhj1prEZiBCiQZIWuGi4tDY2x0g8Ve7psPMXaOXmQNMmdsYOWpvfhA434Nl3PMDF9eDFWVnBLQuNzTRW3guxR0qcTsvOY8nOcEa+/xebj8Yx69oORZuGVKRGgvehH+HTocY2j7d8BhO+luAtRAMnLXDRcOTnwfl/CvaLLnhkJBjnOo+FYU+Ad5+i4keiU+nnkQcbXoU9nxtbSY6ei18zJ1wcbCrcWjRDOZB3y1Kcl1wHyyaSdvc6YvOdWbb7LD8ER3AhO48ePm58MLEH43vUQLd40c+XCznpJY/lZcOfrxp7M/v0M/Zmbl5x9jYhRMMhAVw0DPm5sORmOLPNeN7M30hI0maQkaBk90Jjz+m2V8Owp8hx9ePOhE+YnLIZInKg680w7Clo3hZFYUa2sjnRv99zlud/OkS+SdNDPcL3dv8lbN547sp5Hm1tx43dWzFtsH+5Y96XLDPZyAi3awFklrMVprKCq/5j7M1czSVuQoj6S/63i4bhf68Ywfv6143lUqW7jwc/CsFfwo5P4Oux2KKYbGVFtO94/MY9D+4lE5l083bl651nyM03YVuwycf+c8m89PNh+rZpxvVdWwKB7Dxvx4hDz/JHu1W4TFiIp5tjzf1MabFG0P77c8i5YKxLD7gKKDX73W9AiZ4FIUTjIAFc1H+hq2HXfEK87uDhzV1gcygQWnS6n39zPpjYE9shs4xZ5PuXcexYGPce7MbXY24Fd5cyl+zm7UZOnomTcWl0bulKQlo2Dy8NwdPVnoVT+xjj5gA8BC2SaffXXNjkDGM/qHr/68qkRBhDAKc3w8EfjC7yrrcY3f8tu1/6dYUQDY4EcFG/JZyEX2aS1iKIyWfG0q+9M77NLua+T8vO47cD0bRyc+CFMYFGKtR+97Eq7gjx1uEEuDuVe9muhVuLRqbSwdOFx5bvIz49h1UPDS4WvAtc/awxQ33zm8aEuYlLwanqPOaAsQPY4VVw/H9wdocxkxzAzhm63w5DHgf39tX+tQghGj4J4KL+ys2ElfeglRUP587Co6krn9/dD0e7kjt4NXc6xKKtp+np24wxQa0AOHL+Ah28nC/ugV1KgLsTTeysORSZwsm4NLafSODt24Po5u1WtrBSRhB37wg/PwSLRsDk78ErsPL6X4gxyp/8E5q4G+P1Ax4ydgHz6ibj2UKISsknhKi//ngGzh9kU++P2bLDkQVTupQJ3gAvjgnkYGQKT//wD51aOtPe04Ww6FSGdah4e0xrK0VgK1dW/xNFYnoOk/v7MaGvb+X16XYrNGsD390JX1wHt38JHW8ov+yxdfDzw5CTBmPeg773mZXZTQghCsk6cFE/7f8O9n5N5oDHeHxfSwa1bcHoCrbWtLOxYsGU3jSxs2b6NyGcTcgg9kI2XVqVHfsurpu3G4npOfTwcWP2uCpa04W8+8D0TdCiHXw7ERZeBX88a4zTp8UZvQZrnoZvJ4BLS5j+F/S7X4K3EKLapAUu6hetje091z4L/sN4M+tW0rKjmT2ua6XbxbZyc+Tjyb2564vdTFv8N1AshWoFRnbxYvfpRBbc1Qd7m7It+wq5toZ7/4Cd8+H0Fgj5CnZ/apyzd4PsFBj4MFz7yiVtTyqEEABKa13bdbgsffv21cHBwbVdDVFAa82uU4n0adOsZjKMFVeQq5yQr6DTGI4Mfpcx/7ePuwf5M3tcV7MusWjLKd5YY2RPC3lxJC2cL2PGuLnyciB6P5zZATGHIGgSdBh55d9XCNEgKKVCtNZ9Sx+XFnhDpDVE7TOWIPkOMHvry5qw4UgsDywJZnJ/X968NajigjkZEL4NXLyMCVtWVbRwMxJh5T1Gi3bo4+hrXuKVz/6maRM7Hh/Z0ez63T8sgIORKRyKSrFM8AawsQPf/sZDCCFqiATwhiTxFBxYCQe+h8STxjFXb+h+BwRNMPJ316SYw7BpDtg5gZsvuPlwYn8O7ZTip7+z6enbtOR2laZ8IwAfWAFHfjWSkwDYuxrBzW8QMc16E2Mq2bVtm51EwNansEuPInzouyS0v439287wd3gib97aHbcm5u+frZRi3qSe5ObX754nIYSQLvSG4Nh62PI2ROwBFPgPNQK2bRMjWJ7YADrfaOn2ux/6TLv8SVMJJ+HLUZCfYwTg1EjjPYpJ1C44urfB0cMfHJvC8Q2Qdt4oHzjOSFCSkWh0LZ/dCXFhFb5dvHZlRs7jhOiLO3t193bj55lDsLaSCWBCiIaroi50CeD1XXoCzAsCJw8jMHe/Hdx8SpWJh8M/wf5vIWov9JgMN8279IxhqVHw5Q3Gxhr3rgWPjpCfx197D/Lxqo28MaIpvtYJrNsRTEsdR/9m6VhnxIHfIOPGouOoEpO3TCbNW+vCWPHXfqb6xnFjBydUsXShWkGq5wBymniVqEYvv6Y42UsnkhCiYasTY+BKqVHAPMAa+FxrPbfU+Q+AEQVPmwCeWuumlqxjvbPtfcjNgMnLwbNz+WWc3KH/A0br+6+3YfMcSDxtZAxzrngtdLkyEuGbWyAjCab9agRvAGsbfjwBp5oE0e7aa7GxtqJtx2Tu+L+dDGjSnMUz+5fbUs7Myefx7/ez9vB57hrYjcdu6lphchUhhBAXWeyTUillDcwHRgOBwGSlVInFtVrrx7XWPbXWPYGPgVWWql+9lBJp7FIVNKni4F2cUnD1M3D7V8as6EXXGOPY5sq+AEtvM4L/5O+gda+iU1m5+Ww4EsMNXVsWBeAevk15dXxXth6P58MNx8pcLjY1i4mf7WRd6HleGhvIf8d3k+AthBBmsmQLvD9wQmt9CkAptRwYT/FdJ0qaDLxiobrVT1veAW0ygnJ1lMgYdj2Mnw9dxlU+Wz0zGVZMheh/jJZ7wLASpzcfjSUjJ5+xBalKC03q58u+s0l8vPEEy/ecK3EuLSsPpWDR1L6MDCzZPS6EEKJylgzg3kDxT/AIYEB5BZVSbYAAYGMF56cD0wH8/PzKK9LwJZyEfd9An3uNva+rqzBj2HeTjOVZbr7G+HnQRPDsYpTJy4bj641Z7cfWGRPWblkInW8sc7nfDkTTwsmOAQHNSxxXSvHa+G60dHUgLi2nxDkbK8Xk/n4Etq48oYoQQoiy6uoMoEnAD1qXmtZcQGv9GfAZGJPYLFmxOmPzXLCyhaueuvRruLaGf603lnQd+B62fwTbPgCv7saSs2N/QFaKMUGu733QczK06lHmMpk5+WwMi+WWXt7ldoE72FrzxPWdyhwXQghx6SwZwCOB4rtB+BQcK88kYOYVr1F9FXMYDq6EIbOMfNqXw9YBgu4wHmlxxtaWB76HsN+NlnbQBAi4utKdsQq7z8d0b1VhGSGEEDXLkgF8D9BBKRWAEbgnAXeWLqSU6gw0A3ZasG71y8Y3jLXUQ2bV7HWdPWDADONRDb8djMbd2Y7+pbrPhRBCXDkWm/Krtc4DHgHWAUeAFVrrw0qp15RS44oVnQQs1/V9gfqVEhEMR3+HIY9Ck9oPmBk5eWw8Esuobi1lBrkQQliQRcfAtdZrgDWljr1c6vlsS9ap3tk8F5q4w4CHarsmAGwKiyMzN58x3VvXdlWEEKJRkSZTfXP+AHQaDfbOtV0TANYcjMbd2V66z4UQwsIkgNcnWkNGgjErvA7IyMnjz7AYRndrKfnIhRDCwiSA1ydZKWDKM1Kj1nZVcvN5euUBsnJN3NRDus+FEMLS6uo6cFGejATja5MWtVqNuAvZPLAkmH8iknludGfpPhdCiFogAbw+KQrgtdcCPxZzgXu/2kNCejafTunDqG6XuQ5dCCHEJZEAXp8UBfDaafH+dSyOR5btxcHOmhUzBhHkIxvFCSFEbZEAXp+kxxtfa6ELfd3h8zy8bC8dPJ35clo/Wjd1tHgdhBBCXCQBvD4pbIFbeBLbybg0nlzxD91au7LsgYE428s/GyGEqG3ySVyfZCSAjQPYNqmRy8WkZrFs1xliUrN5YWwXXB1sy5RJz87jwW9CsLOx4tO7+kjwFkKIOkI+jeuTjARjApu69DXXWmv2nk1i8Y4z/HEwmnytsVKKfeeS+OKefvg2b1Ki7DM/HuBkXBrf3DdAus2FEKIOkQBen2QkXNYEtq3H43hrbRiHIlNxcbBh2mB/pg5qQ2RSJg8uDeGWBdtZdHdfevk1A+DL7eH8diCaZ0Z1Zkj72l97LoQQ4iIJ4PVJevwlT2BbsjOc2asP06aFE6/f3I1bennjVNAd3qaFE6seHsK/Fu9h0me7eH9CTzxc7Jmz5gg3dPXiweFta/CHEEIIURMkgNcnGQnQPKBaL8k3af77WyiLd4QzsosXH03uSRO7sn/29p7O/PTwYKZ/E8LMb/fiYm9Dm+ZNeOeOHqjL6LIXQghxZUgq1fokI7FaLfC07DweWBLM4h3h3D80gIVT+5QbvAu1cLZn2f0DuKWXN0rB/03tU+7ENiGEELVPWuD1RV4OZKeYnYUtOiWTfy0O5ljMBV6/uRt3DWxj1uscbK35YGJPcvNN2Mr+3kIIUWdJAK8vMhONr2ZOYnv9tyOcTUjny2n9GN6x+ruXSfAWQoi6TT6l64vCLGxmJnE5EZvG4PbulxS8hRBC1H0SwOuLauxEprUmIikDb1m3LYQQDZYE8Poiw/w86CmZuaTn5OPTTAK4EEI0VBLA64uMwjHwqrvQI5IyASSACyFEAyYBvL4o7EJ3bFZl0YsBvGZypgshhKh7LBrAlVKjlFJHlVInlFLPVlBmglIqVCl1WCn1rSXrV6elxxvB27rqhQMRSRmAtMCFEKIhs9gyMqWUNTAfuA6IAPYopVZrrUOLlekAPAcM0VonKaU8LVW/Oi8jwewkLhFJmTjZWePmKElYhBCiobJkC7w/cEJrfUprnQMsB8aXKvMAMF9rnQSgtY61YP3qtgzz86BHJmfi06yJpEAVQogGzJIB3Bs4V+x5RMGx4joCHZVS25VSu5RSo8q7kFJqulIqWCkVHBcXd4WqW8dkJJqdhS0iKRNv6T4XQogGra5NYrMBOgBXA5OBRUqppqULaa0/01r31Vr39fBoJIlK0uPNzsIWmZQh499CCNHAWTKARwK+xZ77FBwrLgJYrbXO1VqfBo5hBPTGTWtjDNyMLGwpmbmkZuVJABdCiAbOkgF8D9BBKRWglLIDJgGrS5X5GaP1jVLKHaNL/ZQF61g3ZV8AU65ZY+CRBUvIvJvKEjIhhGjILBbAtdZ5wCPAOuAIsEJrfVgp9ZpSalxBsXVAglIqFNgEPK21TrBUHeusoixsVbfAI5MliYsQQjQGFt2NTGu9BlhT6tjLxb7XwBMFD1GoKAtb1S3wwjXgMolNCCEatro2iU2UJ938POiRSZk42FrRwsnuCldKCCFEbZIAXh8UplF1MqcFLmvAhRCiMZAAXh9UYyeyiGTZRlQIIRoDCeD1QUYCWNuDnXOVRSOTMmUCmxBCNAISwOuDwjzoVXSLp2fnkZSRKxPYhBCiETA7gCulpimlJpRzfIJS6u6arZYoId28jUwuLiGTNeBCCNHQVacF/gyQWM7xeKDcrUFFDclIMHMCm2wjKoQQjUV1Arg/cKKc46cKzokrxcydyCIKsrD5yCQ2IYRo8KoTwFOAgHKOtwPSaqY6olwZCeZlYUvKxM7GCndnewtUSgghRG2qTgD/A3hHKdWq8IBSqjXwFqWyq4kalJ8LWSlmt8C9mzpiZSVrwIUQoqGrTgD/D+AEnCzcixujS92p4Jy4EorSqFa9lWhEsiwhE0KIxsLsAK61jgN6AY8CuwsejwC9tdaxV6Z64mIWNnO60GUfcCGEaCyqtZmJ1joL+KLgISzBzCxsmTn5xKflSBY2IYRoJKqzDvxZpdR95Ry/TyklXehXSmELvIpJbLIGXAghGpfqjIFPB46Wc/wIMKNmqiPKMHMnMtlGVAghGpfqBPDWQEQ5x6MA75qpjijDzElsF1vgEsCFEKIxqE4AjwW6l3M8CEiomeqIMjISwMENrG0rLRaRlImttcLTxcFCFRNCCFGbqhPAVwEfKKV6FR5QSvUG3gN+qOmKiQJmZmGLTMqklZsj1rIGXAghGoXqzEJ/AegJhCilCnOiNwe2As/XdMVEATOzsEXIEjIhhGhUzA7gWut04Gql1DVAn4LDIVrrjVekZsKQngBuPlUWi0jKZHhHDwtUSAghRF1QrXXgSqlmgBdgDdgBQ5VSQwG01q/VfPUEGQnQukelRbLz8om9kC1LyIQQohExO4ArpfoBawEFuAJxgCeQAUQDVQZwpdQoYB7GDcDnWuu5pc5PA94BIgsOfaK1/tzcOjY4Wps1Bh6VnAXIDHQhhGhMqjOJ7R3gR8AdyASGAG2AfRh7hVdKKWUNzAdGA4HAZKVUYDlFv9da9yx4NN7gDZCTBvk5VQbwyIJtRGUNuBBCNB7VCeA9gQ+01ibABNhprSMwgvccM17fHzihtT6ltc4BlgPjq1vhRsXMLGyFSVykBS6EEI1HdQJ4PpBb8H0s4FvwfTxGS7wq3sC5Ys8jKD8BzG1KqQNKqR+UUr7lnEcpNb1wR7S4uDjzal8fpRcG8KqysGVibaVo6SprwIUQorGoTgA/gNEKB9gFPK+UugF4k/JTrF6KXwF/rXUQ8D/g6/IKaa0/01r31Vr39fBowDOvzdyJLDI5k5auDthYV+fPKYQQoj6rzif+G0BewfcvYUxg+wMYBjxmxusjudhqB/Dh4mQ1ALTWCVrr7IKnn3NxuVrjVLQTWeVpVCOSMmT8WwghGpnqrAPfUOz7cKCrUqo5kKS11mZcYg/QQSkVgBG4JwF3Fi+glGqltY4ueDoOY6OUxivDvC70yKRMBrarOlubEEKIhqNa68BL01onVl2qqGyeUuoRYB3GMrIvtdaHlVKvAcFa69XAY0qpcRgt/URg2uXUr95LjwcrW7B3rbBITp6J86lZsgZcCCEamcsK4NWltV4DrCl17OVi3z8HPGfJOtVpGQlG61tVnN/8fEoWJg0+TaULXQghGhOZ9VSXZSRWOYEtIlmWkAkhRGMkAbwuy4g3YwJb4T7g0oUuhBCNiQTwusyMncgikzJRClq6yRpwIYRoTCSA12XpcWYlcWnp6oCdjfwphRCiMZFP/boqMwmyUqCpX6XFIpIy8JYJbEII0ehIAK+rEk8bX5u3rbRYZHKmTGATQohGSAJ4XZVUGMADKiySl28iOiVLsrAJIUQjJAG8rko8ZXxt5l9hkfOpWeSbtMxAF0KIRkgCeF2VGA7OXmDnVGGRyKIlZNICF0KIxkYCeF2VdBqaVdx9DhfXgMskNiGEaHwkgNdViacrHf8GYwIbQGsJ4EII0ehIAK+LcjPhQlSVM9AjkjLwcLHHwdbaQhUTQghRV0gAr4uSzhhfzehCl/FvIYRonCSA10VmLCGDwjXgMgNdCCEaIwngdVHRErKKA7jJpIlKzpQJbEII0UhJAK+LEk+DvWulO5HFXsgmN19LF7oQQjRSEsDroqTTRgIXpSosEpFk7AMuWdiEEKJxkgBeF5mxhKxwDbivBHAhhGiUJIDXNaZ8SD5r1iYmAN5NZRKbEEI0RhLA65qUCDDlmrGELIMWTnY42skacCGEaIwkgNc1Zi4hkzXgQgjRuEkAr2vMWEIGxkYmMoFNCCEaL4sGcKXUKKXUUaXUCaXUs5WUu00ppZVSfS1Zvzoh8TRY24Fr6wqLmEyaCEniIoQQjZrFArhSyhqYD4wGAoHJSqnAcsq5ALOA3ZaqW52SdBqatgGrise249OzyckzSRe6EEI0YpZsgfcHTmitT2mtc4DlwPhyyv0XeAvIsmDd6o7EcLOXkEkWNiGEaLwsGcC9gXPFnkcUHCuilOoN+GqtK8T/dgAAIABJREFUf6/sQkqp6UqpYKVUcFxcXM3XtLZobbTAq9yFzAjg0oUuhBCNV52ZxKaUsgLeB56sqqzW+jOtdV+tdV8PD48rXzlLSY+HnDSzJrCBZGETQojGzJIBPBLwLfbcp+BYIRegG7BZKRUODARWN6qJbGYvIcugaRNbnO1tLFApIYQQdZElA/geoINSKkApZQdMAlYXntRap2it3bXW/lprf2AXME5rHWzBOtYuc5eQJcsacCGEaOwsFsC11nnAI8A64AiwQmt9WCn1mlJqnKXqUaclngYUNGtTabGIJNlGVAghGjuL9sFqrdcAa0ode7mCsldbok51StJpcPUGG3sAgsMT8W7mSCu3i8Faa01EUgbDOzagsX8hhBDVVmcmsQlK7EKWkpHL5EW7mLhwFykZuReLpOeQlWuSFrgQQjRyEsDrkqSLAXx96Hly8zXnkjJ4fMV+TCYNFF9CJgFcCCEaMwngdUX2BUiPK5rAtuZgND7NHJl9U1c2hsXyyaYTwMVtRGUNuBBCNG6yDqmuSAo3vjYPICUjl63H47lvWAB3D2rD/nPJfLDhGEE+bkQkZQCyBlwIIRo7CeB1RbElZOtCz5Nn0ozp3gqlFHNu6c6R6FRmLd9P3zbNcHGwwc3RtnbrK4QQolZJF3pdkXgxicvvB6Lxbe5Id283ABztrFk4tQ8mrfkzLFYmsAkhhJAAXmcknQbH5iTlO7L9RDxjurdGKVV0uk0LJz6c2BP+n737jq+yvP8//rqyd0JIAoEQtuwdhmwQAVFxV6zV1lGKo2Id1d+3rbV2WVFbbVW0rlq3FTcoiogMEcLeI6wEAgkkIWSv6/fHHUMCGQSSc06S9/PxOI9zct/Xuc/nDuNzro36v0VERE3oniPD2cRkYXnz+SX9Y08rckGvNjx7/WCNQBcREdXAG8qG5CxmvpbInvScs7tA+RSyzzYdJj4yiD7twqotNq1fLP3jIs4hUhERaQ6UwBvAgk2pXPvCdyzceoRZr68ht7CkfhfY+y1kJZMf1sVpPu8fW6X5XERE5FRK4OfAWsvcJUnc9sZaeseG8fR1g9idlsMD72/EWntmFzm4Ft66DqJ7siDwUkrLR5+LiIjURn3gZ6m4tIzffrCZdxKTuXRAO+Zc3Z8AX29SMvN47PMdDI5vxc2ja99VjPQd8PpVEBQJN3zAB+8doGPrmpvPRUREfqAa+KkK6+7Dzisq4acvr+KdxGTumtiNp64dSICvNwC3jevK5N5t+Mv8bazam1HzRTL3w2uXg7cv3PgRx7wiWZF0rGLut4iISG2UwCtb9g/4VwIU5dZa7KP1h1iRdIzHrurPPZN74OV1MuEaY3j8RwPoEBnEHW+uJS274PQL5KTBfy+H4ly44QOI7MIXW444zefVjD4XERE5lRJ4ZfEj4EQqfP98rcVW780gKsSPaxLiqj0fFuDL3J8MIaeghNvfWMvi7WkVjyWbD3DixemUHk9lzeh/szgzmsXb03hvTTKdo4LpHavmcxERqZv6wCuLHwHdp8Dyf0DCzRBY/XSt1fszSOgYWWtTd4+2ofzt6v7c9dY6bnp1dcXxu33+xzifbdxUdD+LPy0BTp6764Luaj4XEZEzogR+qom/hefHwIp/wgW/O+304eMFJGfk89PzO9V5qekD2jEgLpzM8v28/bIP0HPeZ2R2nM7sCXcyu1JZLwO9VPsWEZEzpAR+qtj+0OdKWPkcDP8FhMRUOZ243xmYNrRT5BldrmPrYDq2Lv/hzVng7Uury/9GqzAtxiIiImdPfeDVmfAbKCmApU+edipxXyaBvt70ru9Ur51fwM4FMO7XENaugQIVEZGWSgm8OlHdYOCPIfElyEqucmr1vgwGxUfg612PX11xASz4NUSdB8Nva+BgRUSkJVICr8m4B5znbx+rOHSioJhtqdln3HxeYcXTkLkPps0BH7+Gi1FERFoslyZwY8xUY8wOY8xuY8yD1ZyfZYzZZIxZb4xZZozp7cr4qojoAAm3wLo34OhuANYdyKLMnnn/N+Ak7qVPQO/Locv4xohURERaIJcNYjPGeAPPABcCKcBqY8zH1tqtlYq9aa2dW15+OvAkMNVVMZ5mzD2w9jX48iEYdReHNh5gmPdBBntFwIHdZ3aNpU+A8YIpf27cWEVEpEVx5Sj0YcBua+0eAGPM28BlQEUCt9ZmVyofDJzhjiCNJCQGzr8dvp0DOz5jBjDDF/hvPa8z6WEIr37RFxERkbPhygTeHqg8IiwFGH5qIWPMHcA9gB8wsboLGWNmAjMB4uPjGzzQKsb+GjqPpbi4mF/8N5EJPWO4YUTHM3+/XwjEDW28+EREpEXyuHng1tpngGeMMT8Gfgv8tJoyLwAvACQkJDRuLd3HDzqPZfOBTL4uLuDq/oOhq9YrFxER93LlILaDQIdKP8eVH6vJ28DljRpRPSTuywQgoWMrN0ciIiLi2gS+GuhujOlsjPEDZgAfVy5gjOle6ceLgV0ujK9Wq/dl0LF1EDFhAe4ORURExHVN6NbaEmPMncAXgDfwsrV2izHmESDRWvsxcKcxZhJQDGRSTfO5O1hrSdyfyYQeMXUXFhERcQGX9oFba+cD80859lCl17NPe5MH2HM0l4zcIoZ2UvO5iIh4Bq3EdgYS9zkbmCTUdwU2ERGRRqIEfgZW78ukVZAvXaOD3R2KiIgIoAR+RhL3ZZDQKRJjjLtDERERAZTA65R2ooB9x/LU/y0iIh5FCbwOa8rnf9d7BzIREZFGpAReh22HT+BloFdsmLtDERERqaAEXoek9BziI4MI8PV2dygiIiIVlMDrkJSWQ9foEHeHISIiUoUSeC1Kyyx7j+bSNUYJXEREPIsSeC0OZeVTWFKm+d8iIuJxlMBrsTs9B0BN6CIi4nGUwGuRlKYELiIinkkJvBZJ6blEBvvRKtjP3aGIiIhUoQRei6T0HPV/i4iIR1ICr8WedE0hExERz6QEXoOsvCKO5hQpgYuIiEdSAq9BUnouAF1j1IQuIiKeRwm8BkmaQiYiIh5MCbwGSWk5+Hl7EdcqyN2hiIiInEYJvAZJ6Tl0jgrG28u4OxQREZHTKIHXICk9V/3fIiLisVyawI0xU40xO4wxu40xD1Zz/h5jzFZjzEZjzCJjTEdXxveDwpJSDmTkqf9bREQ8lssSuDHGG3gGuAjoDVxnjOl9SrF1QIK1tj/wP+AxV8VX2YFjeZSWWSVwERHxWK6sgQ8Ddltr91hri4C3gcsqF7DWLrbW5pX/uBKIc2F8FTQCXUREPJ0rE3h7ILnSzynlx2pyC7CguhPGmJnGmERjTGJ6enoDhuj4YQ54Fy2jKiIiHsojB7EZY34CJABzqjtvrX3BWptgrU2Ijo5u8M9PSsshNjyAYH+fBr+2iIhIQ3BlhjoIdKj0c1z5sSqMMZOA3wDjrLWFLoqtiiStgS4iIh7OlTXw1UB3Y0xnY4wfMAP4uHIBY8wg4HlgurU2zYWxVbDWOlPI1HwuIiIezGUJ3FpbAtwJfAFsA9611m4xxjxijJleXmwOEAK8Z4xZb4z5uIbLNZq0E4XkFJbQNUY1cBER8Vwu7eS11s4H5p9y7KFKrye5Mp7qJKVpBLqIiHg+jxzE5k6aQiYiIk2BEvgpktJzCfbzpk2Yv7tDERERqZES+CmS0nPoGhOCMdrEREREPJcS+CmS0jSFTEREPJ8SeCW5hSUcOl6gKWQiIuLxlMAr2XvUWUJVNXAREfF0SuCVVIxA1xxwERHxcErglSSl5eBloGPrIHeHIiIiUivt1lHJLaO7MLFXG/x9vN0dioiISK2UwCsJD/JlYFCEu8MQERGpk5rQRUREmiAlcBERkSZICVxERKQJUgIXERFpgpTARUREmiAlcBERkSZICVxERKQJUgIXERFpgpTARUREmiBjrXV3DOfEGJMO7G/AS0YBRxvweu6ke/FMzeVemst9gO7FU+leHB2ttdGnHmzyCbyhGWMSrbUJ7o6jIehePFNzuZfmch+ge/FUupfaqQldRESkCVICFxERaYKUwE/3grsDaEC6F8/UXO6ludwH6F48le6lFuoDFxERaYJUAxcREWmClMBFRESaICVwERGRJkgJXEREpAlSAhcREWmClMBFRESaICVwERGRJkgJXEREpAnycXcA5yoqKsp26tTJ3WGIiIg0ijVr1hytbjeyJp/AO3XqRGJiorvDEBERaRTGmGq3zHZZE7oxpoMxZrExZqsxZosxZnY1Za43xmw0xmwyxqwwxgxwVXwiIiJNiStr4CXAvdbatcaYUGCNMeZLa+3WSmX2AuOstZnGmItwFn8f7sIYRUREmgSXJXBrbSqQWv76hDFmG9Ae2FqpzIpKb1kJxLkqPhERkabELaPQjTGdgEHA97UUuwVYUMP7ZxpjEo0xienp6Q0foIiIiIdzeQI3xoQA7wN3W2uzaygzASeBP1DdeWvtC9baBGttQnT0aQPzREREmj2XjkI3xvjiJO83rLXzaijTH3gRuMhae8yV8YmIiDQVrhyFboCXgG3W2idrKBMPzANusNbudFVsIiIiTY0ra+CjgBuATcaY9eXH/g+IB7DWzgUeAloDzzr5nhJrbYILYxQREWkSXDkKfRlg6ihzK3CrayKqXmZuEa2C/dwZgoiISJ20Fnol/1y0iwlPfENeUYm7QxEREamVEngl53dtTVZeMe+vSXF3KCIiIrVSAq9kSMdWDOwQwUvL9lJaZt0djoiISI2UwCsxxvDzMV3YdyyPRduOuDscERGRGimBn2JKnza0jwjkxaV73R2KiIhIjZTAT+Hj7cXNozuzal8GG5Kz3B2OiIhItZTAq3Ht0A6E+vvw4jLVwkVExDMpgVcjxN+H64bHM39TKgez8t0djoiIyGmUwGvws5GdMMArqoWLiIgHUgKvrPAE7PgcgHYRgVzcP5a3VydzoqDYzYGJiIhUpQRe2ZK/wTvXw9HdANw6ugs5hSW8szrZzYGJiIhUpQRe2ci7wCcAvvo9AP3iwhneOZJXlu+joLjUzcGJiIicpAReWUgMjLobtn8KB1YCcNcF3TmYlc+D72/EWq3OJiIinkEJ/FTn3wGhsbDwd2Ato7pFcd/k8/hw/SHmLtnj7uhEREQAJfDT+QXBhP+DlFWw9SMA7pjQjUsHtOOxL7bz1VYtsSoiIu6nBF6dgddDdC9Y9AcoKcIYw2NX9advu3Bmv72OnUdOuDtCERFp4ZTAq+PlDRc+Ahl7YM0rAAT6efPvGxMI8vfh1v8kkplb5OYgRUSkJVMCr0n3C6HzWPjmUSg4DkDb8ABeuGEIh7MLuP2NtZSUlrk5SBERaamUwGtiDFz4R8jPgGX/qDg8KL4Vf768L9/tOcb/1qS4MUAREWnJlMBr024g9PsRrHwWsk4u5nL1kDgGxUfw1KJdmh8uIiJu4bIEbozpYIxZbIzZaozZYoyZXU0ZY4x52hiz2xiz0Rgz2FXx1eiCh5zn8sVdAIwx3D+lB6nHC3h95X43BSYiIi2ZK2vgJcC91trewAjgDmNM71PKXAR0L3/MBJ5zYXzVi+jgrNC2+f2KxV0ARnaNYkz3KJ5ZvFtrpYuIiMu5LIFba1OttWvLX58AtgHtTyl2GfCadawEIowxsa6KsUaj74bQdrDgASg7OXDtvsk9yMwr5iXtWCYiIi7mlj5wY0wnYBDw/Smn2gOVdw5J4fQkjzFmpjEm0RiTmJ6e3lhhnuQXDJMehtT1sPHtisMDOkQwtU9bXly6lwxNKxMRERdyeQI3xoQA7wN3W2uzz+Ya1toXrLUJ1tqE6Ojohg2wJv2ugfYJ8NUfoDCn4vB9U84jr6iE577Z7Zo4REREcHECN8b44iTvN6y186opchDoUOnnuPJj7uflBVMfhZzDsOzJisPdYkK5cnAc//luP6nH890YoIiItCSuHIVugJeAbdbaJ2so9jFwY/lo9BHAcWttqqtirFOHoc60shX/gsx9FYdnX9Aday1PL9rlvthERKRFcWUNfBRwAzDRGLO+/DHNGDPLGDOrvMx8YA+wG/g3cLsL4zszkx52llr98qGKQx0ig7h+eEfeTUxhd1pOjW8VERFpKD6u+iBr7TLA1FHGAne4JqKzFN7e2TP8m7/AniXQZRwAd07sxry1KTz00WbeuHU4ToODiIhI49BKbGdj1F3QqhN8di+UFAIQFeLPr6f2ZEXSMT5af8i98YmISLOnBH42fANh2hNwbBcsf7ri8I+HxTOwQwR/+mwrx/O0uIuIiDQeJfCz1X0S9L4cvp3jbDsKeHkZ/nR5XzJyi3jsi+1uDlBERJozJfBzMfWv4O0H8+8HawHo2z6cn43szJurDrDuQKabAxQRkeZKCfxchLWDib+F3V/B1g8rDt8z+TzahAbwmw82a89wERFpFErg52rorRA7ABY8CAXOwnIh/j78/tLebE3N5j/fabcyERFpeErg58rbBy75O+QcgcV/qTg8tW9bJvSI5smFOziUpRXaRESkYSmBN4T2Q2DoLbDqeTi0DnD2DH/ksr6UWXjg/Y2UlVk3BykiIs2JEnhDmfg7CI6GT2ZDaQngrND2m4t7sXTXUf67Uk3pIiLScJTAG0pgBFz0GKRugO/nVhy+fng843tE85f527TMqoiINBgl8IbU+zI4byos/jNkOjVuYwyPXdWfID9vfvXOeoo1Kl1ERBqAEnhDMgamPQ4YZ5nV8rnhMWEB/OWKfmw6eJx/fq19w0VE5NwpgTe0iA5wwe9g95ew5eSW5xf1i+XKwe15ZvFuLfAiIiLnTAm8MQybCe0GwYIHIP9ksn54eh/ahgVwz7sbyCsqcWOAIiLS1CmBNwYvb7j0KcjLqLJveFiAL49fM4B9x3J5YuFONwYoIiJNnRJ4Y4kdAOffAWtfg/3fVRw+v2trrhsWzyvL97L54HE3BigiIk2ZEnhjGv8ghLaDhb+pGNAG8MCUnkQG+/GbDzZRqgVeRETkLCiBNya/YJj4Gzi4BrZ8UHE4PMiX313Smw0px3njey3wIiIi9acE3tgGXAcxfWDRH6CksOLw9AHtGN0tijmf7yAtu8CNAYqISFOkBN7YvLzhwkcgcx+sfqnisDGGP13el8LSMh75dKv74hMRkSbJZQncGPOyMSbNGLO5hvPhxphPjDEbjDFbjDE3uSq2RtftAugyHr59DPKzKg53igrmzgnd+HRjKkt2prstPBERaXpcWQN/FZhay/k7gK3W2gHAeOAJY4yfC+JqfMbAhX90kveyJ6uc+sW4LnSJDuZ3H26moLjUTQGKiEhT47IEbq39FsiorQgQaowxQEh52eaz2klsfxgwA1bOhawDFYf9fbz50+V9OZCRx9wlSW4MUEREmhJP6gP/F9ALOARsAmZba6vd+cMYM9MYk2iMSUxPb0JNzxN/6zx//acqh0d2jeKivm15celeMnKL3BCYiIg0NZ6UwKcA64F2wEDgX8aYsOoKWmtfsNYmWGsToqOjXRnjuQmPgxG3wcZ34ND6KqfuufA88opK6qyFf7Mjje2HsxszShERaQI8KYHfBMyzjt3AXqCnm2NqeGPugcBWzpajlXRvE8oVg+L4z4p9HD5e/bSyNfszueU/ifzp022uiFRERDyYJyXwA8AFAMaYNkAPYI9bI2oMAeEwajbsWggHvq9y6u5J3Smzlqe/3nXa204UFHP3O+soLbOs2Z+pfcVFRFo4V04jewv4DuhhjEkxxtxijJlljJlVXuSPwEhjzCZgEfCAtfaoq+JzqWEzITgaFlftC+8QGcR1w+J5d3Uy+47mVjn3+4+3cDAzn5tHdSa/uJRNWkddRKRFc+Uo9OustbHWWl9rbZy19iVr7Vxr7dzy84estZOttf2stX2tta+7KjaX8wuG0ffA3m+dRyV3TuiGj7fhH1+d3K3s4w2HmLf2IHdO7M5t47sCsGpvbQP6RUSkufOkJvSWJeFmZ6OTr/9cZaOTmLAAbhrVmY82HGL74WxSMvP4zQebGBwfwV0TuxEd6k/X6GAlcBGRFk4J3F18A2DsfZC8EnYvqnLqF2O7EOLvw5zPd/Crd9ZjLTw1YxA+3s4f17DOrVm9N0M7mYmItGBK4O406AaIiHf6wivVwiOC/PjF2C4s2p7G6n2Z/PHyPnSIDKo4P6JLJCcKS9iWqulkIiItlRK4O/n4wbgH4NA62DG/yqmbRnUmrlUg1wyJ44pBcVXODe0UCagfXESkJVMCd7f+MyCyq9MXXnZyaliwvw9f3zueOdcMOO0t7SIC6RAZyPd7j7kyUhER8SBK4O7m7QMT/g/StsCWeVVO+fnU/MczvHNrVu3NwFr1g4uItERK4J6gz5UQ0we+/iOUnNla6MM6R5KZV8zutJxGDk5ERDyRErgn8PKCCx+BzH2Q+PIZvWV4Z6cffKX6wUVEWiQlcE/R7QLoMh6W/A0K6l5lLT4yiLZhARrIJiLSQimBewpjnFp4fgYs+/sZFDcM6xzJqr3H1A8uItICKYF7ktgB0P9aWPkcHE+ps/iwzpEcyS5k/7E8FwQnIiKeRAnc00z8LdgyWPyXOouO6KL54CIiLZUSuKeJiIfhv4D1b8LhzbUW7RodQutgP75XAhcRaXGUwD3RmHudfcO/fKjWYj/0g2tBFxGRlkcJ3BMFtoKx90PSotM2OjnVsM6RpGTmczAr30XBiYiIJ1AC91TDfg6tOsMnsyE/s+Zi5fPBV6sZXUSkRVEC91Q+/nDVS3AiFT66s8puZZX1bBtGWICPmtFFRFoYJXBPFjcEJj0M2z+F1S9WW8Tby3B+19Ys3p5OmfYHFxFpMZTAPd2IO6D7ZPji/yB1Y7VFpvRpy+HsAjakZLk4OBERcRclcE/n5QWXz4Wg1vC/m6Dw9M1LLujVBl9vw+ebD7shQBERcQeXJXBjzMvGmDRjTI2Tm40x440x640xW4wxS1wVm8cLbg1XvQgZe+Cze087HR7oy8iuUSzYfFjLqoqItBCurIG/Ckyt6aQxJgJ4Fphure0DXOOiuJqGTqNh3IOw8W1nkZdTXNS3LQcy8tiamu2G4ERExNVclsCttd8Ctc11+jEwz1p7oLx8mksCa0rG3gcdR8P8X0Pm/iqnLuzdBi+DmtFFRFoIT+oDPw9oZYz5xhizxhhzY00FjTEzjTGJxpjE9PR0F4boZl7ecPmzzuuP7oCysopTrUP8Gd65NQuUwEVEWgRPSuA+wBDgYmAK8DtjzHnVFbTWvmCtTbDWJkRHR7syRvdr1RGm/gX2LYVVz1c5NbVvW3an5bA77YSbghMREVfxpASeAnxhrc211h4FvgUGuDkmzzToBug+Bb56GNJ3Vhye0qctAAs2qRYuItLceVIC/wgYbYzxMcYEAcOBbW6OyTMZA9OfBt9A+HAWlJYA0DY8gMHxEWpGFxFpAVw5jewt4DughzEmxRhzizFmljFmFoC1dhvwObARWAW8aK2tfT/Nliy0LVz8JBxcA8v+XnH4or6xbE3N5sCxPDcGJyIijc2Vo9Cvs9bGWmt9rbVx1tqXrLVzrbVzK5WZY63tba3ta639h6tia7L6Xgl9roQlj0LqBsDpBwf4fEuqOyMTEZFG5klN6HI2Ln4CgqLg01+BtXSIDKJv+zA1o4uINHNK4E1dUCRM+H9OU3qSs3f41D5tWXcgi9Tj2iNcRKS5UgJvDgb8GMLi4Ju/gbVM7RsLwBeqhYuINFtK4M2Bjx+M+RWkrIK9S+gWE0L3mBA+3nDI3ZGJiEgjUQJvLgb+BEJjYcljAFw/PJ61B7JYsfuomwMTEZHGoATeXPgGwKi7Yf9y2LeMGcPiaRsWwJNf7tQOZSIizZASeHMy5KcQHANLHiPA15s7JnYjcX8m3+5SLVxEpLlRAm9OfANh1GzYuwQOrOTahA60jwhULVxEpBlSAm9uEm5y5oUveQw/Hy9+ObEbG5Kz+Hq7dmcVEWlOlMCbG79gGPlLZ054SiJXDYkjPjJItXARkWZGCbw5GnorBEbCt3Pw9fZi9gXd2XIomy+2HHF3ZCIi0kCUwJsj/xAYNhN2fg7HkrhsYDu6RAXz9y93UlamWriISHOgBN5cJdwMXr6w6t/4eHsxe1J3dhw5wfzN2uRERKQ5UAJvrkLbQJ8rYN3rUHiCS/q3o3tMCH+dv519R3PdHZ2IiJwjJfDmbPgsKDoB69/C28sw55oB5BaVcOVzK1izP8Pd0YmIyDlQAm/O4oZA+wRY9TyUlTGwQwQf3D6KsAAfrvv393y2Uc3pIiJNlRJ4czf8F3BsN+z5GoDOUcHMu30U/dqHc8eba5m7JEnTy0REmiAl8Oau9+UQ0ga+f77iUGSwH2/cOpxL+sfy6ILt3PveBg4cy3NjkCIiUl/nlMCNMSHGmIuNMd0bKiBpYD5+zoj0XQvhWFLF4QBfb56eMYg7JnTlo/WHGPf4Ym5+dTXf7EjTVDMRkSagXgncGPOmMeau8te+wPfAJ8AWY8wljRCfNIQhN5VPKXuhymEvL8P9U3qy7IEJ/HJCNzamHOdnr6xm4hPf8NaqA24KVkREzkR9a+DjgeXlry8FQoFY4GHgd7W90RjzsjEmzRizuY5yQ40xJcaYq+sZm9SkYkrZG1B44rTTseGB3DO5BysenMhTMwYSHuTH/5u3iTX7M90QrIiInIn6JvBI4If1OC8E5llrjwBvAr3qeO+rwNTaChhjvIG/AQvrGZfUpdKUspr4+Xhx2cD2vPXz4UQE+fLcN7tdGKCIiNRHfRN4OtC5/PWFwOLy10FAWW1vtNZ+C9Q1+fiXwPuAts5qaD9MKfv+OSgrrbVokJ8PPxvZia+2pbHj8Ok1dhERcb/6JvD3gDeMMV8BYcCX5ccHArvOJRBjTHvgCuC5Myg70xiTaIxJTE9PP5ePbVlG/hIy9sCWD+os+tPzOxHk583cJUl1lhUREderbwL/NfAPYDNwobX2h7lH7YB/n2Ms/wAesNbWWpMQAWz6AAAgAElEQVQHsNa+YK1NsNYmREdHn+PHtiC9pkN0T/h2DpTV/mtuFezHdcPi+XjDIZIzNMVMRMTT1CuBW2tLrLVPWmvvttZuqHT8cWvtC7W99wwkAG8bY/YBVwPPGmMuP8drSmVeXjD2fkjfDts+rrP4rWM642Xg30v3uCA4ERGpj/pOIxtgjOlT6edpxpj3jDEPG2N8ziUQa21na20na20n4H/A7dbaD8/lmlKNPldA625nVAuPDQ/kykFxvLM6mfQThS4KUEREzkR9m9CfB/oBGGPicBJtCPBz4E+1vdEY8xbwHdDDGJNijLnFGDPLGDOr/mHLWfPyhjH3wZHNsHNBncVnjutCUWkZr67Y64LgRETkTNU3gfcA1pW/vhJYba29CLgRuLa2N1prr7PWxlprfa21cdbal6y1c621c6sp+zNr7f/qGZucqX7XQKtOsOQxqGMd9K7RIVzUty2vfbefEwXFrolPRETqVN8E7gcUlL8eD/xQhdsJtG2gmKSxefvAmHshdT3s+rLO4reN68aJghJeX6nV2UREPEV9E/gO4GpjTDzOPPCvyo/HAlq2qynpPwPC42HJ3+qshfeLC2dM9yheWraXwpLa55CLiIhr1DeB/wH4C7AXWGatTSw/PpmTTevSFPj4wZhfwcFE2LO4zuI3j+rM0ZxClu8+6oLgRESkLvWdRvYREA8MAS6udGoRcH8DxiWuMPB6CGsP39RdCx/VLYpQfx++2Hyk1nIiIuIa9d5O1Fp7xFq7HvAzxgSUH/vOWru1waOTxuXj7/SFJ6+ELfNqLern48X4njF8te0IpdpuVETE7eqdwI0xNxljdgM5QI4xZpcx5mcNHpm4xpCfQewA+OI31e5UVtmUPm04llukXcpERDxAfRdymQ08C3wMXFX++BRn1bRfNnx40ui8vOHiJ+FEKnzzaK1Fx50XjZ+3Fwu3HHZRcCIiUpP61sB/Ccy21t5jrf2o/PEr4FfA7IYPT1wiLgEG3wgrn4MjNfeEhAb4Mqpba77YehhbR5+5iIg0rvom8A44A9ZOtaj8nDRVFzwMAWEw/75aB7RN7tOW5Ix8tmubURERt6pvAk/BWcDlVOPLz0lTFdwaJj0M+5fDxndqLDapVxuMgYVbNBpdRMSd6pvAnwOeNsb8tXwjk2nGmEeBp3D6xqUpG3QjtE+Ahb+F/Kxqi0SH+jMkvhVfqB9cRMSt6jsP/HGcPcGvxxm89inwY+A+a+0TDR+euJSXF1z8BOQdg8V/rrHY5D5t2JqarX3CRUTc6GzmgT9jrY0HwoFwa228tfa5hg9N3KLdQEi4BVa/CAe+r7bI5N7OsvcLt6oZXUTEXercw9sYs7CO8xWvrbWTGyAmcbcLHoKdX8CHs2DWMvALrnK6U1QwPdqEsnDLYW4Z3dlNQYqItGxnUgM/WI+HNAcBYXDFc5CxF758qNoik/u0YfW+DI7lFLo4OBERgTOogVtrb3JFIOJhOo2GEbfDymegxzTodkGV01P6tOWfX+9m0fY0fpSgGYQiIq5W7z5waUEu+B1E9YCP7oT8qsun9mkXRvuIQK3KJiLiJkrgUjPfQLhiLuQcgQUPVDlljOHC3m34dtdRcgtL3BSgiEjLpQQutWs/GMbe7yzusvWjKqem9YulqKSMzzamuik4EZGWSwlc6jb2PogdCJ/cDblHKw4P7dSKHm1CeWXFPq2NLiLiYi5L4MaYl40xacaYzTWcv94Ys9EYs8kYs8IYM8BVsUkdvH2dpvTCbPjq9xWHjTH8bFQntqVms3qfthgVEXElV9bAXwWm1nJ+LzDOWtsP+CPwgiuCkjMU08sZlb7udUheVXH48oHtCQ/05dUVe2t8a35RKX/8dCsHs/JdEamISIvgsgRurf0WyKjl/Apr7Q/VuJVAnEsCkzM37gEIaw+f3QOlzsC1QD9vZgzrwBdbjtSYoP/+1U5eWraXV5fXnORFRKR+PLUP/BZggbuDkFP4h8CUv8DhTZD4UsXhG0Z0xFrL6yv3n/aWzQeP8+LSPXh7GT7dmEpZmfrKRUQagsclcGPMBJwE/kAtZWYaYxKNMYnp6emuC06g92XQZQJ8/Sc44ayFHtcqiMm92/LWqgMUFJdWFC0pLePBeRuJDPbn95f2JvV4AYn71VcuItIQPCqBG2P6Ay8Cl1lrj9VUzlr7grU2wVqbEB0d7boABYyBaY9DSUGVZVZ/OrITWXnFfLT+5Iq6ryzfx+aD2fxheh+uGhxHgK8Xn2w45I6oRUSaHY9J4MaYeGAecIO1dqe745FaRHWDkXfBxrdh33IARnSJpGfbUF5Z7kwpS87I48kvdzKpVwzT+rUl2N+HC3q2Yf6mVEpKy9x8AyIiTZ8rp5G9BXwH9DDGpBhjbjHGzDLGzCov8hDQGnjWGLPeGJPoqtjkLIy5F8Lj4bN7oaTImVI2shPbD59g5Z4M/u+DTXgZeOSyvhU71l06IJZjuUV8t6fGxhURETlDrhyFfp21NtZa62utjbPWvmStnWutnVt+/lZrbStr7cDyR4KrYpOz4BcE0x6D9G3wzk+guIDLBrYnIsiXe99dz9JdR7l/Sg/aRQRWvGV8jxhC/H3UjC4i0gA8pgldmqAeF8HFT8KuL+Dt6wg0RcwYGs+h4wUM7BDBDed3qlI8wNebyX3a8PnmwxSWlFZ/TREROSNK4HJuht4C0/8FSYvhjWu4aVg0o7tFMefq/nh7mdOKXzqgHdkFJSzdebSai4mIyJmqcz9wkToNvgG8/eDDWbT56Ce8fsO74B9abdHR3aKICPLl4w2HmNS7Tf0+pygP8o5B3lHnObIrRHZugBsQEWl6lMClYQy4Frx94P2fw3+vhB/9B8LanVbM19uLi/rG8uG6g+QVlRDkV8dfwaSvKfzyT3inb8WntOpKb2UYvHpcBCNug05jnCluIiIthBK4NJy+Vzk18f/dAk8PhpG/hFGznRXcKrl0QCxvrTrA19vTuKT/6UkegNQN8OXvYc9i0m00X5SO55gNozggEt+wGPK9Q4k4vJxZe7/Bf8d8aNPPSeT9rgYffxfcrIiIe5mmvg1kQkKCTUzUjDOPkrkfFv0BNr8PwTEw8Tcw6Abw8gagtMxy/l8XMSg+gudvOGWyQeY++PrPsOldSvwjeDx/OkvCL2POjKF0jQ4h0M+5RklpGdf9eyV7Uo+x8IIjtN70ojMiPuo8uO5taN3VxTctItI4jDFrqpuZpUFs0vBadYSrX4ZbFzl91J/MhudGwdIn4MBKvMuKubh/LIt3pJNdUOwsybrq3/DKNHhqIGz7mNR+tzEq/0m+DL+K/8wcTd/24RXJG8DH24u/XzuQIuPHrZt7UfKL5XDdO85+5f+e6Ayq8xTWOnElr4ItH0K+lpMVkXOnGrg0Lmth28ewZA4c2eQc8wngRPQg3kiOYmzwAXoVbsRgIbon9LmCjTGXct3bybQJC+DtmSOICQuo8fKfbjzEnW+u466J3bhncg+nBv/WdZC+w9l4ZfgvXN83XlIIO79w7vvoTsjY6+yl/oPgaJj6qNPloH57EalDTTVwJXBxndyjcOA72L8Cu28ZHN7EPtrxcclwFvuM4ry+QxnSsRV//HQb0aH+vD1zBG1qSd4/uO+9Dcxbm8JbPx/B8C6tofAEzJsJO+bD4Bth2hPg49e492YtHFwLG96Czf9zatnB0RA7ACK7nHz4BMBXD8OhtdD1ArjkSWjVqXFjE5EmTQlcPE9JISX4sGJPBh+tP8QXWw6TU1hCp9ZBvD3zfNqG1528AXIKS7jk6aUUlZSxYPZYwoN8oawMFv/JabaPGwqXPQPRPRrnPnZ+4Wzskr7dSdA9L4YBP4Yu452R+acqK4XVL8KiR5zX4x+AEXc0/pcMEWmSlMDF4xUUl7J891H6x0UQHVq/keQbkrO46rkVXNI/ln/MGHTyxOZ58OmvoDgPxv4aRt8N3r4NE3DuUVjwgFPjjuoB598Ofa6AgPAze//xg7Dg17D9U6e2PugGGPJT1chFpAolcGn2nli4g39+vZuP7hjFgA4RJ0/kpMH8+2Hrh9CmL0z/J7QffPYfZC1sfAc+/39Oc/3Y+2H0r86+Bp30tTOIb+fnzrW7TXJWuOs8zllzXkRaNCVwafZyCksYP2cx3WJCeOvnIyp2Qauw/TNn97ScIzDkJhh4vZPIz3QgmbVwYCV8OweSFkHcMOfLQEzPhrmB4ymw9jVY8x/IOewcC2oNEfEQ3sF5jukNHYY70+Q0AE6kRVAClxbhte/28dBHW3jlZ0OZ0DPm9AL5WfDV72HdG1BW7GyJ2nu60/Tdfkj1SfFYklPj3vA2ZO0Hv1C44CEYeit4NcJMzNJi2L0I0rZA1gHISnaejydDSYFTJjASOgxzHt0uhNj+DR+HiHgEJXBpEYpLy7jwySX4+3gzf/aYajdUOZZTSGZGGt0yljrzspO+dpJ5QDgEtnLWcfcLdZ7zjsHBRMA4g9IGzICel5y2upxLlJU509KSv4eUVc688qM7nXPtEyDhZuh7JfgG1n4dETl31jpfqv1CnP83GrFFTAlcWozPNqZyx5trmXN1f65J6FDl3J70HK5/8XsycotY9sBEZ7BcfpYz5Swl0enTLjwBRTnO3G0vH+g1HfpdA+Ht3XRHtcg9Cpv+B4kvOck8INzpGhh8I8T0cnd0Is1PwXHY8A4kvuys/gjg5esMRA2JdlafHP//IG5Ig32kEri0GNZaLn92BWnZBSy+bzwBvs4KbttSs7nhpe8pLbNk5Rcza1xXHpjaQP3X7mYt7F8Oq1+CbZ84LQoxvZ2ugT5XQFR3d0co0rQdXOsk7c3vO7Na2g2C/teCLXMGyuamlz+nOWtPdBjaYB+tBC4tyso9x5jxwkoevKgns8Z1ZX1yFj99eRWBvt68futw/v7VTpbsSGf5gxMJD2ygaWWeIifN6RrY8oGzcA7WGX3fY5rTZ95+CARFujtKkaYhOxUW3O98MfYNcjZMGnLTuc1kqaeaErh2I5NmaUSX1kzsGcOzi3fTOSqYe95ZT+sQf964dTgdIoO4fXxXPtuYyn+/28edE5tZ7TQkBobPdB7Zh2Drx04yX/q4U1sAZ1W4uKFO33lcArTt13Dz40Wag7IyWPcaLHzIGTw68bcwbOaZr/PgAqqBS7O14/AJLnrqW8osdI0O5o1bR1RZ3e3mV1ez7kAmyx+cWPe+5M1BYQ4cWgcpq+HgGuc554hzzicAYgc6yTz+fGcuuu+ZrYQn0uwc3e1swrR/GXQaA5c+5dYdDt3ehG6MeRm4BEiz1vat5rwBngKmAXnAz6y1a+u6rhK41Oav87exLjmL564fTOuQqqu7rdmfwVXPfcfvLunNLaM7uylCN/phFG1KYvljtbMPe2kh+Ic70+v6XwsdR52cLldW5kylO7zJ2TgmIMyZq/7DIyTGGZErTUtpibMU8InDzuDHsHYtc50Ba+H7552lkX0DYPKfnBUS3fy78IQEPhbIAV6rIYFPA36Jk8CHA09Za4fXdV0lcDkX1z7/HfuP5bHk1+Px9/Gus3xmbhEbDx5nbPeo0xeKaQ5KimDfUtj0ntPnV5QDYe2dVeEy98LhzVB0ovZrxA50kn+vyyCqm2vilvrJPeYMejyYCClrnJaZ4tyT5wMjnW6Vtv2cvt4e05r/9MSCbPj4Ttj6EZw31al1h7Z1d1SAByTw8iA6AZ/WkMCfB76x1r5V/vMOYLy1NrW2ayqBy7n4dmc6N768ikev7MeMYfE1lssvKuXl5XuZuySJEwUlNS8U05wU5TnT6za+69TOo86Dtn2dAXFt+ztNikW5kHfUmS+fl+HUynfMd5rowRkJ32s69LrEeV9z/NLTFJSVweENsOtL2LXQaXHBOtOf2vZzuk7aJzg17/TtcHij82UtbavT/xsY6azTn3ALRHSo8+OanMOb4N0bIXM/TPo9jLzLo/6uNoUE/inwqLV2WfnPi4AHrLW1ZmclcDkX1loue2Y5x/OLWXTPOHy8q66sVlJaxruJKTy1aCdHsguZ1CuGTQeP0z0mlNdvrbOBqOU6nuLU4Ld+fHIkfHg89Jzm1OY6jqx90FxpsbP6XMZe58tBUfn8/MIc59nL21lo54eHX4gzZ7+k0Ek4PzyXFjrXKi2G0iIoKwHj5QxECoiAwAjndVh75wtGY6ys5w7F+U53yME1TrLet8yZ3oRxatTdJ0OXCc52t7WNdSgtgQMrYNULzlLE4Pz5DZ8Fnce45FYa3dr/wvz7nK6fq192/m56mGY1Ct0YMxOYCRAfX3OtSaQuxhhuH9+NWa+v4bNNqVzSvx17j+ayLTWbbanZfL7lMHvScxnSsRX/+vFghnaK5JnFu5nzxQ62H86mZ9swd9+CZwqPgxG3OY+cNGejlu3zYc2r8P1cp489PA78gp1V7fyCwTfYSTIZe5zlY23p6dc1Xs4qebbMad7nDCsgXr7OFwZvX2cL16Kc08uEtIHzpjjNp13GOzE1FaXFsH+F83vetwyObDn5+wvvAJ3HOkm72wUQHHXm1/X2cd7beazzZ5L4krNW//ZPnZaVaXM8ppm53jL2wsLfOvfSeRxc9ZKzEEsT4kk1cDWhi1uUlVmm/ONbDh8voLisjIJiZ6qVj5ehT7sw7pjQjQt7t6no887KK2LEXxcxfUA7Hrt6gDtDb3qKciFpMez+yln4oijHqVUX5TqP4NbOFLcfHq06OwPj/EKcmrZv4MmmzbIyp9+28ITTf2nLwMffGVHvE+C89vZzkvapzaGlJc5Ke/mZUJAF6Tud5Ld7kVPb9/Z3kni/a5z93T1xV7iC406T+I4FznPhcSfu+BEnm8TbD4HQNg37ucUFsPIZ+OZvHjXQ64wV5sCyJ2HFv5xWm7H3wajZTquOh2oKTegXA3dychDb09baYXVdUwlcGsK3O9P599I9dI8JpXe7MHrFhtItJqTGgW2/+WAT761JYcWDE4kKqd/e5eLBSoqcJuMdnztdANkpzpeHXpc6I/I7j3Xvf/RlpbBnMax/E7Z96nQRBEU5rQY9LoKuE1zXcuBhU63qVFbmbEr01cPObn/9Zzj93WHt3B1ZndyewI0xbwHjgSjgCPB7wBfAWju3fBrZv4CpONPIbqqr/xuUwMU9ktJzuOCJJfxq0nnMntTMFoIRR1mZk8w3vO2MTC7MhtBYZ9OYITe5trk1fSdseNOJ5USq01/b7xroe7VT23bXl4qKxU5+54w7GHAtDP255+2Ol7waPn/AGRPQfghM/VuDLnXa2NyewBuLEri4y02vrGLTwWyWPzjhjKagSRNWnO80sa99zdm9ztvPSZ4jZjkDwRrDiSPOutsb34HU9WC8ofuFMPDHTo3bx4NafrJT4Zu/OjMWSvKhwwgY9nOnn9zHz41xHXJq3BvfgZC2To27/4wmN1hRCVykgS3bdZSfvPR9tbueNSclpWXsz8ija7QbtlD1ROk7YdXzsP4tpw++wwhnw5geU6FVp7O/rrXOAL79K5ylb/csdvr1Ywc6zfd9r2r4/uyGlp8J696A1S866wYER0PcMIjpCdE9IbqHMx2xseeUF55wBksufdLpdhh5J4y+xz3bADcAJXCRBmat5aKnlgKwYPaYBl3YxVrrMQvFvLP6AA/O28S820YyKF6rrFXIz4L1bzijso/ucI5F93ISefcpEBHvbBpzarKy1hk4l5PmNIcfWu/s8Z78vTNlDpwpd/1/5Dyie7j2vhpCWRkkLYINbznzyTOSnCl8ABjni050z6qJPTj65GyE6mrt1jqj7QtPQH6Gs+5Afqbz+vhB58tP5l7n+YclgntNh8l/PLcvVh5ACVykEby7Oplfv7+RN28dzshu9ZieU85ay7PfJLExJYuM3KKKx/H8Yu6f0pPbxrt/UNA9765n3tqDjO8Rzas31TmutGU6luQ0se9Y4NSgK0+B8wl0+qwDwp1+9Nx0Z056ZZFdocNwiB/u1Fijeza5Zt5alRQ5iTV9G6RtdxaLSd8Bx3Y7W9+eysu3fOS/qTSHv5pylYW2g8jO5Y8uzhLA8SMa5XZcTQlcpBEUFJcy+m9fMyAugjnXDKiYP741NZuUjHz+cFkfesXWPFf8/TUp3PveBrpEBRMT5k/rYH9aBfuSuC+T7Pxilj0wES8v99bEJz7xDSkZ+RSVljHv9pEMVi28dvmZThLPOeK8/qGmWHAc/MOcaXEhMRAc4wyEa9O3fnOzm5PS4vLEvsP5HRXlOt0SP0wrxJTP3/crf/g4v8PAVs7qcEHlzyFtPHOqXwNRAhdpJH//cidPLdpV5VhMqD/5RaXERQbx0R2j8PM5vTaVXVDMxMeXENcqkHm3jaySqD/ecIi73lrHmz8fzsiu9fvPPbugmLIyS0TQuQ8eOp5XzIBHFnL7+K68vTqZvu3Dee1m1cJFXKlZrcQm4kluHtWZ7IJiYsMD6BUbRq/YMKJC/Fm45TAz/7uG575Jqnaq2d+/3Mmx3EJe+dnQ02rZk3u3IdTfh3lrD9Y7gd/6aiIFJaV8fOfoc7ovgI0HswAY2TWKsEBfHl2wnTX7MxnSUbVwEXdrRp0sIu4RHuTL7y/tw8yxXRnTPbpiYZfJfdoyfUA7/rV4F9sPZ1d5z/bD2bz23X5+PCyefnHhp10zwNebaf1iWbAplbyiktPO12TdgUxW7ctgY8pxkjPyzu3GgPUHnATeLy6cG8/vSOtgP/7x1c5zvq6InDslcJFG9PD0PoQH+nL/exspKXWWaLXW8tCHWwgN8OG+yTWPML5qSBy5RaV8seXwGX/ey8v3EeDr/LP+atuRcwseWJ+cRdfoYMIDfQny8+EX47qwdNdR1uzPOOdri8i5UQIXaUSRwX48cllfNh08zvPf7gHgo/WHWLUvg19P6Umr4Jr7qRM6tqJDZCDz1h48o886lJXP/E2p/GR4R85rE8KXW2tP4HvSc/hkw6Eaz1trWZ+cxcAOJ5vLfzKiI1Ehfvz9y101vk9EXEMJXKSRTesXy7R+bXnqq12sO5DJn+dvo39cONcOrX3xFy8vwxWD4li2+yipx/Pr/Jz/fLcPay0/HdmJSb3a8P3eDI7n1Tz15uFPtnLX2+tIP1FY7fmUzHyO5RYxMD6i4liQnw+/GNuVZbuPsnrfyVp4aZll88HjfLjuIEUlZXXGKiLnTglcxAX+ML0vwf7eXPvCSo7mFPLIZX3xPoPpYVcNbo+18OG6mmvKAHlFJbz1/QGm9m1Lh8ggLuzdhtIyyzc706otn5yRx9Jd6Vhbc1P7+mSn/3tgXESV404t3J+/LdjO3CVJ3PzqagY+spBL/rmMu99Zz9/VR+7xPliXwu1vrKGpz0Jq6ZTARVwgOtSfh6f3oaikjGsTOjCwQ0TdbwI6tg4moWMr5q1NqfU/2/fXpJBdUMLNozoDMCAuguhQfxbW0Iz+XmIyAFEh/ny+ufo+9vXJWfj7eNEzNrTK8UA/b24b35XE/Zk8umA7+47lckn/djw1YyCXD2zHC9/uYVPK8TO6P3GPV1fsZ/6mw2xNza67sHgsTSMTcZHpA9rRJizgjJP3D64cHMf/fbCJTQeP0z/u9PeWlVleXr6PAXHhFdO7vLwMk3rF8MmGVIpKyqrMQy8pLeOdxGTGnRdN95gQXl2xj+yCYsICfKtcd31yFn3bh+Prffr3/J+N7ESPNqGc1zaEmNCAiuPje8SwIukY9/9vAx/fObra+e/iXkdzCtmY4rSuzN+USp92p8+CkKZB/7pEXMQYw4gurQnwrd/OZRf3j8XPx6vGwWyLd6Sx92guN4/uXGX99Em92pBTWMLKPceqlP9mRzpHsguZMTSeKX3aUlxqWby9alN7cWkZmw8er/HLhreXYXT3qCrJGyA80Jc/X9GP7YdPMHdJUr3uU1xjyQ6n66RdeADzNx1WM3oTpgQu4uHCA325sHcbPt5wqNoBYi8t20tseADT+sVWOT6qWxSBvt6njUZ/e/UBokL8uaBXDIPjW5UvOlO1zI7DJygsKWNAPVsLAC7s3YZLB7Tjn1/vYueRE/V+vzSur3ekER3qzx0Tu7H3aC7bUvVn1FQpgYs0AVcNbk9GbhHz1qaQlVdUUWvalprNiqRj3Hh+p9OaugN8vRnTPYqvth2pKH/4eAFfb0/jmoQ4fL298PIyTO7ThsU70igoPrkBx7ryAWyDziKBAzx8aW9CA3y5/38bKS1rPjW8zNyiugt5sJLSMr7dmc7486KZ2qct3l6G+ZtS3R2WnCUlcJEmYEz3aKJD/Xlw3iYGPvIlvR76nHFzFnPrfxIJ9PXmumHVT0m7sHcbUo8XsOWQM1jpvcRkyizMqDSFbUqftuQVlbJs19GKY+sPZNE62I+4Vme3b3PrEGfQ3obkLF5etvesruFp3ktMZuifv2L/sVx3h3LW1uzP5ERBCRN7xtA6xJ8RXSKZvylVzehNlBK4SBPg6+3F+7NG8q8fD+K3F/fihhEd6R8XQfuIQO6dfF6NG5dM7BmDl4Evtx6hrMzy9upkRnZtTcfWwRVlzu/SmtAAnyorvm1IyWJgh4hz2pP80v6xTOrVhscX7mDtgcx6v7+0zLItNZvj+XVsI+kCpWXOtq8lZbbOBXI82dc70vApH78AzhoFe47msv2wmtGbIo1CF2ki4lsHEd+6flsmtg7xZ0jHVny59QiDO7biYFY+D1zUs0oZPx8vJvaM4attRygpLSOvuJSk9BymD2h3TvEaY/jzFX258tkVXDP3O+6Y0I1fTuxW7ah2cEbT70w7wYrdx/huzzFW7jnGiYISQv19mDm2CzeP7kyw/5n/l/Xysr1sPnSchy7pfc47sy3ccpi9R3Px8/Hi6+1p3Dqmyzldz12+2Z7O0E6RhJbPOJjSpy2/+3Az8zel1rrtrXgm1cBFmrkLe7dha2o2//hqJ62CfJnSp81pZab2aUtmXrGzEUrycayl3tPdqtMmLID5s8dw2YB2PL1oF1c9tyqZrgAAAButSURBVILdaTkV5621bEzJ4pFPtjLir4uY+o+lPPLpVnYcPsHF/WJ57Or+jOjamie+3Mm4OYt5ZfleCktKa/lEx8GsfB5dsJ15aw9y8dPLWLO//i0AlWOcuySJjq2D+On5HVm1N4MTBe5vFaivg1n57Dhygok9YyqORYX4M6JLaz5TM3qT5NIEboyZaozZYYzZbYx5sJrz8caYxcaYdcaYjcaYaa6MT6Q5mtTLSdjrDmRx1eA4/H1On8Y2rkc0/j5eLNxyhPXJTrI7mxHo1QkP9OXJawfy3PWDSc7I4+Knl/L8kiSeXrSLC55cwvR/Lef1lfsZ2CGCOVf3Z9kDE/j21xN49Kr+/CihA/++MYF5t4+ke0wof/hkKxMfX8I3O6pfYe4HT5WvBjf3J0Pw8oJrn/+O55ckUXYWA+pW7slgQ8pxfj6mC5N6taGkzLK00niB6uw8csLjEuLX5VMFJ1RK4FDejJ6eyw7NGGhyXJbAjTHewDPARUBv4DpjTO9Tiv0WeNdaOwiYATzrqvhEmqsu0SF0jXb6vGfUMNgtyM+HMd2jWbjlMOuTs+hSvgNZQ7qoXyxf3D2WkV1b89cF23nyy51Eh/jz1yv7sfo3k3jhxgSuSehAXKvTuwkGx7fizZ8P5/VbhvP/27vzuKrrdIHjn4cDiCiC7CiiBgqCu2juuUvZ6G2bpmyxaZnFnOrOTFN37vRq5t6pydvUtE+NVnea0jG7NWamlVaa5pq5goqoiCEgLoAssnzvH+cHHuGggIflR8/79eIV53d+55zvE+f4nN93eb7+vg7mvbOdrFPut0tNzy1i6bYsZo+MIaV/JMvnjWNqYgRPfpzGPX/f2uiZ5K+uPUhoZ19uHBbNsJ5d6eLnXZMM3dmQfoJpz65l8ZajjXqd5vZFWi49gjvWvBeqpfSPxEtgxU6djW43LXkFPgJIN8ZkGGPOAYuBWbXOMUD1QEwgcPEC0EqpBvnpVbHMGd2LuPCAes+ZnhTBd2dK+XJ/Xp36554S3sWP1+cMZ8lPRrH+kUn88yejuGVEDIH+l/6yIOKcfLXwzuFUGcOv393p9or6mU/34efjYO7EOMDZA/Dy7KH8YVYSXx04weg/rWH2go385bP9bEg/Qcm5+rvkU7ML+GJfHnNG98LPx4G3w4ur4sP5Yl9uvVfz//v1YQBeXJPepI1dqred9aTS8krWHzzBpPjwOhMTQzt34Mre2o1uRy2ZwLsDrl9Js6xjrh4HbhORLGAFMK9lmqZU+3ZTcg8en5l00XOm9IvA4SWUV5oLdiDzNBFhRO9gugc1bYlaTIg/v7s2ka8z8nlzw+EL7tuVdYYVu45zz9jehHbucMFr3jGqF+/PHc1NydGcPFvOc6sPcOuCTQx4fBW3L9zE4RN1l4e9tjYDf18Ht4/sVXNsUkIYJ4rOsfNY3Xrvx8+U8llqLkNjgjh2uoR3tzXuKvybzFOMfHI1f/xob6MedykbM/IpLa9iQq3u82rXDIziYN5Z9ucUub1ftU1tbRLbLcCbxpho4BrgLRGp00YRuU9EtorI1ry8vBZvpFLtUddOvlzZOxjwzAS25nTz8B5MTgjnqZVppOeeH7udvyqNIH8f7hnvfpZ4UrdA/jCrPx8/MI5vH5vGG3OGc+/4K9hx9DQznl/H0m3nN43JOlXMsh3f1ekhuKqvc2meu270RZszqTKGv9w8hCExQbzUiKvw1ak53Pq3jRSUVPC3dYfqlMC9HJ+n5eLn48WoK0Lc3p+S5OxG/0iLuthKSybwY4DrAFy0dczV3cASAGPM14AfEFr7iYwxrxljko0xyWFhYc3UXKW+f2Zf2ZPEqC4kRLbtJUUiwpM3DMDf18G/L9lBeWUVXx/MZ92BE/x8QmydjVncCezow8SEcH6TksDKB8fTv3sgv3p3B/MWbedMSTkLvzqEAHeP7X3B44I7+TIkpqvb+vGLt2Qyvk8YMSH+PDSlL9+dKWXJ1ktfhf9zSyb3vbWNvhEBrP7lVfQM8efhpTspPlfRqP8v7hhjWLMvlzGxofXW4Q8L6MCI3sF8tPM77Ua3kZZM4FuAPiLSW0R8cU5SW1brnExgMoCI9MOZwPUSW6kWMmNgFCseGGeLXcTCA/x44roB7Mw6w4tr0pm/Ko3ILn7cMapXo5+rW1BH3rl3JL+eHs/K3ce55rl1LN58lJmDu9HNTVf/pIRwdh07Q25Bac2x1ak55BSUcfvIngCM6xPK0JggXv48vd6lb8YYXlh9gN+8t4sxcaEsunckPYL9mX/DQDJPFjN/5b5Gx1LbwbyzHD1ZUm/3ebUZA5zd6Dob3T5a7FNqjKkA7gdWAak4Z5vvEZE/iMhM67RfAveKyA5gETDH6NdBpVQ9rh4QxXVDuvPc6gNszzzNLyb3afRub9UcXsLciXG897PR+DiE0opKfjI+1u251WupP3dZzvbWxiN0D+pYs0xLRHhoavVVeFad5ygtr+S3H+zmz5/u5/oh3Vl4Z3JNoZorrwhhzuhevLnh8GV3pVf3FEy6RAJP6R+Fl8DyHe2zG72yylxQ7789aNGv2caYFcaYvsaYWGPMH61jjxljllm/7zXGjDHGDDLGDDbGfNKS7VNK2c/jM5OICvTjitBO3JQcfdnPN6hHECseGMeqB8cTH+l+1n5CZABRgX414+AZeUWsT8/nlhE9cHidn+U9Ni6UYT271rkK3555imtf+Ip3NmXy06ti+fMPB9WpUPdwSjwxwZfXlb73uwKeX3OAwT2CLjlpMCygA6NiQ1h+iW701OwCrnt5PW9tPNKkWfat5amVacx4fl27GiJo+/1kSil1EYEdfVg+byzv/nRUvWVaG8vf15u+EfUvuRMRJiWE89WBE5RVVPL2pky8vYQfDu9R57yHpvQl+0wpS7YcpbS8kidXpHLDKxsoLqvgf388gkeuTnBbc97f15v5Nza9K/3QibPc8fpmAjp489LsoQ16zA8GduNwfnHN5jfuvPLFQbZnnuZ3H+xm4tNfsGTr0WZZ+uZpmzLyOZh3lp1ZdVcP2JUmcKWU7YV07kCIy7KxljApIZyz5ypZu/8ES7dlkdI/kvAAvzrnjYkLIblnV15Yk841z6/j1bUZ3Dw8hlUPjeeqvhefhDvSpSv9q0tUf3N1/Ewpty3YRJUxvHXPlQ1espfSPxJvL+HDne5LcOQVlvHx7mxnm+4aTkhnXx5eupOpz67lwx1tt2xHZZWpGdtf6bJpj91pAldKqSYYHRtKB28vHl+2hzMl5dxmTV6rrXosPLewjLLyKv5x95U8ef2Amg1FLuXhlHiuCO3EnW9s5plP9l2y2/rk2XPctnATZ0rK+fuPRxAb1rnBMQX5+zK2Tygf7XRf1GXx5kzKKw23j+rJhPhw/jV3DK/dPowO3l7MW7SddQcaP+fYGMOBnMIG1bhvqsP5Zyktr8LbS1i1+3izdqO3ZBe9JnCllGqCjr4ORseGcOx0CX3CO9esoXdnTFwo7/1sFKseGl+zlWdD+ft68/7Pxzg3hFmTzswXv2K3myIyAEVlFdz1xmYyTxaz4M5k+ncPbNRrAVw7sBtZp0r49ujpC45XVFbxzuZMxsaF1nwpEBGmJUXyr/vH0MnXwYpdDb+6LS2vZOm2LGa+uJ6pz67liY9SG93WhkrNdg4J3DgsmowTZy/YUMeTss+UMOHpL/j6oOfW8F+MJnCllGqi6pndt43secm904f1DKZzI7ZDdRXo79wQZsEdyeSfPce/vbSeZz7dT9rxAj7YfownVqRy24JNjHtqDbu/K+DlW4cysp6iLZcyLSkCX4cXH9aajf5Zai7ZZ0q5fVTdnoYO3g6uig/js9ScS24Yk32mhP9ZlcboP63hV+/uoLS8khG9g1m05Sg5LsvyPCk1uwBva5UBwKpm6kb/29pDHDtVQo/gplUZbCzdD1wppZro34Z05+TZcn6Y7H6TGE+bkhhBcq+u/P7DvTy/+gDPrz4AOPd0T4gMYHpSJDMGRjGuT9MLXHXx82F83zBW7MrmP2f0w8uaVf/WxsN0C/Rjcj3L0ab0i2DFruPsPHam3kp+uQWlTH1mLWfPVTClXwR3je7FqNgQsk45r1xf/TKDx35Qe4+ry5eaXUhsWGd6BPszJCaIlXuOc/+kPh59jfyiMhZtzmTW4O5uN+RpDprAlVKqiQL8fHhgimcTwaUE+fvy7M2DuSk5mpyCUhKjAokN64S3h2bgA/xgUBSfpeaw9cgpRvQOJj3XuUzuV9P61vs6kxLCcXgJn+49Xm8Cf++bYxSVVbB83tgLuvd7BPtz/ZDuvL3pCD+bEEtYgPsJiZsy8unS0Yd+UY2rFJiaXVAzxJGSFMmTH6eRdarYo4n2zQ2HKa2o5GcT3JfxbQ7aha6UUjY0OjaU64ZEEx8Z4NHkDc6raT8fL5Zbs9H/sfEIPg7h5uEx9T4myN+X4b268uneHLf3G2N4d9tRknt2dTs2P3diHOWVVSxYl+H28duOnGT2gk3MenE9b2860uDJYqeLz5F9prQm6U9PigRg1R737WyKwtJy3txwmJSkyIvu+OdpmsCVUkpdoFMHbyYlhLNi13EKS8t5b1sWV/ePqvfKuNqUfhHszyniSH7dnd2+yTxNRt7Zeovt9ArtxKzB3fn710fILyq74L68wjJ+/vY3dO/akZGxIfz2/d38eunOBlVW22tNYKtO4L1CO5EQGeDRcfB/bMyksLSCn0+I89hzNoQmcKWUUnVcO7AbJ4rK+I/3d1NYVsEdbiav1TYt0Xl16+4qfOm2o3T0cTBjYLd6Hz93YhylFZUs/OpQzbGKyirmLfqG08XlvDJ7GG/MGc4vJvdh6bYsrn95A5n5xRdtU2q2c/23a7f7tKRIthw+yYlaXxSaorS8koVfZTC+bxgDohs/6/9yaAJXSilVx8T4cPx9HXy44zsSIgMY1rPrJR8TE+JPfEQAn6VemMBLzlXy4Y5srhkQddGZ+HHhnZkxIIq/f32E08XnAHj6k/1szDjJH68bQGK3Lji8hH+f2pfX5ySTdaqYa19Yx4b0+ovcpGYXENq5wwW9BylJkRgDn9XT3d8YS7Ye5UTROeZOcF83vzlpAldKKVVHR18HUxMjALhjVK9LLpOrNiUxnC2HT9UkYICVe7IpKqtoUK36+yfFUVRWwevrD7Nqz3H++uVBbr0yhhuHXfjYSQkRLJ83jtDOHfjdv3bX+3yp2QX0i7pwXLpfVAA9gjtedlW28soqXv0yg+SeXRlxkToAzUUTuFJKKbfuGtObyQnhzBpcf7d3bVMTI6msMjUbvQAs2ZJFTLD/RYvdVEuI7ML0pAjeWH+IXy3ZwcDoQB671v3SspgQf+aM6cXBPPfFWcorqziQU0RirVnrIkJKUiQb0vMpKC1vcGy1fbD9GMdOlzB3YlyDv+B4kiZwpZRSbg3uEcTCOcNrtjltiIHdAwkP6FDTjX70ZDFfZ+Rz47DoBie5eZP6UFhagcMhvDx76EW3iK0ed3c3KS0j7yznKqvcLjubnhTJucqqmu1WqxljOHn2HLkFpRw7XUJmfjEH84o4kFPIgZxC0nMLSc8t4mBeEa98eZDEqC5MiG/6uvvLoevAlVJKeYyXlzC5XwTLvj1GWYWzXKoI3DCs4Vu99u8eyPwbBxIfEXDJtdqRgX4M6hHEJ3uO11Raq5Zaawa6q6ExXQkL6MCSrUc5XVxO2vFC9h0vYH9OEUVlDd++9cVbh7TK1TdoAldKKeVh0xIjWLQ5kw3p+SzdlsXYuNAG74hWrTHV7aYnRTB/5T6yz5QQFXj+dVKzC/B1eHFFWKc6j/Hycnajv7XxCOvT8wns6EN8ZADXD+1Oz5BOdPD2wscheHt54e0QvKwkbTi/YYm/rzdT+rmvTNcSNIErpZTyqFGxIfj7OvjTx2kcO13Cwynxzfp60xIjmb9yH5/syeHO0b1qju/NLqBPROd694l/OCWeq/tHEhvemfCADq12Jd1UOgaulFLKo/x8HIzvE8a+nEIC/Lxrqp81l7jwzsSGdaozDp52vPCiZVcD/HwYHRdKRBc/2yVv0ASulFKqGVQvQZs5qNtFJ6F5yvSkSDYdOsmps87layeKysgrLCMhsuVKm7Y0TeBKKaU8blpSBFf3j+SecS2zucf0JOfytdXWrPLqCWy1l5C1Jy2awEUkRUT2iUi6iDxSzzk/FJG9IrJHRN5pyfYppZTyjAA/H165bRi9Q+tOIGsOA6MDiQr0q+lGv9gM9PaixSaxiYgDeAmYCmQBW0RkmTFmr8s5fYBHgTHGmFMi0nrT+5RSStmGiDAtMYLFW45SfK6C1OxCIrv40bWTb2s3rdm05BX4CCDdGJNhjDkHLAZm1TrnXuAlY8wpAGNMLkoppVQDTE+KpKyiirX789yWUG1vWjKBdweOutzOso656gv0FZH1IrJRRFJarHVKKaVsbUTvYIL8ffhwZzbpuUXtuvsc2t46cG+gDzABiAbWisgAY8xp15NE5D7gPoCYmPo3mFdKKfX94e3wYnJCBO9vz6LKtO/xb2jZK/BjgGtpnWjrmKssYJkxptwYcwjYjzOhX8AY85oxJtkYkxwW1jo1aJVSSrU905MiqHIWStME7kFbgD4i0ltEfIEfActqnfMBzqtvRCQUZ5d6Rgu2USmllI2N7xtGRx8Hfj5eLTYDvrW0WBe6MaZCRO4HVgEO4HVjzB4R+QOw1RizzLpvmojsBSqBXxtj8luqjUoppezNz8fBDwZFkVdYhsPLftXVGkOqi7LbVXJystm6dWtrN0MppVQbUZ3X7Fge1R0R2WaMSa59vK1NYlNKKaUuS3tJ3JeipVSVUkopG9IErpRSStmQJnCllFLKhjSBK6WUUjakCVwppZSyIU3gSimllA1pAldKKaVsSBO4UkopZUOawJVSSikbsn0pVRHJA4548ClDgRMefL7WpLG0Te0llvYSB2gsbZXG4tTTGFNn603bJ3BPE5Gt7mrO2pHG0ja1l1jaSxygsbRVGsvFaRe6UkopZUOawJVSSikb0gRe12ut3QAP0ljapvYSS3uJAzSWtkpjuQgdA1dKKaVsSK/AlVJKKRvSBK6UUkrZkCZwFyKSIiL7RCRdRB5p7fY0hoi8LiK5IrLb5ViwiHwqIges/3ZtzTY2hIj0EJHPRWSviOwRkQes43aMxU9ENovIDiuW31vHe4vIJut99k8R8W3ttjaUiDhEZLuILLdu2zIWETksIrtE5FsR2Wods+N7LEhElopImoikisgom8YRb/0tqn8KRORBO8YCICIPWZ/53SKyyPq3wOOfFU3gFhFxAC8BVwOJwC0ikti6rWqUN4GUWsceAVYbY/oAq63bbV0F8EtjTCIwEphr/R3sGEsZMMkYMwgYDKSIyEjgKeBZY0wccAq4uxXb2FgPAKkut+0cy0RjzGCXtbl2fI89B6w0xiQAg3D+bWwXhzFmn/W3GAwMA4qB97FhLCLSHfgFkGyM6Q84gB/RHJ8VY4z+OCfyjQJWudx+FHi0tdvVyBh6Abtdbu8Doqzfo4B9rd3GJsT0L2Cq3WMB/IFvgCtxVmPyto5f8L5ryz9ANM5/RCcBywGxcSyHgdBax2z1HgMCgUNYk5HtGoebuKYB6+0aC9AdOAoEA97WZ2V6c3xW9Ar8vOr/6dWyrGN2FmGMybZ+Pw5EtGZjGktEegFDgE3YNBary/lbIBf4FDgInDbGVFin2Ol99hfgYaDKuh2CfWMxwCcisk1E7rOO2e091hvIA96whjUWiEgn7BdHbT8CFlm/2y4WY8wx4GkgE8gGzgDbaIbPiibw7wnj/NpnmzWDItIZeA940BhT4HqfnWIxxlQaZ7dgNDACSGjlJjWJiFwL5BpjtrV2WzxkrDFmKM4hs7kiMt71Tpu8x7yBocArxpghwFlqdTHbJI4a1rjwTODd2vfZJRZrnH4Wzi9Y3YBO1B3e9AhN4OcdA3q43I62jtlZjohEAVj/zW3l9jSIiPjgTN5vG2P+zzpsy1iqGWNOA5/j7DoLEhFv6y67vM/GADNF5DCwGGc3+nPYM5bqqySMMbk4x1pHYL/3WBaQZYzZZN1eijOh2y0OV1cD3xhjcqzbdoxlCnDIGJNnjCkH/g/n58fjnxVN4OdtAfpYMwV9cXbjLGvlNl2uZcCd1u934hxPbtNERICFQKox5hmXu+wYS5iIBFm/d8Q5lp+KM5HfaJ1mi1iMMY8aY6KNMb1wfjbWGGNmY8NYRKSTiARU/45zzHU3NnuPGWOOA0dFJN46NBnYi83iqOUWznefgz1jyQRGioi/9e9Z9d/F85+V1h7wb0s/wDXAfpzjlL9t7fY0su2LcI63lOP8Zn43zjHK1cAB4DMguLXb2YA4xuLsJtsJfGv9XGPTWAYC261YdgOPWcevADYD6Ti7Cju0dlsbGdcEYLldY7HavMP62VP9Wbfpe2wwsNV6j30AdLVjHFYsnYB8INDlmF1j+T2QZn3u3wI6NMdnRUupKqWUUjakXehKKaWUDWkCV0oppWxIE7hSSillQ5rAlVJKKRvSBK6UUkrZkCZwpVSzE5EJImJEJLq126JUe6EJXCmllLIhTeBKKaWUDWkCV+p7QETmiUiaiJSKyAER+W11XWYROSwif7R2syoQkRMi8oSIeLk8PkBEXhWRPBEpE5GtIjKt1muEi8gbIpJjvc4+Eflxrab0E5G1IlIsIntF5OoWCF+pdsn70qcopexMRB4H7gIexFmath/wV8AP+J112jyc24UOx7mxx1+BHJwblgC8bt13G85azz8FlovIQGNMmlXr/UugBJgNZABxOPdEdvU08Buc5Yr/A/iniPQ0xpzybNRKtX9aSlWpdkxE/IETwPXGmJUux+8AnjfGBFk7jB01xoxzuf8J4HZjTA8RicNZi3qGMWaFyznfAN8aY34sIncDLwFxxpgsN+2YgHMzhxuMtcOciETg3OM5xRizytOxK9Xe6RW4Uu1bEtAReE9EXL+tOwA/EQmzbn9d63HrgUdFpAuQaB1bW+uctTi3RwUYBux1l7xr+bb6F2NMjohUAhENikQpdQFN4Eq1b9Xj2Dfh3GmvtpMt2BaAc26O6VwcpZpAPzhKtW97gFLgCmNMupufSuu8kbUeNxo4ZowpsJ4DYHytc8bj3C4RYBuQqOu8lWo5msCVaseMMUXAE8ATIjJXROJFJElEfiQiT7mcOlhEHheRviJyK/AA8GfrOQ7i3L/4ZRGZLiIJIvIc0B/4H+vxi4AjwDIRmSIivUVksojc3FKxKvV9o13oSrVzxpj/EpFs4H6cSbkEZ3f6my6nvQD0BLYC5cCLnJ+BDnAPzmT9D6ALsAu41hiTZr1GsYhcBcwHFgOdgcPAn5orLqW+73QWulLfc9Ys9AXGmP9u7bYopRpOu9CVUkopG9IErpRSStmQdqErpZRSNqRX4EoppZQNaQJXSimlbEgTuFJKKWVDmsCVUkopG9IErpRSStnQ/wOVkzTJNqqy8QAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "sg.utils.plot_history(history)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reload the saved weights of the best model found during the training (according to validation accuracy)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "ppnp_model.load_weights(\"logs/best_ppnp_model.h5\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Evaluate the best model on the test set" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "test_gen = generator.flow(test_subjects.index, test_targets)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ['...']\n", "1/1 [==============================] - 0s 15ms/step - loss: 0.8854 - acc: 0.8351\n", "\n", "Test Set Metrics:\n", "\tloss: 0.8854\n", "\tacc: 0.8351\n" ] } ], "source": [ "test_metrics = ppnp_model.evaluate(test_gen)\n", "print(\"\\nTest Set Metrics:\")\n", "for name, val in zip(ppnp_model.metrics_names, test_metrics):\n", " print(\"\\t{}: {:0.4f}\".format(name, val))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using the Approximate PPNP Model\n", "\n", "Lets repeat the training and testing steps with the APPNP model using the same dataset. The downside of the PPNP is that you have to invert the adjacency matrix - which is time inefficient for large graphs - and store that invert matrix - which is space inefficient. The approximate model avoids this issue by using a clever mathematical trick. \n", "\n", "The APPNP model uses the normalized graph Laplacian. To get the normalized graph Laplacian we create a new `FullBatchNodeGenerator` and set `method=\"gcn\"`. We have the option of choosing `sparse=True` or `sparse=False` but will use `sparse=True` for memory efficiency." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GCN (local pooling) filters...\n", " ['...']\n", " ['...']\n", "Train for 1 steps, validate for 1 steps\n", "Epoch 1/120\n", "1/1 - 1s - loss: 2.1611 - acc: 0.1571 - val_loss: 2.0960 - val_acc: 0.3500\n", "Epoch 2/120\n", "1/1 - 0s - loss: 2.0830 - acc: 0.3214 - val_loss: 2.0560 - val_acc: 0.3780\n", "Epoch 3/120\n", "1/1 - 0s - loss: 2.0771 - acc: 0.2214 - val_loss: 2.0171 - val_acc: 0.3200\n", "Epoch 4/120\n", "1/1 - 0s - loss: 2.0152 - acc: 0.3286 - val_loss: 1.9767 - val_acc: 0.3040\n", "Epoch 5/120\n", "1/1 - 0s - loss: 1.9555 - acc: 0.3143 - val_loss: 1.9280 - val_acc: 0.3040\n", "Epoch 6/120\n", "1/1 - 0s - loss: 1.9276 - acc: 0.3357 - val_loss: 1.8699 - val_acc: 0.3160\n", "Epoch 7/120\n", "1/1 - 0s - loss: 1.9307 - acc: 0.3500 - val_loss: 1.8084 - val_acc: 0.3820\n", "Epoch 8/120\n", "1/1 - 0s - loss: 1.8068 - acc: 0.4286 - val_loss: 1.7449 - val_acc: 0.5320\n", "Epoch 9/120\n", "1/1 - 0s - loss: 1.7419 - acc: 0.4357 - val_loss: 1.6791 - val_acc: 0.6180\n", "Epoch 10/120\n", "1/1 - 0s - loss: 1.7992 - acc: 0.4429 - val_loss: 1.6142 - val_acc: 0.6160\n", "Epoch 11/120\n", "1/1 - 0s - loss: 1.6373 - acc: 0.5429 - val_loss: 1.5286 - val_acc: 0.6260\n", "Epoch 12/120\n", "1/1 - 0s - loss: 1.6104 - acc: 0.5000 - val_loss: 1.4470 - val_acc: 0.6480\n", "Epoch 13/120\n", "1/1 - 0s - loss: 1.5940 - acc: 0.5000 - val_loss: 1.3990 - val_acc: 0.6360\n", "Epoch 14/120\n", "1/1 - 0s - loss: 1.6000 - acc: 0.5286 - val_loss: 1.3676 - val_acc: 0.6400\n", "Epoch 15/120\n", "1/1 - 0s - loss: 1.4582 - acc: 0.5786 - val_loss: 1.3376 - val_acc: 0.6620\n", "Epoch 16/120\n", "1/1 - 0s - loss: 1.4981 - acc: 0.5643 - val_loss: 1.3105 - val_acc: 0.7040\n", "Epoch 17/120\n", "1/1 - 0s - loss: 1.4196 - acc: 0.6500 - val_loss: 1.2935 - val_acc: 0.7060\n", "Epoch 18/120\n", "1/1 - 0s - loss: 1.4223 - acc: 0.6286 - val_loss: 1.2826 - val_acc: 0.7040\n", "Epoch 19/120\n", "1/1 - 0s - loss: 1.6010 - acc: 0.5786 - val_loss: 1.2728 - val_acc: 0.7060\n", "Epoch 20/120\n", "1/1 - 0s - loss: 1.4398 - acc: 0.7000 - val_loss: 1.2584 - val_acc: 0.7200\n", "Epoch 21/120\n", "1/1 - 0s - loss: 1.3107 - acc: 0.6786 - val_loss: 1.2481 - val_acc: 0.7240\n", "Epoch 22/120\n", "1/1 - 0s - loss: 1.3125 - acc: 0.6714 - val_loss: 1.2400 - val_acc: 0.7180\n", "Epoch 23/120\n", "1/1 - 0s - loss: 1.3205 - acc: 0.6929 - val_loss: 1.2298 - val_acc: 0.7120\n", "Epoch 24/120\n", "1/1 - 0s - loss: 1.1782 - acc: 0.7500 - val_loss: 1.2171 - val_acc: 0.7020\n", "Epoch 25/120\n", "1/1 - 0s - loss: 1.2335 - acc: 0.7286 - val_loss: 1.2071 - val_acc: 0.6980\n", "Epoch 26/120\n", "1/1 - 0s - loss: 1.2707 - acc: 0.6714 - val_loss: 1.1907 - val_acc: 0.6980\n", "Epoch 27/120\n", "1/1 - 0s - loss: 1.2500 - acc: 0.6643 - val_loss: 1.1814 - val_acc: 0.7020\n", "Epoch 28/120\n", "1/1 - 0s - loss: 1.1690 - acc: 0.7500 - val_loss: 1.1774 - val_acc: 0.7040\n", "Epoch 29/120\n", "1/1 - 0s - loss: 1.3786 - acc: 0.7214 - val_loss: 1.1625 - val_acc: 0.7240\n", "Epoch 30/120\n", "1/1 - 0s - loss: 1.2246 - acc: 0.7429 - val_loss: 1.1497 - val_acc: 0.7360\n", "Epoch 31/120\n", "1/1 - 0s - loss: 1.1109 - acc: 0.7929 - val_loss: 1.1388 - val_acc: 0.7440\n", "Epoch 32/120\n", "1/1 - 0s - loss: 1.0982 - acc: 0.7929 - val_loss: 1.1308 - val_acc: 0.7600\n", "Epoch 33/120\n", "1/1 - 0s - loss: 1.0929 - acc: 0.7357 - val_loss: 1.1294 - val_acc: 0.7500\n", "Epoch 34/120\n", "1/1 - 0s - loss: 1.1645 - acc: 0.7429 - val_loss: 1.1390 - val_acc: 0.7360\n", "Epoch 35/120\n", "1/1 - 0s - loss: 1.0615 - acc: 0.7714 - val_loss: 1.1495 - val_acc: 0.7320\n", "Epoch 36/120\n", "1/1 - 0s - loss: 1.1692 - acc: 0.7643 - val_loss: 1.1454 - val_acc: 0.7340\n", "Epoch 37/120\n", "1/1 - 0s - loss: 1.1044 - acc: 0.8000 - val_loss: 1.1329 - val_acc: 0.7460\n", "Epoch 38/120\n", "1/1 - 0s - loss: 1.0422 - acc: 0.7857 - val_loss: 1.1178 - val_acc: 0.7580\n", "Epoch 39/120\n", "1/1 - 0s - loss: 1.0328 - acc: 0.8571 - val_loss: 1.1105 - val_acc: 0.7660\n", "Epoch 40/120\n", "1/1 - 0s - loss: 0.9567 - acc: 0.8357 - val_loss: 1.1098 - val_acc: 0.7680\n", "Epoch 41/120\n", "1/1 - 0s - loss: 0.9312 - acc: 0.8357 - val_loss: 1.1015 - val_acc: 0.7760\n", "Epoch 42/120\n", "1/1 - 0s - loss: 1.2391 - acc: 0.8071 - val_loss: 1.0930 - val_acc: 0.7740\n", "Epoch 43/120\n", "1/1 - 0s - loss: 1.5978 - acc: 0.8000 - val_loss: 1.0912 - val_acc: 0.7700\n", "Epoch 44/120\n", "1/1 - 0s - loss: 1.0150 - acc: 0.8071 - val_loss: 1.1093 - val_acc: 0.7520\n", "Epoch 45/120\n", "1/1 - 0s - loss: 0.9192 - acc: 0.8071 - val_loss: 1.1448 - val_acc: 0.7380\n", "Epoch 46/120\n", "1/1 - 0s - loss: 0.9793 - acc: 0.8071 - val_loss: 1.1717 - val_acc: 0.7380\n", "Epoch 47/120\n", "1/1 - 0s - loss: 1.1117 - acc: 0.7929 - val_loss: 1.1779 - val_acc: 0.7380\n", "Epoch 48/120\n", "1/1 - 0s - loss: 0.9973 - acc: 0.7929 - val_loss: 1.1706 - val_acc: 0.7420\n", "Epoch 49/120\n", "1/1 - 0s - loss: 1.0187 - acc: 0.7929 - val_loss: 1.1559 - val_acc: 0.7500\n", "Epoch 50/120\n", "1/1 - 0s - loss: 0.9383 - acc: 0.8571 - val_loss: 1.1413 - val_acc: 0.7580\n", "Epoch 51/120\n", "1/1 - 0s - loss: 0.9927 - acc: 0.8571 - val_loss: 1.1302 - val_acc: 0.7600\n", "Epoch 52/120\n", "1/1 - 0s - loss: 0.9229 - acc: 0.8571 - val_loss: 1.1256 - val_acc: 0.7660\n", "Epoch 53/120\n", "1/1 - 0s - loss: 1.1314 - acc: 0.7929 - val_loss: 1.1287 - val_acc: 0.7780\n", "Epoch 54/120\n", "1/1 - 0s - loss: 0.9056 - acc: 0.8357 - val_loss: 1.1345 - val_acc: 0.7760\n", "Epoch 55/120\n", "1/1 - 0s - loss: 1.0820 - acc: 0.8286 - val_loss: 1.1394 - val_acc: 0.7760\n", "Epoch 56/120\n", "1/1 - 0s - loss: 0.9782 - acc: 0.8357 - val_loss: 1.1435 - val_acc: 0.7820\n", "Epoch 57/120\n", "1/1 - 0s - loss: 0.9712 - acc: 0.8500 - val_loss: 1.1485 - val_acc: 0.7780\n", "Epoch 58/120\n", "1/1 - 0s - loss: 1.0927 - acc: 0.8071 - val_loss: 1.1563 - val_acc: 0.7740\n", "Epoch 59/120\n", "1/1 - 0s - loss: 1.0473 - acc: 0.8500 - val_loss: 1.1698 - val_acc: 0.7720\n", "Epoch 60/120\n", "1/1 - 0s - loss: 0.9803 - acc: 0.8286 - val_loss: 1.1760 - val_acc: 0.7640\n", "Epoch 61/120\n", "1/1 - 0s - loss: 1.0508 - acc: 0.8286 - val_loss: 1.1723 - val_acc: 0.7640\n", "Epoch 62/120\n", "1/1 - 0s - loss: 0.9952 - acc: 0.8214 - val_loss: 1.1675 - val_acc: 0.7640\n", "Epoch 63/120\n", "1/1 - 0s - loss: 0.8698 - acc: 0.8857 - val_loss: 1.1602 - val_acc: 0.7660\n", "Epoch 64/120\n", "1/1 - 0s - loss: 1.0041 - acc: 0.8500 - val_loss: 1.1508 - val_acc: 0.7700\n", "Epoch 65/120\n", "1/1 - 0s - loss: 0.8682 - acc: 0.8357 - val_loss: 1.1417 - val_acc: 0.7740\n", "Epoch 66/120\n", "1/1 - 0s - loss: 0.8056 - acc: 0.8786 - val_loss: 1.1343 - val_acc: 0.7720\n", "Epoch 67/120\n", "1/1 - 0s - loss: 0.9993 - acc: 0.8214 - val_loss: 1.1314 - val_acc: 0.7660\n", "Epoch 68/120\n", "1/1 - 0s - loss: 0.8606 - acc: 0.8357 - val_loss: 1.1302 - val_acc: 0.7740\n", "Epoch 69/120\n", "1/1 - 0s - loss: 0.9701 - acc: 0.7929 - val_loss: 1.1283 - val_acc: 0.7800\n", "Epoch 70/120\n", "1/1 - 0s - loss: 1.0286 - acc: 0.8286 - val_loss: 1.1265 - val_acc: 0.7740\n", "Epoch 71/120\n", "1/1 - 0s - loss: 0.9034 - acc: 0.8214 - val_loss: 1.1273 - val_acc: 0.7740\n", "Epoch 72/120\n", "1/1 - 0s - loss: 1.0693 - acc: 0.8071 - val_loss: 1.1319 - val_acc: 0.7840\n", "Epoch 73/120\n", "1/1 - 0s - loss: 0.8972 - acc: 0.8214 - val_loss: 1.1418 - val_acc: 0.7840\n", "Epoch 74/120\n", "1/1 - 0s - loss: 0.8502 - acc: 0.8571 - val_loss: 1.1508 - val_acc: 0.7880\n", "Epoch 75/120\n", "1/1 - 0s - loss: 0.9756 - acc: 0.8500 - val_loss: 1.1568 - val_acc: 0.7860\n", "Epoch 76/120\n", "1/1 - 0s - loss: 0.8226 - acc: 0.8714 - val_loss: 1.1593 - val_acc: 0.7880\n", "Epoch 77/120\n", "1/1 - 0s - loss: 0.8669 - acc: 0.8571 - val_loss: 1.1600 - val_acc: 0.7920\n", "Epoch 78/120\n", "1/1 - 0s - loss: 0.8231 - acc: 0.8929 - val_loss: 1.1553 - val_acc: 0.7940\n", "Epoch 79/120\n", "1/1 - 0s - loss: 0.9313 - acc: 0.8214 - val_loss: 1.1475 - val_acc: 0.7980\n", "Epoch 80/120\n", "1/1 - 0s - loss: 0.9309 - acc: 0.8643 - val_loss: 1.1389 - val_acc: 0.7920\n", "Epoch 81/120\n", "1/1 - 0s - loss: 0.9103 - acc: 0.9071 - val_loss: 1.1309 - val_acc: 0.7940\n", "Epoch 82/120\n", "1/1 - 0s - loss: 0.9027 - acc: 0.8714 - val_loss: 1.1249 - val_acc: 0.8060\n", "Epoch 83/120\n", "1/1 - 0s - loss: 0.7483 - acc: 0.8857 - val_loss: 1.1217 - val_acc: 0.7980\n", "Epoch 84/120\n", "1/1 - 0s - loss: 0.7934 - acc: 0.8857 - val_loss: 1.1188 - val_acc: 0.8040\n", "Epoch 85/120\n", "1/1 - 0s - loss: 0.7704 - acc: 0.8929 - val_loss: 1.1172 - val_acc: 0.7960\n", "Epoch 86/120\n", "1/1 - 0s - loss: 0.8442 - acc: 0.8643 - val_loss: 1.1168 - val_acc: 0.7960\n", "Epoch 87/120\n", "1/1 - 0s - loss: 0.7724 - acc: 0.9214 - val_loss: 1.1138 - val_acc: 0.8020\n", "Epoch 88/120\n", "1/1 - 0s - loss: 0.8009 - acc: 0.8929 - val_loss: 1.1145 - val_acc: 0.7960\n", "Epoch 89/120\n", "1/1 - 0s - loss: 0.7859 - acc: 0.8786 - val_loss: 1.1210 - val_acc: 0.7960\n", "Epoch 90/120\n", "1/1 - 0s - loss: 1.0622 - acc: 0.8143 - val_loss: 1.1252 - val_acc: 0.7940\n", "Epoch 91/120\n", "1/1 - 0s - loss: 1.0906 - acc: 0.8571 - val_loss: 1.1266 - val_acc: 0.7940\n", "Epoch 92/120\n", "1/1 - 0s - loss: 0.8647 - acc: 0.8571 - val_loss: 1.1287 - val_acc: 0.7940\n", "Epoch 93/120\n", "1/1 - 0s - loss: 0.9691 - acc: 0.8571 - val_loss: 1.1297 - val_acc: 0.7920\n", "Epoch 94/120\n", "1/1 - 0s - loss: 0.9680 - acc: 0.8214 - val_loss: 1.1307 - val_acc: 0.8080\n", "Epoch 95/120\n", "1/1 - 0s - loss: 0.7526 - acc: 0.8929 - val_loss: 1.1313 - val_acc: 0.8100\n", "Epoch 96/120\n", "1/1 - 0s - loss: 0.8328 - acc: 0.8857 - val_loss: 1.1308 - val_acc: 0.8080\n", "Epoch 97/120\n", "1/1 - 0s - loss: 0.7748 - acc: 0.9000 - val_loss: 1.1352 - val_acc: 0.8040\n", "Epoch 98/120\n", "1/1 - 0s - loss: 0.7760 - acc: 0.9286 - val_loss: 1.1388 - val_acc: 0.7980\n", "Epoch 99/120\n", "1/1 - 0s - loss: 0.8175 - acc: 0.9143 - val_loss: 1.1458 - val_acc: 0.7920\n", "Epoch 100/120\n", "1/1 - 0s - loss: 0.8016 - acc: 0.8786 - val_loss: 1.1541 - val_acc: 0.7860\n", "Epoch 101/120\n", "1/1 - 0s - loss: 0.9525 - acc: 0.8429 - val_loss: 1.1617 - val_acc: 0.7840\n", "Epoch 102/120\n", "1/1 - 0s - loss: 0.9398 - acc: 0.8857 - val_loss: 1.1624 - val_acc: 0.7820\n", "Epoch 103/120\n", "1/1 - 0s - loss: 0.8202 - acc: 0.9357 - val_loss: 1.1559 - val_acc: 0.7740\n", "Epoch 104/120\n", "1/1 - 0s - loss: 0.7174 - acc: 0.9429 - val_loss: 1.1506 - val_acc: 0.7720\n", "Epoch 105/120\n", "1/1 - 0s - loss: 0.7702 - acc: 0.8929 - val_loss: 1.1487 - val_acc: 0.7760\n", "Epoch 106/120\n", "1/1 - 0s - loss: 0.7437 - acc: 0.8929 - val_loss: 1.1464 - val_acc: 0.7700\n", "Epoch 107/120\n", "1/1 - 0s - loss: 0.9028 - acc: 0.9143 - val_loss: 1.1480 - val_acc: 0.7700\n", "Epoch 108/120\n", "1/1 - 0s - loss: 0.8906 - acc: 0.8643 - val_loss: 1.1473 - val_acc: 0.7800\n", "Epoch 109/120\n", "1/1 - 0s - loss: 0.6920 - acc: 0.8929 - val_loss: 1.1385 - val_acc: 0.7820\n", "Epoch 110/120\n", "1/1 - 0s - loss: 0.9391 - acc: 0.8643 - val_loss: 1.1308 - val_acc: 0.7900\n", "Epoch 111/120\n", "1/1 - 0s - loss: 0.8782 - acc: 0.8786 - val_loss: 1.1131 - val_acc: 0.7980\n", "Epoch 112/120\n", "1/1 - 0s - loss: 0.7309 - acc: 0.9071 - val_loss: 1.0996 - val_acc: 0.7960\n", "Epoch 113/120\n", "1/1 - 0s - loss: 0.7774 - acc: 0.9143 - val_loss: 1.0933 - val_acc: 0.8020\n", "Epoch 114/120\n", "1/1 - 0s - loss: 0.7890 - acc: 0.9000 - val_loss: 1.0939 - val_acc: 0.8080\n", "Epoch 115/120\n", "1/1 - 0s - loss: 0.9179 - acc: 0.8786 - val_loss: 1.1045 - val_acc: 0.8040\n", "Epoch 116/120\n", "1/1 - 0s - loss: 0.7260 - acc: 0.9357 - val_loss: 1.1189 - val_acc: 0.8000\n", "Epoch 117/120\n", "1/1 - 0s - loss: 0.7813 - acc: 0.9071 - val_loss: 1.1254 - val_acc: 0.7940\n", "Epoch 118/120\n", "1/1 - 0s - loss: 0.8243 - acc: 0.8929 - val_loss: 1.1271 - val_acc: 0.8040\n", "Epoch 119/120\n", "1/1 - 0s - loss: 0.9089 - acc: 0.8786 - val_loss: 1.1246 - val_acc: 0.8000\n", "Epoch 120/120\n", "1/1 - 0s - loss: 0.8312 - acc: 0.8929 - val_loss: 1.1206 - val_acc: 0.8060\n" ] } ], "source": [ "generator = FullBatchNodeGenerator(G, method=\"gcn\", sparse=True)\n", "\n", "train_gen = generator.flow(train_subjects.index, train_targets)\n", "val_gen = generator.flow(val_subjects.index, val_targets)\n", "test_gen = generator.flow(test_subjects.index, test_targets)\n", "\n", "appnp = APPNP(\n", " layer_sizes=[64, 64, train_targets.shape[-1]],\n", " activations=[\"relu\", \"relu\", \"relu\"],\n", " bias=True,\n", " generator=generator,\n", " teleport_probability=0.1,\n", " dropout=0.5,\n", " kernel_regularizer=keras.regularizers.l2(0.001),\n", ")\n", "\n", "x_inp, x_out = appnp.in_out_tensors()\n", "predictions = keras.layers.Softmax()(x_out)\n", "\n", "appnp_model = keras.models.Model(inputs=x_inp, outputs=predictions)\n", "appnp_model.compile(\n", " loss=\"categorical_crossentropy\",\n", " metrics=[\"acc\"],\n", " optimizer=keras.optimizers.Adam(lr=0.01),\n", ")\n", "\n", "es_callback = EarlyStopping(\n", " monitor=\"val_acc\", patience=50\n", ") # patience is the number of epochs to wait before early stopping in case of no further improvement\n", "\n", "mc_callback = ModelCheckpoint(\n", " \"logs/best_appnp_model.h5\",\n", " monitor=\"val_acc\",\n", " save_best_only=True,\n", " save_weights_only=True,\n", ")\n", "\n", "history = appnp_model.fit(\n", " train_gen,\n", " epochs=120,\n", " validation_data=val_gen,\n", " verbose=2,\n", " shuffle=False, # this should be False, since shuffling data means shuffling the whole graph\n", " callbacks=[es_callback, mc_callback],\n", ")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "sg.utils.plot_history(history)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ['...']\n", "1/1 [==============================] - 0s 8ms/step - loss: 1.0577 - acc: 0.8158\n", "\n", "Test Set Metrics:\n", "\tloss: 1.0577\n", "\tacc: 0.8158\n" ] } ], "source": [ "appnp_model.load_weights(\"logs/best_appnp_model.h5\")\n", "test_metrics = appnp_model.evaluate(test_gen)\n", "print(\"\\nTest Set Metrics:\")\n", "for name, val in zip(appnp_model.metrics_names, test_metrics):\n", " print(\"\\t{}: {:0.4f}\".format(name, val))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scalable APPNP Training\n", "\n", "Now we're going to exploit the structure of PPNP for scalable training. PPNP consists of a fully-connected neural network followed by a graph propagation step. For each node, the fully-connected network outputs a score for each class and the propagation step basically takes a weighted average of scores of nearby nodes (closer nodes are weighted higher). \n", "\n", "Above, we trained the whole network end-to-end which obtains the most accurate results but requires us to load the entire graph onto our GPU memory. This is because we need the entire graph for the propagation step. Unfortunately, this limits the graph size by our GPU memory. To get around this, we can train the fully-connected network separately and once we have a trained fully connected network we can add the graph propagation step. The advantage of this approach is that we can train on batches of node features instead of the entire graph.\n", "\n", "The model in the propagation step can be any Keras model trained on node features to predict the target classes. In this example we use a fully connected neural network with bag of word features as input. We could easily swap out the bag of words features for the complete text and replace the fully connected network with a state-of-the-art NLP model (for example BERT [1]), fine-tune the model and propagate its predictions.\n", "\n", "\n", "
\n", "\n", "1. Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2018). Bert: Pre-training of deep bidirectional transformers for language understanding. https://arxiv.org/abs/1810.04805" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we create and train a fully connected model." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "model = keras.models.Model()\n", "\n", "in_layer = layers.Input(shape=(G.node_feature_sizes()[\"paper\"],))\n", "\n", "layer = layers.Dropout(0.5)(in_layer)\n", "layer = layers.Dense(64, activation=\"relu\", kernel_regularizer=\"l2\")(layer)\n", "layer = layers.Dropout(0.5)(layer)\n", "layer = layers.Dense(64, activation=\"relu\", kernel_regularizer=\"l2\")(layer)\n", "layer = layers.Dropout(0.5)(layer)\n", "\n", "# note the dimension of the output should equal the number of classes to predict!\n", "layer = layers.Dense(train_targets.shape[-1], activation=\"relu\")(layer)\n", "layer = layers.Softmax()(layer)\n", "\n", "fully_connected_model = keras.models.Model(inputs=in_layer, outputs=layer)\n", "\n", "fully_connected_model.compile(\n", " loss=\"categorical_crossentropy\", metrics=[\"acc\"], optimizer=optimizers.Adam(lr=0.01)\n", ")\n", "\n", "# the inputs are just the node features\n", "X_train = G.node_features(train_subjects.index)\n", "X_val = G.node_features(val_subjects.index)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Train on 140 samples, validate on 500 samples\n", "Epoch 1/2000\n", "140/140 [==============================] - 0s 3ms/sample - loss: 3.8201 - acc: 0.1286 - val_loss: 3.2912 - val_acc: 0.3080\n", "Epoch 2/2000\n", "140/140 [==============================] - 0s 83us/sample - loss: 3.2808 - acc: 0.2714 - val_loss: 2.9294 - val_acc: 0.3020\n", "Epoch 3/2000\n", "140/140 [==============================] - 0s 78us/sample - loss: 2.8792 - acc: 0.3214 - val_loss: 2.6845 - val_acc: 0.3020\n", "Epoch 4/2000\n", "140/140 [==============================] - 0s 84us/sample - loss: 2.6692 - acc: 0.3071 - val_loss: 2.5253 - val_acc: 0.3020\n", "Epoch 5/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 2.4449 - acc: 0.3214 - val_loss: 2.4298 - val_acc: 0.3020\n", "Epoch 6/2000\n", "140/140 [==============================] - 0s 79us/sample - loss: 2.3284 - acc: 0.3143 - val_loss: 2.3773 - val_acc: 0.3020\n", "Epoch 7/2000\n", "140/140 [==============================] - 0s 83us/sample - loss: 2.2412 - acc: 0.3286 - val_loss: 2.3464 - val_acc: 0.3020\n", "Epoch 8/2000\n", "140/140 [==============================] - 0s 103us/sample - loss: 2.2228 - acc: 0.3071 - val_loss: 2.3212 - val_acc: 0.3020\n", "Epoch 9/2000\n", "140/140 [==============================] - 0s 164us/sample - loss: 2.1642 - acc: 0.3429 - val_loss: 2.2951 - val_acc: 0.3220\n", "Epoch 10/2000\n", "140/140 [==============================] - 0s 143us/sample - loss: 2.0998 - acc: 0.3929 - val_loss: 2.2695 - val_acc: 0.3820\n", "Epoch 11/2000\n", "140/140 [==============================] - 0s 141us/sample - loss: 2.0418 - acc: 0.4214 - val_loss: 2.2445 - val_acc: 0.4320\n", "Epoch 12/2000\n", "140/140 [==============================] - 0s 142us/sample - loss: 1.9640 - acc: 0.5143 - val_loss: 2.2181 - val_acc: 0.4480\n", "Epoch 13/2000\n", "140/140 [==============================] - 0s 142us/sample - loss: 1.8945 - acc: 0.5214 - val_loss: 2.1876 - val_acc: 0.4760\n", "Epoch 14/2000\n", "140/140 [==============================] - 0s 151us/sample - loss: 1.8290 - acc: 0.5429 - val_loss: 2.1535 - val_acc: 0.4780\n", "Epoch 15/2000\n", "140/140 [==============================] - 0s 150us/sample - loss: 1.7720 - acc: 0.5786 - val_loss: 2.1225 - val_acc: 0.4800\n", "Epoch 16/2000\n", "140/140 [==============================] - 0s 157us/sample - loss: 1.8089 - acc: 0.5857 - val_loss: 2.0908 - val_acc: 0.4820\n", "Epoch 17/2000\n", "140/140 [==============================] - 0s 157us/sample - loss: 1.6867 - acc: 0.5929 - val_loss: 2.0573 - val_acc: 0.4900\n", "Epoch 18/2000\n", "140/140 [==============================] - 0s 146us/sample - loss: 1.5806 - acc: 0.6286 - val_loss: 2.0274 - val_acc: 0.4940\n", "Epoch 19/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 1.5333 - acc: 0.6357 - val_loss: 2.0046 - val_acc: 0.4920\n", "Epoch 20/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 1.4646 - acc: 0.6500 - val_loss: 1.9873 - val_acc: 0.4920\n", "Epoch 21/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 1.4614 - acc: 0.6500 - val_loss: 1.9709 - val_acc: 0.4940\n", "Epoch 22/2000\n", "140/140 [==============================] - 0s 149us/sample - loss: 1.4018 - acc: 0.7000 - val_loss: 1.9564 - val_acc: 0.5000\n", "Epoch 23/2000\n", "140/140 [==============================] - 0s 143us/sample - loss: 1.3746 - acc: 0.7071 - val_loss: 1.9532 - val_acc: 0.5160\n", "Epoch 24/2000\n", "140/140 [==============================] - 0s 147us/sample - loss: 1.3467 - acc: 0.7143 - val_loss: 1.9540 - val_acc: 0.5240\n", "Epoch 25/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 1.2373 - acc: 0.8071 - val_loss: 1.9415 - val_acc: 0.5120\n", "Epoch 26/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 1.3242 - acc: 0.7571 - val_loss: 1.9392 - val_acc: 0.5080\n", "Epoch 27/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 1.1863 - acc: 0.7857 - val_loss: 1.9469 - val_acc: 0.5080\n", "Epoch 28/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 1.3267 - acc: 0.7857 - val_loss: 1.9560 - val_acc: 0.4980\n", "Epoch 29/2000\n", "140/140 [==============================] - 0s 82us/sample - loss: 1.1390 - acc: 0.8429 - val_loss: 1.9454 - val_acc: 0.5160\n", "Epoch 30/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 1.1522 - acc: 0.8429 - val_loss: 1.9369 - val_acc: 0.5240\n", "Epoch 31/2000\n", "140/140 [==============================] - 0s 158us/sample - loss: 1.1971 - acc: 0.7929 - val_loss: 1.9244 - val_acc: 0.5360\n", "Epoch 32/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 1.1052 - acc: 0.8786 - val_loss: 1.9267 - val_acc: 0.5260\n", "Epoch 33/2000\n", "140/140 [==============================] - 0s 98us/sample - loss: 1.0775 - acc: 0.8786 - val_loss: 1.9390 - val_acc: 0.5320\n", "Epoch 34/2000\n", "140/140 [==============================] - 0s 148us/sample - loss: 1.1779 - acc: 0.8143 - val_loss: 1.9429 - val_acc: 0.5500\n", "Epoch 35/2000\n", "140/140 [==============================] - 0s 155us/sample - loss: 1.1674 - acc: 0.8143 - val_loss: 1.9438 - val_acc: 0.5540\n", "Epoch 36/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 1.0945 - acc: 0.8714 - val_loss: 1.9487 - val_acc: 0.5520\n", "Epoch 37/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 1.0334 - acc: 0.9000 - val_loss: 1.9659 - val_acc: 0.5460\n", "Epoch 38/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 1.1242 - acc: 0.8357 - val_loss: 1.9779 - val_acc: 0.5420\n", "Epoch 39/2000\n", "140/140 [==============================] - 0s 107us/sample - loss: 0.9863 - acc: 0.9429 - val_loss: 1.9859 - val_acc: 0.5420\n", "Epoch 40/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 1.0593 - acc: 0.9143 - val_loss: 1.9760 - val_acc: 0.5420\n", "Epoch 41/2000\n", "140/140 [==============================] - 0s 107us/sample - loss: 1.0438 - acc: 0.8786 - val_loss: 1.9663 - val_acc: 0.5360\n", "Epoch 42/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 1.0331 - acc: 0.8857 - val_loss: 1.9657 - val_acc: 0.5500\n", "Epoch 43/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 1.1313 - acc: 0.8643 - val_loss: 1.9746 - val_acc: 0.5500\n", "Epoch 44/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9899 - acc: 0.9214 - val_loss: 1.9764 - val_acc: 0.5440\n", "Epoch 45/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 1.0035 - acc: 0.9214 - val_loss: 1.9694 - val_acc: 0.5500\n", "Epoch 46/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 1.1105 - acc: 0.8429 - val_loss: 1.9550 - val_acc: 0.5520\n", "Epoch 47/2000\n", "140/140 [==============================] - 0s 156us/sample - loss: 0.9754 - acc: 0.9071 - val_loss: 1.9484 - val_acc: 0.5580\n", "Epoch 48/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 1.0279 - acc: 0.8857 - val_loss: 1.9500 - val_acc: 0.5520\n", "Epoch 49/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 1.0529 - acc: 0.8786 - val_loss: 1.9544 - val_acc: 0.5400\n", "Epoch 50/2000\n", "140/140 [==============================] - 0s 105us/sample - loss: 1.1056 - acc: 0.8357 - val_loss: 1.9536 - val_acc: 0.5440\n", "Epoch 51/2000\n", "140/140 [==============================] - 0s 98us/sample - loss: 0.9449 - acc: 0.9357 - val_loss: 1.9526 - val_acc: 0.5320\n", "Epoch 52/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.9428 - acc: 0.9214 - val_loss: 1.9504 - val_acc: 0.5400\n", "Epoch 53/2000\n", "140/140 [==============================] - 0s 112us/sample - loss: 0.9933 - acc: 0.9000 - val_loss: 1.9406 - val_acc: 0.5500\n", "Epoch 54/2000\n", "140/140 [==============================] - 0s 104us/sample - loss: 0.9363 - acc: 0.9429 - val_loss: 1.9353 - val_acc: 0.5520\n", "Epoch 55/2000\n", "140/140 [==============================] - 0s 83us/sample - loss: 1.0300 - acc: 0.8643 - val_loss: 1.9259 - val_acc: 0.5560\n", "Epoch 56/2000\n", "140/140 [==============================] - 0s 152us/sample - loss: 0.9245 - acc: 0.9214 - val_loss: 1.9302 - val_acc: 0.5680\n", "Epoch 57/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 1.0145 - acc: 0.8929 - val_loss: 1.9363 - val_acc: 0.5660\n", "Epoch 58/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9671 - acc: 0.8857 - val_loss: 1.9351 - val_acc: 0.5620\n", "Epoch 59/2000\n", "140/140 [==============================] - 0s 103us/sample - loss: 0.9474 - acc: 0.9143 - val_loss: 1.9316 - val_acc: 0.5680\n", "Epoch 60/2000\n", "140/140 [==============================] - 0s 84us/sample - loss: 1.0560 - acc: 0.8500 - val_loss: 1.9190 - val_acc: 0.5620\n", "Epoch 61/2000\n", "140/140 [==============================] - 0s 108us/sample - loss: 0.9253 - acc: 0.9357 - val_loss: 1.9100 - val_acc: 0.5500\n", "Epoch 62/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 0.9976 - acc: 0.9000 - val_loss: 1.9112 - val_acc: 0.5500\n", "Epoch 63/2000\n", "140/140 [==============================] - 0s 130us/sample - loss: 1.0005 - acc: 0.8857 - val_loss: 1.9208 - val_acc: 0.5300\n", "Epoch 64/2000\n", "140/140 [==============================] - 0s 111us/sample - loss: 0.8937 - acc: 0.9429 - val_loss: 1.9329 - val_acc: 0.5360\n", "Epoch 65/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 0.9581 - acc: 0.9071 - val_loss: 1.9383 - val_acc: 0.5440\n", "Epoch 66/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 1.0596 - acc: 0.8643 - val_loss: 1.9442 - val_acc: 0.5380\n", "Epoch 67/2000\n", "140/140 [==============================] - 0s 104us/sample - loss: 0.9023 - acc: 0.9286 - val_loss: 1.9479 - val_acc: 0.5420\n", "Epoch 68/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9838 - acc: 0.9143 - val_loss: 1.9516 - val_acc: 0.5480\n", "Epoch 69/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9933 - acc: 0.9000 - val_loss: 1.9460 - val_acc: 0.5420\n", "Epoch 70/2000\n", "140/140 [==============================] - 0s 83us/sample - loss: 0.9406 - acc: 0.9286 - val_loss: 1.9482 - val_acc: 0.5420\n", "Epoch 71/2000\n", "140/140 [==============================] - 0s 99us/sample - loss: 0.8976 - acc: 0.9357 - val_loss: 1.9552 - val_acc: 0.5420\n", "Epoch 72/2000\n", "140/140 [==============================] - 0s 107us/sample - loss: 0.9861 - acc: 0.8929 - val_loss: 1.9647 - val_acc: 0.5140\n", "Epoch 73/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.8325 - acc: 0.9500 - val_loss: 1.9713 - val_acc: 0.5180\n", "Epoch 74/2000\n", "140/140 [==============================] - 0s 99us/sample - loss: 0.8933 - acc: 0.9357 - val_loss: 1.9735 - val_acc: 0.5140\n", "Epoch 75/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 0.9264 - acc: 0.9000 - val_loss: 1.9686 - val_acc: 0.5100\n", "Epoch 76/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9116 - acc: 0.9357 - val_loss: 1.9614 - val_acc: 0.5240\n", "Epoch 77/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9926 - acc: 0.9071 - val_loss: 1.9484 - val_acc: 0.5260\n", "Epoch 78/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9179 - acc: 0.9286 - val_loss: 1.9387 - val_acc: 0.5220\n", "Epoch 79/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 0.8961 - acc: 0.9357 - val_loss: 1.9363 - val_acc: 0.5220\n", "Epoch 80/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 1.0118 - acc: 0.8714 - val_loss: 1.9442 - val_acc: 0.5320\n", "Epoch 81/2000\n", "140/140 [==============================] - 0s 105us/sample - loss: 0.9812 - acc: 0.8857 - val_loss: 1.9578 - val_acc: 0.5320\n", "Epoch 82/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9034 - acc: 0.9071 - val_loss: 1.9687 - val_acc: 0.5340\n", "Epoch 83/2000\n", "140/140 [==============================] - 0s 96us/sample - loss: 0.9148 - acc: 0.9214 - val_loss: 1.9721 - val_acc: 0.5260\n", "Epoch 84/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9112 - acc: 0.9214 - val_loss: 1.9743 - val_acc: 0.5300\n", "Epoch 85/2000\n", "140/140 [==============================] - 0s 80us/sample - loss: 0.9514 - acc: 0.9000 - val_loss: 1.9675 - val_acc: 0.5480\n", "Epoch 86/2000\n", "140/140 [==============================] - 0s 98us/sample - loss: 1.0306 - acc: 0.9071 - val_loss: 1.9527 - val_acc: 0.5480\n", "Epoch 87/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.9282 - acc: 0.9357 - val_loss: 1.9466 - val_acc: 0.5500\n", "Epoch 88/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 0.9865 - acc: 0.9000 - val_loss: 1.9465 - val_acc: 0.5560\n", "Epoch 89/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9454 - acc: 0.9286 - val_loss: 1.9484 - val_acc: 0.5520\n", "Epoch 90/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 0.9295 - acc: 0.9286 - val_loss: 1.9416 - val_acc: 0.5620\n", "Epoch 91/2000\n", "140/140 [==============================] - 0s 152us/sample - loss: 1.0591 - acc: 0.8500 - val_loss: 1.9329 - val_acc: 0.5700\n", "Epoch 92/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.9447 - acc: 0.8857 - val_loss: 1.9279 - val_acc: 0.5560\n", "Epoch 93/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9101 - acc: 0.9357 - val_loss: 1.9303 - val_acc: 0.5500\n", "Epoch 94/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.8793 - acc: 0.9500 - val_loss: 1.9392 - val_acc: 0.5500\n", "Epoch 95/2000\n", "140/140 [==============================] - 0s 91us/sample - loss: 0.8725 - acc: 0.9571 - val_loss: 1.9488 - val_acc: 0.5600\n", "Epoch 96/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 0.9350 - acc: 0.9071 - val_loss: 1.9486 - val_acc: 0.5680\n", "Epoch 97/2000\n", "140/140 [==============================] - 0s 78us/sample - loss: 0.8988 - acc: 0.9357 - val_loss: 1.9448 - val_acc: 0.5700\n", "Epoch 98/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9016 - acc: 0.9357 - val_loss: 1.9352 - val_acc: 0.5500\n", "Epoch 99/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.8885 - acc: 0.9357 - val_loss: 1.9327 - val_acc: 0.5420\n", "Epoch 100/2000\n", "140/140 [==============================] - 0s 105us/sample - loss: 0.9253 - acc: 0.9214 - val_loss: 1.9366 - val_acc: 0.5360\n", "Epoch 101/2000\n", "140/140 [==============================] - 0s 77us/sample - loss: 0.8266 - acc: 0.9714 - val_loss: 1.9448 - val_acc: 0.5280\n", "Epoch 102/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.8642 - acc: 0.9357 - val_loss: 1.9489 - val_acc: 0.5220\n", "Epoch 103/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 0.9301 - acc: 0.9000 - val_loss: 1.9628 - val_acc: 0.5280\n", "Epoch 104/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.8503 - acc: 0.9214 - val_loss: 1.9635 - val_acc: 0.5380\n", "Epoch 105/2000\n", "140/140 [==============================] - 0s 104us/sample - loss: 0.8412 - acc: 0.9357 - val_loss: 1.9618 - val_acc: 0.5440\n", "Epoch 106/2000\n", "140/140 [==============================] - 0s 96us/sample - loss: 0.9407 - acc: 0.9143 - val_loss: 1.9454 - val_acc: 0.5380\n", "Epoch 107/2000\n", "140/140 [==============================] - 0s 83us/sample - loss: 0.9286 - acc: 0.9071 - val_loss: 1.9270 - val_acc: 0.5200\n", "Epoch 108/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9219 - acc: 0.9071 - val_loss: 1.9152 - val_acc: 0.5260\n", "Epoch 109/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.8760 - acc: 0.9286 - val_loss: 1.9144 - val_acc: 0.5260\n", "Epoch 110/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 0.8704 - acc: 0.9357 - val_loss: 1.9226 - val_acc: 0.5320\n", "Epoch 111/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.9061 - acc: 0.9143 - val_loss: 1.9322 - val_acc: 0.5380\n", "Epoch 112/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9191 - acc: 0.9286 - val_loss: 1.9459 - val_acc: 0.5400\n", "Epoch 113/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 0.9249 - acc: 0.9214 - val_loss: 1.9543 - val_acc: 0.5480\n", "Epoch 114/2000\n", "140/140 [==============================] - 0s 98us/sample - loss: 0.9360 - acc: 0.9071 - val_loss: 1.9570 - val_acc: 0.5420\n", "Epoch 115/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.8688 - acc: 0.9286 - val_loss: 1.9520 - val_acc: 0.5340\n", "Epoch 116/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 0.8182 - acc: 0.9500 - val_loss: 1.9471 - val_acc: 0.5340\n", "Epoch 117/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.9340 - acc: 0.9000 - val_loss: 1.9407 - val_acc: 0.5480\n", "Epoch 118/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.8599 - acc: 0.9500 - val_loss: 1.9478 - val_acc: 0.5400\n", "Epoch 119/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9156 - acc: 0.9214 - val_loss: 1.9593 - val_acc: 0.5480\n", "Epoch 120/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9137 - acc: 0.9214 - val_loss: 1.9656 - val_acc: 0.5420\n", "Epoch 121/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 1.0899 - acc: 0.8643 - val_loss: 1.9542 - val_acc: 0.5580\n", "Epoch 122/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.8300 - acc: 0.9571 - val_loss: 1.9495 - val_acc: 0.5520\n", "Epoch 123/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.9260 - acc: 0.9143 - val_loss: 1.9414 - val_acc: 0.5480\n", "Epoch 124/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9196 - acc: 0.9000 - val_loss: 1.9379 - val_acc: 0.5380\n", "Epoch 125/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 0.9593 - acc: 0.9143 - val_loss: 1.9339 - val_acc: 0.5580\n", "Epoch 126/2000\n", "140/140 [==============================] - 0s 86us/sample - loss: 0.9930 - acc: 0.9000 - val_loss: 1.9367 - val_acc: 0.5540\n", "Epoch 127/2000\n", "140/140 [==============================] - 0s 91us/sample - loss: 0.8355 - acc: 0.9500 - val_loss: 1.9413 - val_acc: 0.5560\n", "Epoch 128/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9429 - acc: 0.9000 - val_loss: 1.9489 - val_acc: 0.5460\n", "Epoch 129/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.8404 - acc: 0.9643 - val_loss: 1.9557 - val_acc: 0.5440\n", "Epoch 130/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.9001 - acc: 0.9143 - val_loss: 1.9592 - val_acc: 0.5560\n", "Epoch 131/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 0.9761 - acc: 0.9000 - val_loss: 1.9608 - val_acc: 0.5500\n", "Epoch 132/2000\n", "140/140 [==============================] - 0s 113us/sample - loss: 1.0063 - acc: 0.8929 - val_loss: 1.9530 - val_acc: 0.5580\n", "Epoch 133/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.8973 - acc: 0.9357 - val_loss: 1.9471 - val_acc: 0.5580\n", "Epoch 134/2000\n", "140/140 [==============================] - 0s 148us/sample - loss: 0.9566 - acc: 0.9143 - val_loss: 1.9413 - val_acc: 0.5780\n", "Epoch 135/2000\n", "140/140 [==============================] - 0s 95us/sample - loss: 0.8656 - acc: 0.9286 - val_loss: 1.9347 - val_acc: 0.5660\n", "Epoch 136/2000\n", "140/140 [==============================] - 0s 107us/sample - loss: 0.8765 - acc: 0.9214 - val_loss: 1.9258 - val_acc: 0.5760\n", "Epoch 137/2000\n", "140/140 [==============================] - 0s 84us/sample - loss: 0.8905 - acc: 0.9071 - val_loss: 1.9186 - val_acc: 0.5740\n", "Epoch 138/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 0.9537 - acc: 0.8714 - val_loss: 1.9161 - val_acc: 0.5580\n", "Epoch 139/2000\n", "140/140 [==============================] - 0s 82us/sample - loss: 0.9438 - acc: 0.9000 - val_loss: 1.9166 - val_acc: 0.5500\n", "Epoch 140/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.8830 - acc: 0.9357 - val_loss: 1.9138 - val_acc: 0.5560\n", "Epoch 141/2000\n", "140/140 [==============================] - 0s 104us/sample - loss: 0.9715 - acc: 0.8857 - val_loss: 1.9105 - val_acc: 0.5540\n", "Epoch 142/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.8759 - acc: 0.9357 - val_loss: 1.9025 - val_acc: 0.5620\n", "Epoch 143/2000\n", "140/140 [==============================] - 0s 105us/sample - loss: 0.8466 - acc: 0.9429 - val_loss: 1.8982 - val_acc: 0.5600\n", "Epoch 144/2000\n", "140/140 [==============================] - 0s 103us/sample - loss: 0.8608 - acc: 0.9429 - val_loss: 1.8937 - val_acc: 0.5640\n", "Epoch 145/2000\n", "140/140 [==============================] - 0s 109us/sample - loss: 0.9898 - acc: 0.8643 - val_loss: 1.8865 - val_acc: 0.5680\n", "Epoch 146/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.9417 - acc: 0.9000 - val_loss: 1.8858 - val_acc: 0.5640\n", "Epoch 147/2000\n", "140/140 [==============================] - 0s 107us/sample - loss: 0.9533 - acc: 0.9071 - val_loss: 1.8988 - val_acc: 0.5540\n", "Epoch 148/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9109 - acc: 0.9143 - val_loss: 1.8929 - val_acc: 0.5500\n", "Epoch 149/2000\n", "140/140 [==============================] - 0s 91us/sample - loss: 0.9624 - acc: 0.9000 - val_loss: 1.8700 - val_acc: 0.5600\n", "Epoch 150/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.8296 - acc: 0.9571 - val_loss: 1.8520 - val_acc: 0.5660\n", "Epoch 151/2000\n", "140/140 [==============================] - 0s 159us/sample - loss: 0.9041 - acc: 0.9071 - val_loss: 1.8461 - val_acc: 0.5860\n", "Epoch 152/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.8742 - acc: 0.9357 - val_loss: 1.8487 - val_acc: 0.5720\n", "Epoch 153/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.8634 - acc: 0.9214 - val_loss: 1.8508 - val_acc: 0.5680\n", "Epoch 154/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 0.8694 - acc: 0.9214 - val_loss: 1.8477 - val_acc: 0.5740\n", "Epoch 155/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.8465 - acc: 0.9357 - val_loss: 1.8468 - val_acc: 0.5780\n", "Epoch 156/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 0.8932 - acc: 0.9000 - val_loss: 1.8469 - val_acc: 0.5700\n", "Epoch 157/2000\n", "140/140 [==============================] - 0s 109us/sample - loss: 0.8758 - acc: 0.9286 - val_loss: 1.8585 - val_acc: 0.5560\n", "Epoch 158/2000\n", "140/140 [==============================] - 0s 116us/sample - loss: 0.8477 - acc: 0.9571 - val_loss: 1.8982 - val_acc: 0.5660\n", "Epoch 159/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.9012 - acc: 0.9214 - val_loss: 1.9359 - val_acc: 0.5520\n", "Epoch 160/2000\n", "140/140 [==============================] - 0s 108us/sample - loss: 0.9814 - acc: 0.9000 - val_loss: 1.9290 - val_acc: 0.5480\n", "Epoch 161/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.8479 - acc: 0.9500 - val_loss: 1.9168 - val_acc: 0.5440\n", "Epoch 162/2000\n", "140/140 [==============================] - 0s 74us/sample - loss: 0.9104 - acc: 0.9214 - val_loss: 1.9056 - val_acc: 0.5520\n", "Epoch 163/2000\n", "140/140 [==============================] - 0s 96us/sample - loss: 0.9247 - acc: 0.9214 - val_loss: 1.9101 - val_acc: 0.5560\n", "Epoch 164/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.8298 - acc: 0.9500 - val_loss: 1.9230 - val_acc: 0.5560\n", "Epoch 165/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 0.9262 - acc: 0.9071 - val_loss: 1.9357 - val_acc: 0.5620\n", "Epoch 166/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.8744 - acc: 0.9214 - val_loss: 1.9459 - val_acc: 0.5640\n", "Epoch 167/2000\n", "140/140 [==============================] - 0s 100us/sample - loss: 0.9255 - acc: 0.9143 - val_loss: 1.9505 - val_acc: 0.5600\n", "Epoch 168/2000\n", "140/140 [==============================] - 0s 99us/sample - loss: 0.8452 - acc: 0.9429 - val_loss: 1.9515 - val_acc: 0.5580\n", "Epoch 169/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.8825 - acc: 0.9214 - val_loss: 1.9397 - val_acc: 0.5520\n", "Epoch 170/2000\n", "140/140 [==============================] - 0s 103us/sample - loss: 0.9308 - acc: 0.9000 - val_loss: 1.9303 - val_acc: 0.5580\n", "Epoch 171/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.9189 - acc: 0.9214 - val_loss: 1.9237 - val_acc: 0.5620\n", "Epoch 172/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9386 - acc: 0.9143 - val_loss: 1.9159 - val_acc: 0.5520\n", "Epoch 173/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 0.9751 - acc: 0.8786 - val_loss: 1.9132 - val_acc: 0.5540\n", "Epoch 174/2000\n", "140/140 [==============================] - 0s 96us/sample - loss: 0.9459 - acc: 0.8929 - val_loss: 1.9179 - val_acc: 0.5580\n", "Epoch 175/2000\n", "140/140 [==============================] - 0s 91us/sample - loss: 1.0002 - acc: 0.8714 - val_loss: 1.9227 - val_acc: 0.5480\n", "Epoch 176/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.9078 - acc: 0.9071 - val_loss: 1.9332 - val_acc: 0.5380\n", "Epoch 177/2000\n", "140/140 [==============================] - 0s 98us/sample - loss: 0.8872 - acc: 0.9214 - val_loss: 1.9514 - val_acc: 0.5320\n", "Epoch 178/2000\n", "140/140 [==============================] - 0s 90us/sample - loss: 0.8750 - acc: 0.9500 - val_loss: 1.9614 - val_acc: 0.5260\n", "Epoch 179/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9659 - acc: 0.9071 - val_loss: 1.9632 - val_acc: 0.5240\n", "Epoch 180/2000\n", "140/140 [==============================] - 0s 97us/sample - loss: 0.9674 - acc: 0.9000 - val_loss: 1.9554 - val_acc: 0.5300\n", "Epoch 181/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 1.0248 - acc: 0.8857 - val_loss: 1.9430 - val_acc: 0.5380\n", "Epoch 182/2000\n", "140/140 [==============================] - 0s 84us/sample - loss: 0.8888 - acc: 0.9357 - val_loss: 1.9356 - val_acc: 0.5460\n", "Epoch 183/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9461 - acc: 0.9214 - val_loss: 1.9399 - val_acc: 0.5380\n", "Epoch 184/2000\n", "140/140 [==============================] - 0s 94us/sample - loss: 1.0256 - acc: 0.8857 - val_loss: 1.9492 - val_acc: 0.5380\n", "Epoch 185/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9040 - acc: 0.9143 - val_loss: 1.9593 - val_acc: 0.5320\n", "Epoch 186/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9038 - acc: 0.9214 - val_loss: 1.9628 - val_acc: 0.5300\n", "Epoch 187/2000\n", "140/140 [==============================] - 0s 93us/sample - loss: 0.9496 - acc: 0.9286 - val_loss: 1.9648 - val_acc: 0.5300\n", "Epoch 188/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9602 - acc: 0.8929 - val_loss: 1.9651 - val_acc: 0.5440\n", "Epoch 189/2000\n", "140/140 [==============================] - 0s 84us/sample - loss: 0.8971 - acc: 0.9214 - val_loss: 1.9638 - val_acc: 0.5400\n", "Epoch 190/2000\n", "140/140 [==============================] - 0s 85us/sample - loss: 0.8522 - acc: 0.9357 - val_loss: 1.9591 - val_acc: 0.5380\n", "Epoch 191/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9650 - acc: 0.9143 - val_loss: 1.9527 - val_acc: 0.5340\n", "Epoch 192/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 1.0122 - acc: 0.8929 - val_loss: 1.9389 - val_acc: 0.5340\n", "Epoch 193/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9168 - acc: 0.9286 - val_loss: 1.9256 - val_acc: 0.5540\n", "Epoch 194/2000\n", "140/140 [==============================] - 0s 82us/sample - loss: 0.9403 - acc: 0.9000 - val_loss: 1.9204 - val_acc: 0.5600\n", "Epoch 195/2000\n", "140/140 [==============================] - 0s 87us/sample - loss: 0.9763 - acc: 0.9071 - val_loss: 1.9203 - val_acc: 0.5700\n", "Epoch 196/2000\n", "140/140 [==============================] - 0s 88us/sample - loss: 0.9084 - acc: 0.9286 - val_loss: 1.9263 - val_acc: 0.5660\n", "Epoch 197/2000\n", "140/140 [==============================] - 0s 112us/sample - loss: 0.9424 - acc: 0.9000 - val_loss: 1.9334 - val_acc: 0.5620\n", "Epoch 198/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.8912 - acc: 0.9286 - val_loss: 1.9355 - val_acc: 0.5540\n", "Epoch 199/2000\n", "140/140 [==============================] - 0s 81us/sample - loss: 0.9526 - acc: 0.8929 - val_loss: 1.9298 - val_acc: 0.5480\n", "Epoch 200/2000\n", "140/140 [==============================] - 0s 89us/sample - loss: 0.8537 - acc: 0.9643 - val_loss: 1.9241 - val_acc: 0.5540\n", "Epoch 201/2000\n", "140/140 [==============================] - 0s 92us/sample - loss: 0.9466 - acc: 0.8929 - val_loss: 1.9094 - val_acc: 0.5520\n" ] } ], "source": [ "es_callback = EarlyStopping(\n", " monitor=\"val_acc\", patience=50\n", ") # patience is the number of epochs to wait before early stopping in case of no further improvement\n", "\n", "mc_callback = ModelCheckpoint(\n", " \"logs/best_fc_model.h5\",\n", " monitor=\"val_acc\",\n", " save_best_only=True,\n", " save_weights_only=True,\n", ")\n", "\n", "history = fully_connected_model.fit(\n", " X_train,\n", " train_targets,\n", " validation_data=(X_val, val_targets),\n", " epochs=2000,\n", " batch_size=200,\n", " shuffle=True, # we can shuffle the data here as\n", " callbacks=[es_callback, mc_callback],\n", ") # we're only working with node features" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By itself the fully connected model only gets ~60% accuracy on the test set." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2068/2068 - 0s - loss: 1.8196 - acc: 0.5793\n", "\n", "Test Set Metrics:\n", "\tloss: 1.8196\n", "\tacc: 0.5793\n" ] } ], "source": [ "X_test = G.node_features(test_subjects.index)\n", "\n", "fully_connected_model.load_weights(\"logs/best_fc_model.h5\")\n", "test_metrics = fully_connected_model.evaluate(X_test, test_targets, verbose=2)\n", "print(\"\\nTest Set Metrics:\")\n", "for name, val in zip(fully_connected_model.metrics_names, test_metrics):\n", " print(\"\\t{}: {:0.4f}\".format(name, val))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we propagate the fully connected network - no extra training required and we can re-use the APPNP object we've already created. First we create an intermediate fully connected model without the softmax layer, this is to avoid propagating the softmax layer which may cause issues with further training. We then propagate this intermediate network." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "intermediate_model = Model(\n", " inputs=fully_connected_model.inputs, outputs=fully_connected_model.layers[-2].output\n", ")\n", "\n", "x_inp, x_out = appnp.propagate_model(intermediate_model)\n", "predictions = keras.layers.Softmax()(x_out)\n", "\n", "propagated_model = keras.models.Model(inputs=x_inp, outputs=predictions)\n", "propagated_model.compile(\n", " loss=\"categorical_crossentropy\",\n", " metrics=[\"acc\"],\n", " optimizer=keras.optimizers.Adam(lr=0.01),\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our accuracy is better than the fully connected network by itself but less than end-to-end trained PPNP and APPNP. \n", "\n", "Note that this is partially because 140 data points isn't sufficient for the fully connected model to achieve optimal performance. As the number of training nodes increases the performance gap shrinks. " ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ['...']\n", "1/1 [==============================] - 0s 208ms/step - loss: 1.6038 - acc: 0.7273\n", "\n", "Test Set Metrics:\n", "\tloss: 1.6038\n", "\tacc: 0.7273\n" ] } ], "source": [ "test_metrics = propagated_model.evaluate(test_gen)\n", "print(\"\\nTest Set Metrics:\")\n", "for name, val in zip(propagated_model.metrics_names, test_metrics):\n", " print(\"\\t{}: {:0.4f}\".format(name, val))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Making predictions with the model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's get the predictions for all nodes." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "all_nodes = node_subjects.index\n", "all_gen = generator.flow(all_nodes)\n", "all_predictions = propagated_model.predict(all_gen)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These predictions will be the output of the softmax layer, so to get final categories we'll use the `inverse_transform` method of our target attribute specification to turn these values back to the original categories." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that for full-batch methods the batch size is 1 and the predictions have shape $(1, N_{nodes}, N_{classes})$ so we remove the batch dimension to obtain predictions of shape $(N_{nodes}, N_{classes})$ using the NumPy `squeeze` method." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "node_predictions = target_encoding.inverse_transform(all_predictions.squeeze())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's have a look at a few predictions after training the model:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PredictedTrue
31336Probabilistic_MethodsNeural_Networks
1061127TheoryRule_Learning
1106406Reinforcement_LearningReinforcement_Learning
13195Genetic_AlgorithmsReinforcement_Learning
37879Probabilistic_MethodsProbabilistic_Methods
1126012Genetic_AlgorithmsProbabilistic_Methods
1107140Case_BasedTheory
1102850Neural_NetworksNeural_Networks
31349Probabilistic_MethodsNeural_Networks
1106418TheoryTheory
1123188Neural_NetworksNeural_Networks
1128990Genetic_AlgorithmsGenetic_Algorithms
109323Probabilistic_MethodsProbabilistic_Methods
217139Case_BasedCase_Based
31353Probabilistic_MethodsNeural_Networks
32083Neural_NetworksNeural_Networks
1126029Neural_NetworksReinforcement_Learning
1118017Neural_NetworksNeural_Networks
49482Neural_NetworksNeural_Networks
753265Neural_NetworksNeural_Networks
\n", "
" ], "text/plain": [ " Predicted True\n", "31336 Probabilistic_Methods Neural_Networks\n", "1061127 Theory Rule_Learning\n", "1106406 Reinforcement_Learning Reinforcement_Learning\n", "13195 Genetic_Algorithms Reinforcement_Learning\n", "37879 Probabilistic_Methods Probabilistic_Methods\n", "1126012 Genetic_Algorithms Probabilistic_Methods\n", "1107140 Case_Based Theory\n", "1102850 Neural_Networks Neural_Networks\n", "31349 Probabilistic_Methods Neural_Networks\n", "1106418 Theory Theory\n", "1123188 Neural_Networks Neural_Networks\n", "1128990 Genetic_Algorithms Genetic_Algorithms\n", "109323 Probabilistic_Methods Probabilistic_Methods\n", "217139 Case_Based Case_Based\n", "31353 Probabilistic_Methods Neural_Networks\n", "32083 Neural_Networks Neural_Networks\n", "1126029 Neural_Networks Reinforcement_Learning\n", "1118017 Neural_Networks Neural_Networks\n", "49482 Neural_Networks Neural_Networks\n", "753265 Neural_Networks Neural_Networks" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame({\"Predicted\": node_predictions, \"True\": node_subjects})\n", "df.head(20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have an accurate model that can handle large graphs." ] }, { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden", "tags": [ "CloudRunner" ] }, "source": [ "
Run the latest release of this notebook:
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" } }, "nbformat": 4, "nbformat_minor": 4 }