From 44673d97c61dfc75e99cf4b0bca4bd4bc7f1e9be Mon Sep 17 00:00:00 2001 From: Klaus Reygers Date: Sun, 16 Apr 2023 15:34:52 +0200 Subject: [PATCH] added missing notebooks --- ..._trees_ex_1_compare_tree_classifiers.ipynb | 409 ++++ ...es_ex_1_sol_compare_tree_classifiers.ipynb | 484 +++++ ...ex_2_magic_xgboost_and_random_forest.ipynb | 264 +++ ..._sol_magic_xgboost_and_random_forest.ipynb | 1775 +++++++++++++++++ ...rks_ex_1_hyperparameter_optimization.ipynb | 159 ++ ...ex_1_sol_hyperparameter_optimization.ipynb | 573 ++++++ ...ural_networks_ex_2_mnist_keras_train.ipynb | 249 +++ ..._networks_ex_2_sol_mnist_keras_apply.ipynb | 182 ++ ..._networks_ex_2_sol_mnist_keras_train.ipynb | 467 +++++ 9 files changed, 4562 insertions(+) create mode 100644 notebooks/04_decision_trees_ex_1_compare_tree_classifiers.ipynb create mode 100644 notebooks/04_decision_trees_ex_1_sol_compare_tree_classifiers.ipynb create mode 100644 notebooks/04_decision_trees_ex_2_magic_xgboost_and_random_forest.ipynb create mode 100644 notebooks/04_decision_trees_ex_2_sol_magic_xgboost_and_random_forest.ipynb create mode 100644 notebooks/05_neural_networks_ex_1_hyperparameter_optimization.ipynb create mode 100644 notebooks/05_neural_networks_ex_1_sol_hyperparameter_optimization.ipynb create mode 100644 notebooks/05_neural_networks_ex_2_mnist_keras_train.ipynb create mode 100644 notebooks/05_neural_networks_ex_2_sol_mnist_keras_apply.ipynb create mode 100644 notebooks/05_neural_networks_ex_2_sol_mnist_keras_train.ipynb diff --git a/notebooks/04_decision_trees_ex_1_compare_tree_classifiers.ipynb b/notebooks/04_decision_trees_ex_1_compare_tree_classifiers.ipynb new file mode 100644 index 0000000..36af35f --- /dev/null +++ b/notebooks/04_decision_trees_ex_1_compare_tree_classifiers.ipynb @@ -0,0 +1,409 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic regression with scikit-learn: heart disease data set" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read data " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "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", + " \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", + "
agesexcptrestbpscholfbsrestecgthalachexangoldpeakslopecathaltarget
063131452331015002.30011
137121302500118703.50021
241011302040017201.42021
356111202360117800.82021
457001203540116310.62021
.............................................
29857001402410112310.21030
29945131102640113201.21030
30068101441931114103.41230
30157101301310111511.21130
30257011302360017400.01120
\n", + "

303 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " age sex cp trestbps chol fbs restecg thalach exang oldpeak \\\n", + "0 63 1 3 145 233 1 0 150 0 2.3 \n", + "1 37 1 2 130 250 0 1 187 0 3.5 \n", + "2 41 0 1 130 204 0 0 172 0 1.4 \n", + "3 56 1 1 120 236 0 1 178 0 0.8 \n", + "4 57 0 0 120 354 0 1 163 1 0.6 \n", + ".. ... ... .. ... ... ... ... ... ... ... \n", + "298 57 0 0 140 241 0 1 123 1 0.2 \n", + "299 45 1 3 110 264 0 1 132 0 1.2 \n", + "300 68 1 0 144 193 1 1 141 0 3.4 \n", + "301 57 1 0 130 131 0 1 115 1 1.2 \n", + "302 57 0 1 130 236 0 0 174 0 0.0 \n", + "\n", + " slope ca thal target \n", + "0 0 0 1 1 \n", + "1 0 0 2 1 \n", + "2 2 0 2 1 \n", + "3 2 0 2 1 \n", + "4 2 0 2 1 \n", + ".. ... .. ... ... \n", + "298 1 0 3 0 \n", + "299 1 0 3 0 \n", + "300 1 2 3 0 \n", + "301 1 1 3 0 \n", + "302 1 1 2 0 \n", + "\n", + "[303 rows x 14 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/heart.csv\"\n", + "df = pd.read_csv(filename)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "y = df['target'].values\n", + "X = df[[col for col in df.columns if col!=\"target\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, shuffle=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fit the model" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "lr = LogisticRegression(penalty='none', fit_intercept=True, max_iter=5000, tol=1E-5)\n", + "rf = RandomForestClassifier(max_depth=3)\n", + "ab = AdaBoostClassifier()\n", + "gb = GradientBoostingClassifier()\n", + "\n", + "classifiers = [lr, rf, ab, gb]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LogisticRegression\n", + "RandomForestClassifier\n", + "AdaBoostClassifier\n", + "GradientBoostingClassifier\n" + ] + } + ], + "source": [ + "for clf in classifiers:\n", + " print(clf.__class__.__name__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train models and compare ROC curves" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "### Your code here ###" + ] + } + ], + "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.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/04_decision_trees_ex_1_sol_compare_tree_classifiers.ipynb b/notebooks/04_decision_trees_ex_1_sol_compare_tree_classifiers.ipynb new file mode 100644 index 0000000..aee4ae9 --- /dev/null +++ b/notebooks/04_decision_trees_ex_1_sol_compare_tree_classifiers.ipynb @@ -0,0 +1,484 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic regression with scikit-learn: heart disease data set" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read data " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "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", + " \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", + "
agesexcptrestbpscholfbsrestecgthalachexangoldpeakslopecathaltarget
063131452331015002.30011
137121302500118703.50021
241011302040017201.42021
356111202360117800.82021
457001203540116310.62021
.............................................
29857001402410112310.21030
29945131102640113201.21030
30068101441931114103.41230
30157101301310111511.21130
30257011302360017400.01120
\n", + "

303 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " age sex cp trestbps chol fbs restecg thalach exang oldpeak \\\n", + "0 63 1 3 145 233 1 0 150 0 2.3 \n", + "1 37 1 2 130 250 0 1 187 0 3.5 \n", + "2 41 0 1 130 204 0 0 172 0 1.4 \n", + "3 56 1 1 120 236 0 1 178 0 0.8 \n", + "4 57 0 0 120 354 0 1 163 1 0.6 \n", + ".. ... ... .. ... ... ... ... ... ... ... \n", + "298 57 0 0 140 241 0 1 123 1 0.2 \n", + "299 45 1 3 110 264 0 1 132 0 1.2 \n", + "300 68 1 0 144 193 1 1 141 0 3.4 \n", + "301 57 1 0 130 131 0 1 115 1 1.2 \n", + "302 57 0 1 130 236 0 0 174 0 0.0 \n", + "\n", + " slope ca thal target \n", + "0 0 0 1 1 \n", + "1 0 0 2 1 \n", + "2 2 0 2 1 \n", + "3 2 0 2 1 \n", + "4 2 0 2 1 \n", + ".. ... .. ... ... \n", + "298 1 0 3 0 \n", + "299 1 0 3 0 \n", + "300 1 2 3 0 \n", + "301 1 1 3 0 \n", + "302 1 1 2 0 \n", + "\n", + "[303 rows x 14 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/heart.csv\"\n", + "df = pd.read_csv(filename)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "y = df['target'].values\n", + "X = df[[col for col in df.columns if col!=\"target\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, shuffle=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fit the model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "lr = LogisticRegression(penalty='none', fit_intercept=True, max_iter=5000, tol=1E-5)\n", + "rf = RandomForestClassifier(max_depth=3)\n", + "ab = AdaBoostClassifier()\n", + "gb = GradientBoostingClassifier()\n", + "\n", + "classifiers = [lr, rf, ab, gb]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# train models\n", + "for clf in classifiers:\n", + " clf.fit(X_train, y_train)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Compare two classifiers using the ROC curve" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LogisticRegression AUC = 0.8872549019607843\n", + "RandomForestClassifier AUC = 0.9033613445378151\n", + "AdaBoostClassifier AUC = 0.8300070028011205\n", + "GradientBoostingClassifier AUC = 0.8940826330532212\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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Jxfp+X744QccHR1JTk7mv//9r5Ebe9KkSUV63pwsW7aMxo0b06dPH7P9SUlJdO3alYMHDzJmzBhjddvIyEgmT55MUlISL730UrG3F0xLt0dGRtKgQQNj35IlS9i0aROffvop3t7e1K5dm5SUFCMzoBClTUkGjZwW2M9xISyl1FNAINAhp+Na62XAMjCtPVVYDSztVq5cibOzM40bN2blypVFHjRatGhhJF4KCgri4MGDrF+/vkSCRm4mT57M//73P3755RcaN25s7O/SpQthYWFGPu+SYG9vn23ByKNHj1K/fn0ef/xxs/0+Pnd/U52UlGS2ErEQhaEku6digBqZtn2A2KyFlFJdgNeB3lrron9ypYxIS0tj9erV9O7d28id8Ntvv5mV2b17N82aNcPBwYGAgAB++umnbPVs2bLFyDnt4uJirNpqiYoVK3L79m2zfZcvX2bYsGG4ubnh5OREUFBQttSfaWlpTJs2jZo1a2Jvb0+jRo344osvzMocOnSI7t274+rqirOzMw888ACLFi0CTAFr//79/Oc//zG6zJYvX05iYiJLly7l2WefNQsYGVxdXWnTpk2un+e1116jSZMmVKhQAR8fH5588kni4uLMymzcuJGAgACcnZ2pUqUKrVq1Mktu9fHHH9OoUSMcHR1xd3enQ4cORmKorN1Tfn5+fPzxxxw4cMD4HECO3VNXr15l1KhReHp64uDgQJs2bfjll1/MyiileOeddxgzZgweHh7FksNE3H9K8k5jL1BXKVULOA8MAgZnLqCUehBYCnTXWsdnr+L+9cMPP3Dx4kUGDRpEu3btGD16NCtXrjTSssbGxtKjRw9atmzJmjVriI2N5cknnzRLpARw6tQpevXqxfjx47GxsWHbtm306NGD3bt307ZtW7OyaWlppKamkpKSwu7du1m1ahWvvPKKWZk+ffpw/Phx5s6di7u7O3PmzKFjx44cOHDAyPs9ZcoU3n77baZOnUqLFi1Yu3YtTz75JEopnnjiCQB69+5NgwYN+Oyzz7C3t+fYsWMkJCQAsHjxYh5//HH8/f2NLrLatWuzf/9+bt68Sffu3a26pvHx8UyaNInq1atz6dIl5s2bR6dOnTh48CDlypXjxIkT9OvXj5deeok5c+aQnJzM/v37jSx6u3fv5tlnn2XGjBk8/PDDJCQkEBkZyfXr13M837p165g8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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from sklearn.metrics import roc_curve, roc_auc_score\n", + "\n", + "for clf in classifiers:\n", + " \n", + " y_pred_prob = clf.predict_proba(X_test) # predicted probabilities\n", + " fpr_lr, tpr_lr, _ = roc_curve(y_test, y_pred_prob[:,1])\n", + " plt.plot(tpr_lr, 1-fpr_lr, label=clf.__class__.__name__)\n", + " auc = roc_auc_score(y_test, y_pred_prob[:,1])\n", + " print(clf.__class__.__name__, f'AUC = {auc}')\n", + "\n", + "plt.xlabel('Recall', fontsize=18)\n", + "plt.ylabel('Precision', fontsize=18);\n", + "plt.legend(fontsize=15)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bonus: Check if the performance differences are just statistical fluctuations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aucs = {}\n", + "for clf in classifiers:\n", + " aucs[clf.__class__.__name__] = []\n", + "\n", + "# reshuffle the data 1000 times, train classifiers and save AUCs\n", + "for i in range(1000):\n", + " X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, shuffle=True)\n", + " for clf in classifiers:\n", + " clf.fit(X_train, y_train)\n", + " y_pred_prob = clf.predict_proba(X_test)\n", + " auc = roc_auc_score(y_test, y_pred_prob[:,1])\n", + " aucs[clf.__class__.__name__].append(auc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for clf in classifiers:\n", + " clfname = clf.__class__.__name__\n", + " plt.hist(aucs[clfname], bins=40, range=(0.7, 1), \n", + " histtype='step', linewidth=2, label=clfname);\n", + "plt.legend(loc='upper left')" + ] + } + ], + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/04_decision_trees_ex_2_magic_xgboost_and_random_forest.ipynb b/notebooks/04_decision_trees_ex_2_magic_xgboost_and_random_forest.ipynb new file mode 100644 index 0000000..2e955d0 --- /dev/null +++ b/notebooks/04_decision_trees_ex_2_magic_xgboost_and_random_forest.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hands-on: Separation of gamma and hadron showers measured with the MAGIC Cherenkov telescope using a boosted decision tree and a random forest" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The [MAGIC telescope](https://en.wikipedia.org/wiki/MAGIC_(telescope) is a Cherenkov telescope situated on La Palma, one of the Canary Islands. The [MAGIC machine learning dataset](https://archive.ics.uci.edu/ml/datasets/magic+gamma+telescope) can be obtained from [UC Irvine Machine Learning Repository](https://archive.ics.uci.edu/ml/index.php).\n", + "\n", + "Our task is to separate signal events (gamma showers) and background events (hadron showers) based on the features of a measured Cherenkov shower.\n", + "\n", + "The features of a shower are:\n", + "\n", + " 1. fLength: continuous # major axis of ellipse [mm]\n", + " 2. fWidth: continuous # minor axis of ellipse [mm] \n", + " 3. fSize: continuous # 10-log of sum of content of all pixels [in #phot]\n", + " 4. fConc: continuous # ratio of sum of two highest pixels over fSize [ratio]\n", + " 5. fConc1: continuous # ratio of highest pixel over fSize [ratio]\n", + " 6. fAsym: continuous # distance from highest pixel to center, projected onto major axis [mm]\n", + " 7. fM3Long: continuous # 3rd root of third moment along major axis [mm] \n", + " 8. fM3Trans: continuous # 3rd root of third moment along minor axis [mm]\n", + " 9. fAlpha: continuous # angle of major axis with vector to origin [deg]\n", + " 10. fDist: continuous # distance from origin to center of ellipse [mm]\n", + " 11. class: g,h # gamma (signal), hadron (background)\n", + "\n", + "g = gamma (signal): 12332\n", + "h = hadron (background): 6688\n", + "\n", + "For technical reasons, the number of h events is underestimated.\n", + "In the real data, the h class represents the majority of the events." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# read data\n", + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/magic04_data.txt\"\n", + "df = pd.read_csv(filename, engine='python')\n", + "\n", + "# relabel: gamma shower (g) --> 1 (signal), hadron shower (h) --> 0 (background) \n", + "df['class'] = df['class'].map({'g': 1, 'h': 0})" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# y = value to predict, X = features\n", + "y = df['class'].values\n", + "X = df[[col for col in df.columns if col!=\"class\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# generate training and test samples\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will use [XGBoost](https://xgboost.readthedocs.io/en/latest/). The training will take a few seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# train XGBoost boosted decision tree\n", + "import xgboost as xgb\n", + "import time\n", + "XGBclassifier = xgb.sklearn.XGBClassifier(nthread=-1, seed=1, n_estimators=1000)\n", + "start_time = time.time()\n", + "XGBclassifier.fit(X_train, y_train)\n", + "run_time = time.time() - start_time" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# predect labels for the test sample\n", + "y_pred_xgb = XGBclassifier.predict(X_test) # 0 or 1\n", + "y_pred_xgb_prob = XGBclassifier.predict_proba(X_test) # probabilities" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model Accuracy: 89.54%\n", + "AUC score: 0.87\n", + "Run time: 34.36 sec\n", + "\n", + "\n" + ] + } + ], + "source": [ + "# print some performance parameters\n", + "from sklearn.metrics import roc_auc_score\n", + "print(\"Model Accuracy: {:.2f}%\".format(100*XGBclassifier.score(X_test, y_test)))\n", + "print(\"AUC score: {:.2f}\".format(roc_auc_score(y_test,y_pred_xgb)))\n", + "print(\"Run time: {:.2f} sec\\n\\n\".format(run_time))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "a) Plot predicted probabilities for the test sample for signal and background events" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# your code here" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# plot signal efficiency vs. background efficiency\n", + "# we want the signal efficiency to be large and the background efficiency to be small\n", + "\n", + "from sklearn.metrics import roc_curve\n", + "\n", + "fpr_xgb, tpr_xgb, _ = roc_curve(y_test, y_pred_xgb_prob[:,1])\n", + "plt.plot(fpr_xgb, tpr_xgb)\n", + "plt.xscale(\"log\")\n", + "plt.xlabel('Background efficiency', fontsize=18)\n", + "plt.ylabel('Signal efficiency', fontsize=18);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "b) Which is the most important feature for discriminating signal and background according to XGBoost? Hint: use plot_impartance from XGBoost (see [XGBoost plotting API](https://xgboost.readthedocs.io/en/latest/python/python_api.html#module-xgboost.plotting)). Do you get the same answer for all three performance measures provided by XGBoost (“weight”, “gain”, or “cover”)?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# your code here (one line)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "c) Visualize one decision tree from the ensemble (let's say tree number 10). For this you need the the graphviz package (`pip3 install graphviz`)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# your code here (one line)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "d) Compare the performance of XGBoost with the [**random forest classifier**](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html) from [**scikit learn**](https://scikit-learn.org/stable/index.html). Plot signal and background efficiency for both classifiers in one plot. Which classifier performs better?" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "RFclassifier = RandomForestClassifier(random_state=0)\n", + "\n", + "# your code here\n" + ] + } + ], + "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.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/04_decision_trees_ex_2_sol_magic_xgboost_and_random_forest.ipynb b/notebooks/04_decision_trees_ex_2_sol_magic_xgboost_and_random_forest.ipynb new file mode 100644 index 0000000..1901b07 --- /dev/null +++ b/notebooks/04_decision_trees_ex_2_sol_magic_xgboost_and_random_forest.ipynb @@ -0,0 +1,1775 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hands-on: Separation of gamma and hadron showers measured with the MAGIC Cherenkov telescope using a boosted decision tree and a random forest" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The [MAGIC telescope](https://en.wikipedia.org/wiki/MAGIC_(telescope) is a Cherenkov telescope situated on La Palma, one of the Canary Islands. The [MAGIC machine learning dataset](https://archive.ics.uci.edu/ml/datasets/magic+gamma+telescope) can be obtained from [UC Irvine Machine Learning Repository](https://archive.ics.uci.edu/ml/index.php).\n", + "\n", + "Our task is to separate signal events (gamma showers) and background events (hadron showers) based on the features of a measured Cherenkov shower.\n", + "\n", + "The features of a shower are:\n", + "\n", + " 1. fLength: continuous # major axis of ellipse [mm]\n", + " 2. fWidth: continuous # minor axis of ellipse [mm] \n", + " 3. fSize: continuous # 10-log of sum of content of all pixels [in #phot]\n", + " 4. fConc: continuous # ratio of sum of two highest pixels over fSize [ratio]\n", + " 5. fConc1: continuous # ratio of highest pixel over fSize [ratio]\n", + " 6. fAsym: continuous # distance from highest pixel to center, projected onto major axis [mm]\n", + " 7. fM3Long: continuous # 3rd root of third moment along major axis [mm] \n", + " 8. fM3Trans: continuous # 3rd root of third moment along minor axis [mm]\n", + " 9. fAlpha: continuous # angle of major axis with vector to origin [deg]\n", + " 10. fDist: continuous # distance from origin to center of ellipse [mm]\n", + " 11. class: g,h # gamma (signal), hadron (background)\n", + "\n", + "g = gamma (signal): 12332\n", + "h = hadron (background): 6688\n", + "\n", + "For technical reasons, the number of h events is underestimated.\n", + "In the real data, the h class represents the majority of the events." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# read data\n", + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/magic04_data.txt\"\n", + "df = pd.read_csv(filename, engine='python')\n", + "\n", + "# relabel: gamma shower (g) --> 1 (signal), hadron shower (h) --> 0 (background) \n", + "df['class'] = df['class'].map({'g': 1, 'h': 0})" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# y = value to predict, X = features\n", + "y = df['class'].values\n", + "X = df[[col for col in df.columns if col!=\"class\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# generate training and test samples\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will use [XGBoost](https://xgboost.readthedocs.io/en/latest/). The training will take a few seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# train XGBoost boosted decision tree\n", + "import xgboost as xgb\n", + "import time\n", + "XGBclassifier = xgb.sklearn.XGBClassifier(nthread=-1, seed=1, n_estimators=1000)\n", + "start_time = time.time()\n", + "XGBclassifier.fit(X_train, y_train)\n", + "run_time = time.time() - start_time" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# predect labels for the test sample\n", + "y_pred_xgb = XGBclassifier.predict(X_test) # 0 or 1\n", + "y_pred_xgb_prob = XGBclassifier.predict_proba(X_test) # probabilities" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model Accuracy: 88.96%\n", + "AUC score: 0.87\n", + "Run time: 52.90 sec\n", + "\n", + "\n" + ] + } + ], + "source": [ + "# print some performance parameters\n", + "from sklearn.metrics import roc_auc_score\n", + "print(\"Model Accuracy: {:.2f}%\".format(100*XGBclassifier.score(X_test, y_test)))\n", + "print(\"AUC score: {:.2f}\".format(roc_auc_score(y_test,y_pred_xgb)))\n", + "print(\"Run time: {:.2f} sec\\n\\n\".format(run_time))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "a) Plot predicted probabilities for the test sample for signal and background events" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAESCAYAAAAG+ZUXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAvSklEQVR4nO3deZwU1bn/8c8DDDvIvgjIoiyKGoVBUIkXQRBFQLgquIJoEBR+iTtuFzBumBDNjYqCV1BxGRARYsCIuBuJohgBCQTZBNnd2YTh+f1RNW3PTA/TMz0LFN/369Wv6Tp1quo5Pd1PV5+uPsfcHRERiZYypR2AiIgUPSV3EZEIUnIXEYkgJXcRkQhSchcRiSAldxGRCMo3uZtZEzN7y8y+MLOlZvbbsLyWmc0zs/+Ef2uG5WZm/2tmK83sczNrV9yNEBGR7JI5c98H3OjuxwGdgOvM7DhgFDDf3VsC88NlgHOAluFtKDChyKMWEZEDyje5u/tGd/80vP8jsAxoBPQFng6rPQ2cH97vCzzjgQVADTNrWNSBi4hI3soVpLKZNQNOBv4J1Hf3jeGqTUD98H4j4Ku4zdaHZRvjyjCzoQRn9lSpUqV9mzZtChr7L3Zu++V+5TqF34+ISAnY8N2u2P1GNSoVej+ffPLJNnevm2hd0sndzKoCM4DfufsPZhZb5+5uZgUax8DdJwITAdLT033hwoUF2Ty7hZN/uZ9+ZeH3IyJSAm57eXHs/v39Tyj0fsxsbV7rkrpaxszSCBL7c+7+cli8Oau7Jfy7JSzfADSJ27xxWCYiIiUkmatlDPg/YJm7/ylu1WxgUHh/EDArrvyK8KqZTsD3cd03IiJSApLpljkduBxYbGafhWW3Aw8A08zsKmAtcFG4bg5wLrAS2Amon0REpITlm9zd/X3A8ljdLUF9B65LMS4REUmBfqEqIhJBSu4iIhFUoOvcpeT88MMPbNmyhb1795Z2KCKlLi0tjXr16lG9evXSDuWQoeR+EPrhhx/YvHkzjRo1olKlSsT/pkDkcOPu7Nq1iw0bgiuqleCTo26Zg9CWLVto1KgRlStXVmKXw56ZUblyZRo1asSWLVvy30AAJfeD0t69e6lUqfA/SRaJokqVKqmbsgCU3A9SOmMXyU6viYJRchcRiSAldxGRCNLVMoeQ+JHkSlIqo9blpUuXLtSpU4eXXnqpyPedLDPjL3/5CyNGjCi1GArq559/5r777uP888/npJNOKu1w5CCm5C6l4rHHHiMtLa20wzjk/Pzzz4wdO5ZmzZopucsBKblLqTjuuONKOwSRSFOfuxSLpUuX0rNnT2rVqkWVKlU49thjefTRR2Pru3TpwgUXXJBtm+nTp9OyZUsqVarEmWeeyaJFizAzpkyZEqvTrFkzbrrpJh566CEaN25MzZo1GThwIN99912szo4dOxgxYgStW7emcuXKNG/enOuuu44ffvihwO3Yv38/DzzwAMcccwwVKlSgVatWPP3007H1Y8aMoUGDBuzfvz/bdn/7298wM1auXBkre/LJJ2nbti0VKlSgadOmPPjgg9m2GTx4MOnp6cybN48TTzyRKlWq0LlzZ5YuXRqrU61aNQCuvPJKzAwzY82aNQDcf//9HHPMMVSsWJH69evTs2dPNm3aVOA2SzQouUux6N27N2XLlmXq1KnMnj2bkSNH8uOPP+ZZf+HChQwcOJB27doxc+ZM+vTpw4ABAxLWnTZtGvPnz2fixImMGzeOV199ldtvvz22fufOnWRmZnLvvfcyd+5cfv/73/Pmm29y4YUXFrgdI0eO5J577mHo0KH87W9/o1+/fgwZMoRXX30VgAEDBrB582beeeedbNtlZGTQvn17jjnmGAD+8Ic/MHz4cM4//3xeffVVhg8fzl133cUjjzySbbt169Zx8803c8cdd/DCCy+wZcsWBgwYQDDYKrz55psA3HnnnXz44Yd8+OGHNGzYkGeeeYb77ruPG264gb///e9MmDCBY445hh07dhS4zRIN6paRIrdt2zZWr17NrFmzOOGE4MvYbt1yjQ6dzbhx4zj22GN58cUXMTN69uzJ3r17ufXWW3PVTUtL45VXXqFcueDp+8UXX/Diiy/y2GOPAVC3bl0mTJgQq79v3z6aN29O586dWbduHUcddVRS7Vi5ciUTJkxg8uTJDBoUzEtz1llnsXHjRsaOHct5553Hsccey4knnkhGRgZnnnkmAHv27GHWrFncddddQDCcxNixY7nzzjsZPXo0AN27d2fnzp3cc889DB8+nLJlywLwzTff8MEHH9CyZUsg+OTQr18/li9fTps2bejQoQMARx99NJ06dYrF+tFHH9GjRw+uvfbaWFn//v2TaqdEk87cpcjVqlWLJk2aMGzYMDIyMpL6yfjHH39M7969s/1QpU+fPgnrnnnmmbHEDkH/fc5B1p599llOPvlkqlatSlpaGp07dwZgxYoVSbdj/vz5lClThn79+rFv377YrVu3bnz22WdkZmYCwdn7jBkz2LdvHwBz587lxx9/5KKLgvlrPvzwQ3bs2MGFF16YbT9du3Zl8+bNrF+/PnbMZs2axRJ7VtuAbHUSOemkk5gzZw6jR4/mo48+isUmhy8ldylyZcqU4fXXX6dBgwYMGTKEBg0a8Otf/5pFixbluc2mTZuoWzf7JO45l7PUqFEj23L58uVxd/bs2QPAzJkzueKKKzj11FOZPn06CxYsYObMmQDs3r076XZs27aNzMxMjjjiCNLS0mK3wYMHs2/fPjZuDGaPHDBgANu2bYt1mWRkZHDqqafGPiFs27YNgLZt22bbT9aZ/ldffXXAtiUT95AhQ7jvvvuYNm0aHTt2pH79+tx5551K8ocxdctIsWjTpg0zZsxg7969vPfee9x666306tWL9evXU6ZM7nOKBg0asHXr1mxlOZeTNX36dDp27BjrpgFy9Ykno1atWpQrV44PPvggYcz16tUDgi6S9PR0MjIy6Ny5M3/961+57777su0H4NVXX6V+/fq59tO6desCx5ZTmTJluP7667n++uv56quveO6557jjjjto3Lgxw4YNS3n/cujJN7mb2VPAecAWdz8+LMsAsp6RNYDv3P0kM2sGLAOWh+sWuLueWYextLQ0unbtyg033MAll1zCd999F0t28Tp06BBLilldM7Nnzy7UMXft2kWFChWylT333HMF3k/Xrl3JzMzk+++/p3v37gesO3DgQO699166du3Krl27sn15e+qpp1KpUiW+/vprevXqVeA44iVzJt+kSRNGjRrF5MmT+eKLL1I6nhy6kjlznwI8AjyTVeDuscsYzGw88H1c/S/d/aQiik8OQZ9//jk33XQTAwYMoEWLFnz77beMGzeOX/3qVwkTO8Ctt95Kx44dGThwIFdeeSXLli1j0qRJAAnPmg+ke/fuXHfdddx777107NiROXPmMH/+/AK3o3Xr1gwbNoyBAwdyyy23kJ6ezu7du1m6dCkrVqzgySefjNW96KKLuPnmm7n55ps544wzaNiwYWxdjRo1GDNmDL/97W9Zu3YtZ5xxBvv372fFihW89dZbsS6jZJQvX57mzZszbdo0jj/+eCpWrMiJJ57IyJEjqVWrFp06deKII47grbfe4j//+Q/jxo0rcLslGpKZIPvd8Iw8FwtOsS4CuhZxXJJAcQwDUBwaNGhA/fr1uffee/n666+pUaMGZ5555gETTXp6Oi+88AK33347s2bNIj09nQkTJtC9e/cCT85wzTXXsGrVKv785z+ze/duunfvzvPPP5/t6pJkPfroo7Rq1YpJkybxP//zP1SvXp3jjjuOq666Klu9Jk2acNppp/HBBx/EroiJd8stt3DkkUfy0EMPMX78eCpWrEirVq3yvNzzQB5//HFuuukmzjrrLPbs2cPq1as59dRTmTRpEk888QS7d+/mmGOOYdKkSZx//vkF3r9Eg2VdP3vASkFyfzWrWyau/AzgT+6eHldvKbAC+AG4093fy2//6enpvnDhwgIHH7NwctzOriz8fg4Sy5Yt49hjjy3tMErd1KlTufzyy1m1ahXNmzcv7XDkIBCV10b8OFGpnLSZ2SdZ+TenVL9QvRh4IW55I3CUu283s/bAK2bW1t1z/TTQzIYCQ4GkrzuWaBs+fDjdu3enZs2afPrpp9xzzz306tVLiV2kEAqd3M2sHNAfaJ9V5u57gD3h/U/M7EugFZDrtNzdJwITIThzL2wcEh3bt2/n2muvZfv27dSuXZsBAwbk+om+iCQnlTP3s4B/u3vs1xVmVhf4xt0zzawF0BJYlWKMcpiYNm1aaYcgEhn5XoZgZi8AHwKtzWy9mWV9kzSQ7F0yAGcAn5vZZ8BLwDB3/6YI4xURkSQkc7XMxXmUD05QNgOYkXpYIiKSCg0/ICISQUruIiIRpOQuIhJBSu4iIhGk5C7FImvKuJIwZswY6tSpUyLHKk2PPPJItvHuDxWvv/46Dz/8cGmHcdjRkL+HkvhhFkpSBIZ0kNLz+uuv89JLL/G73/2utEM5rOjMXeQAdu3aVdohiBSKkrsUq1deeYU2bdpQsWJFOnfunGt88fHjx9OhQweOOOII6tevT+/evVm5cmWu/cycOZNTTjmFSpUqUbt2bc4991zWrl2b8JjuzsiRI6lZsyb//Oc/Y2V33XUX9erVo3r16gwZMiQ2X+uaNWsAWLNmDWbGc889xxVXXEGNGjXo3bs3AKtXr+b888+nevXqVKtWLVecWdtmTZydJWf3VFYX0qJFi+jUqROVK1fm5JNP5r33so+vt2fPHkaMGEGNGjWoVasW119/fbZpBA9kyZIl9OrVi2rVqlGtWjUuvPBCNm3aBMCOHTuoUqUKjz76aK7tOnTowGWXXRZbXrduHQMHDqRWrVpUrlyZs88+m+XLl8fWZ7V52rRpXHPNNRxxxBE0btyY0aNHs3///lh7x48fz9q1azEzzIzBgwcDsHTpUnr27EmtWrWoUqUKxx57bMK4pHCU3KXYrF27lhtuuIG77rqL559/nu+//56zzz4720QT69evZ8SIEcyaNYtJkyaRmZnJaaedxvff/zJFwLPPPkv//v05+uijmTZtGpMnT6ZVq1YJZ2rav38/Q4cO5cUXX+TNN9+kY8eOADz88MPcd999DBs2jJdeeolKlSpxyy23JIz7pptuolq1akyfPp3bb7+dPXv20K1bt9gY81OmTGH16tX813/9F998U/AfYO/cuZNBgwZxzTXXMGPGDCpUqED//v3ZuXNnrM6oUaN48sknueuuu3juuedYu3Yt48ePz3ffK1eu5PTTT2f37t1MnTqVKVOmsHTpUnr37o27U6VKFc4777xcQz2sWrWKhQsXMnDgQCCYqLtz584sX76cxx9/nGnTprFjxw7OOuusXJ9mbrnlFqpWrcpLL73EZZddxt13381LL70EwNVXX80ll1xCgwYN+PDDD/nwww9jE4f37t2bsmXLMnXqVGbPns3IkSP58ccfC/x4SmLqc5dis23bNmbNmsVpp50GQPv27Tn66KOZMmVKbOq3hx56KFY/MzOT7t27U69ePWbNmsUVV1zB/v37GTVqFP369eOFF34Z7SLR5NmZmZkMHjyYN954g7fffpu2bdvGyh988EGGDRvG3XffDUCPHj1YvXp1tvlLs3Tq1CnbGeTjjz/OunXrWLFiBS1atACgY8eOtGjRgieeeILbbrutQI/Lrl27ePjhh+naNZgGoWHDhpx88sm8++679OzZk+3bt/P4448zduxYbrzxRgDOPvvs2GTZBzJ27FgaNGjA3LlzY7M2nXjiibRp04Y5c+bQq1cvBg4cyAUXXMDXX3/NkUceCQTzvtasWZOzzz4bCP4vO3bs4LPPPotNsHL66afTrFkznnrqKa677rrYMc8444zYG0/37t157bXXePnll7noooto3LgxDRs2pEKFCtnG09+2bRurV69m1qxZnHBCMORtt27dCvQ4yoHpzF2KTb169WKJHaBp06a0b9+ejz76KFa2YMECunfvTu3atSlXrhyVK1fmp59+YsWKFQAsX76cr7/+miuvPPCXupmZmQwcOJC3336bd955J5bYIZiAetOmTbneEBK9QQC5psL76KOPaNeuXSyxAzRu3JjTTz+d999/P59HIbfy5cvTpUuX2HJW0l6/PhiDb/HixezevZu+ffvG6pQpUybbcl7eeOMN+vXrR5kyZdi3bx/79u2jefPmNGvWjKw5E8455xyqVq3K9OnTY9tlZGTQr18/0tLSYvvJmiglaz/VqlWjffv25Jx7oUePHtmWjzvuuFhb8lKrVi2aNGnCsGHDyMjIYMuWLfm2TQpGyV2KTdYE0jnLNm7cCAR9uj169MDdeeKJJ/jggw/4+OOPqVevXqzrZvv27QDZpq1LZOfOncydO5euXbvSqlWrbOuy+pvr1q2brTzncpack1hv3Lgx4cTW9evXL1S3TLVq1bJNHZhzXtSseHM+fokez5y2bdvGuHHjSEtLy3ZbtWpV7FNKxYoV6du3LxkZGUDwBvqvf/0r1iWTtZ+MjIxc+3nrrbdyfdqpUaNGtuXy5csfcI5XCN6sXn/9dRo0aMCQIUNo0KABv/71r1m0aFG+bZTkqFtGik2is7EtW7bEzqpfe+01du7cyaxZs6hSpQoA+/bty5Ywa9euDRB7Q8hLtWrVyMjIoFevXjRs2JAHHnggtq5BgwYAufroE/XZA7muJW/YsCFLly7NVW/z5s2xLouKFSsC8PPPP2er8+233x4w7kSy4t2yZUu2OWeTObutVasW/fr14+qrr861Lv63AAMGDKB3796sW7eOjIwM6tatG+smytpPnz59Yv3j8apVq1ag9uSlTZs2zJgxg7179/Lee+9x66230qtXL9avX1/geXMlNz2CUmy2bNnCP/7xj9jyunXr+PTTTznllFOAoO+5TJkylCv3yznGtGnT2LdvX2y5devWNGrUiKeffjrf43Xr1o3p06czfvx47r333lh5kyZNaNCgAbNmzcpWf/bs2Um1o2PHjnzyySesXr06VrZhwwb+8Y9/0LlzZyA4q05LS2PZsmWxOj/99FO29ifrhBNOoGLFitni3b9/f674E+nWrRtLly6lffv2pKenZ7s1a9YsVq9Hjx7UqFGDadOmkZGRwQUXXEDZsmVz7adt27a59tO6desCtSe/M/m0tDS6du3KDTfcwMaNG/nuu+8KtH9JTGfuUmzq1KnDZZddxj333EOlSpUYPXo09erVi10K17VrVzIzM7nyyiu56qqrWLp0KX/84x+zfcwvU6YMDz74IJdeeimXXnopF198MWbGm2++ycUXX5zrV7C9e/fm2Wef5dJLL6V69eqMHDmSsmXLcvPNN3PzzTdTt25dTj/9dGbPns3ixYtjxziQwYMHM27cOM455xzuvvtuypYty9ixY6lTpw7XXHNNbB99+/bloYceomnTptSoUYPx48dTqVKlAj9utWvXZujQoYwePZpy5crRtm1bJk2axE8//ZTvtmPGjOGUU06hV69eDBkyhDp16rBhwwbmzZvH4MGDY339aWlp9O/fnz/96U9s3LiRxx57LNt+brjhBqZOnUrXrl0ZOXIkjRo1YvPmzbzzzjt07tyZiy9OOBJ4Qm3atGHz5s1MmTKF448/njp16vDDDz9w0003MWDAAFq0aMG3337LuHHj+NWvfpXt04qkwN1L/da+fXtPycdP/XKLgC+++KK0Q0jZoEGDvH379j5jxgxv2bKlly9f3k877TRfvHhxtnrPPPOMt2jRwitWrOgdO3b0BQsWeNOmTf3GG2/MVm/GjBnerl07r1ChgteqVcvPPfdcX7Nmjbu7jx492mvXrp2t/pNPPullypTxyZMnu7v7/v37/Y477vA6dep41apV/ZJLLvHHHnvMAf/222/d3X316tUO+F//+tdc7fnyyy+9b9++XrVqVa9SpYr36tXLV6xYka3Opk2bvE+fPl6tWjU/6qij/Iknnog9DlkSxeruDvhf/vKX2PLu3bt9+PDhXr16da9Ro4aPGDHCx48f78FL9sCWLVvm//3f/+01a9b0ihUr+tFHH+1Dhw71r776Klu9efPmOeBHHnmkZ2Zm5trPhg0bfPDgwV6vXj0vX768N23a1C+99FJfsmTJAR+vnG3etWuXDx482OvWreuADxo0yDdv3uyXXXaZN2/e3CtUqOD169f3gQMH+tq1aw/Ytii8NtzdR834PHZLBbDQ88irFqwvXenp6Z7zG/gCif9ZfgR+Kh+VGd4PdldffTXz5s3L88dQcvCJymvjtpcXx+7f3/+EQu/HzD5x94SDOKlbRg4LS5YsISMjg9NOO40yZcowd+5cJk+ezLhx40o7NJFioeQuh4UqVarw/vvv88gjj7Bjxw6aNm3K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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# plot predicted probabilities for the test sample for signal and background events\n", + "y_pred_xgb_prob_signal = y_pred_xgb_prob[:,1][y_test == 1]\n", + "y_pred_xgb_prob_backgr = y_pred_xgb_prob[:,1][y_test == 0]\n", + "plt.hist(y_pred_xgb_prob_signal, bins=100, alpha = 0.6, label='signal events'); \n", + "plt.hist(y_pred_xgb_prob_backgr, bins=100, alpha = 0.4, label='background events');\n", + "plt.ylim(0.,200.)\n", + "plt.xlabel(\"signal probability\", fontsize=18)\n", + "plt.legend(fontsize=15, loc='upper center')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# plot signal efficiency vs. background efficiency\n", + "# we want the signal efficiency to be large and the background efficiency to be small\n", + "\n", + "from sklearn.metrics import roc_curve\n", + "\n", + "fpr_xgb, tpr_xgb, _ = roc_curve(y_test, y_pred_xgb_prob[:,1])\n", + "plt.plot(fpr_xgb, tpr_xgb)\n", + "plt.xscale(\"log\")\n", + "plt.xlabel('Background efficiency', fontsize=18)\n", + "plt.ylabel('Signal efficiency', fontsize=18);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "b) Which is the most important feature for discriminating signal and background according to XGBoost? Hint: use plot_impartance from XGBoost (see [XGBoost plotting API](https://xgboost.readthedocs.io/en/latest/python/python_api.html#module-xgboost.plotting)). Do you get the same answer for all three performance measures provided by XGBoost (“weight”, “gain”, or “cover”)?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# your code here\n", + "xgb.plot_importance(XGBclassifier, ax=plt.gca(), importance_type='gain')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "c) Visualize one decision tree from the ensemble (let's say tree number 10). For this you need the the graphviz package (`pip3 install graphviz`)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "fAlpha<20.2574501\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "fLength<119.545746\n", + "\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "fLength<44.3692017\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "fM3Long<-67.6429977\n", + "\n", + "\n", + "\n", + "1->3\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "fM3Long<-84.5366974\n", + "\n", + "\n", + "\n", + "1->4\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "fSize<2.45499992\n", + "\n", + "\n", + "\n", + "2->5\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "fLength<71.4515533\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "fAlpha<8.23324966\n", + "\n", + "\n", + "\n", + "3->7\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "fConc<0.38865\n", + "\n", + "\n", + "\n", + "3->8\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "9\n", + "\n", + "fSize<2.64485002\n", + "\n", + "\n", + "\n", + "4->9\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "10\n", + "\n", + "fAlpha<7.21029997\n", + "\n", + "\n", + "\n", + "4->10\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "15\n", + "\n", + "fWidth<42.7031021\n", + "\n", + "\n", + "\n", + "7->15\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "16\n", + "\n", + "fSize<2.62395\n", + "\n", + "\n", + "\n", + "7->16\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "17\n", + "\n", + "fWidth<11.46035\n", + "\n", + "\n", + "\n", + "8->17\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "18\n", + "\n", + "fSize<2.61910009\n", + "\n", + "\n", + "\n", + "8->18\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "31\n", + "\n", + "fDist<203.910492\n", + "\n", + "\n", + "\n", + "15->31\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "32\n", + "\n", + "leaf=-0.358631641\n", + "\n", + "\n", + "\n", + "15->32\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "33\n", + "\n", + "leaf=-0.0744014606\n", + "\n", + "\n", + "\n", + "16->33\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "34\n", + "\n", + "leaf=-0.443553358\n", + "\n", + "\n", + "\n", + "16->34\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "61\n", + "\n", + "leaf=-0.182048887\n", + "\n", + "\n", + "\n", + "31->61\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "62\n", + "\n", + "leaf=0.335204124\n", + "\n", + "\n", + "\n", + "31->62\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "35\n", + "\n", + "fSize<2.78240013\n", + "\n", + "\n", + "\n", + "17->35\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "36\n", + "\n", + "fWidth<50.6043472\n", + "\n", + "\n", + "\n", + "17->36\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "37\n", + "\n", + "fLength<17.9172516\n", + "\n", + "\n", + "\n", + "18->37\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "38\n", + "\n", + "fConc<0.489749998\n", + "\n", + "\n", + "\n", + "18->38\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "63\n", + "\n", + "leaf=0.358831823\n", + "\n", + "\n", + "\n", + "35->63\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "64\n", + "\n", + "leaf=-0.568417907\n", + "\n", + "\n", + "\n", + "35->64\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "65\n", + "\n", + "leaf=0.40175578\n", + "\n", + "\n", + "\n", + "36->65\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "66\n", + "\n", + "leaf=0.0195091218\n", + "\n", + "\n", + "\n", + "36->66\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "67\n", + "\n", + "leaf=0.0970883071\n", + "\n", + "\n", + "\n", + "37->67\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "68\n", + "\n", + "leaf=0.3321895\n", + "\n", + "\n", + "\n", + "37->68\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "69\n", + "\n", + "leaf=0.197235689\n", + "\n", + "\n", + "\n", + "38->69\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "70\n", + "\n", + "leaf=-0.376783282\n", + "\n", + "\n", + "\n", + "38->70\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "19\n", + "\n", + "leaf=0.0770212337\n", + "\n", + "\n", + "\n", + "9->19\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "20\n", + "\n", + "fAlpha<0.949499965\n", + "\n", + "\n", + "\n", + "9->20\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "21\n", + "\n", + "fDist<221.908005\n", + "\n", + "\n", + "\n", + "10->21\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "22\n", + "\n", + "fAsym<101.736496\n", + "\n", + "\n", + "\n", + "10->22\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "39\n", + "\n", + "leaf=-0.132379785\n", + "\n", + "\n", + "\n", + "20->39\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "40\n", + "\n", + "leaf=-0.467667967\n", + "\n", + "\n", + "\n", + "20->40\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "41\n", + "\n", + "fAsym<95.0730438\n", + "\n", + "\n", + "\n", + "21->41\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "42\n", + "\n", + "fWidth<39.6760483\n", + "\n", + "\n", + "\n", + "21->42\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "43\n", + "\n", + "fM3Long<-54.6403008\n", + "\n", + "\n", + "\n", + "22->43\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "44\n", + "\n", + "fDist<142.462997\n", + "\n", + "\n", + "\n", + "22->44\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "71\n", + "\n", + "leaf=-0.401033938\n", + "\n", + "\n", + "\n", + "41->71\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "72\n", + "\n", + "leaf=0.0877427235\n", + "\n", + "\n", + "\n", + "41->72\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "73\n", + "\n", + "leaf=0.296984643\n", + "\n", + "\n", + "\n", + "42->73\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "74\n", + "\n", + "leaf=-0.100294389\n", + "\n", + "\n", + "\n", + "42->74\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "75\n", + "\n", + "leaf=-0.164229944\n", + "\n", + "\n", + "\n", + "43->75\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "76\n", + "\n", + "leaf=-0.384120196\n", + "\n", + "\n", + "\n", + "43->76\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "77\n", + "\n", + "leaf=-0.333947897\n", + "\n", + "\n", + "\n", + "44->77\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "78\n", + "\n", + "leaf=0.0786020905\n", + "\n", + "\n", + "\n", + "44->78\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "11\n", + "\n", + "fAlpha<49.9686012\n", + "\n", + "\n", + "\n", + "5->11\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "12\n", + "\n", + "fWidth<14.2644005\n", + "\n", + "\n", + "\n", + "5->12\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "13\n", + "\n", + "fWidth<14.2378006\n", + "\n", + "\n", + "\n", + "6->13\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "14\n", + "\n", + "fSize<2.67589998\n", + "\n", + "\n", + "\n", + "6->14\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "23\n", + "\n", + "fLength<11.7320004\n", + "\n", + "\n", + "\n", + "11->23\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "24\n", + "\n", + "fLength<25.7173996\n", + "\n", + "\n", + "\n", + "11->24\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "25\n", + "\n", + "fAlpha<37.5266495\n", + "\n", + "\n", + "\n", + "12->25\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "26\n", + "\n", + "fDist<201.460495\n", + "\n", + "\n", + "\n", + "12->26\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "45\n", + "\n", + "leaf=-0.420416087\n", + "\n", + "\n", + "\n", + "23->45\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "46\n", + "\n", + "fConc<0.805799961\n", + "\n", + "\n", + "\n", + "23->46\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "47\n", + "\n", + "fSize<2.24055004\n", + "\n", + "\n", + "\n", + "24->47\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "48\n", + "\n", + "fLength<32.0728493\n", + "\n", + "\n", + "\n", + "24->48\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "79\n", + "\n", + "leaf=0.304020494\n", + "\n", + "\n", + "\n", + "46->79\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "80\n", + "\n", + "leaf=0.00599159906\n", + "\n", + "\n", + "\n", + "46->80\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "81\n", + "\n", + "leaf=0.295767903\n", + "\n", + "\n", + "\n", + "47->81\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "82\n", + "\n", + "leaf=0.0670232847\n", + "\n", + "\n", + "\n", + "47->82\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "83\n", + "\n", + "leaf=-0.093419373\n", + "\n", + "\n", + "\n", + "48->83\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "84\n", + "\n", + "leaf=-0.418354958\n", + "\n", + "\n", + "\n", + "48->84\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "49\n", + "\n", + "fWidth<11.3221998\n", + "\n", + "\n", + "\n", + "25->49\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "50\n", + "\n", + "fSize<2.52285004\n", + "\n", + "\n", + "\n", + "25->50\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "51\n", + "\n", + "fAlpha<38.1006012\n", + "\n", + "\n", + "\n", + "26->51\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "52\n", + "\n", + "fAlpha<35.2190475\n", + "\n", + "\n", + "\n", + "26->52\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "85\n", + "\n", + "leaf=-0.320837349\n", + "\n", + "\n", + "\n", + "49->85\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "86\n", + "\n", + "leaf=0.16285798\n", + "\n", + "\n", + "\n", + "49->86\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "87\n", + "\n", + "leaf=-0.186974645\n", + "\n", + "\n", + "\n", + "50->87\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "88\n", + "\n", + "leaf=-0.446950704\n", + "\n", + "\n", + "\n", + "50->88\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "89\n", + "\n", + "leaf=0.331136853\n", + "\n", + "\n", + "\n", + "51->89\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "90\n", + "\n", + "leaf=0.124574758\n", + "\n", + "\n", + "\n", + "51->90\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "91\n", + "\n", + "leaf=0.0928332582\n", + "\n", + "\n", + "\n", + "52->91\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "92\n", + "\n", + "leaf=-0.262255192\n", + "\n", + "\n", + "\n", + "52->92\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "27\n", + "\n", + "fSize<2.50750017\n", + "\n", + "\n", + "\n", + "13->27\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "28\n", + "\n", + "fAlpha<41.9882011\n", + "\n", + "\n", + "\n", + "13->28\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "29\n", + "\n", + "fM3Long<-123.029602\n", + "\n", + "\n", + "\n", + "14->29\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "30\n", + "\n", + "fSize<4.77664995\n", + "\n", + "\n", + "\n", + "14->30\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "53\n", + "\n", + "fWidth<11.7434998\n", + "\n", + "\n", + "\n", + "27->53\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "54\n", + "\n", + "leaf=-0.493121028\n", + "\n", + "\n", + "\n", + "27->54\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "55\n", + "\n", + "fM3Long<10.9937\n", + "\n", + "\n", + "\n", + "28->55\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "56\n", + "\n", + "fDist<134.518494\n", + "\n", + "\n", + "\n", + "28->56\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "93\n", + "\n", + "leaf=-0.309237778\n", + "\n", + "\n", + "\n", + "53->93\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "94\n", + "\n", + "leaf=0.248309985\n", + "\n", + "\n", + "\n", + "53->94\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "95\n", + "\n", + "leaf=-0.297579974\n", + "\n", + "\n", + "\n", + "55->95\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "96\n", + "\n", + "leaf=0.0561074428\n", + "\n", + "\n", + "\n", + "55->96\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "97\n", + "\n", + "leaf=-0.124954633\n", + "\n", + "\n", + "\n", + "56->97\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "98\n", + "\n", + "leaf=-0.400526643\n", + "\n", + "\n", + "\n", + "56->98\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "57\n", + "\n", + "leaf=0.200113192\n", + "\n", + "\n", + "\n", + "29->57\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "58\n", + "\n", + "fM3Long<116.981003\n", + "\n", + "\n", + "\n", + "29->58\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "59\n", + "\n", + "fM3Long<68.6705475\n", + "\n", + "\n", + "\n", + "30->59\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "60\n", + "\n", + "fM3Trans<81.1044006\n", + "\n", + "\n", + "\n", + "30->60\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "99\n", + "\n", + "leaf=-0.371340662\n", + "\n", + "\n", + "\n", + "58->99\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "100\n", + "\n", + "leaf=0.0246473085\n", + "\n", + "\n", + "\n", + "58->100\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "101\n", + "\n", + "leaf=-0.453947127\n", + "\n", + "\n", + "\n", + "59->101\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "102\n", + "\n", + "leaf=-0.391275704\n", + "\n", + "\n", + "\n", + "59->102\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n", + "103\n", + "\n", + "leaf=-0.328859806\n", + "\n", + "\n", + "\n", + "60->103\n", + "\n", + "\n", + "yes, missing\n", + "\n", + "\n", + "\n", + "104\n", + "\n", + "leaf=0.127982572\n", + "\n", + "\n", + "\n", + "60->104\n", + "\n", + "\n", + "no\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# your code here\n", + "xgb.to_graphviz(XGBclassifier, num_trees=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "d) Compare the performance of XGBoost with the random forest classifier from sci-kit learn. Plot signal and background efficiency for both classifiers in one plot. Which classifier performs better?" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "RFclassifier = RandomForestClassifier(random_state=0)\n", + "start_time = time.time()\n", + "RFclassifier.fit(X_train, y_train)\n", + "run_time_rf = time.time() - start_time" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# predect labels for the test sample\n", + "y_pred_rf = RFclassifier.predict(X_test) # 0 or 1\n", + "y_pred_rf_prob = RFclassifier.predict_proba(X_test) # probabilities" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model Accuracy: 87.91%\n", + "AUC score: 0.86\n", + "Run time: 11.07 sec\n", + "\n", + "\n" + ] + } + ], + "source": [ + "print(\"Model Accuracy: {:.2f}%\".format(100*RFclassifier.score(X_test, y_test)))\n", + "print(\"AUC score: {:.2f}\".format(roc_auc_score(y_test,y_pred_rf)))\n", + "print(\"Run time: {:.2f} sec\\n\\n\".format(run_time_rf))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fpr_rf, tpr_rf, _ = roc_curve(y_test, y_pred_rf_prob[:,1])\n", + "plt.plot(fpr_xgb, tpr_xgb, label='XGBoost')\n", + "plt.plot(fpr_rf, tpr_rf, label='random forest')\n", + "plt.xscale(\"log\")\n", + "plt.xlabel('Background efficiency', fontsize=18)\n", + "plt.ylabel('Signal efficiency', fontsize=18);\n", + "plt.legend()" + ] + } + ], + "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.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/05_neural_networks_ex_1_hyperparameter_optimization.ipynb b/notebooks/05_neural_networks_ex_1_hyperparameter_optimization.ipynb new file mode 100644 index 0000000..c12a975 --- /dev/null +++ b/notebooks/05_neural_networks_ex_1_hyperparameter_optimization.ipynb @@ -0,0 +1,159 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hyperparameter optimization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Superconductivty Data Set: Predict the critical temperature based on 81 material features." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import mean_squared_error" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/train_critical_temp.csv\"\n", + "df = pd.read_csv(filename, engine='python')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y = df['critical_temp'].values\n", + "X = df[[col for col in df.columns if col!=\"critical_temp\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, shuffle=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.neural_network import MLPRegressor\n", + "import time\n", + "\n", + "mlpr = MLPRegressor(hidden_layer_sizes=(50,50), activation='relu', random_state=1, max_iter=5000)\n", + "\n", + "start_time = time.time()\n", + "mlpr.fit(X_train, y_train)\n", + "run_time = time.time() - start_time\n", + "\n", + "print(run_time)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_pred = mlpr.predict(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.scatter(y_test, y_pred, s=2)\n", + "plt.xlabel(\"true critical temperature (K)\", fontsize=14)\n", + "plt.ylabel(\"predicted critical temperature (K)\", fontsize=14)\n", + "plt.savefig(\"critical_temperature.pdf\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rms = np.sqrt(mean_squared_error(y_test, y_pred))\n", + "print(f\"root mean square error {rms:.2f}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Now try to optimize the hyperparameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "### Your code here\n" + ] + } + ], + "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.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/05_neural_networks_ex_1_sol_hyperparameter_optimization.ipynb b/notebooks/05_neural_networks_ex_1_sol_hyperparameter_optimization.ipynb new file mode 100644 index 0000000..0191bb0 --- /dev/null +++ b/notebooks/05_neural_networks_ex_1_sol_hyperparameter_optimization.ipynb @@ -0,0 +1,573 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hyperparameter optimization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Superconductivty Data Set: Predict the critical temperature based on 81 material features." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import mean_squared_error" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "filename = \"https://www.physi.uni-heidelberg.de/~reygers/lectures/2021/ml/data/train_critical_temp.csv\"\n", + "df = pd.read_csv(filename, engine='python')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "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", + " \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", + "
number_of_elementsmean_atomic_masswtd_mean_atomic_massgmean_atomic_masswtd_gmean_atomic_massentropy_atomic_masswtd_entropy_atomic_massrange_atomic_masswtd_range_atomic_massstd_atomic_mass...wtd_mean_Valencegmean_Valencewtd_gmean_Valenceentropy_Valencewtd_entropy_Valencerange_Valencewtd_range_Valencestd_Valencewtd_std_Valencecritical_temp
0488.94446857.86269266.36159236.1166121.1817951.062396122.9060731.79492151.968828...2.2571432.2133642.2197831.3689221.06622111.0857140.4330130.43705929.0
1592.72921458.51841673.13278736.3966021.4493091.057755122.9060736.16193947.094633...2.2571431.8881752.2106791.5571131.04722121.1285710.6324560.46860626.0
2488.94446857.88524266.36159236.1225091.1817950.975980122.9060735.74109951.968828...2.2714292.2133642.2326791.3689221.02917511.1142860.4330130.44469719.0
3488.94446857.87396766.36159236.1195601.1817951.022291122.9060733.76801051.968828...2.2642862.2133642.2262221.3689221.04883411.1000000.4330130.44095222.0
4488.94446857.84014366.36159236.1107161.1817951.129224122.9060727.84874351.968828...2.2428572.2133642.2069631.3689221.09605211.0571430.4330130.42880923.0
\n", + "

5 rows × 82 columns

\n", + "
" + ], + "text/plain": [ + " number_of_elements mean_atomic_mass wtd_mean_atomic_mass \\\n", + "0 4 88.944468 57.862692 \n", + "1 5 92.729214 58.518416 \n", + "2 4 88.944468 57.885242 \n", + "3 4 88.944468 57.873967 \n", + "4 4 88.944468 57.840143 \n", + "\n", + " gmean_atomic_mass wtd_gmean_atomic_mass entropy_atomic_mass \\\n", + "0 66.361592 36.116612 1.181795 \n", + "1 73.132787 36.396602 1.449309 \n", + "2 66.361592 36.122509 1.181795 \n", + "3 66.361592 36.119560 1.181795 \n", + "4 66.361592 36.110716 1.181795 \n", + "\n", + " wtd_entropy_atomic_mass range_atomic_mass wtd_range_atomic_mass \\\n", + "0 1.062396 122.90607 31.794921 \n", + "1 1.057755 122.90607 36.161939 \n", + "2 0.975980 122.90607 35.741099 \n", + "3 1.022291 122.90607 33.768010 \n", + "4 1.129224 122.90607 27.848743 \n", + "\n", + " std_atomic_mass ... wtd_mean_Valence gmean_Valence wtd_gmean_Valence \\\n", + "0 51.968828 ... 2.257143 2.213364 2.219783 \n", + "1 47.094633 ... 2.257143 1.888175 2.210679 \n", + "2 51.968828 ... 2.271429 2.213364 2.232679 \n", + "3 51.968828 ... 2.264286 2.213364 2.226222 \n", + "4 51.968828 ... 2.242857 2.213364 2.206963 \n", + "\n", + " entropy_Valence wtd_entropy_Valence range_Valence wtd_range_Valence \\\n", + "0 1.368922 1.066221 1 1.085714 \n", + "1 1.557113 1.047221 2 1.128571 \n", + "2 1.368922 1.029175 1 1.114286 \n", + "3 1.368922 1.048834 1 1.100000 \n", + "4 1.368922 1.096052 1 1.057143 \n", + "\n", + " std_Valence wtd_std_Valence critical_temp \n", + "0 0.433013 0.437059 29.0 \n", + "1 0.632456 0.468606 26.0 \n", + "2 0.433013 0.444697 19.0 \n", + "3 0.433013 0.440952 22.0 \n", + "4 0.433013 0.428809 23.0 \n", + "\n", + "[5 rows x 82 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "y = df['critical_temp'].values\n", + "X = df[[col for col in df.columns if col!=\"critical_temp\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, shuffle=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.9422240257263184\n" + ] + } + ], + "source": [ + "from sklearn.neural_network import MLPRegressor\n", + "import time\n", + "\n", + "mlpr = MLPRegressor(hidden_layer_sizes=(50,50), activation='relu', random_state=1, max_iter=5000)\n", + "\n", + "start_time = time.time()\n", + "mlpr.fit(X_train, y_train)\n", + "run_time = time.time() - start_time\n", + "\n", + "print(run_time)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "y_pred = mlpr.predict(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkcAAAG1CAYAAADz8VB4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAADjNUlEQVR4nOydeXhTVd7Hv1maJm2adC9NaaFAW5CWRcCyCCiC4rgigtso6ogs4gK4jM6Lo+OoM46CG4ijI+ooq4C4zOiwKGhZBGRpAaGFQqH73qZt2mZ5/0jOybk3N0vTdIPzeR4faXJzc+65N/d872+V2Ww2GzgcDofD4XA4AAB5Vw+Aw+FwOBwOpzvBxRGHw+FwOBwOAxdHHA6Hw+FwOAxcHHE4HA6Hw+EwcHHE4XA4HA6Hw8DFEYfD4XA4HA4DF0ccDofD4XA4DMquHkB3x2q1oqioCGFhYZDJZF09HA6Hw+FwOD5gs9lQX18Pg8EAubxttiAujrxQVFSExMTErh4Gh8PhcDgcPzh//jx69+7dps9wceSFsLAwAPbJ1el0XTwaDofD4XA4vlBXV4fExES6jrcFLo68QFxpOp2OiyMOh8PhcHoY/oTE8IBsDofD4XA4HAYujjgcDofD4XAYuDjicDgcDofDYeDiiMPhcDgcDoeBiyMOh8PhcDgcBi6OOBwOh8PhcBi4OOJwOBwOh8Nh4OKIw+FwOBwOh4GLIw6Hw+FwOBwGLo44HA6Hw+FwGLg44nA4HA6Hw2Hg4ojD4XA4HA6HgYujboDZYsWZciPMFmtXD4XD4XA4nEseZVcP4FLHbLHithW7cbSwFkMS9Ng0fyyUCq5ZORwOh8PpKvgq3MUUVDXiaGEtAOBoYS0Kqhq7eEQcDofD4VzacHHUxSRFhmBIgh4AMKS3HkmRIV08Ig6Hw+FwLm24W62LUSrk2DR/LAqqGpEUGcJdahwOh8PhdDFcHHUDlAo5+sVou3oYHA6Hw+FwwN1qHA6Hw+FwOAK4OOJwOBwOh8Nh4OKIw+FwOBwOh8GvmKPGxkbs3r0bWVlZuHDhAioqKhASEoKYmBhkZGRg4sSJGDBgQKDHyuFwOBwOh9PhtEkc7dmzBytXrsQXX3wBk8kEm80muZ1MJsOgQYMwd+5c3HfffdDpdAEZLIfD4XA4HE5HI7O5UzgMx44dw1NPPYXvv/8eCoUCV111FcaMGYORI0ciLi4OkZGRaGpqQlVVFU6ePIm9e/dix44dKCgoQFRUFJYsWYL58+dDqex5yXF1dXXQ6/Wora3lIo/D4XA4nB5Ce9Zvn8SRUqlEnz59sHDhQtx5552Ijo72aec7d+7EBx98gHXr1uGFF17An/70pzYNrjvAxRGHw+FwOD2PDhdH//rXvzBr1iy/LT+5ubm4cOECrr76ar8+35VwccThcDgcTs+jw8WRv1gsFigUio7afafAxRGHw+FwOD2P9qzfPqfy7927t007tlgsuOuuu9r0GQ6Hw+FwOJyuxmdxdMMNN+D48eM+bWuz2XDPPfdg48aNfg+Mw+FwOBwOpyvwWRwZjUZcd911OHfunMftrFYrfv/732P9+vUYPXp0uwfI4XA4HA6H05n4LI4+//xzFBcXY8qUKSgrK5Pcxmaz4f7778eaNWuQmZmJ77//PmAD5XA4HA6Hw+kMfBZHt99+O9577z3k5eXhuuuuQ11dneB9m82GBx98EJ999hlGjhyJ77//Hlot7zTP4XA4HA6nZ9Gm3mqzZ8/Gq6++iiNHjuCmm26CyWQSvPfJJ5/g8ssvx9atW3lmF4fD4XA4nB5JmxvPPvPMM3jyySfx008/YcaMGWhtbcXs2bPx0UcfYdiwYdi2bRv0en1HjJXD4XA4HA6nw/GrquNrr72GqqoqfPTRR0hLS8PZs2eRkZGBrVu3Ijw8PMBD5HA4HA6Hw+k8/G529s9//hO1tbXYuHEj0tPTsWPHDkRFRQVybBwOh8PhcDidjs/i6LLLLnN5raWlBTKZDNXV1Rg/frzL+zKZDMeOHWvfCDkcDofD4XA6EZ/F0W+//eb2vcLCwoAMhsPhcDgcDqer8VkcWa3WjhwHh8PhcDgcTregzdlqHA6Hw+FwOBczXBxxOBwOh8PhMPgkjtauXduuLzl//jyysrLatQ8Oh8PhcDiczsAncfT73/8eQ4YMwSeffAKj0ejzzg8cOIA5c+YgJSUFP/zwg9+D5HA4HA6Hw+ksZDabzeZto0OHDmHRokXYuXMnQkJCMHXqVGRmZmLEiBGIi4tDeHg4TCYTqqqqcPLkSezbtw9bt25Fbm4udDodnn32WTz++OMIDg7ujGMKKHV1ddDr9aitreUtUTgcDofD6SG0Z/32SRwRduzYgffeew9fffUVWltbIZPJJLez2Wzo168f5syZg4ceeggRERFtGlR3gosjDofD4XB6Hp0mjgg1NTXYtWsXsrKycOHCBVRWVkKj0SAmJgYZGRmYOHEihgwZ0tbddku4OOJwOBwOp+fR6eLoUoKLIw6Hw+Fweh7tWb95Kj+Hw+FwOBwOAxdHHA6Hw+FwOAxcHHE4HA6Hw+EwcHHE4XA4HA6Hw8DFEYfD4XA4HA4DF0ccDofD4XA4DN1aHO3atQs33XQTDAYDZDIZvvzyS8H7999/P2QymeC/qVOnCrapqqrCPffcA51Oh/DwcPzhD39oUwsUDofD4XA4lxbtFkfHjx/Hpk2b8O9//zsQ4xHQ0NCAoUOHYvny5W63mTp1KoqLi+l/a9asEbx/zz334NixY9i6dSu++eYb7Nq1Cw8//HDAx8rhcDgcDufiQOnvB/fv34/Zs2cjOzubvnbvvfcCsFt8pk6dirVr1+Lmm2/2e3DXX389rr/+eo/bBAcHo1evXpLvnThxAt999x3279+PkSNHAgDeeecd/O53v8Prr78Og8Hg99g4HA6Hw+FcnPhlOTp27BgmTZqE/Px8LFy40EXAjB8/HtHR0diwYUNABumJH3/8EbGxsUhLS8O8efNQWVlJ39uzZw/Cw8OpMAKAyZMnQy6XY9++fZL7a25uRl1dneA/DofD4XA4lw5+iaM///nPAICDBw/i9ddfx6hRowTvy2QyjBkzBvv372//CD0wdepUfPrpp9i+fTv+/ve/Y+fOnbj++uthsVgAACUlJYiNjRV8RqlUIjIyEiUlJZL7fPXVV6HX6+l/iYmJHXoMHA6Hw+Fwuhd+udV27tyJ6dOnY8CAAW63SUpKwnfffef3wHzhzjvvpP/OyMjAkCFD0L9/f/z444+45ppr/Nrns88+i0WLFtG/6+rquEDicDgcDucSwi/LUX19vYtFRkxTUxO14HQW/fr1Q3R0NPLy8gAAvXr1QllZmWAbs9mMqqoqt3FKwcHB0Ol0gv84HA6Hw+FcOvgljhITEwWB2FL8+uuv6N+/v1+D8pcLFy6gsrIS8fHxAIAxY8agpqYGBw8epNvs2LEDVqsVmZmZnTo2DofD4XA4PQO/xNGNN96I//3vf9i2bZvk++vXr8fevXtx6623tmdsMBqNOHz4MA4fPgwAyM/Px+HDh1FQUACj0YinnnoKe/fuxdmzZ7F9+3bccsstGDBgAK677joAwKBBgzB16lTMnj0bv/zyC7KysrBgwQLceeedPFONw+FwOByOJDKbzWZr64fKy8tx+eWXo7S0FLNmzUJJSQn+85//4J133sGePXuwZs0aJCUl4dChQ9Dr9X4P7scff8TVV1/t8vqsWbPw3nvv4dZbb8WhQ4dQU1MDg8GAa6+9Fi+99BLi4uLotlVVVViwYAG+/vpryOVyTJ8+HW+//Ta0Wq1PY6irq4Ner0dtbS13sXE4HA6H00Noz/rtlzgCgNOnT+O+++7Dnj17XN7LzMzEmjVr0LdvX3923a3g4ojD4XA4nJ5He9Zvv4tA9u/fH1lZWTh8+DD27t2Lqqoq6HQ6ZGZmuqT2czgcDofD4fQU/BJHDz74IDIyMrBw4UIMGzYMw4YNC/CwOBwOh8PhcLoGvwKyV69e7ZIiz+FwOBwOh3Mx4Jc46t+/P4qLiwM9Fg6Hw+FwOJwuxy9x9OCDD+Lbb79FYWFhoMfD4XA4HA6H06X4FXM0ffp0/PDDDxg7diyefvppjBo1CnFxcZDJZC7bJiUltXuQHA6Hw+FwOJ2FX6n8crkcMpkMNptNUhDRnctkMJvN7RpgV8NT+TkcDofD6Xl0eir/fffd51EUcTgcDofD4fRU/BJHH3/8cYCHweFwOBwOh9M98Csgm8PhcDgcDudihYsjDofD4XA4HAa/3Gr9+vXzaTuZTIbTp0/78xUcDofD4XA4XYJf4shqtUoGZNfW1qKmpgYAEB8fD5VK1a7BcTgcDofD4XQ2fomjs2fPenxv0aJFKC0txdatW/0dF4fD4XA4HE6XEPCYo759+2LdunWorq7Gn/70p0DvnsPhcDgcDqdD6ZCA7KCgIEyZMgXr16/viN1zOBwOh8PhdBgdlq3W2NiIqqqqjto9h8PhcDgcTofQIeLop59+wpo1a5CWltYRu+dwOBwOh8PpMPwKyJ40aZLk62azGYWFhTRg+/nnn/d7YBwOh8PhcDhdgV/i6Mcff5R8XSaTISIiAtdeey0WLVqEKVOmtGdsHA6Hw+FwOJ2O33WOOBwOh8PhcC5GePsQDofD4XA4HAa/xFG/fv3w9ttve9xm+fLlPrcZ4XA4HA6Hw+ku+CWOzp49S9uEuKOmpgbnzp3zZ/ccDofD4XA4XUaHudVqa2sRHBzcUbvncDgcDofD6RB8DsjetWuX4O+zZ8+6vAYAFosF58+fx+eff47U1NT2j5DD4XA4HA6nE5HZbDabLxvK5XLIZDKfdmqz2SCTyfDxxx/j3nvvbdcAu5q6ujro9XrU1tZCp9N19XA4HA6Hw+H4QHvWb58tR88//zxkMhlsNhv+8pe/YOLEibjqqqtctlMoFIiMjMTVV1+NQYMGtWkwHA6Hw+FwOF2Nz5YjlquvvhoPPPAA7rvvvo4YU7eCW444HA6Hw+l5dIrliOWHH37w52McDofD4XA43R5eBJLD4XA4HA6HwW9xdP78ecyZMwf9+/eHRqOBQqFw+U+p9MswxeFwOBxOt8NsseJMuRFmC2+hdbHjl3o5c+YMMjMzUV1djcGDB6O5uRl9+vSBWq3GmTNn0NraiqFDhyI8PDzAw+VwOBwOp/MxW6y4bcVuHC2sxZAEPTbNHwulgjtfLlb8OrMvvvgiamtrsX37dhw5cgQA8MADD+DEiRM4e/Ysbr75ZjQ0NOCLL74I6GA5HA6Hw+kKCqoacbSwFgBwtLAWBVWNXTwiTkfilzjatm0bfve732HixIn0NZL0Fh8fj3Xr1gEAnnvuuQAMkcPhcDicriUpMgRDEvQAgCG99UiKDOniEXE6Er/cahUVFRg4cKBzJ0olGhudKjo4OBhTpkzBl19+2e4BcjgcDofT1SgVcmyaPxYFVY1IigzhLrWLHL/EUXR0NBoaGgR/nz17VrhjpdJrc1oOh8PhcHoKSoUc/WK0XT0MTifgl/RNSUnB6dOn6d9XXHEFvv/+e5w5cwYAUF5eji+++AL9+/cPzCg5HA6Hw+FwOgm/xNH111+PH374gVqGnnjiCdTX12PIkCEYNWoUUlNTUVJSgkcffTSQY+VwOBwOh8PpcPwSR/PmzcOPP/4IhUIBALjqqquwdu1a9OnTBzk5OYiLi8Pbb7+N2bNnB3SwHA6Hw+FwOB2NX73VLiV4bzUOh8PhcHoe7Vm//bIcTZo0CUuWLPHnoxwOh8PhcDjdGr/E0b59+2CxWAI9Fg6Hw+FwLlp4+5Geg1+p/AMHDsS5c+cCPRYOh8PhcC5KePuRnoVfZ+bRRx/Fli1bcPz48UCPh8PhcDiciw7efqRn4ZflqF+/frjqqqswevRozJkzB6NGjUJcXBxkMpnLthMmTGj3IDkcDofjH2aLVbKqs7vXLwUCcext3QdpP3K0sJa3H+kB+JWtJpfLIZPJaD81KVFE6OmxSTxbjcPh9FTcuXIuZRdPII7d332IBZU/Iq29wq4zRXFXC/D2rN9+WY6ef/55j4KIw+FwOF2PlCunX4zW7esXM2Shtlht7T52f+ePbT/ij8Dy5TOeBElniuKeLsD9EkcvvPBCgIfB4XA43ZeufgL2F3eunEvNxWO2WDFteRayi+qQHh+GjAQ9sttx7IGYP38ElrfPeBMknSmKe7oA90sccTgczqVCT34CdtdJvqd1mG+vOM2vaEB2UR0AIKe4Ht89Ph4qpbzN+2PH0d7580dgefuMN0GSFBmCDIMO2UV1yEjQuXw+kA8BPV2At0scHTp0CGvWrMFvv/2GxsZGbNu2DQBw7tw57Nu3D5MnT0ZkZGRABsrhcDhdQY9/AnbTSb6ndJjvCHGqkMvafOxS42jP/PkjUL19xidBQkNihKExbZlnX0RUTxPgYvwWR08//TTeeOMNyaBsm82Gu+++G2+88QYef/zx9o+Sw+H4RE91/3RnevoTcE8nEOI0OTqUutIyEvRIjg7tknGI8UegevqMN0FSUNWIbMcxZIuOQXx8+RUNUMhlklmOvoqoniLApfDr7rlq1Sq8/vrruPHGG3H06FE8++yzgvf79u2LK664Al999VVABsnhcLxDblqT3tiJ21bs5lV4AwRZcHYsnohN83qOS+1igYhTAH6LU6VCjs2Oc7jZT8tTIMbRGRBBInWMno6BfS8jQY9F6w5L3ksulXpNfv3KV6xYgUGDBmHjxo1IT0+HSqVy2WbgwIHIzc1t1+B27dqFm266CQaDATKZDF9++aXgfZvNhueffx7x8fHQaDSYPHmyy3dWVVXhnnvugU6nQ3h4OP7whz/AaDS2a1wcTnfkUrlpdQWeFhzeEkKaQM2LN3EaqO/xtp/OFMn+HJMvn/F0DOx7S2cOpTFa4nuJQa+GJkgBANAEKWDQq9t6eD0Cv87u8ePHMWXKFCiV7r1ycXFxKCsr83tgANDQ0IChQ4di+fLlku+/9tprePvtt7Fy5Urs27cPoaGhuO6662Aymeg299xzD44dO4atW7fim2++wa5du/Dwww+3a1wcTnekpzzZXkxwa500gZ4Xd+LU1+/xtp2v+/EkkgOFP3PXls+Ij4EVVeS95OhQt/eSoloTmlrt9QubWi0oqjUJ9s/uz5Ng6+4PFX7FHCmVSrS0tHjcpqioCFpt+3yN119/Pa6//nrJ92w2G95880383//9H2655RYAwKeffoq4uDh8+eWXuPPOO3HixAl899132L9/P0aOHAkAeOedd/C73/0Or7/+OgwGg8t+m5ub0dzcTP+uq6tr1zFwOJ1FTw+A7In09GDtjsLfeWlrzJyv3+Ntu+50Hjsqxd9dlXSp+CFP9xJPMXjs/jIS9IDNZs+MM+iw9I5hSI4O7TFFSP0aTUZGBnbs2OG2+jXJXBsxYkS7BueJ/Px8lJSUYPLkyfQ1vV6PzMxM7NmzBwCwZ88ehIeHU2EEAJMnT4ZcLse+ffsk9/vqq69Cr9fT/xITEzvsGDicQNMZT7YcJ9xaJ40/8+KPxcTX7/G2XWedR1+sJf6MxdNnPM2rJ1c8G0zNjtmTa47dX3ZhLXXNZRfVYcqyXfT78ysaun0IgF+WowcffBAPPfQQ5s6di3fffVfwXl1dHR566CGUlJTgrbfeCsggpSgpKQFgd9+xxMXF0fdKSkoQGxsreF+pVCIyMpJuI+bZZ5/FokWL6N91dXVcIHE4HEm4tU4af+bFH4uJr9/jaTtiVVk/ZzSKak0e92NqMWNffhUykyOhVrVt+fTVWhLoFH9P8+otE9OTZUnq3LD7SzfokFtaj2aLs0MZyYJbtP4IfU2q3lJ3wG9xtG3bNvzrX//CunXrEB4eDgC44oorcOLECTQ0NOD+++/H7bffHsixdgrBwcEIDg7u6mFwOJweQk9OV+5I2jov/pZM8PV7pLZri3vH1GLG8Je2oanVAk2QAoeWTG6TQGqL+Atkir+nefUl9V9qzFJuOvLa6oeuwMGCGsTp1Jj61k+C/aXF2cdHygkAwNKZw7rlQ4XfdY5Wr16Nq6++Gu+++y5ycnJgs9lw4MABDBo0CI899hjmzJkTyHG60KtXLwBAaWkp4uPj6eulpaUYNmwY3UYcFG42m1FVVUU/z+FwOJyuh12oDXp1p1jj2iJY9uVXCQKR9+VXYWJarOS2UnRVvSxvAsiTEJOqqC0lKAHQ1zRBCjS1WpBh0CHdoEOOw7WWGqfFlkfGQamQC+bBn5pTnUG7KmTPnj0bs2fPRlNTE6qrq6HT6dodhO0rycnJ6NWrF7Zv307FUF1dHfbt24d58+YBAMaMGYOamhocPHiQxj/t2LEDVqsVmZmZnTJODofD4fiGUmFv6dFRwbpii0dbBEtmciRd+DVBCmQm+9b9gf3O9XNGU7dcoEWfp2D2dlk3RRW13cUpkdeIgMwuqsPWhRPobkgwNoAe4YoOSG81jUYDjUYTiF0JMBqNyMvLo3/n5+fj8OHDiIyMRFJSEp544gn89a9/RUpKCpKTk7FkyRIYDAbceuutAIBBgwZh6tSpmD17NlauXInW1lYsWLAAd955p2SmGofD4XD8w5dMM1+28cWa408leHcuNF8XarVKif3PTcK32SW4IaOXTy41d9lbHSH6PAlKdr4A+Dx34oraWXkVyEyOFFQbj9WqsP9cNbUSaYLkaGq1It0QJhBEJBjdoFd7je3qDrRLHBUXF2Pt2rU4dOgQamtrodfrMXz4cNx5550CV5e/HDhwAFdffTX9mwRKz5o1Cx9//DGefvppNDQ04OGHH0ZNTQ2uvPJKfPfdd1CrnUWpPv/8cyxYsADXXHMN5HI5pk+fjrfffrvdY+NwOByOHV9id3yN7/E3SNgb7kQXsSD5Iuzu/vAXHC2sxef7Cnz6XnH2FqEt6fa+4Ck2iARAZ/sh0NhzoQlSYNaq/cgw6EBCrK1WK0a9sh1NrVZoguTYMn8M7vinPRP8dHkjTC1mlBlbYNCrMfP9vQK3W3p8GBZfl4Yx/aLaHNzeGchspDlaG1m+fDmeeuopNDc3Q7wLtVqN119/HfPnzw/IILuSuro66PV61NbWQqfTdfVwOBwOp9txptyISW/spH/vWDzRxdrjyzYET0KhLfsR75OKqt56mobuq9jy9L2+1BESCBPm+13G1oamrwBojBYRH2TfgDMOyB2+zJ3ZYkVWXgVmrdrvcTsAeHJKKl7feor+nRwVgvzKRqTFaXGyVLozhT/B7b7SnvXbr9GsXbsWjz76KKKjo/GnP/0J48ePR1xcHEpLS7Fr1y689dZb9P2ZM2f68xUcDodzydFTGwf7ErvTlvgeb0HC/ma1SbnQfA3Kdve9ZosV01bsppYZtneb+DvJ97Ul3Z7Fk5tOXIrgTLnRRRiJBZq3uSPXY2ZyJD32jAQdABmyHen6p8uNDsuRAr8fnYjlP55GU6sFwUo58ivt8UgnS41Ii9XiZJmRWo4I/gS3dwZ+WY4uv/xyXLhwAYcPH5aM3blw4QKGDx+OpKQkHDx4MCAD7Sq45YjD4XQGPaFqsCd8jTnKr2gAIAzQ7Yjvasu+pCxKvn5vbmk9pizbRbfZunACUuLC2jRWX8cgtl6xfPLAKIwbEE0/Z2ox4+blWThVakS6QYdljgrVgG8xR+LrkRVfZouVBpYDENR+IrWgRiSFUzfkkN56rH/Y/nmDXo2zlY2YtmK332URfKXTLUcnTpzAH/7wB7dBzb1798aMGTPw8ccf+7N7DofDueToTi0spPC2yPuaEbV4/RGfAoc9LdyBrC3VkYU8A134kbVesVYgEg/EptbPeH8vThFXls0mEKO+uDPF12NRrYnGMVEXnuP7WKuPWqXEuAHRkoU1yfcOjNfh0JLJfhfU7Az8GlF4eDhCQz3XJtBqtbQ4JIfD4XA801V1cHwhUFYtTwKwKy1nvogtd+NLjg4V1AJi6/YEWvBKuenYeCBSgbqopkkQAJ5TXO/1u6UsRVLXoy993Hw5j2qVstu50lj8Ekc333wzvv76a7z88stQKl130draiq+//po2hOVwgJ4bTxFo+DxwpOjOrUgCtch7EoDd3XLmKdtt8yPj2tyklUUsKEiVaSmrChFy7uKBSGYaG9vjS4sOKUuR1PXo7Zi6+3n0Fb/E0WuvvYbJkyfj2muvxSuvvILRo0fT9/bs2YPnnnsOYWFh+Nvf/hawgXJ6Nj09niJQ8HngeKK7tiIJlFXL327v/hLIBxFvbTikzpuUpedMudFrQPaIl7ej2Wx1G4/jLh7IYrXR+KemVgtW3T8SvSNCXOK7pObFoFcLilwa9GrJ4/Im4tl5SovTwqBXoyfilzgaPnw4Wlpa8Ouvv2LcuHFQKpWIjo5GRUUFzGYzACA+Ph7Dhw8XfE4mk+H06dPtHzWnx3GxPE20Fz4PnJ5GWxqz+oKvQiKggdYBeBDxd3yspcfdeFhhEqSQodlsBeA+k8tTPBAr4ManxPhcb6qo1iRoj0L26emY3L23fs5o3LI8CydLjZj5/t4e+RDolziyWq0ICgpCUlKS4HVxgLY4Ec7Pkkqci4DuHE/Rmfg7D9wV1z56wvx1xzF2tqUzkJazjqq0HcjxkMBni9VGhUmrxQaVQoYWi81tmxJ39xFfBJy7eQnkPbqo1kTrGpE4KDaDryfglzg6e/ZsgIfBudjpzvEUnYk/88Bdce2jJ8xfR46xIyovt3e/gfi8NwJdabu950jcxNWgVwtqFpH3gpVyNJutSI4MwdePjqM1i9h58nQfYQWm1By3R1i16VgdLUYAYNG6w9jsaDrbU+h++XOci5buGk/R2bR1Hrgrrn30hPnz1P6hvQKkvQu6u8KH7dlvZwhW4t4RN3olc2qx2tp0XQTiOrKS/9uA89VNgtYi3ywYh7mf/YoLNU0AgPyqRlyoMeHpL45KzpO3+4i7OfYWBxWI34ZSIcfSmUNp/FN2UV23/N15oufIOM4lCWlWaLZYvW98kUIWKACXtEvSX3rC/EmNkSxuk97YidtW7PbrN+Cug7qvkIV0x+KJgsKE7d2vu88H8vdO6vHMWrUfM9/fC7PFKpjThesOQ620Hw8JQPZEe6+j3NJ6HCuqAwAcK6pDc6uZ7i8jQY9F6w9TYUR4bM0hv+fZ0zliRVB7rzF3kBIHgG/Zct0Nvy1H9fX1+Ne//oUjR46gqKgIra2tLtvIZDJs3769XQPkXLr0BHdIZ9AWc3d3jFvpanqCS1dqjGz7B38tFYGII5GyJnjary/XoNTnA/17F4sDUv+HvJbjECqA9wBkMg/uriPxMUvNQXGtSbC/svoWrH7oCnybXYL0BD1ueOdnl+88VWZEamwoTpU1+CwwyHfHalW0p1lGgh4Wqw1mi9VjltxPueWS2W1+I5ORf7R/X52MX+Jo//79uP7661FdXe0xyFom63kTwuk+9AR3SGfRniJ1nJ7h0hWPMVDCpiOEoTvXjKABahsrQnsSg/6IfnE16UXrDtNq0k2tljb3GSPjlgrqnrY8yx5LZNBhw9wxgjkgWX5X9I2AWimHyWyFWinH5Ul6jHplhyN1Xo5ghQzNjmDslLgwHHPEJlkdS6zUUktadRC3YX5Fg8txpsZqYbNaMWXZLpdzwsZBaYLkeODjAwCA9PgwfLngynaLUxJzlN0D799+iaPHH38cNTU1+Nvf/oa77roL8fHxUCgUgR4b5xKnKzPceqIFhovJiwt3MTP+7CfQ14G4MzwR5Wz3dW/XoJQYZAOW2xvfxAowcf0f0ocM8K3PmNRxk+3zKxqQ7bBCZRfVYffpSsHvkPQ3y0jQ48CfrqHFHfflVzGp8053VovFhievTUXvCLs17fq37RalnKI6QdaXqcWM4S9tQ1OrBWqlHANitS7WMMBufSJInhOHEYMdQ05xfbszzHp6hrJf4ujQoUO488478dRTTwV6PBwOpavcIT3VAtPTb0YcIVI9rLrDdSjoDG/QYdG1qVQMsN3X/boGJdwwgRD9iREawW+DbdBKAt+J5et8tT3uJ14XLKhS7e6+II7Tider6Xelxmppf7PswloU1zXTmkUjksIhA0AMQsEKoNlij3964OMDGJKgx2u3D3E5FiLQzlU2UAFkMlsFwgiATxYy1roTaHqCO9sTfomjyMhIxMTEBHosHI4LXeEOaevNuLtYmTr7ZtRdjvtiQTyfHWEJDMQ5Y8eVXVSHBz4+QBditvt6W7/DnRvGXiBRjqZWKzRBcreB01JxP+66yovjhch2bMsNAqlSXVRrkqxT9PQXR+m26QYdUuLC6O+wxWzF1Ld+khxvmbEFrKes2QL8/bYMPLMpm36HQi5DenwYcorrkW4IQ2KEhrrwBseH0XlhLUcZCXosnTkUiREaerxkfsXZaewDVbohDM1mG3LL7FauxAiNZDXvttAT3Nnu8Esc3XrrrdixYwesVivkcn5T5FxctMUC092sTJ11M+pux93TkZrPQFsCA3XO2HERWFeVLynmbWkfcr66ibp8mlqtOF/d5OLukTo2d1WkxbDbiYUReW1ffhXGDYhGukGHHIcwOVvRgBazlbrUAGDZHcNcLFLumtKyVbEBIN0QhluGGfD5vgI6B4kRGsgca6xMJsfZykb6fceK6/Hto1eiwthM3a7ieWWP112VbnHsWEFVo8+xY22hpz1M+SWOXn31VUyaNAn33HMPXn/9dSQkJAR6XBxOl9EWC0ygn+57yg2kI4sDeqOnzJGvmC1WZOVVSM5nIC2BgbxW35g5FBarDU99cRTZEq4qd3iz5vh7vO6qT/siLtntpCxHMthdYGaLFXmO+J1jxfV48JMD0ATJqWAa0lsvED+A/V6yYe4Y7D5diXiRxcsu+pzfteyO4VCrlII5EFvTimuFqf4qpVzQWoR1EUplzrm7BsQiSio4nnzen2uxJz5M+SWOdDod/vnPf2Ly5MlYv349IiIioNPpXLbjvdQ4PRVfLTCBfLoPxA2ks4RDRxUH9EZPvMl6QsqlI65a3BYB4+n8B+JaFc//hjb2WxMvzre8m2WPT2LOpfh4Sb0c1vrCZmmpVUrJY/NVbLGB7yOSwnGhxoS5nx3E2Up7XSAb7C6wc5UNMJmF8UVNrVYsvjYVfaJCJb/DbLFixso91NqTkaDH5vljAdirRhMyEpzCip0D8XENT9TTOCUZ7HFRns7P+jmjXTLn2ioYh/TWC6p5+/O764nJIn6Jo+3bt+Omm26CyWRCUFAQNBqNZEo/76XGudhhb8AGvbpdwqS9N5DOFA7uFp6OvglK1a5RyGXd1orkTayKXTqsa6qt38OmcUudf3LO8isa2rzfFrMVF6obUW5sFsz/z3kV6BMV6vZzgD0Ymg1yJiIwWCnHyTLv/beI9YWIIbPFSrO02K71UtejryUwxC6k7x4fTxunpsWFwaBXo6nF1eWmCVJgTL8oqFXSS2lBVaPA7UZiqQAIXl86c6hPJQ+y8iponJINwMGCGoHlSPz72Jdf5eJa9FUwii1Y7fld98RkEb/E0TPPPAObzYZ169bh9ttv5/WMOF1OV7palAo5kiJD2i1M2nsD6eyns7YWB2wLvsSlsLVr2jLnnXWt+CJWxfPVFmFEjoONDyG4O/+mFjMe/vQA8isbvc6Z2WLFtBW7XbKZ2Ayrhz49CADIMOho7yzx59RKGUxm+ydSY7XUldRsttqzuRwCyV3/LbF4eWJyiqB7POla72+8nbvfzZZHxtktW6X1uOXdLLwxc6jgc69OS8e04QluhREgLE8A2C1E5DfBnnexO46FPa7M5EgqLqWa0oqvp8zkSEmLmi/z5MmC1dbfdU/MXPNLHB0/fhy///3vMWPGjECPh8NpM93B1RIIYdLeG0h3eDoLxE3Q0/l0V7vG1zlvy7UiruXT1grlvlwTnuZL7DpydxxsbSGC1Pk3tZgx4uXtaHa4hrzNmbs0byl/AOmdRawb7OeIMALsNXfIeIf01uO16UNoNpe7/lvieYxnApndda1vCwbR/iJDlNh5sgxxOjW1bJ0sM2Lh+iO0iKMmSOFVGAH287v5kXHUisZWnvbnd6JWKXFoyWS314XU9RQIURKI/fS0zDW/xFFMTAw0Gk2gx8Lh+EV38Gd3F2HirWhgZ1hN2nsT9HY+yf7NFmub59zXa0VQy4etE+NBUEnFe7BWLqn2DezxsLAF/ljXkdRxnCw1UgsMSeOWav+wL7+KCiMASI4KEcyZ+NpIihR2Vieog+ToHx2KY8X19DVxl3k2sJm1HGWI4pTIa9mOOZI6h+w4MhL0SIkLw/7nJuHb7BLckNFLMC+sNc3XWKiiWpPAEpX56g9oNtvLBqTEhCK33C5scpliir60GyEoFXK37kIiotsyXrVKKXClSe1X6vfSXnqauGkvfomje+65Bxs2bEBTUxMXSZwup7sIk460mPj6eU/pt4HYf3uyVXz9rPhJ3l1dG3/m3NdrRVDLxwd3lVTGGYnvILFA4vYNnixTwurJTtcRexyscFEpZNi6cILHnlisSyZYKcfXC5wuLHfXxmbH+EnMkVwmw/AkHf53rByDDTqolPYu78nRoS7xU6vuH4neESGCmCMyPjazkfbF8BSjymxjtlhx94e/4GhhLT7fV4BNjgBnqdYZvlgHWxxCqKnViiCFjArIplYrnrl+IP7x/Unan8xmtSKnuD4gjVRZ9yP5fl9+l909W7O7j89X/BJHL7zwAk6cOIGpU6filVdewdChQ6HVXjqK8mKlp17U3cWf3ZEWE1/OjTerSHssbG0RVmJ3kKfKwlLHJH6S9/SE7m7O3e3b12uFFR/pBh1kAK0wbNCrXVKlyfGReBwi6swWK349V01jTsi8G/RqmqmVYdABMpk9Jd4xP6yQCZIDgw2u7rilM4dSt2JOcT0UcpnHa9+TS8bdtaFUyJEYobGLs9QYmFrNGP7Sdpotlf3nKdBqVADsopa4zNLiwjCqTwTKjC0AIAiaZ4O1AQhab7hzq7HbiIOM8ysasHj9EUHMFbl+2GNhr0sA2H26Eku3nhJUlm61OAWaDEC8XoMtj4xDUa0JBr0a01fuAQDa76w95Fc0UHFL6jh5+112hxACT4j7zEnFkPUU/BJHxFpks9kwYcIEt9vJZDKYzWb/RsbpVDriR9eZYutiMPlKWUxoFtL6I4LFU2o+vVlF2mNh81VYSbmD3FUWdne9sUGs/jyhu6ulw7oufBKdDmuFDMCGuWNQVGtCrFblkn7Ozg1ZM5taLThb2YhpK3ajqdVCRRMRVze/+zNOldkFApu1xGbg/fDklRj96k60WoFRL/+AQ0uuQVWjmY41OTq0zedTqZAjUeJY3VnrhOdTjoiQIEG21LfZJbjjiiRqtTxZakSQQoaTpfW0qWqwUo5ms5Weixnv76WigK3y7M5K6C3ImMwbCzvfSZEhLsdhtdrQbPGscGwAbnjnZ3qec0vrcYwUYCyqQ25pPQYZ9JKf9ffe5+08docQAk+I+8y1tz9bV+KXOBo/fjzPULvI6Ihiht35Cac7IraYnK9ucnki9nRulAo5Vj90BY3FkIptkbKa+HIj99XVJeUOGjcg2mUR93q9SfTY8hXxvknjT3aRJq4Yd9eo2FpBRNUNb/8kSD8XFxtkLUcXqhvpXNhgbw0xfURv5Fc0UGEEACkxIQgOUiKnqA7pBh11DSXonTVs7Av1bhTWNAnGKq5u7Kndg6ffpDtrnbg5alNts2Cf1w2OdZlzYn1hs9LIfO05UylwU7JxS+6shN6CjAFn5hc7X2xZhKy8Cskmr75AznNxrUnw+oXqJgQHKVzm29d7H1u/Kd2gw7I7hnl0iwKBr6vW1db27oxf4ujHH38M8DA4XU2g43a6+xNOd0R8DgDXJ2JP58bUYqZP6y98fdwliFcc40IabfrSJsCbq4vse0RSuEsmkdTi5ul6Y7OksgtrkZVX0aYUd3E8Dmn8Kc7SYudXfI1KFcHLyqsQZIWlxWkFi3VWXgVmrdpP5yghXCOYi1uGGSSPYdkdw/DHjfZ+Ws0tZuRW2MdWKBIihTVNLmNlg9O9LcieakS5E7/C1HE5ekdokMsIu0PnazE+RQWDXk3FJyFIIRO4qVJjtXj9+5OCMV3WS4v8yiYXa6m7ekVs9Wf2+qOxXcTCKiqLwB6HsNmrDMvuGIr5qw+7nBeSmUauT4NeTV8LVsjw1vZce2VsCWHty72PZLK1RaAEKoSgox5ek6NDBcHznkoUdHf8Ekeci49Ax+1ILX4Xw5NKRx6DpyfidIMOi69NxZh+UW6/d8+ZSoGA2XOmElcPjKPjlsq+Ih3UAc83ck9iRnyj3f/cJEE3c3Js4gwad5l17HdpghSYtWp/m27g4ngcMWlxYfR6dNdBnj0XrIAkC2xaXBg2zh0tuBbEFrKUuDBBjI9SIceZciMSIzS05US6QQelQoEchwUlt6IRKoUMLSKXT7ACSIlztqkQ/558WZANejVS4+xd4lkL1ZAEPd6YOVTS4ieOUwKAm97NoplbD3x8gGbINYuqR8tsNqTEhiK3rAFpcVq8MWMIbnx3t2Cbp6YOxAMfH6Dfy1pLxefcW4mHlLgwbHZzDyPHsflQIZ7dnENf3zhvDIKDpJfBLx8ZB5VSTvelVMhx+Pkp2JdfhdiwYFz/9s+S892WB01/wgECEULQUQ+vJIi/p9/ngXaKo5aWFmzbtg2//fYbGhoasGTJEgCAyWRCXV0doqOjeWPaHkQg43akFvqe7mbrDFeh+Byw2U4PfHxA4BIS34CiQoWtBNi/3WVfnRTVnXF3I/cknsU32jJji8dUY8BzZp2UJYZYOrzFLxDBkBihoQvU4Hgt8sob0Wy2Ilgpx8a5owHAHiPjOP71D4+WdEOK+0w1tVrw4X0jAAB3/nMvcorrBeMXCz6lwt77is1MSjc4Wy1JOQ3Fwgiwd2x/fcZQulgD8Fg2oMVsRW5pPX1yz69owMJ1h6kVzdTSirwKpyXKYrUJLCusIFWrlBg3IBoFVY2I1apwrlJYYZtcT2LXVosVeO53g9AnKhQGvRozHMHMhHRDGMb0ixJYGsh4yP/ZRdvXulFSFs2kyBCoVUqM7CusiRQcpERydCgVq6TsQFqcFn2jQlzqCJE0ek9lJDwJ/+5CR2b4Xgzxn0A7xNFXX32Fhx9+GOXl5bDZbJDJZFQcHT16FGPGjMG///1v3H333QEbLKdnwf5IpBoZ9rQfkLebc0dYlZQKORRymSDbic3OYRfmygahG+ZYUS0uM+hc3FjilOQNc8b4VGPF3U3PWzyS1Lz4Usto3IBogXvMUwVlsYUnI0GPf9w+BAq5XX4QK1Kz2YriumYU1dTQ7z9ZaqRuQqmxsnOXbgjDo2sOCxqGsrFH7gQfm5nEZkdlF9XBZrNJ1hMChDWCntpwhB6/+PfElg1YuPYQLayYbtBB5siEY8mraEJqTChOlTdgSG89FHKZID6K7JdklRF3VXJkiIt4I+6T1Q9dISgyGayQ0dYaZ8qNgsBzwN5l3v6FzjR9VtSKF213C7q7353Uw4y4T1tihEaQOdc/RotWqw0nS42Y+f5et5mVnh4WvJXUaC+BuM90lwzf7oxf4igrKwu333474uPj8dZbb2Hv3r1Ys2YNff+KK67AgAEDsHHjRi6OOAA8L6CefuzdyRXXFteSuNt4IL8XkH66HtMvSvD0/+zmHKz55bxL8K5Br8aM9/cCcMbhtEfkeYpHcmdtY+M31Eq5ZIC32D0mlerN7j85MgT5jlii7MJaTH3rJ0mrikstHMZNRaw7qXFarH84E4fO1yJer8Hqh67AwYIatFqstGUGISNBB4vVhvyKBsmsvIKqRrSIXE59o0JoY9OnvziKNbMzsf9cNd74/iRyiuuREhuKxVPS8I/vjuN0pcnl+KWuRSKkc5gg5xyRIGFZesdQhAQH0evYaT2xn5d0gw6PfH5QEDxO5peQGKHBgqv7w2yx4mBBjcC19qffDZTMQCRkF9p7f4kD390t2lILOnvOSFNXbwKcxPlItV1hA8SlxGGGQYelTOC0VNZjR8ZbBjJV/mKx8HQUfomjl156CeHh4Th48CCio6NRWVnpss3IkSOxb9++dg+Qc3HgbgH15KrqyqKFUrTFtUSaVgbiyVH8vWaLVVJoSsVVsO4o1k3EBivf8m4Wvn18vHOxaePN11twtdRCcb66iXY4N5mtOF/dJOky85auzu4/v6rRJSiYtaoUVAlbjogbveaW1gvmZdhL2+l+iGAYHO8cowzAlkfG4bnN2ZiybBfSDToqANLitIjVqujCrQ4SziERRoBdFNz4bhbOVjZisEGHbx+9EgvXH8bcz38VfCY1NlRQY0l8TWTlVWBEUriLCCHWp/7RGpx2uNIAQKlQ0MXR1GLG6XK7y81ms+H9ey7H69//RoPDCeJWJeermzDns1+hVsrw8zNXCeb/+a9P4LNfzuMrcg05MhDZjL4RSeE+9/4S10cChBa5bJHr1d11KeUuZRls0OFYUZ1ASLPnSqqYJ3ufWv3QFT5ldvrDxZQq393x6469b98+3HLLLYiOjna7TWJiIkpKSvweGKdzINkfZkvb0lvbCrlRAcKMK6nFk+DpPU+YLfZ4i2krdmPSGztx24rdXo/P13kgN1axYGCPj11A2jJuT2NjBdn56iaXlH92fKt/OS/4/KL1RwTHlRQZgrQ45+JzssxIxyh18/UGEW87Fk/EpnlCIUgshoB9MYzVqnCm3AiLRBU9U4sZO0+WwdRipucDANbPGY1PHhglGReUFBmCtFjnsTSbrVh1/0h7YUXAZcElYou8l5kciYKqRq/nnQg51rJgA3DgXBW1zuQU1eHFmwejd7gaJ0uNuO29PXThNnlIHw9WyqhYOlZUh/mfH6SxQSz/uH0IZr6/l17TAOgDxvCXtmHWqv0Y9coOrJmdiY9mjWTGbp/rC9XCVHSL1UaveXswv32MzRYb5nz+q0AY9Y0MwXePj8fGuWPQL8q1K4LJbMMty/e4BGWfKjXipnd+FghPthZUcV0zXrplMJ6YPAB/vSXd7e+QWIimLNuFKct2YdryLJ9+q+6uS0D4m2VZPCUVOxZPxNKZQ11cgQT2dy2+Tx0sqHF5EAwEZou9Sjmnc/DLctTc3AydTudxm5qaGh6M3Qm0t6VDZwVJu7O6eHK3tTXGgLxHLB8Eb6ZtT6Z5X76PvEeCMIf21mHM337068mRVPEdkRSOMmOLZKq9J9g0eEK2xPG/dedwPLbmEE6JMrWaW4VFW8V/uzt2d0/7Yovh9JV7aCsG4sbJSNAjXhcsKNLXP0aLnKI6pMZpoVLIJVOm6bHcNRyPrT2EU46g8jH9orD0jmEA4FI3hr0OY7UqgYVv9UNX0OwqQNh9niU5Mhj5Vfb4rr98c0Lw3p0f7KUxOafKXAWOGJVChmaz8FvOVTVJbltS1yyZin+2okEwx/vPVSMx0rUvmrjo4cL19gDtIQl6vHpbhtsxBivlOFvViKe+OAqrxYIzldLjK6yRFgG55Q1YsPqgy+tqpRyPr/kVx0vs8/Tmtjyo5PZAbsm6U8yxEBejVAwRW+vJk+uIXAt5ZUZarFMTpMDY/lG0srvTHavDP24fiqe+OEpLBZDfjLcilYEIdmbv1eR+2dNT5bs7fomjfv36Yf/+/R632bNnDwYOHOjXoDi+YbZYcevyLJoS/OUjwl5Jnhb0/IoGnO+kWkTsWMT79xSvIpX14U3QsZYPgqdSAmaLFT/llrs1zfvq9mNbQKTFan1uf8HCVvElC7OUFUq8ILA3SHEaPBtTQ76DbVsh7sdVUicM6i6pa0a6m3Pqbl7YNg3seNhjyS6sxdaFE2idHXGRPmKNYS0o4mtUPP9bF05AYoSGisnUmFC8dddw6lJkz79Br8b1b/5EY2iOFtZi+so9yC1rQGqcFstmDsOT637FiTLXJ/WxA2KRL7LOAUCQXJhplhCudisYCFKZaUkRGhRUNyFep0JxXYvzDRsEizWJg0k36ATxW698ewK55Q3IMOiw4q7hmL/mkOR3n2KuK7nM6ToUQ6xBUgHjUgQr5XjmujT85VuncGTdeQST2UqFEaHF8fVS6fGs2COV05UKuWQMka8Pe0qFHAPjdZJtVaQe6KTS1KW2C3SwM2udEruDOR2DX+Jo+vTp+Otf/4pVq1bhgQcecHn/9ddfR05ODl577bV2D5DjntzSeoFJn5Sz97agEysJAJdeUIHGm5jxFuQsvtm1Ndhx1f0jMT4lBoBrKQH2NXd4+j5BejwjyHxNjxfDViMmS+bJUqNLLR6lQo4Nc8dgz5lKxOtdXRxvzBwKwB4sywaFmy1Wu6XEYdHILqpz6cfVSye8BmK0wbRYJLsvd/NiF3hbHe0g5Di0ZIpkvaAhvfVUlJktVsTp1IJigxarzUU4iEWuxWoTzL9CLhO0KjlV3oDr3/6ZdoInbSvSDTq0mC2C4OLkqFAq3E6VGlFc2yQpjNRBcuzOK5c8f6znLFghwx+nDsSjaw/T1/pHqXG60oRBcSH4rbRR0ipF+PbRK/H42kMAnOJILpdh/ZzROF/dhDNl9ZjzuV305BTVYcv8Mdh5qgJfHSmiXeSzi+qgULivMK6UA2arPdtMqZAWRgCQEqtFbpkR/aNDcFoUg9Q3XIWzNS2C15rNViREaJi2IHL0iw6lLkmn5cMeyH6ccVVSy5FEejxpggsILYJSMURtfdhz1+ne16Bl8XaBDnYW3ye5MOp4/BJHTz31FDZu3IiHHnoIq1evRnOz/Wnz6aefxp49e7B7924MGzYMCxYsCOhgOULE5eyLa00YZNB7XdDZJ0DW/++rhcNXpDqVs4soeVJjW14AzhYIUschtkSIBZ24Quv4lBjJ1GfikhALo3SD0BITq1VRASkDEBmipONj3wPsC6fJ0SNq49wxKDO2tOnJcURSuIsrJzVOi6Uzh0GllAvExO0r91BhnB4fhmV3DhdYTYgAFDeelarwzCIe65NfHEFuWYOgy/n6OaNhsdqo9Yptxnqm3EhjV5parbQQJRmHVLYREaiD48Pw+9F9MKR3OG5452fnHMSGYvk9I+h5IW7T9Pgweq7JGM5XO1PUCdmFwrYV4gyu5KgQfL1gLO30TjICxcSGqfDhfaNw8/IswetBcqEwAuwuLFYYAcDSO4ajpsmMOJ2aptpLUVDdhPmfHcS5aqG1Zfa/D+KyuFDUmIRxLP2i7SUExG6zYKUcpXXuLVdEC1ksFsTrgpESE4LccqH4uSw+DC0m+z7EwgiAizAizPnsVwyICcEfrx+EKx0LORE2iREaGieXGKFBXpkRhy/UYHhiBPpEamgBUam6U56Cj9tTu8eX8ISubInEU+87H7/EkVarxU8//YQFCxZg/fr1sFjsT7uvv/46ZDIZZs6ciRUrViA4ONjLnjjtYWz/KIE5fWz/KJgtVvvCxSwa4lohUjVV3KVTi/E1xsmdjzwp0t4EcthfttrL8CtlsNns7oUXvj5GY008ZX38fXoGHl97yKUWCWC/iWxgXHGAs00Gm8WzaP0RbGBSvMk8ip+zDxbUCBpt3rp8N85W2ftbPTE5RSBkTFQU2OM+ekcIb85sPR6pNP/iumbB/gx6NU6VGnHDOz/TzDHA7jpkF/ic4npMWbZL0gXHiiO2QnJqnBZbRJloUgGfJP6G7XJOepUNNujwwb0jEK8Pxu3v7UZOcT36Rwmvodgw13YQYsFGBOqx4no8uzkHKTGhCFbaY3GClXJsmjeWdn7PLa2n5zCnuB7fPT4eKse1SyxDgw06wUKfkaB3KZA5IFpjr/UTq8WmeXYhS6wyABCvC6Zil1BW34InvziCy3ppBe4gX1t1Ld5wFHnlDbgsPgzp8WHIKa5368oSCyPC8VLXAPkzEqIFsFtwnv/quNdxHS8x4tYVu5FX7rqfqZf1wtLtuV73IUVeeSNe/vYE/uvIhEyODqVBzOI6Xem9w9stPqTc8L7g6/d2ZIq+L/DU+87F7yKQERER+Pzzz/H2229j//79qKqqgk6nw6hRoxAXFxfIMXIYxAvNgJhQ5BTXY0CM/alaHIMhFZBKzNNnKxow+9/2QElP6dTsd0vdRLwV+aMF8xzF3nafrqQLAhuMysaaSGV9uGvEyvaIAuAsBMjEAQ1J0OO124fQkv/ZTIo3W4lZXEsnMzlSsICdrXJWFY7Xq2maNNveQROkoC0RMgw6bJg7Buerm1zr64jm8PE1wtRt1jqQXVRHe4y5C5KWcsGx527Gyj00zsQmyhZjz60UZMypsVq6j2NFdfT6IZCaPIRzlUY8s/EocorqkBITimV3DIVSoYBCLkO8LhjnKhswuJcWxxixkctYfZod1+UghzgSZyg1NrdCpQwWpHQfK6rDNwvG0rYQiREa3Pyu0NrT4AhuUciB297bg1Nl9pYaLa0WnCpvQHp8mLM4IcOpUiMendTfJVbGF/Icx3W8uB79Y+znpn+sFvMm9MeCtcK4IHfB4B1FXrl0VqK/woiQX9mIW97NwsZ5Y2gwfmpsKK2dxP5+WTepP+LD3+KLvoqejqwqzel+tLu3WlRUFKZOnRqIsXC8IBYnb8wcSgu+5RTXY19+lUsMhtTNwZt52t13S7nIkiJDJAUTeyMhEOER78ZCJYPdjH+suB5pcVqXGijke1nYWiRkTqTigI4W1kKpkEvWVJHqGk9Qq5TYPH8sFVWEIb31SIzQQCazL2NyuRxrZ2fiYEENFVpkDCQjisBaYciNOLe03uOCq1LIaEuH+Vf1F7yXFKFGQbUJQ3rrsfoPV0i6JQqqGgXzkVvegFuWZ+Hbx8YDgODcSrF5/ljYbDYcOFuNJV8dc7udGLahZ255g6C3lq8CoKCqEYMM9vMvLgEwfeVe2ACkxAqzdhatP4KvFlyJoloTzlc3CTLHZLBb6QDgBDPnYmucO97ZcdqHUXvmdLkzdf+170+4vN+ZwqijOVlmxNS3fsIFR3A6W1Qy3RCGhesO06QS1lXbVvHhr2XHV9ETSNdWdypu647OHGN3nA+/xJFCocALL7xA24VI8fLLL+PPf/4zzGb3qcCctiH+8QMQ/KjdpZC6u/B87aAs5SJjO5VL3ZDIjYT0BRPf8EgaN3GfAPYF4bFrUvDqf3/DyVIj7v7wF0GlabZRKGl2CThbQ4jnJCNBB5sNNF08OTpU0uzu7aaXEhcmqLC8dOZQJEeHOjKsnPE1BwtqXFpepMaGCoQRAJc5zC2tx2MiqxFLnwgNdbMcLaylLTEIK+65HCHBQR6zdaQqFJ8sNQpakZBxqRRAi7M7BnqHqxGtVWL8azvp8Yrxx9Lh6/ZW5ivFcXZkH7llDYLYn1NlDbj+rZ+QX9mIjAQ9PfYEfbBLt3spgmSA2dY5IqWgOjB1cLozF9xk7T0xOZVWHM8pqhO4ST0tlt7avLRFXPkrevxd0LsydslXOnOM3XU+/BJHNpsNNgmTs9R2nMAh/vEnR4d6TSH11snalw7KUmmkmcmRNMZDvNiTgGUAUMhl2DDXtXfXl47021itCrc53D2aIDnmfOYUCUcLa6mrj5jMSSbYhjmjXWqRiOdE0OzSZoOpxUxN+1Jz4ekpk2SAsW7KzORIQUwUEVyb54/Fb8V1OHqhFr/LiMN9Hx0QCCuSRSbVvoDl1WnpGNk3EvG6YIx6ZQf9njH9Iqm4HGzQIThI6bFtAbmJ//sPo/D10RJ8sjsfeeWNSI3TClwZTa0WrLp/JF7//qSg2OGFGhNGv/ID2HI8iyanYOk2p8tF6pfO1gySwldBZYOVXlPurI6AMPYnSG536QB2F+p/H7sSZfXN0KmDMO293S6fFVfWbm3nrSstRo07rkgWpLO7I0EXhMK61vZ9YQ+hT6QGWnUQrUAtjssj7nGpzFJynwKkm1i3x7LjSzyPu9IdbV3Quzp2yRc6c4zddT7a7VZzR3l5OTQa1zRjjv+4+/F7SiHNK/Oc3kpcYJ5uKFJppGyMR1OrBa9OS8dNQ+IFjT9hs1F3F7nBsQXayMKtclhCpKwSpNko+wNiG4V6mhO22WV2UR1uejeLLphSNXOk5kB8Q2T7KqlVSux/bhLNtCP1UcwWK2a8vxdNrRa89O0J7H9ukkvmGnGluRNGMgA3DYmHVqNyZIA5Y6/KjC34wpHK/8b3J2k7g/VzRgssgcTaRsYvFiOnSo1YvO6QQODF6zUCYUTnQSQWJqZGY+vxUjq/pNM865pSyWX472NX4qkv7DFHKoUMLRYbBsSEQgYbcssb0TdCg7fuGg4AOFRQA7kcyEgIFwiYpd+fRF5lEzIMOrx2+xDJ+SL7JrCX0oBYLZ7+4iiyi+qQGit90xVXdk43hOF0eSOaWi0C66avnKtudhF+MSFylDdaEaWRo7LJ+X1NPhrXbxtmwKbDRW0aR3dDKbM5kx5sNvQOFxaBTYzQuCyW4kbLrOtc/Dv2N2jZFyuQu9IdbV3Qe0LsUmeOsbvOh8/i6NNPPxX8ffjwYZfXAHta6Pnz5/Hpp58iPV2qfBynPYh//J5+1KYWM6atcAaiDo4Pc7nwfDFp+vJE9uzmHKzKyqfxBGw2nNQNjnxPfkWDx/gOEojsqeqsuzmJ1arojTdYKafCCADS4pxz4WkOxDdEtq8SAJr+/fm+Avo5tl5RU6sFBwtqXGqomC1WLFp3mP6dbtDh0UkDqOXMBrvFZqBG5XLzYCs7s3N8vrpJ0OFcPH6p5Z0NhG5qtcBms9EAdKkUdUJIcBA2PzJOUHcGAH48WUbdJMdKjFAq5PjykXH4KbecBqmzwb9nq5twy4rdgiD1mSMTaZB2vyg18hwVmbOL6ty24ZAqpkhobG5FXpndlXaqzOhiJWIZHB+G6y7rhYlpMbjF0aJDLIxiQoNQ3uDZ0mMy21BlFLrvaprt+xF/tKrRu9UoWCnHzJG9JcWRHIC7hLneuiAEqYKQ7yajraMICwLqHYdFahcBJGDf2UhXKukCgKBHndli9RhO0N7F1Fe3Dvs7zEjQAZBJZgR7oyek5XfmGLvrfPgsju6//35H8Ckgk8mwZcsWbNmyxWU74krTaDR44YUXAjNKjiTeftT2Rdp522wwuT6i+mrSFAsQtkozgQ20HBwfBhnsga32G4l0J3kxH943Ar0jQmiZfk2QggYie+t0Typ/kxgntlJ1s9kZr5QWp8WWR5yWLE9ZMlKB5WQb8TGRrJsRSeEu7jYyPnIDEAdIL7tjmEsafXFtEwbG66BUyGktqGsGReOmd7JcuqOTgHXWUiauCyVFuiEMMpmc3uStNmcfsVYr0D8mFKfLGwQZe6QWlFRgf58oYdwaOSdv/O8UfW1wfBjkMpng+Nkg9fPVTZAr7P3YxPFBP5woFfxNqkgPiAl1m3FVVNtMyxykxYXhZKmrGA9WyLB69hWYvnIfjhXXY9n2XJqyPzg+DHllRjRbbFApZPjvE1fS+CuxxYrl6oFxWL7zDP271bGdyWzFu3cOw9nKRtx5RQIe/PhXj8HwMVoVyo0tuPPDX1zeM+hUKKqTrjUEABfqWgE4xVd8WBCK64ViLCFcg4XXDMCTG7Pd7scbMthdZmermpAap8WmuWNwocaE4tomhKrkmPlP59iDFTI0W2zQBMkFSRfiqt8kXu/pL44KSpNIhRO0h7bcA9nvJZ/1Zww9IS2/M8fYHefDZ3G0atUqAHbx8+CDD+LWW2/FLbfc4rKdQqFAZGQkxowZg4iIiMCN9CKkvRH63n7UmcmRgqfks9VNLtu0J4iRWA7EnasBoMViRbBS4fhLhsQIjeT3iIPCr0qLpXE7bIo9G38khbGphXY2J5xkrASaIAU2znMWZgSEZQ/YMVisNpgtVkEcQ35FA71xs+NnA7XJPGQk6LHu4dE4VlSLm4bEQ61S2tt2MH28Pn1wpKC4ZLwuGIlMVeFgpQyj+th/P6YWM405ErvGUmJD8czUgegdEWKvzcPUvTLo1XT8J0vqBYUVk8KD8d69o5DWyx7PRYLUf86rEMxrkyMym63Fs+yOYW5LOLDHoA6S46kNR1wsgzVNZmx5ZDTu+mA/ch1ZZOQzQ3rb559YHlmrTWqcFgMNwvOvcHzvuUr3sU2psfaaTiTOixTQZGOimi02ZOVW0c/YANQ6HiaMLRZaYLHFYkOdyYpDS6bQHnh3/HOvpCuypsm9aEmKCsVlCXqEh6ixaf5YrN1fgP/7UjoLsNwovR+VQuZRGAHAZb1CcaKkgV5nYmEEAIU1TQhRKVxebws2OMtcnCo14tblWVAFKXC8uB6xWmGNKTKXTa1WFNc1U8FhsdpocgXrns0uqhO0mpEKJ2gPbbkHihfx7ragcwKHz+Jo1qxZ9N87d+7EtGnTcPPNN3fIoC4FAhGh7+1HrVYpcfBP11BLg9Q2vpo0pRZCYjkgIumRz3+lKdNsIC5bU0hqH+76FdkDnuXU+rVw7SF8ueBKSffhiJe3ubg/WGFIYnXIzYytmJ3tyJIprm0SxPCw50Qhl2GDhOVK6saeXVhLqyiv/uU8NswZTfuZAXah9/2xMkFxSeJ62//cNTQ26q4Pf8HSmUNxobrRpa0IAPSN1EClVFA3VkpMCBUxbN0qpUKOCpGLp6CmGc9uysb6OaMFcWLi7FJxR/HkqFDE64Jdrl9i1WsxW+n5MrVaJV2mhTVNGPPqDwKX3drZmQjTqKh4EROslGPT3DH2WC+mOCPpNM/u68WbLsOfv3YWP3zy2jS6qJlazMh1WI7OiixN3x4rFo3Tvu9zjOBWK+VobrVAqZBTV+nj16Ti4c+E9Z40QXLJ1i6ExRuOILfMSOdu1c/5brdlYV2dUhYrIp5TYkLxzt2X43xVI61FZQMQpABaLYACAJOQ6NJTj1jEPLlWPZHHuPHKjJ6zA9n4Q/Zhg8YsMq1mAoX4ftYd3TqcrsWvgGxiReL4TyAi9H35UWs1KmxdPNHjNt5Mmr4IOYVchk3zxtDMs3SDDjKZ0Cfv7nvcxQyxCy1gd9GRQohi96FUwGyz2YoBURrkVTZhcLyzVQatIs40byVuPAI5Jwa9WmDxEfepI/NqtlipK40lu7AW+/KrqDAC7JaMwQYd03vK6XorM7YIsqymLNuFwb20LhajtLgwvDEjQ1A3SNz6gS2YyGbWsce4+3SlUyR6cO2kxIaioKoJ+ZUNGPXKDmyeP1Zw/ZI5GiA6v4k6Fc7XtSDdEIbqxlYqOMQLbmVDK4YmReJMudGlvQdgP5dE3H45f5zb9hvJUSEYbBC2/3j4s4P03O0+XUktF+KMtJM+FHY0ma24/u2f6f7MFiseW+tahqGp1QqbzUpdSGJyGaG8L79KsjWHGJdGtBLYYHdN94kKRXJ0KFpEsVXk9FtEnxNn1e16egJ2nqzCM5uErrZ+URoU1praHKDOQix24qbJgXBbtacNCLcCcVg6LFuN4xlvPcJ8xZcfdXt/+J6EnCCbK0FPM89kgKSlRQr2hgaANsZNEWUWBSvthRAzEvTYzIiUzORIBCuAZtEdP1gBnHYE8x4vNsLUYoZapRSMd+vCCQCctZIIGQk6NLdacPM7P9M+XeL0eHFBTrEwsu/HXn+KCLGUmBColHLc+G4W0g06LL42FWP6RdFMN4NeLWgDAgiDpgE4SymILCzip3x2ztUqJQ4tmUwz3Egs2NKtzliglJhQQXVqQlqcFounpFHrSFOrBcW1TYLrl4w3r1w41vN1LUiL0+KLuWNxurxB4Noj4yWtb8jx940MwVlRTFWq4zdyptyI3uGucwTYrR12i9tel2Mg585TKYDB8WGQyWSS4szd/s5VNsDkRigU1pgEwohYMtMNOthgLwCZbtBhRFK45PXLEqyUexVGhL9/dxK5ZfZq6QsmDXC/TzfCDQDuen+/S1ybUga8eeflLr3l2sozUwdS8SaV/OGv26qntAHh9Ay4OOoilAp7HyDyxC3uEdadMOiF6baskBNkczGWh+yiOppub7ZYBSn8LOIb2t+nZ9D95JYZ6VNm36gQGk+U7Qh+Jr2aIkOUtGgha2FhFxsbgG+zS3B5nwjBeBVyGQx6tSBWZ+O8sfjjpmyXqthshpv4Bmux2lz2QZrF2gdmF42tViCX9AYrqkOfqFBBCYCZ7++lLRaCFHIcK653scLRUgqiRbzVKhQciREaul8iPsf0i8Li69IQr9dAIZcJROHbdw3HY2sPCVyiH80aibH9owSuLk2QHGP6RWH8/BiaFTjtvT3ILTPisvgwQZd1wFl6Ia1XGK3PlG7Q0YrimcmRtGbVzPf34mxVo0tGmQI2zFi5R9B+JTVWC5VChpzieoGgapVY8In10myxUrecOkiOH58cj/W/FGFiWjQGJ4Qjv6LBRSizDIgNRV5ZAzIS7FmDu0UxWiziYp2b5o2FRqVArFaFEX/dCgDILa3DuaomwbXKurwG9dLi+vR4zBxlwPjXdkJCf7tArFIny4x49b+/Cd5LDFfhfI3dkme12nC8xCjIJgMcIrPK1ZJltgGVDd4LaAKudbBIwLwmSI6HPj0oyPj0hbam2nsSPd01dZzTveDiqAspqjV5bBTqjs4utV5UaxKk2xLRA4jTW4VxAuI6O1JPc+Ib2qGCGsF3v3PX5VAp5WgxWwWuFIvVRvfbO1wtiN9hYYOerxsci3v/5WztQWoB5Vc0CGJ1SutMLi6mtDgtNs4dTeddfIMlnyX/VymdmVxnyo10f2crnQs/O0ckbonMxamyBqQ6+uW1tFqwaf5YQTD5ovVHJM8VsRyZzFZqtSPzlG7Q4XS50RHwLce+Z68WHENKXBjevnO4QBTG69XYl18lsKZsmDOGCrqkyBDc+u7PdEE+U27EgT9dja3Hy/HZnrM4VmLPDozVqlBQ1YgvHH3mAPsDQqLjeHJL63Gh2nktiFPtTzANV8m1eKrMiO8eH4/SOhOitcECqxTLh/eNoIH++RUNNF7J1GrFvR8eQG55A7aeKMXmR8YhRhuEIIVMUmABAByuSovZGSRPYK0/6QYdrhwQjUFxoThR2oDe4fbecAa9GhsOXKDbNVuAA+eqhF/B/Du3zIgT23Kx/MfTHoWRUg6YraC9/gjimLG37hyBmqZWNLdaMW+13R3Y4mNMkRxAZEgQkzQgR78oDU6UNiA1OhinKpzC6e7M3nhv5xlaRiPI8ZMnbvK23u98sQjZH+KIq9p9I20eY9R2umN7j46Gi6MuxJ8nmECWWvf1ghe6AMNg0As7rbuLEwDgtr2I1L7VSjme+zKHmvszEnQYEKulmVFsjJBCLqP7FbcmIAtSRoIOq+4fgbW/FOL3oxNR1WgWWFuWzhwqedyxYSqB4PvH7UNgs9lw1wf7BEUt2eMm9X6kiNWq0Dtcgws1dlHQbLbikwdGYdyAaADSWXNsyvmp8gZMe28PVtxzOZ1fd/FBpPUHWRxY8ckKnGazFdNW7MF/Hx8vcH0mR4cyVkI5ntxwxCUT648bj+LLBVfS88sGXZvMNhwqqENmvyjcNCSeViQf8fJ2NJutgsrC7PeQRZP9t5i+jlRxInhVChkWbziCY0V1GBzvvlfgsm25uMoRPC3uzUbciNlFdThWWIvbV+52iYdSAjDD3sOO1Fw6Xio83w+O7YuPdp+lfz8xOQUniuupqLtQ04Ib3vnZxUoDALFharfVxIlGbDZbYdCrXcSOeDt3Lj7C42t/xfkaz9Yfd6UJrABuWeG0IDabrTRWihVGAJBdWC8oo3FCNF/kPuILvliEzBYr9pypFLTzEWe3iu933JXmG740HAf8L2vQXenR4uiFF17Aiy++KHgtLS0Nv/1mNyWbTCYsXrwYa9euRXNzM6677jqsWLECcXFxXTFcF/x5ggmUv7wtIovU2bnpnSycLK3HjPf3ulS/FscJuOvHJtXvbdP8sdh1qhwPfmIvEthsseGjWSMxITVGmNXmqJQtTqMXx58svWM4yuqbMSIpHHd+sM/es+lYCdbOzhS4vojbKTk6FIMdDW8B4NlNOVjjcPmMSAqnhR4J7LyT43bXp45NwycQ15hSIXfJmiMpywa9Gje/+zOtHZVbZsSUZbuQYdDhHzOGMu6pMNggwzGH8CHuxaZWK06XN0Aucx9bkl/ZiLOVjRgQq6XzKrQSWiVT1HOK6wVFPcWZT3/79hhOV5loXSnAaQmSqm3EiqGmVis+uHcE3t6ei+yiOiqENEEKfPPolYLGvi0WGz1uqXESjjkKiRIx6o45n/4imZlF8vc89UD7aPdZ6tIMVoBmEIqRstK8syPXY5sVgjth1Ba8CaO24k5Ivf79SbfFNvtGheBkab3PoQTeHiLZe407umv/rp6A1JrDWqSluiFcDHPbo8URAAwePBjbtm2jfyuVzkNauHAhvv32W2zYsAF6vR4LFizAbbfdhqys9gUUBpK2PsEEyl/eFpFltlgxfeUeGocgldUl/qxUPzYiCKRuVImi40h0iEVTi5nW4FGrlILvIcIyVquiFoqMBD1tV8EWBswpqsPu01WSqe4A0MpYFLKL6mjWXWqsVtDRHbA/9cZqVYI4KnclCdhq2QDw99syMH1Eb/q+a9Vd0M+/fdflLllZ2UV1mPrWT1ATPwVkWDg5RXIxvu293ZKLE1tR+dYVWegfHYpjxfVIjdNi9UOjBK5IqaVPXNRT7O05XWVfxE+WGV2KJCZFqKHTqJDDxA6JF9G+0aFYMzuTFr08eqEe8Xo11Colxg2Idhs47g5NkJwWEn1l2mC325UY29ckmwgrT4HVUohjtAbFheKay3rhs935qGn2I4++GyAWq+Qcs78nXx/uvD1EsvcagjgTjgdh+4/UmuMu1vRimtseL46USiV69erl8nptbS3+9a9/YfXq1Zg0aRIAewmCQYMGYe/evRg9erTk/pqbm9Hc7Hy6qqvznrnSmUilu7oLdvaELyKLjYVhLTPsYpaRoJP8bFJkiCD4lk2/F9+o8sqMUMhldHtieTG1mDH8pW00EPzQksk01oXMBXmCOVlqz875220ZNPZEXDG5sEYYZNrcaqbjOcUcX5BCRv8+VWZESqwWuWVGDDbo0NpqwcnSemoN8vakJG5Oe8swg0spgPVzRuN8dRMWrT9itw45GtT2DlcjNSYUp8obXIQKiZvJKarDQ58elBQa7lpksK+aGOvQqVIjbnl3tyB+KyFcTdPvAWeaeLwumH4nWz0bcMa9SPUkK6g2ISMkGFsXTqANeGO1KkxbsRu55Q1IN+gQrwvGyJe32fehAAbE6Wij0jUPXYFmi3fBkBKrxe8zkxCv19Asu6OFtZj/b6eIZONzLosPg8xmc8kMDASRIUFYcsNlUAcpaJyPcwxy9I4IEWT5nShtwInS05L7GhATgnOVjX7VHupM2PYaaXFh2Dh3NMqMLYJmy20tOutuwRU/YCydOcwlE44HYfuPlDj1Fmt6MeCTOCLioq3IZDJs377dr8/6Sm5uLgwGA9RqNcaMGYNXX30VSUlJOHjwIFpbWzF58mS67cCBA5GUlIQ9e/a4FUevvvqqi6uuu8EWTfPXVOztaUzccJW4jJKjQpHPVCNeOnOY21Yepx03/NPlRlpxGrDfqFg31rQVu9HUaqGp9eTGlpVXIQgE35dfJehRZrZYBTFNJ8uMKK5tcnvMvXTConyPrz2M/7vxMozqE0EFEOCa7WSx2EVUc6sZeY5aQmy7i6y8CoxICsdt7+3BqTKjoNQASaFnrV/i+R2SoMdrtw+hT2CkvhERH8lRIYK+cFI0tVqw6v6RGNUnglrRnC4pOZbOHIZ5n7vW4xFTWNsssBxtnJeJWR8dpFa5t7bZ3V3JUSF0DkwiEUYER7PZhj6RGpyrEp6TbEd2X35FA4od4kgd5KjQbLNhw4Hzzn1YQF1n9nnZ6VNKe26ZEX/++jgyEvS0TxsAFDDtSNbPGYvbV+5Gi8WGM+UNOPCna3CuqgnzPzuIc9Xur6O2UtXYivd+zMNXj15JHwAG9dLivjF9cdOQeOzNr3LrhmNJiQnB6zOG4pHPD+BCrWul636RwThf2+I+mNwNiRFqnPfgMhSjlLk2IiZoghTYPH8sBjjKcLD3F63GHpTuTzC0p/hIX8ITeBB2+xCL00C2Uumu+CSOfvzxR792TnqxdRSZmZn4+OOPkZaWhuLiYrz44osYP348cnJyUFJSApVKhfDwcMFn4uLiUFJS4nafzz77LBYtWkT/rqurQ2JiYkcdQpsR9+dqj6nY09OYuOEqGwvDPvklRmgkLVdsX7emVnt7inEDoqkbjH1SJossSa0n+xmRFC5YqEckhQvmQRzTBABvbj0lsFjZrFYcKzEi3RCGpCjhE83pikY88PEBaILksFidCzwJaiacqbQvHHnljVREsdagWav2Cyw24lIDSZEhVNSRXmNsZtbRwlo8tkaqkKB9EPmVjTSuisyHWinDF3PtJQdIoPUb/zuFLx8Zh28fGy9oANvUakVydChS47QCCxkA9I/W4HSFUwgkhQejwBGXYgNwx/u/YMU9I6BS2s8JSXPPZ7LuWKEr5p27LsfiDYeRW9YgqGx964os+m/W9ZZTXI+cb3+T3BcAn2v9ELILa/HXWwe7tOZIjdXiWFEt/V6T2YqDBTVIjAyRFEb9o0Mgk8nc9m/zxqnyBpyvbsKXTMudZzfn4OOss/h89ii3LkzCgJgQqIKUgoBowmXxYVg6cxjmfnZQIIxitSp8dP9I9I0Kxd78KlisNry57RROOIRikBwOEa8QuG9VCmBArL0kg7h2VnJUCL5eMA7Fdc2oa2rGHf/cB7PVHtf27t2XY3xKtMC660vRV2/42hy7o+u9cYRc7K1UfBJHVmv3tOFef/319N9DhgxBZmYm+vTpg/Xr10OjcV+63xPBwcEIDg72vmEH4ekJSaplQ6BNxeT7DXq1YN/EBcI+MQiEkuimJXYnjUgKp2NPjgwRuFvI4sgWwzRb7IsV6+IpM7bQp09xTBMhp7he0IcJAM0kE2cqEcTZUS0W0LpKYsuHqcX+xJ6gD8aT1w3EXIc1RuzCamqx4Ia3fsJJpkXE+eomLFx3mIoZkpnlthmqQ3xkJOhpQc1YrUpQG+j1GUPpwpZTVEdF2d//e8Jlf189Mo62MSHuB7PFKkjdVwUp0T9KTotnnqtqwg3v/IwMgw4b5o4RBL+TrDuL1UaD6QFhTNOfvszB1wuupK1FyFhNzJy3WGzoE6HGuTZYLwDXopdSaIIUGJIQLngtKUINlUKGZzfnCAK+M5MjoVTI6XWfEhNCq46frmjE+7+/HHM+825984RSIYdC7my6e7LMiBkr90kKI7akQF65e8uhQiaDQi4T9BUE7L+XGe/vw09PT8DL356wC1qF/YG1T4Qa3z42HlqNCmaLFQOiQ2jLjxaLMw6q1epsOZISG4qvF1wJtUqJFI0KZ8plzmw6iw39Y7UCy2hnN4blcAJJj485YgkPD0dqairy8vIwZcoUtLS0oKamRmA9Ki0tlYxR6g60tSaQu35lUvv15Ublrl+WQa/GjPf30kyszY7sNDbTir1pkSDqPX+8Ckcu1CEzORJFtSa6rbjA3I4nx+PeDw/gZKkRt7ybhY3zxtAMMalMN8C1MGX/6BDkFNe79GEyW6w0qyo1TotBsSE4UebZRaVW2hea5MgQvD4zA9NX7qPvkWyfvIpGLPnSfRfzx9YeoovV0cJaQW81QlOrlbrCbntvN81MA+yCkdSQMTlio8iCwLoWxTS1WPBTbrlLK5Hi2iYMiNXi28fHC64Fs8UqcCnmlTdApXC1+GYX1eF8dRPWPZyJG9/JwoUaE826M1usgrijxMgQnKsSFuwk2YNEeIiDsMn5Iq+L45gAUMtXn0gNnrw2FTKZHAvXHaIZYpC5xjg1tVqgUSmQHh+GnOJ62nOMiDQbgCenpOL+sX3owk5+U00tFkHtpJf/4yo4AaBPhAbnqpuQkaCD2WyhaesqBSCX2Y9DE+TMjkyKDBFk8uVXNgqKnBJaLTbBfPSPCZW00GUX1aHFbJV0vza1WjDmbz9SkUWyFs9Vm/DL2WqaEfrH3w0SuPaC5DKapECePc6LLGru4nhMLWZ6vQcie4nHC3G6gotKHBmNRpw+fRr33nsvRowYgaCgIGzfvh3Tp08HAJw8eRIFBQUYM2ZMF4/UiSc3mbiPmNRNor190djvzy2tF3z/+eomKOQyezVmJh4mv6IBKY5q0eL6R+6CqNltU2NDBULg9//cj7OOG+/JMiNtvArYb+5k8WJra1isNkE80j9mDEVJncml2Wd+RYOzsGKpEQa9d6sgiXfJr2rEMxuz3WZvlTcI4z7IE3awUi5Y6HqHq12EESFer8HdH/4imA/Abk0hi2xuWQNuXp6F/zw2XrKnHcuM9/e4WLE0QXI88PEBybILAARiyKBTue30/sS6wzhdZoTJbC8AuPoPV9BMvS/mjqZ93s4x4letlOGW5T87ai8psP+5SSgztrgID1Ivp9lsRa+wICgUchTWNNO6QEN66/HpAyMxbcUe5Fc24rG1RwTnwp4h5tqqgwT3fzFvLI37AkAD3ZUy4PWtp/DV4UJ89ai9qTH5PfxWLMyAKqiSjkNa8fsRkMtgj58KU9F5sLtmna7lPWcqMT4lBgDw1l3D8eiaQ8gts/chZBv+SlkUTWYr7snsg+e+zHH5/kFxIZj+3m4XMQnYrXjuYpAe/OQAdZONdswLoVXCympqtWLFD3l48Mq+2H26EqdKjPjo/stRZ7LSe5GxqQXXvfUzCh01vY467heJERqXuDtvuKuldrHEtHC6NzKbzeZ3B0GTyYT9+/ejqKhIkOHFct999/k9OG88+eSTuOmmm9CnTx8UFRXhz3/+Mw4fPozjx48jJiYG8+bNw3/+8x98/PHH0Ol0ePTRRwEAu3fv9rJnJ3V1ddDr9aitrYVOpwvo+KUsNcRNRS0mjAXHn8C3M+VGTHpjJ/17x+KJkn3R0g065JbW0yfLwQYd5LA/lYrFzNaFE2gKvKnFTPuPZRh0WHRtKh742Oli+eSBUYJ4m4KqRjS3Wlxac4gh38m6PfY/N4lalNhighkJethsNuquyjDosPmRcTBbrILeaL4QrJAhKSrEbd2ZpHA1Cmpc3T/ieB7ifiIuQ2IJGRwfhtwyo+M1Gb6YO0bQPJYg5TISnzvi2mTrIYl5dVo6nt3sXFDZkgqAvTK1u3YZKoUMb94xFPNXH5Z8f9X9I9EnKhSxWhVuW7Hbp3km14PZYsWty7OQU1QnaSViIS4gsXWNZUBMCNRBSuQU1SElNhQquQzHSozUHUhaj6THhwFu+qelxIYiWCFHTnE9BseHIa/M6Lb3GEEGYM+zEzHxHz9RC8+AWC1yiuok6/ykxmmhkttbnpDjTgwPFtQf6helxpKb0jE8UY8xf/sBTa1Wwe9A3MNPKZfB7MZl/On9I3Ef83uUIlgpx8a5Y3Dju/6VOHn7jmG4drC9dtyQF//nUvvosl5a5Fc20ibL4qxTKXhdIk4gaM/67bflaPny5ViyZAlqa6ULb9lsNshksg4VRxcuXMBdd92FyspKxMTE4Morr8TevXsRE2N/Olu2bBnkcjmmT58uKALZXXDnJsvKq6CF7o4W1gq6wq+fI8yyc+cycxc7xJqk3VVPBoB7rkiiT6mklcWpctdO2uerm+iimF1Uh9gwtUusERuwTdxuREykG3SQOT7LLiYqpQKv3JpOx9DUasG32SWCIHHSOiJOpxYElGY7Ym8WrP7V64ItbhXRbLHhnbsux+NrD+GkY3yk5YZaKUeYJghgxJFaaQ9EHZ0cSYXbkN56rH94NHafrqSxOCazFR/NGglDuMYZd2O2YeHaw3RfrMASC6M+kRqcq2yAQa+GUiEXLhzzxtIMNXbxzEjQYdrwBKz55TytQD5r1X4qGIpqTW7jsFhX05CEfBwtrMVgh4Bucbh7/vHdbzheYnRb7E+MSiGj10OsVkXdhZ6EEWB3Ae0/V+1WGAGAjYmLlMHZrDe7qA67T1fSGJ8cD8UiWUEsdl/RAo+iY7UBuPkdp7XOZLZi0ZRUKOQy+htmYQU0OW5xYcYzlSY88PEB9IlQ03g4cpZIVuKLXx2nveTcCSMAKPShcGSz2YqjF9wXUPTGY+sOQ62U4527hksWhTxeIky+EGedSsHjjDhdjV/iaNOmTXj00UeRkZGBJUuWYPHixbj11luRmZmJXbt24b///S+mT5+OG2+8MdDjFbB27VqP76vVaixfvhzLly/v0HH4i9AtpaUL37gB0ZLVn9nYFbGliX26MrWYXQQV2yKC/X7SkuMyx5Nyi8UGTZACNw+Nx9r95wWLvdQ+xKiUcpq6zlaXZhtNznx/L0456hJ9MXcMdWWwAbs5jpoZrEtrYlokkiNDkF/VaC/2uOEItQawbSdSYkNdajOlxmrx9l3D8eSGI8hxtJt48ro0DE/UY+Y/99FFK90QZo/NecwZm2NqMePb7BIMNoS5WHlidWo89OlBWoOHDZaWKmxpFtXoya1wuqDevnM4nv7iqEsfNJVChtK6ZkdmnQKb5o0RLBzFdc149257a5HECA3OVzfBYrXRzD9xBfLsojqBtU+cbaZSyPD61lP4/ngpNjvapORXNOCJNb+ixWKDUmZfUMmiJyjgKIqdYdtipMRqaQsWX4KpCZf10rq4SzfNHYMFnx9EUb3dBXi60gTALgROlTXQmJ4hvfWIF7WpGBATIhngzBYNBYTWu1ar3eqVmRyJtfvP44Wvj9PtyoxON2SwUo6x/aOgVMhp+Qv7nAozIH1BKkB9SG89xqfE4JtHx+Hyv26TFCOsS/H69DiB5dCZ7WjP0Gy1gv7e1/xSgOyiOskWJ94gQk/KCii2HGWKXHhS8DgjTlfjlzh68803ERsbiz179iAkJASLFy/GsGHD8Mwzz+CZZ57B6tWrMWvWLDzyyCOBHu9FhVIhx/o5o6mQYcvpS2WEsTEIRwtrseVwkWRZdzb4l1ik3D51Ocot5Fc0oMViozEIWo3Kxc8vtQ+pthlKhRwT02IlA7bJvwF7fBEZG6nbxN4Qg4MUgmw14rpQKWR4+dZ03Lzc7gYQWwNyyxrw1BdHqfBLiwvDlkfs80qia85UNDjjcOaOoTWKZDJnuxIyJiLwxCIsSO6MQ8kurKX7IEJQPDeJERrMYLrbsx3sZbBb+z59cCS+P1aGGzJ6QamQY19+FVotViYt34KzFY0C0fjE2kM4Vlwv+F5vFchZa9/WhRMA2Os4PbL6EM3Oyy6sxYYD5zFteAIsVmeBRHc1bkixv7s+/IUe82vTM6gLlRVgbSli+NTUgRgQqxXM5ZDEcPxz1kiBWCXiJiNBhzUPZVKhCghFmkqpwMp7Lsfr/zuJvPIG2l5FrZQLCpH++0FnjBMJPgeADfsL6HcGK2RIiQtDjqP209cLxkGtUsJsseJvt2XQKuVymRwDotU0I8wTUuIkWAF8+ciVgvIQm+ePE8RtkQKdJLOUxDGyfPPolSirN+GN/50SjFmrUWGzo8wAyahMCNfQ2CHAHjsn7mNIUCvlGJ8SjcPPT8Hu05WICg3CkxuOIre8AQq5HPufu0bw4OANXpeI09X4JY6OHj2KmTNnIiTEecO1WJyPRXfffTc++eQT/OUvf8FVV13V7kFezBTVmgSWIWI+ZsWIlFDSBCnwzKZsQTaXQa9GVl6FIPg3zRE4LeV+YxuYkgU/v7JRkDLvDXdtMwD3T3/i18SBl8cKa7DzZAUiQhR0WzYTp8Viw2NrfqULmdRikl1Yi/8+diWCgxR0XGfKjdS9wnYHP1hQQ1saZItM+ALXo0iEiRd4cVuEpMgQLJ05FADoosb2Fps6uBcVRzYAN76bRUXPC18fx6ElkzExLRamFrNAlP3tuxMC0UhEBwl+LappchGlrFBjXZlsdt+ZcqNLwcZnN+fgL9+cwBu3D3E592RM6QYdlt0xjLpbiYvLZrW6/V6pfm/E6jAgJgSnyxup+BvVJ0LyOgsOEt6+SF01mw0CgQabTeAyO15cj7mf/4oMgw6r7h9JY+TEZSCUCjm2Lpoo+M7c0npBFe3EyBB84XBRshmA4l5fJrMV91+Z7FJvqW9UCGw2m2DeW6yg1zuZk5Q4uzubtRSvnzNa0Iz5qrRY+vsj16/4N5jWKwwalYK60dnfOykzQN4rrGmiFjhx/0LA7gZeOmMoyuqbMbZ/FBU9kwbF4Uy5UdDUt8zY4tWVJobXJeJ0JX6Jo9bWVhrXAwAajQY1NTWCbYYOHYp//vOf7RrcpYAv5mOxUGJjkkjfshFJ4bh5eRZOlRqZbBcttjxid2Wx1a7/MWMoFHIZ4nXBNM6FfIaMwdd0XFLUkP2bXUyknv7ElVWnLc+y3+ANOqx6YAQtdLd0ey4O/Olq1JmsiNWqaGd3ADhb1YTUOHtVZXcugKc2HMGyO4dLzjUrKkckhdN09lSm1hIgLBnABtuKg8Av6xWKMxVNtKmtTi3HlKU77VYHx/yJv3/ptlyXDDg2toTEZqhVSqydnUnn5VxVE9Pk1Gm5yEjQY+HaQ4Jg34wEHY0r2jxfuqItYA/cN+jVAlcQmLH8/XtnYUYy5v4xWiqK2ABvIiJziuvtLjZHzocMoLFOBr0aZysbcb6qEYZwDVSORsAkDooEidsAFNc1Q2FsQVJkCLXmnSk3IjFCQ8WBPYDfvniz8XPiY2HJLqpD7wjh70/cdsLbAp3nKO7Idn+X6vUFAMMTIwTzq5QDZysbkR4fJrBskbpW+/Kr6O88p6gO+/KrXLJJl94xDIDdnequWvF6x75IHScpdz5BfD8i7nS2nAdgT5j46pFxDpFqnwN27gLhFgtkrSQOp634JY4MBgOKi4vp33369MGhQ4cE25w7d07QBJYjDREQrMAQI75JjBsQLXAxZCZHCjKWSP2c8Skx9GmXDWQmcT2sNSIhXIN3776clv2/ZbnQNceOj9wEzRYrFTYAhBYJRlCJFxf2tdzSevr57KI6vPLtScG2q/dewI3DDFCrlNj37NW48e0sXKg1ST7JAsI4kZxieyYWOxbWCkdu+rev3EPr/JwqNeL2lXuoNYAtGWAyW7HsjmFuC0w6A62tGP3qD7RAHmsRFItbG+wZZZ/vKxAs6mxFcLPFiic3HBVeE459y+UyrJ2diTJji7DIotnR3X5HnmAOxBVtxVlBGxzFKlvMVty+cg/t18ZaNoiAyymqE1Q0l6K4tklwfll3z4BYLQbGCzNIxO7VjAQ9Fq07TK8pcZwdK7bI62xfL7bvE7neiXAkYsib+4b9/SVHhwqEDDn3bNIBKwyIhSzdEIa0XmHYPH8sckvrMe+zgzjrmFNisSKQ3xcbe0hEPJvsQISwIHOT+benuER37nyp3wg5rs3MfSo5OhRmixW/e/snGq9HskTF+/FH3PBsNU5X45d6GTVqFH791VkpdurUqXjrrbfw6quv4uabb8bPP/+MTZs2CfqacTxDChWKbwRSNwkA9GkcNhtOlze4ZPLEhqmpgFm07rDkd7KVofPKG/D4mkO0SCArPFQKGZ5Yd5j2uCI3QbGbiF3cWdeSuOigpxvmpsNFgr+/P16Cpdtz6SJHhNHGuc5CkWynb6lYFnfuSlLIUpypl1NURxeOjAQ9tU5IWRaIxSBXVOGajUlNjgoRuA8zkyMFi96MkYmYMTIRP+WWUxcPsZikaFTIKzO6dKF3WpjslcQnpsW6jAFwWk7cZfxIZUySY5IKrGcFdUaCq0VAHGc1qk+EYEEnaf/eWkGQhZW1Ih0trHWxnrDxdGKLJFnIiUWKFcRiN5g7pH5/Xy+4kga0pxvC8NQXR6kYcSfC2es9OEhBhRFgL/sgvq7E80B+R2xtL2KhY3+D2aLfoHi+yDXgzp1Pvpc0dBafJ3JtmC1W3PJuFv3dke8W78dftxjPVuN0NX5J8RkzZqC5uRlnz54FYO9H1rt3b/zf//0fhgwZgnnz5kGr1eK1114L5FgvWqRuBJ7eY0VJdlEdbnvPtU7OwvWH6WLM3jBTYp1p+Jog4ek/WWakN+K0OOeNqMVio8KIfCfZLsMgXTtCpZChvqkF05ZnYdIbO3Hbit0wtZhx24rdmPTGTkxbnoXc0nq7ayRB7/L5B8f2xZb5Y2g8TXZhrbPlQqkRZcYWbJo/FjsWT8SmeWOgIY1LGVIdVjCxWZ+4ZcwWq8NtJpyHlNhQunBkF9Zi6R3DHN8zli6m5POE5OhQpDvmYnB8GNSOXmQqhQzv3DWMLrKT3tiJme/vxeqHrsAnD4zC6j9cQc937whX14PZYsVjaw+5vE4Cy9nsHyJMALsV761tp+j2UkIGcLoNyb5YF4tapcTEtFganP/JA6MEgnrpzKGSC/pmx3nZPH+sveAjs6AfLKhxKXQqJU7IwpocHYohjmMa0ltPhSX5mz0m8hkypsXrj2DKsl2Y+f5eJEWGQK1Sol+Mlv6fjQ8i16h4LFK/P7VKif88MQE7Fk/EsjuGuwhQdizsdxGIZQmAI1lgnFurCBEqbFkOAFS02/+to+ed/TdrbRKfX3YMUm4vT/ck8r64sGlGgi5gWWXexsfhdDR+WY6mTZuGadOm0b9jYmJw+PBhfPjhhzhz5gz69OmDe++9FwkJCQEb6MWMJ/+8t6Bmdx3bT5U6hY44hoC0AUiM0OBsZSMeW/MrTpU1CKpubxH14bLZnJYhchNUKuTY/Mg4QZo4ocViEzTJFD/FZhfVUXcPceUsWn/E/gTeW4/nbhgkOE7WPSKuDn6m3OhSGM9d+QGxJeCNmUMFC/6H943AlQOiBc11xe1IyOftMV3jaCAqESxymQx7n70a/8kuxee/FODGd3e7lGRw1iWyW2JInAkbYJsYoUFWXoWgNk5KbChW3DMCMdogmtVGvl+pkNNYFXHtJ7GQcVdpnFhWxNWMlQo5MpMjBQG6pB2GGNZiIL7+WKsZadrryW0i5Z7xxV3jq+XB23bufn9sNmNbY2va4nJy19JHKm5M6t9iaxNraXuDSRYQj4E97owEPSxWG8wWq2RMESmTMSBW6/FY2gLPVuN0Ne2qkH0p0JEVslm8NZwVv0dei9WqMOqVHQ63hRy9IzTIdQgd1tLha0yFu9YiAATxBuLtyA3cXUFAkl49/b09Lk+cpPKzp+P0VB2c/X7SUFXqhg+4VgzfunACdWmyac3u5kT8+TSmXxn7urhiNtnWXeYPGQvJahNnJja1WgSp4lIuD+E8CMUkuRZc50u43eo/XMFcT85qxlLn2NdYEPFcmi1WQdwVew0ECoGoEB1/W7fz9/cTCDxVuPcF8fGRhyP6IOJDsgUb8yV2+XPxwunOdHqFbIvFgoaGBmi1Wsjlrj8Kq9UKo9GI0NBQKBSu7g6OE/YG4+6m5y2omcSGkGwU8Q3Lm+/f3fvs62aLVZDiLN6OPOVFhihx67u7aa80wmvTh+DuD3/BSUdGmEohpxlW7FOpp+ME4Hacvj5lxmpV1NpG3A+fPjgSma/+gPzKRox6ZQcVBFLfRVyORNywrkg2E0ksjFhLVqxWJSkSybEkRYYgK6+CWjSaWi324peVjbj7w1/wxsyhktYO1gqSXVjrkpZO8LRdVl6FwNJAMubYzxDx628siFSwcaDdJr5eE75s5+/vJxC0N+tLHP9EBDfB0zkkqf3EnU3coKT9TFuPm4spTk/Cryv0xRdfRGxsLCorKyXfr6ysRFxcHF5++eV2De5ix1u8g6+Q2BC1Sim4YYnjYgI1TlOL2WXfZFG/76MDOFvdhJRYLY1vGtJbD6VCTm/Kp0qNWHbHMHuGjs0ecOvL8ZtazNh5sgymFrPLe74ct6nFjFGv7EB+ZSOClTJYrVZMWbYL01Y42z8QQcBS02DCu9tzUdNgL4D31p3Dkeo4towEHZpbLcivaMDfbstw+c50gw5bF07ApnljaQPeuxwiMSVWi8HxYXQ/JANo2vIszFq1n8YtpcWFIV9UQNMZY+JcMIlAI68nR4e6xLuQ7dh4Dna7zORIQYwKiWdiP0Pe92WxdneNk0WbjeUKNOIYpPZu1xVIzZNUzJu3fZAgbHGJAW/nUHzeZ63a79e9KlD3Og6ns/DLcvTNN9/gmmuuEdQ6YomJicHkyZOxZcsWPP/88+0a4MWMvxkZvpj5A5kGKx6nu/pH7Ha5ZUaBRQIQFn8kXbrZp9L8igYo5DLEalUu1XRNLWYMf2mrowWBHJvnjxPEOHhzAQDAvvwqahVpNttosLc4Zmtobx2dY51ajpEv/wDA3r19UFwoTpQ2IDVWi28fvRLPbDxKK0Crlc7u9mqlDCazDTKAFkc8U25Ei9lKrUu5ZUZBoUoA2HWqnM4J6cd2Rd8IgasrXhcsyFYU4O51Bk/WErVKKbBEsjFHnjKw3OHpGu9Ii8vFhNiC6+9vWxhH5Nn9zH63VL/HtloMefYZp6fhlzg6c+YMrr76ao/bpKWlISvLvy7Plwr+mMzZ2kJsXRGWQN+IhEXjhC1M2H2Lj4eth1RQ1UiDSaXiadh6NmwHcuLi2nOmkgZON7Xa6/mwpQ3EFYmljttuFZFTgdU/RutooRCK/Epnqvyh87VYujUX2YW1iA0TVgo/UWrf7lSZEQtW/yoQViamrwb5N2mCS+KaUuOk3YZmixXTVux2KVqYGBkimfHFZiuybjWp16XwJEyIJdLTZ3y9nkhGIwky51lH7aM9v22lQlgQ0pc2HuRz7XWDBqIoJIfTmfhdIVsq1ohFJpPBZPLeEfpSxp+MjPyKBsECmF/RIKjOCwT+RuQubkEqlVp8PFJPuuwNvqnVgg/vG4GSOhNtrSBVJVrceBSQ7tdGkDpupcIpiPrHaGmhx8gQJTJf/QHNZrtoam51WnfK6lvgjvzKRlpZWwwJWtYEKWC2WAUuRZZ4XbB9XxUNLsKIuMYAuM34Im1jSIXrbrkAyYhFTeZxM457yANGe86x2WKVLAjpC+3NHvP0eR6LxOmO+CWOBgwYgB07dnjcZseOHUhOTvZrUJcSHeFa6Ig0WHacnvYtPh6pJ11WvKUbdHh0zSFBOj1rORqRFI4z5Ub00qmgUsgEXcjZxYFYJ9g+X1IWNVKOIIep1jxteRaNObJarZj7+a+Cz63+QyYeXfMrKhtbXfq4BSvl+O9jV8JqA6a/txsms1WQsdfUaoFMJhMUT2QhBRzFsBXOpeZcujGxvThmmaPVhq9ZRYFenNj9FVQ5+/eJ+9ZxfMNTOn9bzld7LcrtvVdJfZ5XwuZ0V/y6Cm+77TYcPnwYzz//vKDhLGDPZFuyZAkOHz6MGTNmBGSQHCdsoT/WsiCmI4JMSSAoAJ/3LVXMjQ0yXXxtqoto6B9ttxL1iw7BXR/sw6Q3diLz1R8EwuiTB0YJA3kd1gmZTOY2jkI8FtKoly2S2Wxx+RiWbMlGZWMr+kRqXPq45RTVIThIAZWjJQVgz+YiBSjTDTocOFclKYxUCpmwgCNT1I8VRoDr+ZQKsj1ZasT09/ZI1nVyFwgb6EBZ8f7YwoXdypoVQNoaIN1WpKqY+/Pb9lZYsaOPQwpvxSY5nK7CL8vR4sWLsXbtWrz88stYu3Ytrr76aiQkJKCwsBA//PADTp8+jUGDBuHJJ58M9HgveZQK1+7kBF8sAP5aCbw94bnbr9jKwW7TL0YraOwKACkxIcgtt98gScA0AEHtpLQ4LcYNiAZgD3K2WG0C6wQJ7PY2FmJxEVukxJyusI9H3LEeAG3sSpq7Et6+azhsNhumrdjt0omdMCBWi92nK2lHc9KSpS3nxl1pAfKE7s1aEOj4NKmF/GIu5tcZlo9Aucm9uba6woLDY5E43RW/xJFWq8WuXbswb948bN68GXl5efQ9uVyO22+/HStWrIBWy83ngcadCDG1mGnzWXeB2u25AXpaRL3tV6mQw6BX035l7DYkO2rPmUrE6zXoGxXCNBBlm4baBZS93YIwCDvDoBP081q47jCtobRZYiziOkItFhv6RGpwrqoJg+PD8NrtQzH9vSyYzDaPwunD+0bgzW25mLJsF9INOgyOD8Ox4nqkG3QYEKtFVl4FtSZJcby4Hg9+ckAQeO5PzSC2mrmnCuveKh0HYnGS2t/FnJXWGVlYgXSTuzsXXZVN1hEhABxOIPBLHAH2dP0vvvgCpaWlOHDgAGpraxEeHo6RI0ciNtY1hoIjjanFLMge8VYpWyr2IFarwo1v/0wLL7oL1HZ3A/TFmmTQq6mFIjVOixazlS6y+RUNHm+spEklKXoo3katUuLqgXF021empePohVrcPDQeapXSJX0cgEDcZBfV0bIBbGd6YkVi58HY1IKb3s1CfmUjFVwpsaFQKRUAmqgQ6hcdiuMlRgyICQVsNhwvFTZ+lQFotdgEMUwpMQ4Xp82G/IoGjEgKp13ZPcEGnvtSrVx8jtQqJa3S7c5aRsockJYtUl3YA2FxvNQWO2/iMlDxXB0tMLvSgnMxi2dOz8VvcUSIi4vDDTfcEIixXHLYa/dso/Vr9j83iXY/l7LAiMXNzY6u2O5adoiRugEKWkkYdFgqEcxstlgx4/29OFlqRLBShlOlRkx96ydkGHTYMHcMFq47TLdNN+hcrBMFVcImlalxWsE2RCCOSArHnR/so4LjxW+OY9+z9pIRbMo7Ga+zL5mOjvm3Ymf8EAD6PaTVyoiXtwuCpQEgt8wpfHLLjLjhnZ/p38dLjEiS6CFmAzBPFLidW27fT05xPaYs24WkCA08yyI7aqW9+CKbzs9avUwtZkmrG3t+2BYrZ8qNLhXSxZWOpeoNmVrMyMqrcEnzbqvF8VJa7Lqjq8ofLjVRy+F4o93iiOM/bFHCplYLvs0u8WiBYcVN36gQnHIIDrEwUgfJBU1B2cWTWBEIglYSTDPY9XOcDWrZmJ5mppZPdlEd9pyppGKGjEVsnWBr3QDAuYoGus3qh5y9vMQir9lsxahXtqPVYhddXz4yTmClIkHOVhuQV2aEQi5Dc6uwerbZYsXv3v4Jp0qNSAhX+yQixRRUu8YaiVHIALGByJfPAcD/3Whvssum8xOrV3J0qEerm7hPms1mk3QperMMCIW6sMimWJS7i+kiXGqp2d3NVeUvl5Ko5XC84ZM4evDBByGTyfDKK68gLi4ODz74oE87l8lk+Ne//tWuAV7MkFYNxHJ0Q0YvfL6vwO0CRoq4EYuRO0ytVpyvbkJKXJikK44UJCR/k0WTcLSwFjcvz6I1eUgbEDEZCTqX+kO5Eou4UiHHP2YMpe4u4mY6WliLb7NLmKrVVhr7Q3C8hZyiOhwrrMGTXxx1Gcexojq6b7aSzqBeWsz//CAKqu31tgprOq7ulhfPGS1PYNAHQx2kwJkKZ1bO/315DC99cwJrZ48W7tNqQ16ZUWB1S4sLE1wX4j5pBLFL0ZtlwF5kkwh1YZFNcWVlcdNSMg4yrp5iLeloeLAxh9Nz8Ukcffzxx5DJZHjmmWcQFxeHjz/+2Kedc3HkGalWDWQBi9WqJF0cRbUmF2HkKWhY/PS6L79KMpsov6KBBjKnxoYKihXmljXYXytrQLohDP+4fSiUCjktI0CsQoPjtThT0UgrULNxSTaJdhZDeutxQ0YvvPD1cWqxePq6gXhkzSHJY5n374Mo8lCUEYDAjfVbidEnt1Zn0D8qGHmVzSiqbZZ8v9lsxYI1Qjddc6sZd37wC/07JSYEWx4Rio1YrYoKL/J/f/BUZLNfjJZelxarvRceeZ+t/j0kQe+2Ke6lSCBcVZeaFY7D6S74JI7y8/MBAAkJCYK/Oe2HbdXAxsawrqaDf7oGWo29jYW4+3vfSA3OilLMU2NDEa8LlqyaLK6uzD7NEgETpJAj3aCj7rJBvbTYPH8cbf3BFqAzW6xYescwWKw2nK9qxOx/HwTgtD6kRIfg68fGu9zYP5o1EhNS7b35Ns0bg4KqRvzj+9/cCiMAXoURIBQInoRCjFaFcqP3/QWKvEppUcQitmxlF9ZRaw4APHhlP5d5PFhQIzjePhFqnKs2Id0QJqiB5S3+ZUCsFunxYcgprkewwl7viW33wcZ8sdcPAIEYAsCtJQztcVX1pJglDudiwydx1KdPH49/c9qHuGlqclSIwNU09c2fsG3xRBr/sYGJB0qM0NDU93SDDi1mC06VNVBxJVVRl+2vBLj2JTtWXI/PHxyFez6yN5o8UWJETZMJFqsNM1buQXZRHdJitVg3JxMz39+HU2VGQa0iltyKRtz0zk/YPH8c1I5CiWqlHGP7Rwm+WyqoXCkDmBAnBMmBViuglAN9IkNo/SHA7vp7567LEa1VIvPlHyBRy1GAqhusMUTIEctfapxWYLEbnhRB51UG4NnNOVjzy3nBIsm6ZtVKuV1EV5sgk7Wt355SIceXC65EfkUDnlh7CMeK6yV714prRZ2vbqKWQ9JPjwf2BoaeFrPE4VxM+BWQ/Ze//AVXXXUVJkyY4Habn376CT/88AOef/55vwd3KcA+HRLyKxsFrrILtSbcvDwLwQq5ZMd54hY7X9WIBz85AMCZiUVcaeMGRFNLD9tfiXWDsIgtONcv+wnVJqd4OVlmxBWv7KBjlBJGhNzyRuw/V01r/pjMVhTVmuj4ANegckAojAC7MAIAsxUCYQQAK+4ZgZS4MOSW1nsVRgBQWOef1Ugs2FhIULa3opIJejVuG5GAWWOSUF7fitxSI05XGHHv6EQ8sOogsh2uzf4xoTi0ZDK2HC7CM5uyAUiXQSCu2diwYFz/tj3TTtyqw5f4F3I9keKbOW5KQpAgezYQfOvCCYIsR3EpBy6W2g6PWeJwug6/7lQvvPACfvzxR4/b7Nq1Cy+++KI/u7+kYJ8OWRIj1DDonB3hT5UaXVKxWRavP0ILCgIQ/H/Wqv244e2fYGoxuzyNWqw2pDlaXWiCnJdDTZMw64sVRgR3AmBATAjUzL4u6xWKN/53iv6dkWC/0SdFhiDd0TKjPZBUfrPFiifWCkXdwLhQOhfitqcqRdsaoWqC5Pj5jxPp54KVMgQrnPsi09FisYEcvkJiP4W1Jryz4zSufG0nbln+Mx5bdxhvbc/DqJd/wAezhiM5KgSnyhow8/29UCrkmD6it0vbB1OLGTtPlsHUYqau2ZS4MLodW/ARcFp8diyeiE3z7EHU7WkVIQ4EV8hlbjPXAtmepCfT1vYc4nPGhSWH03l02K+tpaUFCoXU0sBhYfsdpcY5n7ZPVzQhVB1EX8tI0NPeW+KnSHGX+08eGIVDSybjkwdGUYvOyVIjbn73Z8RqVVQMZSTosHj9YZwsMyIlNhSfPjDKtzGH2zvJs2KKJa+8ERvnjqX1gVosEKT7/+P2IbQA4aIpqYLP9gpVol+0Mzg4WCktYPpGarBl/hisun8kNswZQ4tRsi1HAODJ6wbSORBLucgQu+E0MVzt5Yjt9NarcaSgnorCZrMNy+4Yjr/floFfnptEzw/gtHJZ4L4XvanVihbGzGUDcMvyvcivtAvfo4W1yMqrAADBImm2WDH8pW2YtWo/hr+0DaYWu5Ali+nWhRMAmz1wmhUkbPyLO8Hia+8+b326CD2xd1ZH9BjzVyR2RI9EDofjHb/rHMlk7p+6W1pa8NNPP/FK2V4g7gZSU4gtpgjYs8RI5WcS3wHApUij2PxOXGiZyZHoGxWCs47F9lRZA25bsRunyhuQHBWCF2+6DLet3Eu/a8Y/99F9DooLxZyJ/fHUF0ch7pn64JX90Sc6BLFhakHBREJGgg42m43W+ckrb0CQwpmWv3jdIWx51B6kfZlBuPiWNJiBBqfVqtmND+tsVRPu/OAXNLVakG7QYZkjKFzMm9tyaQD7YIMOxxiRVlLfCgA4X2OCSg6XprJicisa8ajIMrVw3WE0W2z4fJ8er90+hLq1WEgKvzhTTR0kh9UqFEildc5tgpVyzFq1n7pRibDJyqsQ1Mci1bUB7wUfAc+xLJ5697H4monVVa6hjuoh6C88fojD6Vn4LI769esn+HvZsmVYtWqVy3YWiwUVFRUwmUyYPXt2+0d4kSK+Cb92+xCBdQWwV05OjNBAqZC73LBZpBYqEltEhBHhlKOKc35lIx5de9jt+E6VNuCJ9a41hQDghW+OAwAGG3QYEK1BXoVdBJEAY1JniYUNSTpWYsSuU+W4om8E/vr1b27HwBKvC0ZxnVBcEIGQ4yhemS4aD3lv60J7bBwbk8UyICYU5yobXF4HgKQINYIVcuRWNCI5KoRadQhszSalQu4SVA3YRc5XC8Zi+oq9OFfdhP7RIXhm6iAkRYWgd7gaP+dVotzYjJuG9MJ9Hx3A0cJawXeJF1NxfSwSWE/H7EWQeHvf1wwrX7brisrLHdVDsD3w+CEOp2fhsziyWq3UWiSTyWCz2SRr1wQFBWHw4MGYNGkSlixZEriRXmSIb8KPSaSwm8x2kaGQy1xu2EmRIbTStZTrw10sE0thjcltbRxfgpqPicQc2U9umRGvfCvdiZ7w4CcH2lSXRyyMpBCLS8Ae/2Sx2vDUhiPILqqTDJaeOaI3XvnupOQ+C6pNSInV4qNZIzGkdxhGvfyDYMzkGDRBCiRGaLBp7hiMeHkbtXglRaixaf4YzFi5D+ccgvF0RSPe2HpSsh3I+jmjsedMJWLD1Pjjpmx7sUXRYipVH4vFnSARV0rvLMHS2ZWX2yNwOkrE8PYcHE7PwmdxdPbsWfpvuVyOhQsX8ky0dsDehNPiwnCytF5yu0Xrj2DDnNG07lC6QYdYrQrXv7kTueV2ywIJambbRrD7dwdpJCuFAr4JJHecr2n2mrXV3gKNcgDeIjfOVTbS6tmAdBD5v34+I/j79elD8M4PeTjniI/JLTPiwU8OoG+ksFfa32/LoFlkTa0W/JRbAaVCJnAFvn/vSNzzwX6BxSk5KoTOu7gB8O0r91CRlx4f5pIFRmDrY0lBMso8Va6+WN067RE4HSlieHsODqfn4FfMUX5+PsLDwwM8lEsLtt7QiKRw3PXhL4L2D4Tswlrs+K0Mp0rtC2ZeWT1uXZ6FPCaVnbWYZBfW4rfiOgyM1+GNmUPR1GLBLcuzXIRISkwols4chkdW/+riegOAtF5a5JUZaRxOsNK+6KuVMphEcUCk/pBYUHkSRoB0RWdSxNAXfAlpFcdLSVFqbBX8/eTGo5J1kM5WNVHBl5Ggwy3DDPhsXwE9b6QAJmmIO6S3HkqFXND+o2+kBl8vGOdsMMws3vkVDYJzmVNc7zYLzBti15JU5WpWPLWnerM4Hg5Al1pI2itwuIjhcDh+iSNeBLL9sFaClFgt3CR+AQDmr3a63Exmm0AYSXHbe7uREqvFseJ6ZCTosXHuaDy65hAKmYDg3PIG3PDOz7islxZBChlaRULmeIkR/aPthRb7R4ciWCnD8RIjYrQqnK9x7ic+TIVqkxmtVivkCsDig7lJBuCbR69En0gNsk5X4pX//EatNFp1EC7rpcTxEve94wJNUngwCmqEbjt3wdlE8FltwPnqJvzttgyXoPSmVis+mjUSiZEhSIzQCJruhqqDBG1i2MVbHFCeEhPqt1tH7FoChJWrDXp1uwKPWfHFFgBNjw+DTC4X9F7rKoHEBQ6Hw/EXn8TRX/7yF8hkMjzyyCOIjIzEX/7yF592LpPJeNyRG3JL66mVINdDE1kpEsODBQJFTIvFRlPaswtraUaaFESExIQqUd4grG1ECi2ernAGK4u/t5hp6dFqgaTQuqyXFrnlRhqUbQNQYWxGWq8w9IvR4pmpaVQAHiuuR6qj0S2xSLlDpYAg04uw5qGRiA4Lwb78Svzfl+5jn966Yxj+/p/jLsLIF445gsDZ8guEdEMYlm3LpQLh1dsycOO7WfRzpLCiePFWyIUZoO/cfXmbhQVrzWHFkLhydXsDj8XlIwg5TCkFnpXF4XB6Kj6JoxdeeAEymQx33HEHIiMj8cILL/i0cy6O3FNc63+H+JX3jsL8zw8Kute3F7Ew8gd1kByGsCCcqbKLDeKKazZbBdlqwUo5RiSF49blWS5B1MFKOU6V2cWYN5eYlDACgOe/OoH/Pj5BMrWfoATw9MYjbksF+MqpUiNSY7U4VWbEgJhQ/PH6gUgI19CU/qOFtSg3+ia+kqNDqZUpI0GHAbFtExViV5q4bQyANlXM9gT7edY9OjheC7lcIRlIzuFwOD0Fn8TRDz/8AABISkoS/M3xn7H9o2ivMQAYFBeC0xVN1G3jLph5cLwWKqUc79x1OW5entWm7/QWIO0rERoF/jFjGP7+3xM0KBwAYkOcwghw1igSt/pIDLfHqEhllzWbregbocHZav+FX25ZA7LyKjAiKZzG/4gxAzBLCCPxHImtdGJrliZIgU3zxqC4rhmL1h3GQ58eRIZBR2srDemtx5h+UQLR466wolIhx+ZHxvkdKyO2BhXVmtxabQIRl7Np/lhk5VVg1qr99PU377wcydGhPCuLw+H0aHwSRxMnTvT4N6ftqFVKHPjTNfj6aDGG9A6HSinHlGW76PvuRExDixVTlu0StOfwlRaLDfE6NYrrvFutwoOAmlbp96JDlHjo04MYbNAhJToEuQ7xU1Drm4Ukr6LRreXssvgwtxWlfUUGYNaq/UiN1UoKI0+w854Sq7W3CnGIowHRIS7xXk2tFpQZWwSFF7OZ2kqEpXcMA+BawFNcrLA9sTJttQa1Ny5HqZBj3IBoF/cdj/fhcDg9Hb8CsidNmoRx48bhpZdeCvR4LhnMFqszY8nhAukbqcFZD64yBUAzy0weFv2EcDUKa6TFhy/CCLALo97hwbggEY+TW2l/7VhRHV66ZTCWbBHG9QQr5Wg2W91abYb01mNs/ygM7qXFMVHg9aIpqXjo04Mun0mJCcXfp2fgf8dKsfKnfMF78ToViplGskTenCozok9UCM5JZOP5gkssmEyG9PgwQVxNRoKOihBWJCRGaGiDXxKwnBarxZYF4wCAxgWxTYDbG7zcFbV0/P1O3oyWw+F0Z/wSR/v27cPo0aMDPZZLCrEL5ItfL+Aftw8RtPAQ42vdIbWy/YvN4Hgt/nX/CIx/bZdLgDXLki3HqKvpsl5aLL1jOGw2G5QKOeJ1wdh/rhqvf38Sx4rraZsP4lZ6YkoaTX8n2GygNZ1YcssbcOcH+yQtaqwwEuOvMCKwtZTyyhvw4X0jBOJt6cxhggKOpDBjUa3JJWD5ZJm9v11wkBLZhbVIi9XSNP9ABS93hdWmrd/ZUS06OBwOJ1D4JY4GDhyIc+fOBXoslxSxWpUgkNVTVpU7eutVuFArFAYkONhXiJWHYNAHY+XvR6JfdAhGvLzdozAiEOPQ8RIjFm84gmOOYpQ2qxU5xfUuxQzNFiumrdjtUtcpSG6vFdQnQroRbCDipfpHh6CwpsmlVhMA/PnGQZg23ICb381CgaPWktjuFa/XuLiRANB2LawlkE3hJ5Bgc8Aulkghzp4cvNxWKxDvM8bhcLo7fj2uPfroo9iyZQuOHz8e6PFcMhwsqGlThejE8GCX18TCCABemZbRpnGwwggAimqboVUrcbCgxuU9XyAtRbILa6n7ifzfbLFi58ky/FZc6yKMEvUqKrLOVZsQpLBHHg2ICYFB73rsAGhtqLaEX52uaJQURgCw5pcCXKhuosJICpXS7kbasXgiNs1zWjzyKxoEC/756iYsujbV5fMZCTra9X5Ibz22PDLOZV+eusJ3RMf49uBPt3kSGwWgR4tCDodz8eKX5ahfv3646qqrMHr0aMyZMwejRo1CXFwc7b3GMmHCBIk9cNjmob7w7t2XY+b7e2mjU3c8vs61R5s7DDoVIkKDcay4no4lI0EHi9WGEUnhfmW39Y8JxenyBqTEhiKXsZI0t5ox7C9bYTJboZSIuBZXqW612NArLAgFVfYMPnE17f7RGpx2NJj1FHOthD0zzRdOlTVgzr9d450Ig+PDJAOOzRYrFq07TP9ON+iwaP0RZDPxRqlxWrx953Cans9aWsT7cudy6o7uKLEViNRw8gTvM8bhcLo7fomjq666ijaffeONNyRFEcHiS8nkSxC1Sok9f7wKU9/6CSUSMTOb5o7GMxuPIre8ESkxIQgOUnoVRgDcBmJLUVTXguomM757fDyitUqs3nsB3x8voR3uwTQWlgH40+8G4q//+c3jPk+X2wVRkMzZRkMTpMC5yiZatkDKcCMlwkrqnYJJ/G6Bj6n+7907Agq5DC1mK+Z+/qvX7QtrhT3h5ADeunMoUuLsdYekFvL8igaB+2zxtal44OMDAOzxRsmRIThVasTTXxylgsadG0lsgWJdTt3RHZUUGSJwHy5afwSbfRBtPKONw+F0Z/wSR88//7xHQcTxjtlixW3v7ZEURimxWqTGhSE4yH56cssbMeffByVTycV4aiYrRVOrFf/NLsZbO/IEr4sDom2AV2HEcrzUaTVqarXgte+lu977iy8GN02QAuNToqFWKWG2WCUDvaVghZoVwLs/nMa3j42XXPDNFisWrT9C/85I0GFUnwhqMQpWypHvaI1CLCsKuUzSYiJlgbJYbTBbrLSRbEd0jG8PSoUcS+8YRstQZHcT0cbhcDjtQWaz2dof5XoRU1dXB71ej9raWuh0uoDt90y5EZPe2OnyukEfjKLaZug1StQ2CR1CShnQNzoUeeUNLp8D7MJo3cOZOHS+Fq9/9xtNkxc3hPWFeJ0KlQ0tbqtQe4OtlNxWwRYovn30Sgx2xLYAdvGRW1qPC9VNWLbtFI4zKfkDojWQyRXILTMi3aDDqdJ6gUjasXii5IIvPo9bF06AQi4TvEay0jISdABkgr5jAAQtPdjPpcaE4lR5g8CF1h1T4AXuvt56QfwUh8PhdBXtWb/5HayLSIoMwaBerottkaOQolgYAXZ3VKvVhr/eOtjlvSA5cLLUiMxXf8ADHx+ATC7HP38/AknhwW6FUYRG4XZ8xXUtaLUAD1/ZRxDwrHLzkSRHhhnZttUKrHnoCuxYPBEb545BmqMHWd+oEPzl5svcfi8AWgRSCSBRInOtb5RvFhO2V5nZYkVemRGPrz2E2f8+iDMOgTkgJhQpsaHIq2iCWinH1oUTsOyOYQJhlBqnpRYccUC0OLg4OTrU5bUtC+xB10tnDqOB6MSKxAYzk35oAJAWF4ZTjjESFxrgdEd1J/FBYojEgeUcDofTU/HrLpaVlYVFixahpKRE8v3i4mIsWrQIe/e6b3h6qaNUyPHvP4xqczXoc5WNOFfhajkiQckkwyynqA4Pf3bQY1PViBCVx++yAfjnz+cEAc/uLEkkw4tse6rUiNve243mVgvu+mAfTpYaEaSQ4WxlI9b9UuD2O5+YPIDGF5kBzJs4wGUbrUqB/z52JTIM9ieBlBhpsfTUF0epoJm2PAtT3/qJptKT+Ke88gYaOE7iZhIjNLRWlEoBBMllmLJsFya//iNufvdnTHpjJ6Y5MrOUCjnWzxmNTx4YhfUPj6ZVrlmxoFYp0S9Gi8QIDTRBdnWpCVLAbLG6tPsgn9s4d7RgW4NeurxBd6E7ijYOpyfS3TJSL1X8upMtXboUX3/9NXr16iX5fnx8PL755hssW7asXYO7mDG1mDHmbz+2KZ2f8MHPZwMyhjOVgWtcK8WpsgZc//bPVHSQmkniqtiEy3pp8fWvF+jfmiAFfpcRhzRRA9ac4noEBymwYe4YfPLAKGyeP84plGKdfctI/EtBVaNLvaFgh/hJN4QJPrNo/RGcLm+g4qnFAhxzuN/OVjdRV1y2w/JD6hvNWrUfM1buQW5pPRVNxA1HbnRFtSaandjUaoHV5hwHEUDkc2XGFsG2Re1oVMzhcHoG/pTG4HQMfgVk79+/H9dcc43HbSZMmICtW7f6NahLgX35VT4VWOyJiNPuxagUMshkzsa0hJMlRoEL8JVb0/H7f+3HyTIj+kSGQKuS41iJvWCiuPXGhrljUFRrQmSIEsNf2g6bYxyxWhXUKqUgoyo1TotNcx3NYtcfQW6ZM/You7AWj4iy2hL0ahS6ESdsBll2UR2mLNuFjAQ9NjviidjU+/VzRtOA6owEHRauO0wtfUQAEUHVHYOvORxOx9IdM1IvVfwSR2VlZUhISPC4Ta9evVBWVubXoC4FMpMjoVK4d1O1F6VMOmWe8MQ1A/DN0WLJ4O4l1w/ES//1PTNNzGW9tFh4bZqgzUZsaBDKGuyp+e5qJ4mnYuEGZxbYuapGpMSG0krb7jrQ7zxZRoWZDfZimxPTYrH5kXHId7gjSa0ihbHFpRhlWlwYTpY6xVJqnBbrH85E5qs/oNlspcIvI0FHq2MTEUPIZrLSpNxmBVWNsFhtgkbDaXFhAgHEawFxOJce/KGo++CXOAoPD0dBgfu4EQA4d+4ctFqueN2hVimx/O4RLr3FAsUT1/RHq02GLQfO4Wxtq8v7b27PQ7BCBqUcEBfCbo8wAuxuM5vNngGW5yjUWNbQSusH9YkMwbmqtvc8I7FBntLaRySFUwEjc/xNPiMuTmjQq2kmXUaCHktnDhU0jO0bGYKlM4ZCq1bhyPNTsC+/CiOSwlFmbBEIlk3zx2LXqXI8+MkBwf6lxkjcZmaLlb6XFqfFlkdcA5kDXQuoO2a6cTgcJ/yhqPvgVyr/rbfeiu3bt+P48eNITEx0eb+goACDBw/GpEmTsGXLloAMtKvoqFR+ADA2tSD9xYvP9RiskPlUsFKKIDkgl7n//If3jUCfqFBqtRFbg3JL6wUWGXcp+Gz6eVqsFlsWjINaZX9WMLWYcfM7P9NsMeIm83SjIkHf2UV1yEjQYfP8cVAq5DC1mGkzWlJvidz4AHTaTbA7VtfmcDicjqTTU/kXLVqExsZGjBs3Dp9++imKi4sB2LPUPvnkE4wbNw5NTU1YvHixP7u/ZDjbzo7x3RV/hRFgz3Z7fcZQ3DWyN8RVA9RBcjz06UFMWbYLv3tzF4ymFixY/SumLNuFaSt247fiOixkiihmJEibpc0WK7LyKqjL62SZkQY8my1W7MuvosIIcAZ2e8oiUSrk2Ozok0aEERusPfP9vTC1mAXBlgD8yvAi9ZpI8LcvSMUycDgcDkcav9xqEyZMwNKlS7F48WI88MADAEDbiQCAXC7HW2+91a36qi1fvhz/+Mc/UFJSgqFDh+Kdd97BFVdc0WXjMbWYcdt7WV32/V2NWilDRKgKxbXCUgPBCuDRtYddtg9SyGBiagqcKm/AFa/soPFL2YW1mPrWT4LPLJ05VLIKNbGgkCrWxOVlajHjlnezcLLMSFufAHaRZdCrPfY8IxYg1kolFiT78qvaHWxptlgxbcVuGiuVYdBh8yPjJMfCHrunWIZAu9u6g/uuO4yBw+H0XPwSRwDw+OOP4+qrr8bKlSuxf/9+1NbWIjw8HFdccQXmzp2L9PT0QI6zXaxbtw6LFi3CypUrkZmZiTfffBPXXXcdTp48idjY2C4Z0+7TlR0WjN0TMJltAmEkA7Dy95djzmfS/c+kMvs8NcUlBRnFiyQrWJpaLfjkgVHITI5EfkUDHln9K06VGR3vWfHKrekYnhSOxAgNthwukmywamox45blWYK4JeLiEwuSzOTIdgdbFlQ1CoLIs4vqqMjy5DpzF8sQaHdbd3DfdYcxcDicno3f4ggAhgwZghUrVgRqLB3G0qVLMXv2bGrlWrlyJb799lt89NFH+OMf/yjYtrm5Gc3NzkW7rs57Ly5/iO/mRf06g5hQJcob7JXAbbC7mAb30rqtgySGWH76RGpwrspZs+mDe0fg6oF20SteJKUECwnAFvPclzkYHB8mqHtEWLjuMF6fMRSPrf6VuuCyC2sxZdkuwYIsFiSb5o9FXpkRxbVNtB5SW0iKDBH0iFMr5bRApLc0YKkA70CnDneHVOTuMAYOh9OzaZc46gm0tLTg4MGDePbZZ+lrcrkckydPxp49e1y2f/XVV/Hiiy92+LgSIzQd/h0dQZAcgorZ7YEII8C+yJstVmycPw6nyxtw6Hw1Mgx6KBVyHDhXhT9/dVzwWWLxKao1ocVsFbjU+josN2fKjZKLJCtY2IVUimNM/zWWnKI6Fzcegf0usSAhbrGmVgs0QQocWjKZBoL7glIhxzKm0avJbMX56iYo5DLafqQtlqlApw53h1Tk7jAGDofTs7noxVFFRQUsFgvi4uIEr8fFxeG331xT1p999lksWrSI/l1XVyeZkddeDhbUBHyfnUGghJEYk9mK69/+mVpdBifoqUssIVwoJPtGhWDcgGhBWjwp8sjWH3K3SLKChd0m3aBDi9lCW4wQiCBUK+UYEKulVhuW1FgtVAoZcorrPS7I+/KrBJWv9+VXYWJa21y7ydGhgmKSi9Yfoc1s188ZjaJak8+xNoFOHe4OqcjdYQwcDqdnc9GLo7YSHByM4ODgDv+ezORIBCmA1ks47kgKYnVJigyhLrF0g44GSAcr5fhmwTjBgkcyxcSLIel7RlLppRZJ8UIK2MsDLFx3GDlFddR1lxwVgq8d6f75FQ1YtO6wQ4w544wA76n5mcmRdJ+aIAUykyPbPEfsmNlikmwxzLbuL5Bup0Dvr6eOgcPh9FwuenEUHR0NhUKB0tJSweulpaVue8N1BkqFHPG6YBRUu28MeymSGqt1cXflFNXhu8fHo7TOROsFiZFaDEkqvbfAXPFnU+LC8OUj45CVV4FZq/YDAPIrG1FmbEG/GBVS4sIkxRgArwuyWqXEoSWTBbWPfEUcXC4uJsldSBwOhxMYLnp7s0qlwogRI7B9+3b6mtVqxfbt2zFmzJguG1dBVWO3FkYDYkKRHOkaNN5LK64+FFiW3TFMkOkFAMlRoegdrsbEtFgaS+RLfR93tX187XptCNfQhrZi4dGeLvRqlRIT02LbLIykGlISK9KOxROxaR7PyuJwOJxAcEncSRctWoQPPvgAn3zyCU6cOIF58+ahoaGBZq91Bezi3x3JK29AfpVrs9USY8f6AZ/ZeBSmFjMKqhrx6YMjoVLIkF/ZgJEvb4exqUUgEEwtZo8ih51jIm586XpNtpmybBcgk2HrwgldLjw8FXH0JtR8FYMcDofDsXPRu9UA4I477kB5eTmef/55lJSUYNiwYfjuu+9cgrQ7E6VCjn/eNwyjX93ZZWPwRJ+oEJzrggreOUV1tBBj30gNrWVkMlux+ZCw1hCpL+TOZSYVmOsug42FFSLZhbVQyGVdbpFhA8czEvSwWG0+lQLgNX84HA6n7Vwyd8kFCxbg3LlzaG5uxr59+5CZmdml4zFbrLjp7e5bIXvBVclIibWLhuCO9aQJSI3T4qSjEONZpnYRAHyy9yx1c5GGsYCrJYW1lIitKlLWJDG+bNPZEKG3deEEwGYPwnZn+WLhbUM4HA6n7fhkOZLL5ZDJZG3euUwmg9ls9r7hJUh+RYOgzk9346mNx+i/e4drcLqyycPWwKr7R+KVb48jt9y3xffD+0bgzW25jowweyZaaqwWm+aOwd0f/kLT1E2tFuQ6UuvzyhqwdeEEWtOHBlszAsabpcSXNO/umgquVMihkMuQ7Sgl4EuBQ17zh8PhcNqOT+JowoQJLuKouroaR48ehUKhQGJiIuLi4lBaWorz58/DYrFgyJAhiIiI6JBBXwwUV/ecJ3ixMOoToca5amc8kgzAqD4R+PrR8bjuzV2CatVSpBt0uCotFlelxQoywk6VGVFmbBEIE7PFSt1spCUIEStSafpiS0l+RQMUcplLir+3rLLumgreVrHTXYUeh8PhdGd8Ekc//vij4O8LFy5g3LhxuPvuu/HKK68gKSmJvldQUIBnn30WWVlZ+OabbwI62IuJFTvzunoIPiMDMKiXFsdLjMhI0GHDnDHY9GshnvsyB4C99cfBghpMTIvF+/eOdFs5mt0fYF+4xw2IdlnsWWGiVMjx7ePjJXuCSaXpC2NzhAUS/Y236U5NTP0RO91V6F3KdKdrisPhuOJXQPaTTz6J+Ph4fPbZZy7vJSUl4fPPP8fo0aPx1FNPYc2aNe0e5MXITUN6Y29+TVcPwydsAJ6aOhB9okKppWL1LwX0fbVSTosZDojV/n97dx4XVbn/AfwzCzOsM8jugAiyqCnuioqKAaW537xpaW75y1QsXG7ZzetWmUtqmalpmWlZhqa5Xa/hhiuIGyIqbiAG6KAo+zYzz++PcY4zzADDMIAy3/fr5avmnOec+c4zy/nynGfBS08TKc2+iuuSaS+WauxtLs3cR4YWkK24XEdlEySassbW89ihmZKdF1tdfKYo2SLEvEz6Fh06dAjh4eFVlgkLC8OhQ4dMCsoSFBQ9v3McAYCTjQAigbqNx8ZKgB4tnLnkIz2nSGcJjR2Te3Bz9iiUKtx++OyWYcXECHg20aOGMUPR/7HmFMJWxOIfa05BoVRV2Wlacz7NMhuGyhiLOjQTczP3Z8qY6SkIITVjUstRSUkJsrKyqiyTmZmJ4uKq+55YsrTc57tucorV8xlZ8YHl/2wHQP0jnPqwEGUKFQLc7LiO0h/vTMJXIzvA18UOZ+48QqlWQuTtZIOsJ8U6a7JNj/CvUSypDwu5TshJmXm4JS+ASMivdh0xc/S3oQ7NxNzM/ZmqrBWVEGI6HmOM1fSg0NBQJCQkVDrL9OnTpxEeHo7u3bvj6NGjZgm0oeTl5UEqlSI3NxcSicRs5z1x8z7GbDxvtvPVNbGAB393ByQbWHRVI0gmgZIxXH26kr1YyIeTjQBZ+eX6ZT2l2PX0doIm6QKg0+Fa4+aDfO72GAAEuNnjprxA5xx1iW5ZEHMz52dK5zadl7TBJywl5HlRm+u3SS1HixYtQnh4OHr37o3BgwejV69ecHNzg1wux4kTJ7Bv3z4IhUJ8/vnnppzeItx79PzdVpNJxMjMMxxXqZJVmRgB4Fp3NBQKFbLyDTfxJ2ktMDv025NIfppQ+bvZYd+0XjpLa/i62CHIU4qkjNynLVYF3DlSHxYiwN2h2tdWm4sR9fEh5mbOzxSNSCTE/ExKjnr16oX//ve/mDRpEnbv3o3du3eDx+NB0wjl6+uLDRs2ICQkxKzBNiZ9WtZ8Nfa6ZC3kITOvFEI+oFABAW52eLOzFz47kMKVEfAApYF2RiEPUDCghZMYd3KeJVdVLTQS6K7ud3RLXsAlRoB6LqPB357CgajeOkPvdz398S9TqKodDVfR89ip2hjUYkWMRQk8IeZl8vIh4eHhuHXrFk6ePInExETk5uZCKpWiffv26NWrl0mTRlqSHQmZDR0CZ8Hgl7Bg71UA6sRIJOBh15SeyMorBbSSI0OJEaBOjAAgNce41jA/FxvsiQyBUMBHloG+VzflBXr9JrRXoQ+SSZCUmYcgTwl8Xeyqfb4XsU/Gi5rQEUJIY1CrtdV4PB569+6N3r17mysei+Hv1nAX54otQJrESKNMyZBw9zF6B7hyt7M8Ha2R8UR/IVptlXVea+Yoxr0nzxKn/wxqw13oe7RwhrUVHyVaPbbbyiR6nVS1W1F2RYYgPacIMqm1US0rL2Kn6hcxoSOEkMbCpA7Z2q5evYrr16+jsLAQY8aMMVdcz4266pB9PSuvxreHqsND5QlKTQW42mLv+72hUKrQedFhlCpU3PmtBDyUa2VXFZ830N0eyqdD+tvIJFg2vB1mRF/CjQcFsLESoLhcqdMaUlKmwMlbD6FUMXg72SLA3UEn2THUigJAZ1t1I9fM3QG2rm93USdbQgipndpcv03+tU1ISECHDh0QFBSEN954A+PHj+f2HT9+HLa2ttizZ4+pp2/0vBytzX5OcyVGAHAzuwhDvz2FhLuPuaH5DMDif7RFwidh8H3a+hLoZq/zvD+M7QyRgM/NdXTrQT4Grj4JsYCPTeO7oLhc3RNJe34Xa5EQES95oF/bpmgtk+olAYZaUSpuG/p0HqTK5nmpbi4lY9XXnDKaTrZHZoVSYkQIIfXMpF/c5ORkhIWFITU1FTNmzMBrr72ms793795wcXHB9u3bzRJkYxSXmtPQIVQrRV6AjMfFsBY++5j8EncXY348h9ScIvg62+LLfwbpHCPg83QmiCx92sKUlJkHryamrXZvaMJH7W2BbvZIeaAewVbXEzXW56SQ5kroCCGE1IxJfY7mz58PADh//jz8/f2xcOFCHDhwgNvP4/HQo0cPJCQkmCdK0iB4AP6zO5mbKRuAzsiy1EdF+HDHZbSVSXAlMw9BnlL0aOHM9VMCni0folk01pQhx5UNVd45tSdSHxZixraLXNlAd3vIpOZvldN4EfsvEUIIqRmTkqPY2FgMHz4c/v6Vz3Ts7e2N//3vfyYH1th1ae7Y0CFUS3O7rEzJ4ONkg7ScYrSVOaBMwXDj6VxDN+SFiJnRBwL+s5Xvdz1NWgCgWRMbvb5ApnQsFgr4kEmtcerWQwT7OsFaJIRQwFe3VGklbDceFGDE+rg6G91Fc8oQQkjjZ9Ive35+Ptzc3KosU1xcDKWyqpluLNvFe7kNHUKVRALAxkr98bAW8mFnbQVAnSj9+m5X+DirW0yCPNUtQpqFYRVKFYQCPgLcHRDg7gBrkdAst4ZKyhTo+NkhjNuUgI6fHUJJmQKA7i03DbrdRQghpDZMajlq1qwZkpKSqixz4cIF+Pn5mRSUJWgqtTHr+Vo420DJgLs5tV+zTcADTn/8MuzFIsSn5sDNQYzXvjkJQN0y02PJMW60GlOpoFCqMGJ9nNnm5DE0Giw+NYfrzF1crkR8ag5CW7pxLTmpDwsxMzoRSXS7ixBCSC2ZdAUbNGgQ/vrrLxw6dMjg/ujoaMTFxWHYsGG1ia1R83K0hjmnybzzqNgsiRGgngNp9A8JEAr4CG3phgB3B7R0f3YrTHsY/5WsfMSn5pitk3Jlo8GCfZ1gYyUAANhYCRDs+2yGcU1L1S4a3UUIIcQMTLqCfPLJJ5DJZBgwYADeffddnDt3DgCwdu1ajBkzBqNGjYKPjw9mzpxp1mAbk/PpT8w69N7cUh4UcEmOUMDHH5N7GJx+wMfJFp29HU0ahWZIZaPBrEVCXJwbgc0TuuLi3Aidtdc06HYXIYQQczDptpqrqytiY2MxZswYbNy4kds+bdo0AEBwcDB+++03SKXSyk5h8dQtIXwUl9fNPDk1IRKo18XTDqXl07XPAHVrzqgfzuLvJyUQCXgoe9pyJBLwkJZThFE/nK1yEsaaTJpY1Wgwa5EQoS2r7utGCCGE1FatZ8i+dOkS4uLikJOTA4lEguDgYHTt2tVc8TW4upohGwAupOXg9e/OmPWclWnuZAMBj+HOI90lQLwcbbB+TGcMXH2S2+brbIsDUb251pk72QUIWxHL7f9xXBfweMCEn85x247MCjU4Cs2UNcJowVVCCCG1VZvrd63WVgOADh06oEOHDrU9jcVRKFWYuT2x3p7PUH+kADd77J2mXgBW01rT0t0euyNDdG5bVWzN6RPoCgBGzfdjzBphFZMhWmGcEEJIQzIpOWrRogWmT5+ODz74oNIya9aswYoVK3Dnzh2Tg2vM0nOKkPao7oabG4MHxiUjVc3dU9UkjNW18FQ3aSKtPk8IIeR5Y1JylJaWhidPnlRZ5smTJ7h7964pp7cIMqk1RAKgrB6mgrLiA+UqIMDNDmVlStx9or61dkNeiFO3HiLE34VrrVEoVbiTXaCX8BhqzTGmhae6xItWnyeEEPK8qbM/0XNzcyEWi+vq9C+8e4+La5UY8QBIRfqTAWiW+tBaDg3lKvXUATflhRCJhAhwVbfe2FgJMG5TAjdkvq4WVa1qFJmhddMIIYSQhmR0y9Hx48d1HqelpeltAwClUol79+5h69atCAwMrH2ExCAGILdMvy/9nmm9IBLy4WYvwvDvziDlQQGEfB7+ftpadFNegEA3e3w/pjPe/fk8AN0h8+ZoxalJh2pajoMQQsjzxujkqG/fvuDx1K0SPB4PmzdvxubNmw2WZYyBx+NhyZIl5omyEfJ1sYO/qy1uZZuv35FYwIOHRIQL6bkoLVdi6/91RZdFR6FQ6SZRN+QFWHrgGveYB8DNXgRrkbDWi6qa0oeIOmATQgh5nhidHM2bNw88nno+nE8//RShoaHo27evXjmBQAAnJye8/PLLaN26tTljbVQUShXXmmMupUqGbl8c4eYh8jQwaSMAiIV83Hr4LCljUE9KGdrSTa8VR9MKJJNaVzqPkTbqQ0QIIeRFZ3RytGDBAu7/Y2NjMWHCBIwdO7YuYrIIZ+48QomZJ4CUSUTIzCvjHmdUknyVKlQIcLHFzacJkvZyHNqtONqtQDZWAhSXK6ttDapudBohhBDyvDNptNrRo0fNHYfFcbU3f2f1/wxqg5nRl1CiULcc+Tjb6kwX4Otsi9RHRWjnJUX0pO64nV2Iy38/weB2TSEU8PVGqWm3AmkWfa2uNYj6EBFCCHnRmZQcnT59Gjt27MBHH30EDw8Pvf1ZWVn48ssvMWLECHTv3r3WQTZGmv5bpgpws8dNeQH3WCTgYeqvF+HnYouxPX3Q2dsRXk1s0PGzw2BQ9yvaNbUHsgvKuWM+3pmEpIxcbI1PBw9AUmaeTsuQdisQ13JkRGsQ9SEihBDyIjMpOVqxYgUuX76MlStXGtzftGlT7Nu3DxkZGfj9999rFWBjlZWrP2N1TdyUF8BTKkZGbims+OD6Gd1+WIT5e64iSCbBypEduMVtGYDsgnLMik7E5YxcBLrZ48bT5OpKZh53Xu2WIe1WIGP7HBFCCCEvOpOucgkJCejVq1eVZfr06YO4uDiTgrIErvaiWp8jI7cUVgIeDHVdSsrMg1LFdOYQAp4N1b+h1eoEAIFudlw57ZYhTSuQtUhIK94TQgixCCa1HMnlcnh6elZZxsPDA3K53KSgLEF2QVn1hYxQrmRo3sQadx/rd77+cMdlbH+vO9fiAzxbDy3IUwqmUuFKVj6CPCXY/l4P3Htcu9YsQgghpDEwKTlydHREenp6lWXu3r0Le3vqd1IZrya6/XbEAh5KlfqTOlbHxoqPNaM7YdC3p/X2JWXkIjO3RKf/z86pPZH6sBAA0KyJjU7ipLnlRmucEUIIsWQmXf26d++OXbt24d69ewb3p6en488//0TPnj1rFVxj5u9mDz+XZwmSKYnRt292RMIn4RBbCdFWJuG221ip39bKOk/Pik7EK18dx4j1cVwfIkPzExFCCCGWyKTkaObMmSgqKkJISAi2bNmCrKwsAOpRaps3b0ZISAiKi4sxa9Ysswbb2NR2xJqdtQCjfjiLV75SL+Pyw9jOOPBBL1yc+wqOzArFzinq5PROdgG3TlrFJEjTikRrnBFCCCFqPMZYzZssAKxatQqzZs2C5nDN7NkAwOfz8fXXXyMyMtJ8kTaQvLw8SKVS5ObmQiKRVH+Ake5kFyBsRazONiEPUFR4N0Z0liH6fKbe8TZWfHw9sgPe++WCznbtW2Lakzi2dLfH7sgQCAV8/GPtaSQ9TZCCZBLserq9JmuiEUIIIc+z2ly/Tb4CRkVF4cKFC3jvvffQqVMntGjRAp07d8aUKVNw8eLFRpEY1SVvJ1sEuOn2yVIwQCbVXfIjITUHVlrv0ktNHfD50DbwdbbVS4wA3Vti2q1EKQ8KMPTbUwCAlSPac+WTMvOQnlNEiREhhBDylEkdsjXatWuHtWvXmisWiyIUqFt+Bq4+yW3zbmINK4HurbbUHPUoNB9nW6wa2R7/+TMZ/9mdrHc+f1c73Mou1Lkl5u1ki5bu9kh5oB62nyIvQOrDQvi62Oks8SGTWtd4sVhCCCGksaIrYANRKFWY/cdl7rGQB6Q/LsHth4aH06c9KkJOUTmStCZs1Pb34yL8L6q3Tj8jANgdGYJAVzuu3MzoRADqUWuafkmZuSXUGZsQQgh5yqiWI82wfU9PTwgEgmqH8Wvz9vY2LbJGLvVhoc7M1BX7GlUU4GaHFQdTuMdtZRL8s5MXFuy7CgAoUTA8yCuBv5u9XivQmrc7c522k7RmwNYM8afFYgkhhJBnjEqOfHx8wOPxcO3aNQQGBnKPq8Pj8aBQKGodZGOkVNWsH/zY7j6Yu+fZ7bTlb7THv7Ynco9trPgI9nXSG4126tZDBPs6VZn80GKxhBBCyDNGJUdjx44Fj8eDVCrVeUxMJ+Abrj9/F1tYi4S4kpkHsZCPUoV6CP7cPcmwseKjuFyFdl5SMMZ0Wp52TQ2BtUiot1jsuE0JaOcpRbTWTNmGkh9aLJYQQghRM3kov6Woq6H8CqUKQ1afwNX7BXr7Ymb0gYDPQ5lChf6rTujs2zyhK4J9nfDGd2e4/kdBnlLs0upErVCqcOrWQ4zblMAdd2RWKCU/hBBCLEaDDOUntSMU8DHt5QC97e28pGgqEeNeThG8HK0RpDXzdZCnFCH+LsjMLdHpmL1yRHud1iChgI8Qfxea1JEQQggxQa2G8hPTFRSXYepvF3W2WfGBDWM6oOsXR1BcroSNFR87JvcEYwzZBaXo0cIZgLq/UpBMgqTMPLR0t0ezJjZ656d+RIQQQohpjLqtFhYWZtrJeTwcPnzYpGOfF3V1W+3XuLv45M8retvdHcR4kF+qs03T96htUweUKRluyAvQViZBmVKFGw8KuFFpAIxKhmjCR0IIIY1dba7fRrUcHTt2zOB27SVDDG2nTtuVayNzMLi9YmIEgOuUfSUrn9um3Rlbs0barOjEaidy1F5SpC4mfKTEixBC6g79xtYPo2pWpVLp/CsuLsagQYMQGBiIn3/+GWlpaSguLkZaWhq2bNmCwMBADB48GEVFNJlgZWzFVtWWsari3QlwtUOgu7qDdTsvdd8iYyZyrDjU35wTPmoSr7AVsXh97WlusVtCCCG1R7+x9cektHP+/PlISkpCQkICRo8eDW9vb4jFYnh7e+Ptt99GfHw8EhMTMX/+fHPH22j4utjpzFwNqJcIadtU3aIU6GaHcq3PvY+TDdo87Zwd6G4PkYCHGw8KEOhmh+hJ3bklQYCqO2BrhvpXV84UdZl4EUKIpaPf2PpjUnL066+/Yvjw4bC3Nzw0XCKRYPjw4fjtt99qFVxjpukwLRY+ewtsrfjYMaUnYmb0gUgo4LYHutlj3/u9uDeLqVRIfjoFwA15Ie49LubOp1kSpLLmVmPLmaIuEy9CCLF09Btbf0y6MmZnZ6O8vLzKMgqFAnK53KSgjKWZqVv735IlS3TKXL58Gb1794a1tTWaNWuGZcuW1WlMNSEvKOP6EwHA1fsFuPdYvbaadp+iNaM7QV5Qxg3fv5lt+K8F7Ykc72QXVNrkqiln7vvVdZl4EUKIpaPf2PpjUs36+flh+/btePTokcH92dnZiI6Ohr+/f62CM8ann36KrKws7t/777/P7cvLy8Orr76K5s2b4/z58/jyyy+xYMECbNiwoc7jMoa3ky3Xb0hDqWKY+fsl7nHg06H62n8xBHlK0PbpLbYgTyl8XZ7dnispU2DgNycM3pNWKFVVJk3mUFeJFyGEEPqNrS8mzXM0ffp0TJo0CZ06dcLMmTPRq1cvuLm5QS6X48SJE1i5ciXkcjkWLVpk7nj1ODg4wMPDw+C+rVu3oqysDD/++CNEIhHatGmDS5cuYeXKlZg0aZLBY0pLS1Fa+mzEWF5ensFy5vLNmx3x/m8XcFNeiCBPCQR8ns4EjzceFGDE+jjsnNpTZ94iQH/YvkKpwtBvTyFFrr7lpllbLcTfBQDqdJQaaTxoNAwhxNKZvHzIZ599hs8++wxKpVJnO2MMAoEA8+bNw9y5c80SZGV8fHxQUlKC8vJyeHt7Y9SoUZgxYwaEQnXON3bsWOTl5eHPP//kjjl69CjCwsKQk5ODJk2a6J1zwYIFWLhwod72ulg+RJOsBMkkWDmyA9cCpNmuzZjlP+5kFyBsRSz3WDM/UjtPKVaMaI9Xvjpeo/MRy1PXUz0QQkh9qfN5jgyZO3cuRo0aha1bt+Ly5cvIzc2FVCpF+/btMWrUKPj5+Zl6aqN98MEH6NSpE5ycnHD69Gn8+9//RlZWFlauXAkAuH//Pnx9fXWOcXd35/YZSo7+/e9/Y+bMmdzjvLw8NGvWzOyxa4860LQUaS5CO6f2ROrDQsyMTkRSRi7X8a66v+i1F531dbZF6iN13yTN82j2UUc+UhlDo2EoiSaEWJpaLR/i5+eHefPmmSsWAMDHH3+MpUuXVlnm2rVraNWqlU4S065dO4hEIrz33ntYvHgxxGKxSc8vFotNPrYmvJ1suSVAAGBmdCK3eKxQwEeAuwN2VbiNVt1f9NpLhsik1hixPo5Lhnxd7Gg5EVIt7QSbkmhCiKUyy9pqOTk5KCwsNEsLy6xZszB+/Pgqy7Ro0cLg9uDgYCgUCqSlpaFly5bw8PDAgwcPdMpoHlfWT6m+CAV8rBzZgbvVlZSRi1vyArRqKtEpoz36zJi/6LWPMZQMUSsAqQqtyUcIISaOVgPUfXCioqLg7u4OV1dXndtX8fHxGDBgAM6fP1/j87q6uqJVq1ZV/hOJRAaPvXTpEvh8Ptzc3AAAPXr0wPHjx3WmHYiJiUHLli0N3lKrb74udtyoMwD4x9pTKClT6JQpKVMgNkUOJ1shWrqpE5uW7vaQSa0BVD0CjUY1EFPQ54YQYulM+vXLyclBcHAwVq9ejWbNmqF169Y6a6y1a9cOp06dwtatW80WaEVnzpzB119/jcTERNy5cwdbt27FjBkz8Pbbb3OJz6hRoyASiTBx4kQkJyfj999/x6pVq3RuxzUkoYCPWa8Gco+Ly1WIT83hHpeUKdDxs0MYtykBHT87jBR5AcRCPlKejmArKVPU+1Ty9TEdACGEENKQTEqOFixYgBs3bmDbtm04d+4c3njjDZ39NjY2CA0NxZEjR8wSpCFisRjbtm1DaGgo2rRpg0WLFmHGjBk6cxhJpVL89ddfSE1NRefOnTFr1izMmzev0mH89U2hVMFDYg3rp7Nk21gJEOzrxO2PT81Bcbl6NKAm9dRMGnk5IxfxqTn1OpU8retDCCHEEpjU52jPnj0YNGgQRowYUWkZHx8fnD592uTAqtOpUyfExcVVW65du3Y4ceJEncVhKu0h021lEsx8JRA9/ZwhFPBxJ7sA3k62CPZ1go2VAMXlSvCgTpA0j9t5SRHs61SvnWdpJBMhhBBLYFJylJWVhTfffLPKMmKxGIWFhSYFZQm0E40rmXnwcbGDUMDXG5F2cW4E4lNz0NnbEVl5pVCqGAR8Hnyflq/PzrM0kokQQoglMCk5cnZ2xr1796osc/36dTRt2tSkoCyBt5MtgjylSMrIReDTDtYVW2Y0s1uHtnSDQqnCrOizOokToDs6ra7RSCZCCCGWwKSrW58+fbB79278/fffBvdfvXoV//vf/xAREVGr4Bo7lUrdZ+fGgwK88d0ZyKTW3PppNlYCjNuUwPXtMXRLqyHQSCZCCCGNnUlXuDlz5kCpVCIkJARbt27Fw4cPAagnZ9y4cSPCwsIgFovx4YcfmjXYxiT1YSGSs/K5x0mZecjMLcHOqT2xeUJXriO2JhHSXniWbmkRQgghdcek22pBQUH4/fffMWbMGIwdOxaAek21tm3bgjEGBwcHREdHIyAgwKzBNmZiIR8yqTWEAj5C/F30+vbQLS1CCCGkfpg8Q/aQIUOQmpqKzZs3Iz4+Hjk5OZBIJAgODsaECRPg4uJizjgbHV8XOwS62eGGXN1pvVShQmZuCXfLSrO+mrb67F9ECCGEWCoe05690UhbtmyBu7s7+vXrVxcxPVdqs6pvdUrKFBi65hRSHhSgnZcUO6c8Wy/N2NXRq1uMlhBCCLFEtbl+m9RyNHHiREybNs0ikqO6ZC0SYv8HvQ0mN8bMKWRsAkUIIYQQ45l0JW3atCkUCkX1BUm1Khv9ZUwH7OdlBBshhBDSmJjUcjRkyBDExMSgtLQUYrHY3DERGDenEE3KSAghhJifSX2OcnNzERYWBg8PDyxbtgxt2rSpi9ieC3XZ58gcqM8RIYQQoq8212+TkqMWLVqgtLQU9+/fBwBYW1vDzc0NPB5P9+Q8Hm7fvl3T0z9XnvfkiBBCCCH66r1Dtkqlgkgkgre3t872inmWCXkXIYQQQkiDMik5SktLM3MYhBBCCCHPB+qk8hxSKFW4k10AhVLV0KEQQgghFsfkGbI1Hj16hMTEROTm5kIqlaJ9+/ZwdnY2R2wWieYuIoQQQhqWyclRWloaoqKisH//fp2+RTweD4MGDcLXX38NHx8fc8RoUYyZ/JEQQgghdcek5Oj27dsICQmBXC5HQEAAQkJC4O7ujgcPHuD06dPYs2cP4uLicPr0abRo0cLcMTdqNHcRIYQQ0rBMSo5mz56N7OxsfPfdd3j33Xd1hvAzxrBhwwZMnToVs2fPxvbt280WrCUwZvJHQgghhNQdk+Y5atKkCfr27Ytdu3ZVWmbo0KE4fvw4Hj9+XKsAGxrNc0QIIYS8eGpz/TapWUKpVFY7K3bbtm2hVCpNOT0hhBBCSIMxKTnq1KkTkpOTqyyTnJyMLl26mBQUIYQQQkhDMSk5WrRoEQ4cOIAffvjB4P4NGzbg4MGD+Pzzz2sVHCGEEEJIfTOpz9Gnn36KM2fO4K+//kJgYKDOaLVTp07hxo0b6NevH7p37677ZDwe5s6da7bg6wP1OSKEEEJePPW+8Cyfb9oIKh6P98L1Q6LkiBBCCHnx1PvCs0ePHjXlMEIIIYSQ555JyVFoaKi54yCEEEIIeS7QDIOEEEIIIVooOSIWRaFU4U52ARRKVUOHQggh5Dll8sKzhLxoFEoVXl97Wr1unacUO6f2pOVZCCGE6KErA7EY6TlFuJyRCwC4nJGL9JyiBo6IEELI84iSI2IxvJ1s0c5TCgBo5yWFt5NtA0dECCHkeUS31YjFEAr42Dm1J9JziuDtZEu31AghhBhEyRGxKEIBHy1c7Rs6DEIIIc8x+tOZEEIIIUQLJUeEEEIIIVooOSKEEEII0ULJESGEEEKIFkqOCCGEEEK0UHJECCGEEKKFkiNCCCGEEC2UHBFCCCGEaKHkiBBCCCFECyVHhBBCCCFaKDkihBBCCNFCyREhhBBCiBZaeLYajDEAQF5eXgNHQgghhBBjaa7bmut4TVByVI38/HwAQLNmzRo4EkIIIYTUVH5+PqRSaY2O4TFTUioLolKpkJmZCQcHB/B4PLOeOy8vD82aNcO9e/cgkUjMeu4XCdXDM1QXalQPalQPalQPz1BdqBlTD4wx5OfnQyaTgc+vWS8iajmqBp/Ph5eXV50+h0QisegPuQbVwzNUF2pUD2pUD2pUD89QXahVVw81bTHSoA7ZhBBCCCFaKDkihBBCCNFCyVEDEovFmD9/PsRicUOH0qCoHp6hulCjelCjelCjeniG6kKtruuBOmQTQgghhGihliNCCCGEEC2UHBFCCCGEaKHkiBBCCCFECyVHhBBCCCFaKDlqIGvWrIGPjw+sra0RHByMs2fPNnRIdW7x4sXo2rUrHBwc4ObmhmHDhiElJUWnTElJCSIjI+Hs7Ax7e3sMHz4cDx48aKCI68eSJUvA4/Ewffp0bpul1ENGRgbefvttODs7w8bGBkFBQTh37hy3nzGGefPmoWnTprCxsUFERARu3rzZgBGbn1KpxNy5c+Hr6wsbGxv4+fnhs88+01kPqrHWw/HjxzF48GDIZDLweDz8+eefOvuNed05OTkYPXo0JBIJHB0dMXHiRBQUFNTjq6i9quqhvLwcs2fPRlBQEOzs7CCTyTB27FhkZmbqnKOx10NFkydPBo/Hw9dff62z3Vz1QMlRA/j9998xc+ZMzJ8/HxcuXED79u3Rr18/yOXyhg6tTsXGxiIyMhJxcXGIiYlBeXk5Xn31VRQWFnJlZsyYgb1792L79u2IjY1FZmYmXn/99QaMum4lJCRg/fr1aNeunc52S6iHx48fIyQkBFZWVjhw4ACuXr2KFStWoEmTJlyZZcuW4ZtvvsF3332H+Ph42NnZoV+/figpKWnAyM1r6dKlWLduHb799ltcu3YNS5cuxbJly7B69WquTGOth8LCQrRv3x5r1qwxuN+Y1z169GgkJycjJiYG+/btw/HjxzFp0qT6eglmUVU9FBUV4cKFC5g7dy4uXLiAnTt3IiUlBUOGDNEp19jrQduuXbsQFxcHmUymt89s9cBIvevWrRuLjIzkHiuVSiaTydjixYsbMKr6J5fLGQAWGxvLGGPsyZMnzMrKim3fvp0rc+3aNQaAnTlzpqHCrDP5+fksICCAxcTEsNDQUBYVFcUYs5x6mD17NuvVq1el+1UqFfPw8GBffvklt+3JkydMLBaz3377rT5CrBcDBw5k77zzjs62119/nY0ePZoxZjn1AIDt2rWLe2zM67569SoDwBISErgyBw4cYDwej2VkZNRb7OZUsR4MOXv2LAPA7t69yxizrHr4+++/maenJ7ty5Qpr3rw5++qrr7h95qwHajmqZ2VlZTh//jwiIiK4bXw+HxEREThz5kwDRlb/cnNzAQBOTk4AgPPnz6O8vFynblq1agVvb+9GWTeRkZEYOHCgzusFLKce9uzZgy5duuCNN96Am5sbOnbsiO+//57bn5qaivv37+vUg1QqRXBwcKOqh549e+Lw4cO4ceMGACAxMREnT57Ea6+9BsBy6qEiY173mTNn4OjoiC5dunBlIiIiwOfzER8fX+8x15fc3FzweDw4OjoCsJx6UKlUGDNmDD788EO0adNGb78564EWnq1nDx8+hFKphLu7u852d3d3XL9+vYGiqn8qlQrTp09HSEgI2rZtCwC4f/8+RCIR94XXcHd3x/379xsgyrqzbds2XLhwAQkJCXr7LKUe7ty5g3Xr1mHmzJn45JNPkJCQgA8++AAikQjjxo3jXquh70pjqoePP/4YeXl5aNWqFQQCAZRKJRYtWoTRo0cDgMXUQ0XGvO779+/Dzc1NZ79QKISTk1OjrZuSkhLMnj0bb731FrfgqqXUw9KlSyEUCvHBBx8Y3G/OeqDkiDSIyMhIXLlyBSdPnmzoUOrdvXv3EBUVhZiYGFhbWzd0OA1GpVKhS5cu+OKLLwAAHTt2xJUrV/Ddd99h3LhxDRxd/YmOjsbWrVvx66+/ok2bNrh06RKmT58OmUxmUfVAqldeXo4RI0aAMYZ169Y1dDj16vz581i1ahUuXLgAHo9X589Ht9XqmYuLCwQCgd7IowcPHsDDw6OBoqpf06ZNw759+3D06FF4eXlx2z08PFBWVoYnT57olG9sdXP+/HnI5XJ06tQJQqEQQqEQsbGx+OabbyAUCuHu7m4R9dC0aVO89NJLOttat26N9PR0AOBea2P/rnz44Yf4+OOP8eabbyIoKAhjxozBjBkzsHjxYgCWUw8VGfO6PTw89AayKBQK5OTkNLq60SRGd+/eRUxMDNdqBFhGPZw4cQJyuRze3t7c7+bdu3cxa9Ys+Pj4ADBvPVByVM9EIhE6d+6Mw4cPc9tUKhUOHz6MHj16NGBkdY8xhmnTpmHXrl04cuQIfH19dfZ37twZVlZWOnWTkpKC9PT0RlU34eHhSEpKwqVLl7h/Xbp0wejRo7n/t4R6CAkJ0ZvK4caNG2jevDkAwNfXFx4eHjr1kJeXh/j4+EZVD0VFReDzdX+KBQIBVCoVAMuph4qMed09evTAkydPcP78ea7MkSNHoFKpEBwcXO8x1xVNYnTz5k0cOnQIzs7OOvstoR7GjBmDy5cv6/xuymQyfPjhhzh48CAAM9eDaf3ISW1s27aNicVi9tNPP7GrV6+ySZMmMUdHR3b//v2GDq1OTZkyhUmlUnbs2DGWlZXF/SsqKuLKTJ48mXl7e7MjR46wc+fOsR49erAePXo0YNT1Q3u0GmOWUQ9nz55lQqGQLVq0iN28eZNt3bqV2drasl9++YUrs2TJEubo6Mh2797NLl++zIYOHcp8fX1ZcXFxA0ZuXuPGjWOenp5s3759LDU1le3cuZO5uLiwjz76iCvTWOshPz+fXbx4kV28eJEBYCtXrmQXL17kRmEZ87r79+/POnbsyOLj49nJkydZQEAAe+uttxrqJZmkqnooKytjQ4YMYV5eXuzSpUs6v52lpaXcORp7PRhScbQaY+arB0qOGsjq1auZt7c3E4lErFu3biwuLq6hQ6pzAAz+27RpE1emuLiYTZ06lTVp0oTZ2tqyf/zjHywrK6vhgq4nFZMjS6mHvXv3srZt2zKxWMxatWrFNmzYoLNfpVKxuXPnMnd3dyYWi1l4eDhLSUlpoGjrRl5eHouKimLe3t7M2tqatWjRgs2ZM0fnwtdY6+Ho0aMGfxPGjRvHGDPudT969Ii99dZbzN7enkkkEjZhwgSWn5/fAK/GdFXVQ2pqaqW/nUePHuXO0djrwRBDyZG56oHHmNY0rIQQQgghFo76HBFCCCGEaKHkiBBCCCFECyVHhBBCCCFaKDkihBBCCNFCyREhhBBCiBZKjgghhBBCtFByRAghhBCihZIjQgghhBAtlBwRYiF4PB769u1bo2N8fHy4RR3rQ9++fetlxW3SuBQVFcHT0xOTJk2q1XlSUlIgFAqxdu1aM0VGXlSUHJFG79ixY+DxeFiwYEFDh/LcGT9+PHg8HtLS0ho6lBpLS0sDj8fD+PHjGzqUF96L/h358ssv8fDhQ/znP//R2a5Jtu/fv693zNWrV+Hl5QU+n481a9YAAFq2bIm33noLCxcuRH5+fr3ETp5PlBwRYiGuXbuGLVu21OiYw4cP66yKTsjzJi8vD8uXL8fIkSPh7e1t1DFnz55Fnz59IJfL8csvvyAyMpLb99FHH0Eul+Obb76pq5DJC4CSI0IsRKtWrYy+eGj4+fnBz8+vjiIipPZ+/vlnFBQUYOzYsUaVP3z4MMLDw1FcXIzdu3dj1KhROvuDgoLQrl07fP/991CpVHURMnkR1HipWkJeIPPnz690RevU1FTGGGPjxo1jANjt27fZ8uXLWevWrZlIJOJWgtbs15Q3dH7t1bE1YmNj2aBBg5izszMTiUTM39+fzZkzhxUWFtboNdy+fZu9++67zMfHh4lEIubq6spCQ0PZpk2buDKa1aznz5/PTp06xV555RUmlUqZ9lccAAsNDeUeN2/e3GC9VCzTvHlzvZhUKhX78ccfWa9evZhUKmU2NjbM39+fTZo0id29e5crd+7cORYZGcnatGnDJBIJs7a2Zm3btmWLFy9mZWVleucNDQ1lxvwsbdq0yaiVylUqFdu4cSPr2bMnc3BwYDY2Nqxz585s48aNeufUfi9//PFH1rZtW2Ztbc18fHzYqlWruPMtX76cBQYGMrFYzPz9/dnmzZv1zqX9mVq6dCnz9/dnYrGY+fj4sIULFxp87YwZ/5kx5v3euHEjGzJkCGvevDkTi8WsSZMm7NVXX2VHjhwx+Lqr+o5U9b4Y+n5o3p9NmzaxPXv2sJ49ezJ7e3udz1JpaSlbsWIF69ixI7O1tWX29vasV69ebPfu3QafpzKdO3dmTk5OTKlU6u3TxJ2VlcUYY+yPP/5gYrGYOTo6spMnT1Z6zs8//5wBYIcOHapRLKTxENZh3kVIg+vbty/S0tKwefNmhIaG6nRIdnR01Cn7/vvvIy4uDgMHDsTgwYPh5uZm8vOuW7cOkZGRcHR05M517tw5LFq0CEePHsXRo0chEomqPc/JkycxcOBA5Ofno1+/fnjzzTfx+PFjXLx4EatWrdLrb3P69Gl88cUXePnllzFp0iSkp6dXeu7p06fjp59+QmJiIqKiorj6qK4DtkqlwsiRI7Fjxw54enrirbfegkQiQVpaGqKjo/Haa69xLVTff/899u7diz59+mDAgAEoKirCsWPH8O9//xsJCQn4448/qq0DQzp06ICoqCisWrUK7du3x7Bhw7h9mvgZYxg9ejR+++03BAQEYNSoURCJRIiJicHEiRNx9epVLF++XO/cX3/9NY4dO4ahQ4ciLCwMf/zxB6KiomBra4uLFy/ijz/+wKBBgxAeHo5t27Zh3Lhx8PHxQZ8+fQzW8alTpzBixAjY29tj7969mD9/Pi5fvowdO3bolDXlM1PV+x0ZGYn27dsjIiICrq6uyMjIwJ9//omIiAjs3LkTQ4cOBVCz70hNbd++HX/99RcGDRqEqVOnIi8vDwBQWlqK/v3749ixY+jQoQMmTpyI8vJy7N+/H0OHDsXq1asxbdq0as+v+S68+uqr4POrvhGyceNGvPfee3B1dcXBgwfRrl27Ssv26NEDwLNWJmKBGjo7I6Suaf+VbYjmL18vLy+dVo+K+41tOUpOTmZCoZC1b9+ePXz4UKf84sWLGQC2fPnyauMuKSlhnp6ejM/nswMHDujtv3fvnt5rBMB+/PFHg+dDhVah6l4bY4ZbjlavXs0AsPDwcFZUVKSzr6ioiD169Ih7fPfuXaZQKHTKqFQq9s477zAAen+9G9tyxBhjqampDADXwlfRhg0bGAA2YcIEnZaa0tJSNnjwYAaAnTt3jtuueS+dnJzY7du3ue3p6elMJBIxqVTKAgMDmVwu5/bFxcUxAGzw4ME6z62pV1dXV533qbS0lPXp04cBYDt27OC21/QzY8z7fefOHb1tmZmZTCaTsYCAAJ3t1X1HTG054vP5LCYmRu+YTz75hAFgc+fOZSqVituel5fHunTpwkQiEcvIyDD4fNr279/PALA5c+ZUGfe//vUvBoD5+vqyW7duVXve3NxcBoD16dOn2rKkcaI+R4Q89eGHH9a4T44h69evh0KhwOrVq+Hs7Kyz76OPPoKrqyt+++23as+ze/duZGRk4O2330b//v319nt5eelt69SpEyZMmGB68EZYu3YtBAIB1q1bBxsbG519NjY2cHJy4h57e3tDIBDolOHxeFwH2EOHDtVZnN9++y3s7OywZs0aWFlZcdtFIhEWLVoEAAbfh6ioKLRo0YJ73KxZM/Tq1Qu5ubmYM2cOXF1duX3BwcFo0aIFEhMTDcYQFRWl8z5pP/dPP/3EbTf1M1PV++3r66u3rWnTphg+fDhu3ryJu3fvGjzOnIYOHYqIiAidbSqVCuvWrYOfnx8WLlyoM3WDg4MD5s2bh7KyMuzcubPa8//9998AAHd39yrLLV++HHw+H/v27TOqD51EIoG1tTV3fmJ56LYaIU9169bNLOeJi4sDABw8eNDgSC8rKytcv3692vOcPXsWAPDqq68a/dxdu3Y1uqwpCgoKcO3aNfj7+yMgIKDa8mVlZfj222+xbds2XL9+HQUFBWCMcfszMzPrJM6ioiIkJSVBJpNh6dKlevvLy8sBwOD70KFDB71tTZs2rXJffHy8wTh69+6tt61Hjx4QCoW4ePEit83Uz0xV7/edO3ewePFiHDlyBBkZGSgtLdXZn5mZiebNm1d6vDkY+k6lpKTg8ePHkMlkWLhwod7+7OxsAIbfm4oePXoEoPrbf6+88gpiYmIwduxYxMTEoEmTJtWe28nJCQ8fPqy2HGmcKDki5Knq/vo0Vk5ODgBwLQSmys3NBQB4enoafYy5XkNlahrTP//5T+zduxeBgYEYOXIk3NzcYGVlhSdPnmDVqlV6F2xzefz4MRhjyMjIMHgB1igsLNTbJpFI9LYJhcIq9ykUCoPnN/R+CAQCODs7c3UJmP6Zqez9vnXrFrp164a8vDy8/PLLGDx4MCQSCfh8Po4dO4bY2Ng6q/vq4tO81uTkZCQnJ1d6rKH3piJNy2VJSUmV5TZt2oTZs2dj69atCA8Px6FDh3RaOA0pLi6Gra1ttTGQxomSI0KeqmxmZk1HT0MXQO0LnIbmApqXlwcHBweT49H8NZyRkWH0MXU9u7RUKgVgXEwJCQnYu3cv+vXrh/379+vcXouLi8OqVavqLE7Ne9C5c2ecO3euzp6nOg8ePEDLli11timVSjx69EgncTD1M1PZ+/3VV1/h8ePH+Pnnn/H222/r7Js8eTJiY2ONfg5A9zugSRQ1DH0HqopP81qHDx+u1ym9pjS3ODUJV2UEAgG2bNnC/TcsLAyHDh2Ci4uLwfIqlQq5ublo06ZNreIjLy7qc0QaPc1FWalUmnS8pgneUEKgfWtEIzg4GMCzWyWm0tyS+Ouvv2p1nqrUtG7s7e3x0ksvITU1FTdv3qyy7O3btwEAAwcO1Ot3dOLECROi1VVV7A4ODmjdujWuXbuGJ0+e1Pq5TGXodZ45cwYKhQIdO3bktpnrM6OhqXvNiDQNxhhOnTqlV766z0Fl3wGVSlVpf6vKtG7dGhKJBOfOneNub5oqKCgIgPpWXXX4fD42bdqECRMmIDExEWFhYdwtvIpu3rwJlUrFnZ9YHkqOSKOnaT6/d++eScdr+nVod6AFgB07dhj8C3zq1KkQCoV4//33DQ6lf/LkicGkqqIhQ4bAy8sLv/zyCw4ePKi3vyYtSpUxpW4iIyOhVCoxdepUFBcX6+wrKSnh/orX9Gc5efKkTpnk5GQsXry4NmEDUF+weTxepbF/8MEHKCoqwrvvvmvwFk1qamqdL5uyatUqnU69ZWVlmDNnDgDoTMNgrs+MRmV1v2TJEly5ckWvfHWfg8q+AytXrkRqaqrRcQHq25BTpkzB3bt38a9//ctggnTlyhXI5fJqzxUUFAQnJ6dK+3xVxOfzsXHjRvzf//0fkpKS8PLLLxt8Hs35QkNDjTovaXzothpp9Fq1agWZTIZt27ZBLBbDy8sLPB4P77//PnebqCpDhw6Fn58ffvrpJ9y7dw8dO3bEtWvXcOTIEQwYMAD//e9/dcq3bdsWa9euxZQpU9CyZUsMGDAAfn5+yM/Px507dxAbG4vx48fju+++q/J5xWIxoqOj0b9/f7z22mvo378/2rdvj7y8PFy6dAlFRUU1umAaEhYWhuXLl2PSpEkYPnw47Ozs0Lx5c4wZM6bSY6ZMmYLY2FhER0cjICAAQ4YMgUQiQXp6Og4ePIiNGzdi2LBh6NatG7p164bo6GhkZWWhe/fuSE9Px549ezBw4MBa31Kxt7dH165dcfz4cYwZMwYBAQHg8/kYM2YMmjdvjvfeew9xcXHYvHkzTp06hYiICMhkMjx48ADXr19HfHw8fv311zpdWLd79+5o3749Ro4cCTs7O+zduxcpKSl4/fXXMXz4cK6cuT4zGpMnT8amTZswfPhwjBgxAs7OzoiLi8OFCxcwcOBA7N+/X6d8dd+RCRMmYNmyZViwYAEuXboEPz8/nDt3DleuXEFoaGiNb9MtXLgQFy5cwDfffIP9+/ejT58+cHNzQ0ZGBpKSkpCYmIgzZ85UO9cYj8fD0KFD8dNPP+Hvv/82OILT0DEbNmyAQCDA+vXr0bdvXxw5cgQeHh5cmZiYGAiFQgwaNKhGr4s0Ig08lQAh9SIuLo6FhoYyBweHSmfIrmyuH8bUc+oMGzaMOTg4MDs7OxYeHs4SEhKqnCH77Nmz7M0332QymYxZWVkxFxcX1qlTJ/bxxx+za9euGR37rVu32MSJE5mXlxezsrJibm5urG/fvmzLli1cmermqWHM8DxHjDG2bNkyFhAQwKysrGo0Q/YPP/zAunfvzuzs7JitrS0LCAhgkydPZunp6Vw5uVzO3nnnHSaTyZi1tTULCgpia9asYXfu3DE4R1FN5jlijLGUlBQ2YMAA5ujoyHg8nsH34vfff2cRERGsSZMmzMrKinl6erK+ffuyFStWsOzsbK5cVe9lVZ8RQzFrz5C9ZMkS5u/vz0QiEWvevDlbsGABKy0tNfh6jP3MGPN+Hz16lIWEhDAHBwfm6OjIBgwYwM6fP1/p66zqO8IYY5cuXWLh4eHM1taWSSQSNnToUHbz5s1qZ8iujEKhYOvXr2chISFMIpEwsVjMvL29Wf/+/dm6detYQUFBpcdqi4+PZwDY0qVL9fZVnCFbm0qlYlOnTmUAWMuWLVlmZiZjjLHCwkJmb2/Phg0bZtTzk8aJx5jWuFpCCCG1Nn78eGzevBmpqal12jJF1Hr37o3s7GxcvXq12pmyq/PDDz/g3XffRWxsrMFZz4lloD5HhBBCXmhffvklUlJSsG3btlqdR6FQ4IsvvsCQIUMoMbJw1OeIEELIC6179+5Yv369ySNSNdLT0zF27Ngq+9wRy0C31QghxMzothohLzZKjgghhBBCtFCfI0IIIYQQLZQcEUIIIYRooeSIEEIIIUQLJUeEEEIIIVooOSKEEEII0ULJESGEEEKIFkqOCCGEEEK0UHJECCGEEKLl/wH2UasrleLipAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.scatter(y_test, y_pred, s=2)\n", + "plt.xlabel(\"true critical temperature (K)\", fontsize=14)\n", + "plt.ylabel(\"predicted critical temperature (K)\", fontsize=14)\n", + "plt.savefig(\"critical_temperature.pdf\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "root mean square error 22.29\n" + ] + } + ], + "source": [ + "rms = np.sqrt(mean_squared_error(y_test, y_pred))\n", + "print(f\"root mean square error {rms:.2f}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Hyperparameter optimization" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/lib/python3.10/site-packages/sklearn/model_selection/_validation.py:378: FitFailedWarning: \n", + "10 fits failed out of a total of 35.\n", + "The score on these train-test partitions for these parameters will be set to nan.\n", + "If these failures are not expected, you can try to debug them by setting error_score='raise'.\n", + "\n", + "Below are more details about the failures:\n", + "--------------------------------------------------------------------------------\n", + "5 fits failed with the following error:\n", + "Traceback (most recent call last):\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/model_selection/_validation.py\", line 686, in _fit_and_score\n", + " estimator.fit(X_train, y_train, **fit_params)\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 762, in fit\n", + " return self._fit(X, y, incremental=False)\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 385, in _fit\n", + " self._validate_hyperparameters()\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 508, in _validate_hyperparameters\n", + " raise ValueError(\"learning rate %s is not supported. \" % self.learning_rate)\n", + "ValueError: learning rate 0.0001 is not supported. \n", + "\n", + "--------------------------------------------------------------------------------\n", + "5 fits failed with the following error:\n", + "Traceback (most recent call last):\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/model_selection/_validation.py\", line 686, in _fit_and_score\n", + " estimator.fit(X_train, y_train, **fit_params)\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 762, in fit\n", + " return self._fit(X, y, incremental=False)\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 385, in _fit\n", + " self._validate_hyperparameters()\n", + " File \"/opt/homebrew/lib/python3.10/site-packages/sklearn/neural_network/_multilayer_perceptron.py\", line 508, in _validate_hyperparameters\n", + " raise ValueError(\"learning rate %s is not supported. \" % self.learning_rate)\n", + "ValueError: learning rate 1e-05 is not supported. \n", + "\n", + " warnings.warn(some_fits_failed_message, FitFailedWarning)\n", + "/opt/homebrew/lib/python3.10/site-packages/sklearn/model_selection/_search.py:953: UserWarning: One or more of the test scores are non-finite: [-491.79222643 -338.81111017 -359.406494 -512.73262966 -450.1530479\n", + " nan nan]\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "text/html": [ + "
GridSearchCV(cv=5, estimator=MLPRegressor(max_iter=5000, random_state=1),\n",
+       "             param_grid=[{'hidden_layer_sizes': [(5, 5), (20, 20), (50, 50)]},\n",
+       "                         {'activation': ['relu', 'logistic']},\n",
+       "                         {'learning_rate': [0.0001, 1e-05]}],\n",
+       "             scoring='neg_mean_squared_error')
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "GridSearchCV(cv=5, estimator=MLPRegressor(max_iter=5000, random_state=1),\n", + " param_grid=[{'hidden_layer_sizes': [(5, 5), (20, 20), (50, 50)]},\n", + " {'activation': ['relu', 'logistic']},\n", + " {'learning_rate': [0.0001, 1e-05]}],\n", + " scoring='neg_mean_squared_error')" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "param_grid = [\n", + " {'hidden_layer_sizes': [(5,5), (20,20), (50,50)]},\n", + " {'activation': ['relu', 'logistic']},\n", + " {'learning_rate': [0.001, 0.01]}\n", + "]\n", + "\n", + "rgr = GridSearchCV(\n", + " MLPRegressor(random_state=1, max_iter=5000), param_grid, scoring='neg_mean_squared_error', cv=5)\n", + "\n", + "rgr.fit(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'mean_fit_time': array([9.26026688e+00, 5.38674998e+00, 3.01752081e+00, 2.39675040e+00,\n", + " 6.93448777e+00, 1.16915703e-03, 1.12295151e-03]),\n", + " 'std_fit_time': array([1.62185829e+00, 1.45875884e+00, 3.64975502e-01, 8.09020523e-01,\n", + " 2.24471612e+00, 4.18326171e-05, 2.05156382e-05]),\n", + " 'mean_score_time': array([0.00132494, 0.00277996, 0.00223546, 0.00275273, 0.0047976 ,\n", + " 0. , 0. ]),\n", + " 'std_score_time': array([9.74773887e-05, 2.08459164e-03, 2.29868718e-04, 7.39559789e-04,\n", + " 1.71814052e-03, 0.00000000e+00, 0.00000000e+00]),\n", + " 'param_hidden_layer_sizes': masked_array(data=[(5, 5), (20, 20), (50, 50), --, --, --, --],\n", + " mask=[False, False, False, True, True, True, True],\n", + " fill_value='?',\n", + " dtype=object),\n", + " 'param_activation': masked_array(data=[--, --, --, 'relu', 'logistic', --, --],\n", + " mask=[ True, True, True, False, False, True, True],\n", + " fill_value='?',\n", + " dtype=object),\n", + " 'param_learning_rate': masked_array(data=[--, --, --, --, --, 0.0001, 1e-05],\n", + " mask=[ True, True, True, True, True, False, False],\n", + " fill_value='?',\n", + " dtype=object),\n", + " 'params': [{'hidden_layer_sizes': (5, 5)},\n", + " {'hidden_layer_sizes': (20, 20)},\n", + " {'hidden_layer_sizes': (50, 50)},\n", + " {'activation': 'relu'},\n", + " {'activation': 'logistic'},\n", + " {'learning_rate': 0.0001},\n", + " {'learning_rate': 1e-05}],\n", + " 'split0_test_score': array([-337.26593326, -374.62590294, -320.12378376, -622.21350077,\n", + " -441.23453102, nan, nan]),\n", + " 'split1_test_score': array([-352.98713915, -308.15961551, -320.85973223, -322.17792968,\n", + " -406.32690689, nan, nan]),\n", + " 'split2_test_score': array([-1131.85755686, -413.69988392, -376.10052041, -456.73858549,\n", + " -458.85602326, nan, nan]),\n", + " 'split3_test_score': array([-325.8868918 , -289.44625711, -424.39045007, -841.68007514,\n", + " -534.05373457, nan, nan]),\n", + " 'split4_test_score': array([-310.9636111 , -308.12389139, -355.55798352, -320.85305721,\n", + " -410.29404375, nan, nan]),\n", + " 'mean_test_score': array([-491.79222643, -338.81111017, -359.406494 , -512.73262966,\n", + " -450.1530479 , nan, nan]),\n", + " 'std_test_score': array([320.32871333, 47.34793777, 38.84687957, 198.22042277,\n", + " 46.26894811, nan, nan]),\n", + " 'rank_test_score': array([4, 1, 2, 5, 3, 6, 7], dtype=int32)}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rgr.cv_results_" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([22.17638894, 18.40682238, 18.95801925, 22.64360019, 21.2168105 ,\n", + " nan, nan])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sqrt(-rgr.cv_results_['mean_test_score'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/05_neural_networks_ex_2_mnist_keras_train.ipynb b/notebooks/05_neural_networks_ex_2_mnist_keras_train.ipynb new file mode 100644 index 0000000..382ca2c --- /dev/null +++ b/notebooks/05_neural_networks_ex_2_mnist_keras_train.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise: Training a digit-classification neural network on the MNIST dataset using Keras\n", + "\n", + "This example is from [Stefan Wunsch (CERN IML TensoFlow and Keras workshop)](https://github.com/stwunsch/iml_tensorflow_keras_workshop). See also the example on the [Keras website](https://keras.io/examples/vision/mnist_convnet/).\n", + "\n", + "The MNIST dataset is one of the most popular benchmark-datasets in modern machine learning. The dataset consists of 70000 images of handwritten digits and associated labels, which can be used to train neural network performing image classification.\n", + "\n", + "The following program presents the basic workflow of Keras showing the most import details of the API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "np.random.seed(1234)\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download the dataset\n", + "\n", + "The code below downloads the dataset and performs a scaling of the pixel-values of the images. Because the images are encoded with 8-bit unsigned int values, we scale these values to floating-point values in the range `[0, 1)` so that the inputs match the activation of the neurons better." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.datasets import mnist\n", + "from tensorflow.keras.utils import to_categorical\n", + "\n", + "# Download dataset\n", + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "\n", + "# The data is loaded as flat array with 784 entries (28x28),\n", + "# we need to reshape it into an array with shape:\n", + "# (num_images, pixels_row, pixels_column, color channels)\n", + "x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)\n", + "x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)\n", + "\n", + "# Convert digits to one-hot vectors, e.g.,\n", + "# 2 -> [0 0 1 0 0 0 0 0 0 0]\n", + "# 0 -> [1 0 0 0 0 0 0 0 0 0]\n", + "# 9 -> [0 0 0 0 0 0 0 0 0 1]\n", + "y_train = to_categorical(y_train, 10)\n", + "y_test = to_categorical(y_test, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Addtionally, we store some example images to disk to show later on the inference part of the Keras API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import png\n", + "\n", + "num_examples = 6\n", + "# offset = 100\n", + "offset = 200\n", + "\n", + "plt.figure(figsize=(num_examples*2, 2))\n", + "for i in range(num_examples):\n", + " plt.subplot(1, num_examples, i+1)\n", + " plt.axis('off')\n", + " # example = np.squeeze(np.array(x_test[offset+i]*255).astype(\"uint8\"))\n", + " example = np.squeeze(np.array(x_test[offset+i]).astype(\"uint8\"))\n", + " plt.imshow(example, cmap=\"gray\")\n", + " w = png.Writer(28, 28, greyscale=True)\n", + " w.write(open(\"mnist_example_{}.png\".format(i+1), 'wb'), example)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Model / data parameters\n", + "num_classes = 10\n", + "input_shape = (28, 28, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define the model\n", + "\n", + "The model definition in Keras can be done using the `Sequential` or the functional API. Shown here is the `Sequential` API allowing to stack neural network layers on top of each other, which is feasible for most neural network models. In contrast, the functional API would allow to have multiple inputs and outputs for a maximum of flexibility to build your custom model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense, Flatten, MaxPooling2D, Conv2D, Input, Dropout\n", + "\n", + "# conv layer with 8 3x3 filters\n", + "model = Sequential(\n", + " [\n", + " Input(shape=input_shape),\n", + " Conv2D(8, kernel_size=(3, 3), activation=\"relu\"),\n", + " MaxPooling2D(pool_size=(2, 2)),\n", + " Flatten(),\n", + " Dense(16, activation=\"relu\"),\n", + " Dense(num_classes, activation=\"softmax\"),\n", + " ]\n", + ")\n", + "\n", + "model.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compile the model\n", + "\n", + "Using Keras, you have to `compile` a model, which means adding the loss function, the optimizer algorithm and validation metrics to your training setup." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.compile(loss=\"categorical_crossentropy\",\n", + " optimizer=\"adam\",\n", + " metrics=[\"accuracy\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train the model\n", + "\n", + "The cell below shows the training procedure of Keras using the `model.fit(...)` method. Besides typical options such as `batch_size` and `epochs`, which control the number of gradient steps of your training, Keras allows to use callbacks during training.\n", + "\n", + "Callbacks are methods, which are called during training to perform tasks such as saving checkpoints of the model (`ModelCheckpoint`) or stop the training early if a convergence criteria is met (`EarlyStopping`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n", + "\n", + "checkpoint = ModelCheckpoint(\n", + " filepath=\"mnist_keras_model.h5\",\n", + " save_best_only=True,\n", + " verbose=1)\n", + "early_stopping = EarlyStopping(patience=2)\n", + "\n", + "history = model.fit(x_train, y_train, # Training data\n", + " batch_size=200, # Batch size\n", + " epochs=50, # Maximum number of training epochs\n", + " validation_split=0.5, # Use 50% of the train dataset for validation\n", + " callbacks=[checkpoint, early_stopping]) # Register callbacks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### a) Plot training and validation loss as well as training and validation accurace as a function of the number of epochs " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# hint: use\n", + "# history.history[\"loss\"]\n", + "# history.history[\"val_loss\"]\n", + "# history.history[\"accuracy\"]\n", + "# history.history[\"val_accuracy\"]\n", + "\n", + "### Your code here ###" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### b) Determine the accuracy of the fully trained model\n", + "The prediction of unseen data is performed using the `model.predict(inputs)` call. Below, a basic test of the model is done by calculating the accuracy on the test dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "### Your code here ###" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/05_neural_networks_ex_2_sol_mnist_keras_apply.ipynb b/notebooks/05_neural_networks_ex_2_sol_mnist_keras_apply.ipynb new file mode 100644 index 0000000..a74398c --- /dev/null +++ b/notebooks/05_neural_networks_ex_2_sol_mnist_keras_apply.ipynb @@ -0,0 +1,182 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load and apply a trained Keras model\n", + "\n", + "This example is from [Stefan Wunsch (CERN IML TensoFlow and Keras workshop)](https://github.com/stwunsch/iml_tensorflow_keras_workshop).\n", + "\n", + "The code of this notebook shows how you can load and apply an already trained Keras model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import png\n", + "from tensorflow.keras.models import load_model\n", + "from os import listdir\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load the model\n", + "\n", + "Loading a Keras model needs only a single line of code, see below. After this call, the model is back in the same state you stored it at the training step either by the `ModelCheckpoint` or `model.save(...)`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "model = load_model(\"mnist_keras_model.h5\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Apply the model\n", + "\n", + "The application is done as shown in the testing phase of the training script. Simply call `model.predict(inputs)` on your data." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-03-12 17:54:48.613328: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)\n" + ] + } + ], + "source": [ + "predictions = []\n", + "images = []\n", + "for f in sorted(listdir(\".\")):\n", + " if \"mnist_example_\" in f:\n", + " image = np.zeros((1, 28, 28, 1), dtype=np.uint8)\n", + " pngdata = png.Reader(open(f, 'rb')).asDirect()\n", + " for i_row, row in enumerate(pngdata[2]):\n", + " image[0, i_row, :, 0] = row\n", + " images.append(image)\n", + " \n", + " prediction = np.argmax(model.predict(image))\n", + " predictions.append(prediction)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "num_examples = len(images)\n", + "plt.figure(figsize=(num_examples*2, 2))\n", + "plt.rcParams.update({'axes.titlesize': 'xx-large'})\n", + "for i in range(num_examples):\n", + " plt.subplot(1, num_examples, i+1)\n", + " plt.axis('off')\n", + " plt.imshow(np.squeeze(images[i]), cmap=\"gray\")\n", + " plt.title(\"{}\".format(predictions[i]))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction for each class: [[2.3904847e-16 9.0325976e-12 4.8380059e-07 9.9989939e-01 4.1473118e-05\n", + " 5.7533276e-09 4.0925880e-09 5.8235182e-05 3.4916306e-07 2.5625425e-16]]\n", + "Predicted digit: 3\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "f = \"your_own_digit.png\"\n", + "image = np.zeros((1, 28, 28, 1), dtype=np.uint8)\n", + "pngdata = png.Reader(open(f, 'rb')).asDirect()\n", + "for i_row, row in enumerate(pngdata[2]):\n", + " image[0, i_row, :, 0] = row\n", + " \n", + "prediction_vector = model.predict(image)\n", + "prediction = np.argmax(prediction_vector)\n", + "print (f\"Model prediction for each class: {prediction_vector}\")\n", + "print (f\"Predicted digit: {prediction}\")\n", + "plt.axis('off')\n", + "plt.imshow(np.squeeze(image), cmap=\"gray\");" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/05_neural_networks_ex_2_sol_mnist_keras_train.ipynb b/notebooks/05_neural_networks_ex_2_sol_mnist_keras_train.ipynb new file mode 100644 index 0000000..3dd8d0a --- /dev/null +++ b/notebooks/05_neural_networks_ex_2_sol_mnist_keras_train.ipynb @@ -0,0 +1,467 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise: Training a digit-classification neural network on the MNIST dataset using Keras\n", + "\n", + "This example is from [Stefan Wunsch (CERN IML TensoFlow and Keras workshop)](https://github.com/stwunsch/iml_tensorflow_keras_workshop). See also the example on the [Keras website](https://keras.io/examples/vision/mnist_convnet/).\n", + "\n", + "The MNIST dataset is one of the most popular benchmark-datasets in modern machine learning. The dataset consists of 70000 images of handwritten digits and associated labels which can be used to train neural network performing image classification.\n", + "\n", + "The following program presents the basic workflow of Keras showing the most import details of the API." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "np.random.seed(1234)\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download the dataset\n", + "\n", + "The code below downloads the dataset and performs a scaling of the pixel-values of the images. Because the images are encoded with 8-bit unsigned int values, we scale these values to floating-point values in the range `[0, 1)` so that the inputs match the activation of the neurons better." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.datasets import mnist\n", + "from tensorflow.keras.utils import to_categorical\n", + "\n", + "# Download dataset\n", + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "\n", + "# The data is loaded as flat array with 784 entries (28x28),\n", + "# we need to reshape it into an array with shape:\n", + "# (num_images, pixels_row, pixels_column, color channels)\n", + "x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)\n", + "x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)\n", + "\n", + "# Convert digits to one-hot vectors, e.g.,\n", + "# 2 -> [0 0 1 0 0 0 0 0 0 0]\n", + "# 0 -> [1 0 0 0 0 0 0 0 0 0]\n", + "# 9 -> [0 0 0 0 0 0 0 0 0 1]\n", + "y_train = to_categorical(y_train, 10)\n", + "y_test = to_categorical(y_test, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Addtionally, we store some example images to disk to show later on the inference part of the Keras API." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7YAAACYCAYAAADQtHVDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAAASAklEQVR4nO3df6zVdf0H8M8F/AHGoKE0MBNHmApNsiLbULcoGeKVYpgwwWossBb+qjRAW7uh/dzIEnNIY/mjLaOhojeI1bwu21oQua5khCE/rhbcaT8Ak+E9/fX98TmvT94Ph3PuuW/u4/Hf67n3OedlfjiXl58+r9tSqVQqGQAAACRqULMbAAAAgONhsAUAACBpBlsAAACSZrAFAAAgaQZbAAAAkmawBQAAIGkGWwAAAJJmsAUAACBpQ8oebGlpaWQfJKhSqfTJ57j2qNZX116Wuf6IfPfRLL77aCbffTRL2WvPHVsAAACSZrAFAAAgaQZbAAAAkmawBQAAIGkGWwAAAJJmsAUAACBpBlsAAACSZrAFAAAgaUOa3QCQZe9617tCtnz58lz9pz/9KZy58847G9YTAACkwh1bAAAAkmawBQAAIGkGWwAAAJJmsAUAACBpLZVKpVLqYEtLo3shMSUvneM2EK69bdu2hezCCy/M1UX/e0+bNi1kTz31VN366q/66trLsoFx/XFsfPfRLL77aCbffTRL2WvPHVsAAACSZrAFAAAgaQZbAAAAkmawBQAAIGlDmt1AI8yaNStXv+Md7whnvvvd74asp6enps8bNCj+94Ey7/XTn/40ZKtWrQpZR0dHTX3RP33sYx8L2bvf/e5eX1e0TMGCBVIwf/78XD1lypRw5oYbbuirdgDqbvLkySHbuHFjrr744ovDmRdffLFBHcHA444tAAAASTPYAgAAkDSDLQAAAEkz2AIAAJC05JdHfeYznwnZN77xjVw9bNiwcKZouVOlUqmph1rfa/bs2SE7+eSTQ/bb3/42ZIcPHy7ZHc308Y9/PGTz5s0LWdECsmpdXV2lMuhvqq/Tf/3rX+HMueeeG7IdO3Y0rCfScdNNN4XslltuCdlHP/rRkP3ud79rQEcQFS0qHT16dK7+4Ac/GM5YHpWO6vkiy7Ls1ltvbdjnrVixImR33HFHwz7vROCOLQAAAEkz2AIAAJA0gy0AAABJS/4Z26Jnb4qeqU1Fa2tryMaMGROyF154oS/a4TgV/TL2WbNmhWz9+vUhe/XVV3P1PffcE854BpEUfOtb38rVb3vb28KZ8ePHh2zu3LkN64l03HjjjSF77bXXQrZv376+aAdq9uc//7nZLVDS1KlTQ3b99deH7Dvf+U6u/sEPflDq/SdMmBCy6t07S5cuDWdef/31kN11110hK9r/MxC4YwsAAEDSDLYAAAAkzWALAABA0gy2AAAAJC355VEDwZw5c0JW9Euiab4777wzVy9ZsiScefLJJ0M2b968kB05cqR+jUETvec978nVlUolnFmzZk1ftUM/N27cuFw9duzYcKZoodT+/fsb1RLkDB06NGQrV64M2XPPPZert27d2rCeqK+ihYZPP/10yJYtW5arixbbFens7AxZ9SLRkSNHhjNtbW0h6+7uDtl9991Xqo8TjTu2AAAAJM1gCwAAQNIMtgAAACTNYAsAAEDSkl8e1dHREbKiB75TNnXq1JBZHtV81YuisizLbr311lzd1dUVzixdujRkFkVxovjyl78cskGD8v8NddeuXeFM9ZIVBq73v//9ufqkk04KZw4cONBX7UAwd+7ckJ1zzjkhq/5eK1qcR//00EMPhWzdunUhK7ssqhbt7e0hmzlzZsjOPPPMhvWQGndsAQAASJrBFgAAgKQZbAEAAEiawRYAAICkJb88avXq1SEbM2ZMr6+76aabavq822+/PWTXXXddTe9V1h//+MeGvj+9W7BgQciqF0VlWZYNHjw4V99///3hTGdnZ/0agya6+OKLQ/bFL34xZD09Pbl669at4czLL79cv8ZI2vTp05vdAryp2bNnlzq3efPmBndCo7zxxhshO3ToUBM66d3f/va3ZrfQb7hjCwAAQNIMtgAAACTNYAsAAEDSkn/GdsuWLSFrbW3t9XUjR44M2emnnx6y66+/Pldfeuml5ZurweOPPx6yr3zlKw39THo3ZcqUkFU/T5tlWdbV1ZWr16xZ07Ce6m3YsGEhu+yyy3p93dGjR0PmuaKBYdq0aSEbOnRor6/78Y9/3Ih2AOpu8uTJISvaL/D3v/89ZCtWrGhARwwU73vf+0K2Z8+ekD322GN90U4S3LEFAAAgaQZbAAAAkmawBQAAIGkGWwAAAJKW/PKoWq1fvz5kl1xySRM6ydu9e3fIDh8+3IROBq6zzz47ZAsXLiz12jlz5uTq/vpLsydNmhSym2++OWSf+tSnen2vnp6ekD3zzDMh+8QnPhGyF198sdf3p3/49Kc/HbLly5eXeu2TTz75pjX8f52dnc1uAf7XJz/5yZCNGjUqZBs2bAjZK6+80oiWOEGtXLkyV1f/nTLLsuzRRx8N2d69exvVUnLcsQUAACBpBlsAAACSZrAFAAAgaQZbAAAAknZCLo9qb2/P1dOnTw9nBg2KM33REpwy6vleLS0tNb2O+tm0aVPITj311JD99a9/DdkLL7zQkJ6OxfDhw0N2+eWX5+p77703nDnjjDNq+ryi679oEdv8+fNDtmLFipo+k8YbMiT/4+Gqq64KZ0455ZSQHTx4MGRFr4X/ZujQoc1uAd7U0aNHQ/bggw82oRNSUPSzcvPmzSGbOnVqrn7uuefCmc9//vP1a+wE5I4tAAAASTPYAgAAkDSDLQAAAEkz2AIAAJC05JdHFS28GTVqVK6uVCrhTNFyp6JzZdTzvRYsWBCyn/3sZyHbuHFjTe9P784555xS59avXx+y7u7uerfzpooWRc2ePTtka9euzdX//ve/w5ktW7aU+synnnoqV3/hC18o9TrScvvtt+fqGTNmhDNF33NtbW0N64mBYfz48c1ugQFs5MiRufq6664LZ/bt2xeydevWNaolEldmUVSRiRMnhuyZZ54J2f79+0P2y1/+Mld/85vfDGcOHTrUaw+pcccWAACApBlsAQAASJrBFgAAgKQl/4ztiWbEiBEhq34+MsuyrLW1NVeXfT6S6JprrsnVQ4aU+2NR9ExDI73lLW8J2apVq0I2f/78kFU/U3vbbbeFM9/73vdK9XH66afnas/YnpjuuOOOXF30PG31MzxZVv46AuiPlixZkqurn7nNsiz74Q9/2EfdkJqVK1eGrMzztFmWZdu2bcvV999/fzgzZsyYkF111VUhq/4Zftlll4Uzs2bNCtk//vGPXvvsz9yxBQAAIGkGWwAAAJJmsAUAACBpBlsAAACSlvzyqAMHDoSsu7u7T3t4+umnQ3b++eeHrHrpTllnnHFGyEaNGlXTexGde+65ubqlpaXU6+65555GtPNfzZw5M2RlFkVlWVwWdTwLfubOndvrmaNHj4bML6/vv77//e/X9LqiX/h+5MiR422HAW79+vW5euHCheHM4MGD+6odTmAnn3xyyK688spc/c9//jOceeyxxxrWE2krWupZdA1Vf89lWZZ1dXXl6qIZp0hbW1vIFi1a1Gtfl1xyScieeOKJUp/ZX7ljCwAAQNIMtgAAACTNYAsAAEDSDLYAAAAkraVSqVRKHSy5UKeMcePGhay1tTVXFy1kevbZZ0u9f3t7e66ePn16ODNoUJzpd+3aFbK1a9fm6q9+9aulepgxY0bIyjyQXdRXT09PyKoXCW3cuLFUX/VU8tI5bvW89opMmjQpV2/bti2cKVpUUr10KsuybOfOnXXr68ILL8zVmzdvDmeKFpIVnSv6M1DtpJNOCtkNN9wQssWLF+fq8ePHhzP33ntvyJYsWdJrD2X11bWXZY2//vra5MmTQ9bR0RGy4cOH5+qvf/3r4cyyZcvq1ldKTpTvvv5q9OjRuXrPnj3hzE9+8pOQLViwoGE99Re+++rrne98Z8h27NiRq3//+9+HMxdddFGjWurXfPela/fu3aXOTZw4MWQHDx6sdzvHrOy1544tAAAASTPYAgAAkDSDLQAAAEkz2AIAAJC0Ic340IcffjhkH/jAB3J1d3d3OPOhD30oZNu3bw/Zl770pVz9xhtvlOpr6dKlIevs7Oz1dUXLsO66666QlXnwuWhRVNHr+nKBxImu+t9x0b+DouVRjz/+eMiqlzTt3bu35r7Gjh2bq4sWRR05ciRkX/va10JWvRjqggsuCGeWL18esquvvjpk1ddeV1dXOFPPRVHU14QJE0J22mmnhaz6O7hoIRg0wv79+3N10Xcy1MOcOXN6PbNhw4Y+6AT63llnnRWyU089NWT9YXlUWe7YAgAAkDSDLQAAAEkz2AIAAJC0pjxjW+Z5maLnCYuec7j22mtDVv1s2M0333wM3eVV//Luoucxino4//zza/5Mmuvw4cMhGzFiRMjOO++8kG3atClXd3R0hDN33313yHbu3Bmy1tbWN+0zy4p/cfyrr74asoceeihXFz07W9aBAwdy9YwZM2p+L/reNddcU+rc2rVrc/W+ffsa0Q5A0xT9/a3aK6+80gedAPXgji0AAABJM9gCAACQNIMtAAAASTPYAgAAkLSmLI+aP39+yJ544olcXbR86eyzzw7Zr371q5p6aGlpCVmlUmn6exXZvn17yJ5//vm6vT95H/nIR0L2i1/8ImTDhw8PWfVCqaIFU4sXLw7Zww8/XKqPalOmTAnZtm3ben1dkaJr9oEHHgjZt7/97Vzd2dlZ0+fReO9973tDdsUVV5R6bXt7e73bgZq89NJLzW6BAaTo73SQmkmTJuXqoiWoRX9fLFqgmhJ3bAEAAEiawRYAAICkGWwBAABImsEWAACApDVledTu3btDtnfv3lx9wQUXNLSHQYPiTN/T09P09/rDH/4Qsg9/+MMh6+7urun96d2WLVtCNm3atJDddtttIZs1a1auHjKk3B+xa6+9tmR3tTl69Giu/tGPfhTO/PrXvw7Z6tWrG9YTjVd0jZ5yyikhO3jwYMg6Ojoa0hMcq7Fjxza7BQaQei7/hL4wceLEkP385z/P1UU/+xctWhQyy6MAAACgiQy2AAAAJM1gCwAAQNIMtgAAACStKcujirS1teXqyy+/vKGfV7TcqdaFAfV8r/vuuy9kFkU1X9FCqauvvjpkkydPztVXXnllzZ+5ePHiXH3mmWeGM3v27AnZmjVrQvbII4/k6h07dtTcF/1X9XKIt771reFM0XeTJWGkZsaMGc1ugcRMnTo1ZG9/+9t7fd1LL73UiHagVyNGjAjZZz/72ZAtW7YsZNWLbefNmxfObN269Ti665/csQUAACBpBlsAAACSZrAFAAAgaS2Vkg+DtrS0NLSR0047LVcXPQtx6aWXhmzBggUhK/PL3Iv+eWp9Lrbsez377LO5uuj/E79p06aaemiGvvol5o2+9khPX117WZbW9XfWWWfl6l27dpV63csvv9zre/F/fPf1rXXr1oXsiiuuCNmwYcP6op2m8t1Xu1WrVoWs6HnF7du35+qLLroonHn99dfr11hCfPc11pIlS3L15z73uXBmwoQJIXv++edDVj1jPProo8fXXJOVvfbcsQUAACBpBlsAAACSZrAFAAAgaQZbAAAAkjak2Q38j0OHDuXqoiVKRdnq1atD1tra2uvn3X333cfQ3Zu78cYbS53bsGFDrt69e3fdegCoXgLV3t4ezhQt3SlaHgX9xWuvvRaywYMHh2z06NEh279/f0N6Ij2/+c1vQjZ79uyQ3XLLLbl6oC6Kon7OO++8kBX9fB43blyu3rlzZzhTtAStra0tZAcOHDiGDk8c7tgCAACQNIMtAAAASTPYAgAAkDSDLQAAAElrqVQqlVIHW1oa3QuJKXnpHDfXHtX66trLMtcfke++vlW9UCXLsuwvf/lLyBYtWhSyNWvWNKKlpvHdRzP57qtN9fLYLMuymTNnhmzhwoW5+pFHHglnqpftDhRlrz13bAEAAEiawRYAAICkGWwBAABImsEWAACApFkeRc0sEaBZLFChmXz30Sy++2gm3300i+VRAAAADAgGWwAAAJJmsAUAACBpBlsAAACSZrAFAAAgaQZbAAAAkmawBQAAIGkGWwAAAJJmsAUAACBpBlsAAACSZrAFAAAgaQZbAAAAkmawBQAAIGktlUql0uwmAAAAoFbu2AIAAJA0gy0AAABJM9gCAACQNIMtAAAASTPYAgAAkDSDLQAAAEkz2AIAAJA0gy0AAABJM9gCAACQtP8ALm91Qw50ezgAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import png\n", + "\n", + "num_examples = 6\n", + "# offset = 100\n", + "offset = 200\n", + "\n", + "plt.figure(figsize=(num_examples*2, 2))\n", + "for i in range(num_examples):\n", + " plt.subplot(1, num_examples, i+1)\n", + " plt.axis('off')\n", + " # example = np.squeeze(np.array(x_test[offset+i]*255).astype(\"uint8\"))\n", + " example = np.squeeze(np.array(x_test[offset+i]).astype(\"uint8\"))\n", + " plt.imshow(example, cmap=\"gray\")\n", + " w = png.Writer(28, 28, greyscale=True)\n", + " w.write(open(\"mnist_example_{}.png\".format(i+1), 'wb'), example)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Model / data parameters\n", + "num_classes = 10\n", + "input_shape = (28, 28, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define the model\n", + "\n", + "The model definition in Keras can be done using the `Sequential` or the functional API. Shown here is the `Sequential` API allowing to stack neural network layers on top of each other, which is feasible for most neural network models. In contrast, the functional API would allow to have multiple inputs and outputs for a maximum of flexibility to build your custom model." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"sequential\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " conv2d (Conv2D) (None, 26, 26, 8) 80 \n", + " \n", + " max_pooling2d (MaxPooling2D (None, 13, 13, 8) 0 \n", + " ) \n", + " \n", + " flatten (Flatten) (None, 1352) 0 \n", + " \n", + " dense (Dense) (None, 16) 21648 \n", + " \n", + " dense_1 (Dense) (None, 10) 170 \n", + " \n", + "=================================================================\n", + "Total params: 21,898\n", + "Trainable params: 21,898\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense, Flatten, MaxPooling2D, Conv2D, Input, Dropout\n", + "\n", + "# conv layer with 8 3x3 filters\n", + "model = Sequential(\n", + " [\n", + " Input(shape=input_shape),\n", + " Conv2D(8, kernel_size=(3, 3), activation=\"relu\"),\n", + " MaxPooling2D(pool_size=(2, 2)),\n", + " Flatten(),\n", + " Dense(16, activation=\"relu\"),\n", + " Dense(num_classes, activation=\"softmax\"),\n", + " ]\n", + ")\n", + "\n", + "model.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compile the model\n", + "\n", + "Using Keras, you have to `compile` a model, which means adding the loss function, the optimizer algorithm and validation metrics to your training setup." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "model.compile(loss=\"categorical_crossentropy\",\n", + " optimizer=\"adam\",\n", + " metrics=[\"accuracy\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train the model\n", + "\n", + "The cell below shows the training procedure of Keras using the `model.fit(...)` method. Besides typical options such as `batch_size` and `epochs`, which control the number of gradient steps of your training, Keras allows to use callbacks during training.\n", + "\n", + "Callbacks are methods, which are called during training to perform tasks such as saving checkpoints of the model (`ModelCheckpoint`) or stop the training early if a convergence criteria is met (`EarlyStopping`)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/50\n", + " 12/150 [=>............................] - ETA: 0s - loss: 17.0395 - accuracy: 0.0942 " + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-04-14 11:48:41.118317: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "140/150 [===========================>..] - ETA: 0s - loss: 3.4982 - accuracy: 0.1353\n", + "Epoch 1: val_loss improved from inf to 1.84449, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 8ms/step - loss: 3.3907 - accuracy: 0.1458 - val_loss: 1.8445 - val_accuracy: 0.3156\n", + "Epoch 2/50\n", + "148/150 [============================>.] - ETA: 0s - loss: 1.6724 - accuracy: 0.3665\n", + "Epoch 2: val_loss improved from 1.84449 to 1.58089, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 1.6707 - accuracy: 0.3670 - val_loss: 1.5809 - val_accuracy: 0.3983\n", + "Epoch 3/50\n", + "148/150 [============================>.] - ETA: 0s - loss: 1.4790 - accuracy: 0.4209\n", + "Epoch 3: val_loss improved from 1.58089 to 1.33352, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 1.4755 - accuracy: 0.4219 - val_loss: 1.3335 - val_accuracy: 0.5253\n", + "Epoch 4/50\n", + "146/150 [============================>.] - ETA: 0s - loss: 1.2029 - accuracy: 0.5586\n", + "Epoch 4: val_loss improved from 1.33352 to 1.18135, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 1.2032 - accuracy: 0.5593 - val_loss: 1.1813 - val_accuracy: 0.5806\n", + "Epoch 5/50\n", + "140/150 [===========================>..] - ETA: 0s - loss: 1.0944 - accuracy: 0.5868\n", + "Epoch 5: val_loss improved from 1.18135 to 1.09381, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 1.0921 - accuracy: 0.5873 - val_loss: 1.0938 - val_accuracy: 0.5917\n", + "Epoch 6/50\n", + "143/150 [===========================>..] - ETA: 0s - loss: 1.0173 - accuracy: 0.6051\n", + "Epoch 6: val_loss improved from 1.09381 to 1.04734, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 1.0192 - accuracy: 0.6051 - val_loss: 1.0473 - val_accuracy: 0.6206\n", + "Epoch 7/50\n", + "143/150 [===========================>..] - ETA: 0s - loss: 0.9230 - accuracy: 0.6555\n", + "Epoch 7: val_loss improved from 1.04734 to 0.89113, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.9215 - accuracy: 0.6564 - val_loss: 0.8911 - val_accuracy: 0.6717\n", + "Epoch 8/50\n", + "145/150 [============================>.] - ETA: 0s - loss: 0.7411 - accuracy: 0.7521\n", + "Epoch 8: val_loss improved from 0.89113 to 0.70894, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.7397 - accuracy: 0.7534 - val_loss: 0.7089 - val_accuracy: 0.7917\n", + "Epoch 9/50\n", + "150/150 [==============================] - ETA: 0s - loss: 0.6071 - accuracy: 0.8192\n", + "Epoch 9: val_loss improved from 0.70894 to 0.61332, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 8ms/step - loss: 0.6071 - accuracy: 0.8192 - val_loss: 0.6133 - val_accuracy: 0.8285\n", + "Epoch 10/50\n", + "147/150 [============================>.] - ETA: 0s - loss: 0.5089 - accuracy: 0.8581\n", + "Epoch 10: val_loss improved from 0.61332 to 0.49433, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.5086 - accuracy: 0.8583 - val_loss: 0.4943 - val_accuracy: 0.8716\n", + "Epoch 11/50\n", + "147/150 [============================>.] - ETA: 0s - loss: 0.3716 - accuracy: 0.9059\n", + "Epoch 11: val_loss improved from 0.49433 to 0.36685, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.3701 - accuracy: 0.9060 - val_loss: 0.3669 - val_accuracy: 0.9154\n", + "Epoch 12/50\n", + "149/150 [============================>.] - ETA: 0s - loss: 0.2866 - accuracy: 0.9238\n", + "Epoch 12: val_loss improved from 0.36685 to 0.32505, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.2869 - accuracy: 0.9238 - val_loss: 0.3250 - val_accuracy: 0.9172\n", + "Epoch 13/50\n", + "146/150 [============================>.] - ETA: 0s - loss: 0.2295 - accuracy: 0.9359\n", + "Epoch 13: val_loss improved from 0.32505 to 0.27026, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.2292 - accuracy: 0.9359 - val_loss: 0.2703 - val_accuracy: 0.9292\n", + "Epoch 14/50\n", + "146/150 [============================>.] - ETA: 0s - loss: 0.1937 - accuracy: 0.9450\n", + "Epoch 14: val_loss improved from 0.27026 to 0.24167, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1949 - accuracy: 0.9447 - val_loss: 0.2417 - val_accuracy: 0.9374\n", + "Epoch 15/50\n", + "142/150 [===========================>..] - ETA: 0s - loss: 0.1748 - accuracy: 0.9496\n", + "Epoch 15: val_loss did not improve from 0.24167\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1737 - accuracy: 0.9501 - val_loss: 0.2418 - val_accuracy: 0.9384\n", + "Epoch 16/50\n", + "143/150 [===========================>..] - ETA: 0s - loss: 0.1605 - accuracy: 0.9535\n", + "Epoch 16: val_loss improved from 0.24167 to 0.23019, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1607 - accuracy: 0.9536 - val_loss: 0.2302 - val_accuracy: 0.9406\n", + "Epoch 17/50\n", + "142/150 [===========================>..] - ETA: 0s - loss: 0.1472 - accuracy: 0.9569\n", + "Epoch 17: val_loss improved from 0.23019 to 0.22133, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1466 - accuracy: 0.9571 - val_loss: 0.2213 - val_accuracy: 0.9423\n", + "Epoch 18/50\n", + "149/150 [============================>.] - ETA: 0s - loss: 0.1381 - accuracy: 0.9596\n", + "Epoch 18: val_loss improved from 0.22133 to 0.20980, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1378 - accuracy: 0.9596 - val_loss: 0.2098 - val_accuracy: 0.9475\n", + "Epoch 19/50\n", + "145/150 [============================>.] - ETA: 0s - loss: 0.1266 - accuracy: 0.9632\n", + "Epoch 19: val_loss improved from 0.20980 to 0.20645, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1264 - accuracy: 0.9631 - val_loss: 0.2065 - val_accuracy: 0.9483\n", + "Epoch 20/50\n", + "141/150 [===========================>..] - ETA: 0s - loss: 0.1222 - accuracy: 0.9652\n", + "Epoch 20: val_loss did not improve from 0.20645\n", + "150/150 [==============================] - 1s 8ms/step - loss: 0.1222 - accuracy: 0.9652 - val_loss: 0.2111 - val_accuracy: 0.9489\n", + "Epoch 21/50\n", + "146/150 [============================>.] - ETA: 0s - loss: 0.1142 - accuracy: 0.9661\n", + "Epoch 21: val_loss improved from 0.20645 to 0.19401, saving model to mnist_keras_model.h5\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1136 - accuracy: 0.9664 - val_loss: 0.1940 - val_accuracy: 0.9506\n", + "Epoch 22/50\n", + "142/150 [===========================>..] - ETA: 0s - loss: 0.1114 - accuracy: 0.9683\n", + "Epoch 22: val_loss did not improve from 0.19401\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1105 - accuracy: 0.9684 - val_loss: 0.1999 - val_accuracy: 0.9514\n", + "Epoch 23/50\n", + "142/150 [===========================>..] - ETA: 0s - loss: 0.1030 - accuracy: 0.9696\n", + "Epoch 23: val_loss did not improve from 0.19401\n", + "150/150 [==============================] - 1s 7ms/step - loss: 0.1037 - accuracy: 0.9692 - val_loss: 0.1991 - val_accuracy: 0.9509\n" + ] + } + ], + "source": [ + "from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n", + "\n", + "checkpoint = ModelCheckpoint(\n", + " filepath=\"mnist_keras_model.h5\",\n", + " save_best_only=True,\n", + " verbose=1)\n", + "early_stopping = EarlyStopping(patience=2)\n", + "\n", + "history = model.fit(x_train, y_train, # Training data\n", + " batch_size=200, # Batch size\n", + " epochs=50, # Maximum number of training epochs\n", + " validation_split=0.5, # Use 50% of the train dataset for validation\n", + " callbacks=[checkpoint, early_stopping]) # Register callbacks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### a) Plot training and validation loss as well as training and validation accurace as a function of the number of epochs " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+8AAAHHCAYAAADOGmlXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAADIeUlEQVR4nOzdd3hU1dbH8e/MpEMSWhICCb0X6SWgCAqCCoKgSO+KvmDDe1G8XhRRsaNX7IpgA6UrCEiRDtJ776EklJDeZ877x5CBSIAEkswk+X2e5zxz5px9ZtbMvXKyZu+9tskwDAMRERERERERcVlmZwcgIiIiIiIiIjem5F1ERERERETExSl5FxEREREREXFxSt5FREREREREXJySdxEREREREREXp+RdRERERERExMUpeRcRERERERFxcUreRURERERERFyckncRERERERERF+fm7ABchc1m48yZM/j6+mIymZwdjoiICIZhEBcXR7ly5TCb9Xt7btD9XkREXEmO7vWGGIZhGOHh4QagTZs2bdq0udwWHh7u7Ntkrlu5cqXRuXNnIzg42ACMOXPm3PSav/76y2jUqJHh4eFhVK1a1fjuu+9y/L6632vTpk2bNlfcsnOvd8me988//5zPP/+c48ePA1C3bl3Gjh3L/fffn2X7KVOmMHjw4EzHPD09SU5OzvZ7+vr6AhAeHo6fn9+tBS4iIpKLYmNjCQ0NddyjCpOEhAQaNGjAkCFD6N69+03bHzt2jAcffJAnn3ySn376iWXLljFs2DCCg4Pp2LFjtt9X93sREXElObnXu2TyHhISwttvv0316tUxDIOpU6fStWtXtm3bRt26dbO8xs/PjwMHDjie53QoXEZ7Pz8/3cxFRMSlFMbh3ffff/91f5TPyhdffEHlypX54IMPAKhduzZr1qxh4sSJOUredb8XERFXlJ17vUsm7126dMn0/M033+Tzzz9nw4YN103eTSYTZcuWzY/wREREJJ+tX7+e9u3bZzrWsWNHnnvuuRtel5KSQkpKiuN5bGxsXoQnIiKS51y++o3VamX69OkkJCQQFhZ23Xbx8fFUrFiR0NBQunbtyp49e/IxShEREclLERERBAUFZToWFBREbGwsSUlJ171uwoQJ+Pv7O7bQ0NC8DlVERCRPuGzyvmvXLooXL46npydPPvkkc+bMoU6dOlm2rVmzJpMn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511ERESkEIvca0/c486AbzD0m8VZrypMmLIKgOfaV+e59jWcHKSIFFSqjpGPAnztFebPac67iIiISOFyfC1818meuJepCUOXQFBdxv22l/iUdBpVKMEz91R3dpQiUoCp5z0fBajnXURERKTw2TsPZj0O1hQIbQm9p4FPKZbujWTRnggsZhNvPVxfc9xF5LYoec9HjmHzcUreRURERAqFv7+yLweHAbU6Q49vwN2bhJR0Xv1tDwDD7qpM7WA/58YpIgWehs3no4ye98RUK/Ep6U6ORkRExPk+/fRTKlWqhJeXFy1atGDjxo03bP/RRx9Rs2ZNvL29CQ0N5fnnnyc5WYVgxQkMA5aOg4X/BgxoOhR6fg/u3gB8tPQgp6OTCCnpzbP3ari8iNw+Je/5qJinG8U8LIB630VERH755RdGjRrFq6++ytatW2nQoAEdO3bk3LlzWbb/+eefeemll3j11VfZt28f3377Lb/88gsvv/xyPkcuRZ41Deb+H6z50P78nlfgwQ/AbP87b/fpGCavPQ7A+G718PHQYFcRuX1K3vOZlosTERGx+/DDD3n88ccZPHgwderU4YsvvsDHx4fJkydn2X7dunW0bt2aPn36UKlSJe677z569+590956kVyVEg/TesGOn8FkgYc+gTb/hstLv1ltBv+ZswurzeDBO4JpVzPQyQGLSGGh5D2fqWidiIgIpKamsmXLFtq3b+84Zjabad++PevXr8/ymlatWrFlyxZHsn706FH++OMPHnjggeu+T0pKCrGxsZk2kVsWfx6mdobDS8HN216YrvGATE1+3HCCHadi8PV049XOdZwUqIgURhrDk88CtVyciIgIFy5cwGq1EhQUlOl4UFAQ+/fvz/KaPn36cOHCBe68804MwyA9PZ0nn3zyhsPmJ0yYwLhx43I1dimioo7a13CPOgrepaDvDAhpmqlJREwy7y0+AMDo+2sR6OfljEhFpJBSz3s+U8+7iIjIrVmxYgVvvfUWn332GVu3bmX27NksWLCA8ePHX/eaMWPGEBMT49jCw8PzMWIpNM5sg2/vsyfuJSrY13D/R+IO8Pr8PcSnpNMwtAR9m1dwQqAiUpip5z2fBWi5OBEREcqUKYPFYiEyMjLT8cjISMqWLZvlNf/973/p378/w4YNA6B+/fokJCTwxBNP8J///Aez+do+CU9PTzw9PXP/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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "epochs = range(1, len(history.history[\"loss\"])+1)\n", + "plt.figure(figsize=(12,5))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(epochs, history.history[\"loss\"], label=\"Training loss\")\n", + "plt.plot(epochs, history.history[\"val_loss\"], label=\"Validation loss\")\n", + "plt.legend(fontsize=15), plt.xlabel(\"Epochs\", fontsize=15), plt.ylabel(\"Loss\", fontsize=15)\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(epochs, history.history[\"accuracy\"], label=\"Training accuracy\")\n", + "plt.plot(epochs, history.history[\"val_accuracy\"], label=\"Validation accuracy\")\n", + "plt.legend(fontsize=15), plt.xlabel(\"Epochs\", fontsize=15), plt.ylabel(\"Accuracy\", fontsize=15);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### b) Determine the accuracy of the fully trained model\n", + "\n", + "The prediction of unseen data is performed using the `model.predict(inputs)` call. Below, a basic test of the model is done by calculating the accuracy on the test dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "313/313 [==============================] - 0s 621us/step\n", + "Test accuracy: 0.9522\n" + ] + } + ], + "source": [ + "### Your code here ###\n", + "\n", + "# Get predictions on test dataset\n", + "y_pred = model.predict(x_test)\n", + "\n", + "# Compare predictions with ground truth\n", + "test_accuracy = np.sum(\n", + " np.argmax(y_test, axis=1)==np.argmax(y_pred, axis=1))/float(x_test.shape[0])\n", + "\n", + "print(\"Test accuracy: {}\".format(test_accuracy))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "313/313 [==============================] - 0s 788us/step - loss: 0.1853 - accuracy: 0.9522\n" + ] + }, + { + "data": { + "text/plain": [ + "[0.1852734535932541, 0.9521999955177307]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.evaluate(x_test, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}