From d566375aa6292892bfdc482e4d7af76f2bb14a2a Mon Sep 17 00:00:00 2001 From: Tambet Matiisen Date: Wed, 20 Jun 2018 21:26:44 +0300 Subject: [PATCH] Initial commit. --- imitation/AlphaGoZero model.ipynb | 365 ++++++++++++++++++++ imitation/Clean.ipynb | 469 ++++++++++++++++++++++++++ imitation/Conv model.ipynb | 294 ++++++++++++++++ imitation/Discount.ipynb | 161 +++++++++ imitation/Fully connected model.ipynb | 240 +++++++++++++ imitation/Linear model.ipynb | 262 ++++++++++++++ imitation/collect_simple.py | 87 +++++ imitation/eval_model.py | 122 +++++++ mcts/mcts_agent.py | 234 +++++++++++++ 9 files changed, 2234 insertions(+) create mode 100644 imitation/AlphaGoZero model.ipynb create mode 100644 imitation/Clean.ipynb create mode 100644 imitation/Conv model.ipynb create mode 100644 imitation/Discount.ipynb create mode 100644 imitation/Fully connected model.ipynb create mode 100644 imitation/Linear model.ipynb create mode 100644 imitation/collect_simple.py create mode 100644 imitation/eval_model.py create mode 100644 mcts/mcts_agent.py diff --git a/imitation/AlphaGoZero model.ipynb b/imitation/AlphaGoZero model.ipynb new file mode 100644 index 0000000..2df17ee --- /dev/null +++ b/imitation/AlphaGoZero model.ipynb @@ -0,0 +1,365 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from keras.models import Model\n", + "from keras.layers import Input, Conv2D, Flatten, Dense, BatchNormalization, Activation, add\n", + "import tensorflow as tf\n", + "import keras.backend as K\n", + "from sklearn.metrics import explained_variance_score, accuracy_score\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# make sure TF does not allocate all memory\n", + "config = tf.ConfigProto()\n", + "config.gpu_options.allow_growth = True\n", + "K.set_session(tf.Session(config=config))" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((594333, 11, 11, 18), (594333,), (594333,))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('simple_600K_disc0.99_cleaned.npz')\n", + "x_train = data['observations']\n", + "p_train = data['actions']\n", + "v_train = data['rewards']\n", + "x_train.shape, p_train.shape, v_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((95623, 11, 11, 18), (95623,), (95623,))" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('valid_100K_disc0.99_cleaned.npz')\n", + "x_test = data['observations']\n", + "p_test = data['actions']\n", + "v_test = data['rewards']\n", + "x_test.shape, p_test.shape, v_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "__________________________________________________________________________________________________\n", + "Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + "input_5 (InputLayer) (None, 11, 11, 18) 0 \n", + "__________________________________________________________________________________________________\n", + "conv2d_14 (Conv2D) (None, 11, 11, 256) 41728 input_5[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_13 (BatchNo (None, 11, 11, 256) 1024 conv2d_14[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_11 (Activation) (None, 11, 11, 256) 0 batch_normalization_13[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_15 (Conv2D) (None, 11, 11, 256) 590080 activation_11[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_14 (BatchNo (None, 11, 11, 256) 1024 conv2d_15[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_12 (Activation) (None, 11, 11, 256) 0 batch_normalization_14[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_16 (Conv2D) (None, 11, 11, 256) 590080 activation_12[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_15 (BatchNo (None, 11, 11, 256) 1024 conv2d_16[0][0] \n", + "__________________________________________________________________________________________________\n", + "add_4 (Add) (None, 11, 11, 256) 0 batch_normalization_15[0][0] \n", + " activation_11[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_13 (Activation) (None, 11, 11, 256) 0 add_4[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_17 (Conv2D) (None, 11, 11, 256) 590080 activation_13[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_16 (BatchNo (None, 11, 11, 256) 1024 conv2d_17[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_14 (Activation) (None, 11, 11, 256) 0 batch_normalization_16[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_18 (Conv2D) (None, 11, 11, 256) 590080 activation_14[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_17 (BatchNo (None, 11, 11, 256) 1024 conv2d_18[0][0] \n", + "__________________________________________________________________________________________________\n", + "add_5 (Add) (None, 11, 11, 256) 0 batch_normalization_17[0][0] \n", + " activation_13[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_15 (Activation) (None, 11, 11, 256) 0 add_5[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_19 (Conv2D) (None, 11, 11, 256) 590080 activation_15[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_18 (BatchNo (None, 11, 11, 256) 1024 conv2d_19[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_16 (Activation) (None, 11, 11, 256) 0 batch_normalization_18[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_20 (Conv2D) (None, 11, 11, 256) 590080 activation_16[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_19 (BatchNo (None, 11, 11, 256) 1024 conv2d_20[0][0] \n", + "__________________________________________________________________________________________________\n", + "add_6 (Add) (None, 11, 11, 256) 0 batch_normalization_19[0][0] \n", + " activation_15[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_17 (Activation) (None, 11, 11, 256) 0 add_6[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_22 (Conv2D) (None, 11, 11, 1) 257 activation_17[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_21 (BatchNo (None, 11, 11, 1) 4 conv2d_22[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_19 (Activation) (None, 11, 11, 1) 0 batch_normalization_21[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_21 (Conv2D) (None, 11, 11, 256) 590080 activation_17[0][0] \n", + "__________________________________________________________________________________________________\n", + "flatten_3 (Flatten) (None, 121) 0 activation_19[0][0] \n", + "__________________________________________________________________________________________________\n", + "batch_normalization_20 (BatchNo (None, 11, 11, 256) 1024 conv2d_21[0][0] \n", + "__________________________________________________________________________________________________\n", + "dense_1 (Dense) (None, 256) 31232 flatten_3[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_18 (Activation) (None, 11, 11, 256) 0 batch_normalization_20[0][0] \n", + "__________________________________________________________________________________________________\n", + "activation_20 (Activation) (None, 256) 0 dense_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "flatten_2 (Flatten) (None, 30976) 0 activation_18[0][0] \n", + "__________________________________________________________________________________________________\n", + "dense_2 (Dense) (None, 1) 257 activation_20[0][0] \n", + "__________________________________________________________________________________________________\n", + "p (Dense) (None, 6) 185862 flatten_2[0][0] \n", + "__________________________________________________________________________________________________\n", + "v (Activation) (None, 1) 0 dense_2[0][0] \n", + "==================================================================================================\n", + "Total params: 4,398,092\n", + "Trainable params: 4,393,994\n", + "Non-trainable params: 4,098\n", + "__________________________________________________________________________________________________\n" + ] + } + ], + "source": [ + "def ConvBlock(mod):\n", + " mod = Conv2D(filters=256, kernel_size=3, strides=1, padding=\"same\")(mod)\n", + " mod = BatchNormalization()(mod)\n", + " mod = Activation('relu')(mod)\n", + " return mod\n", + "\n", + "def ResidualBlock(mod):\n", + " tmp = mod\n", + " mod = ConvBlock(mod)\n", + " mod = Conv2D(filters=256, kernel_size=3, strides=1, padding=\"same\")(mod)\n", + " mod = BatchNormalization()(mod)\n", + " mod = add([mod,tmp])\n", + " mod = Activation('relu')(mod)\n", + " return mod\n", + "\n", + "def PolicyHead(mod):\n", + " mod = Conv2D(filters=2, kernel_size=1, strides=1, padding=\"same\")(mod)\n", + " mod = BatchNormalization()(mod)\n", + " mod = Activation('relu')(mod)\n", + " mod = Flatten()(mod)\n", + " mod = Dense(6, activation='softmax', name='p')(mod)\n", + " return mod\n", + "\n", + "def ValueHead(mod):\n", + " mod = Conv2D(filters=1, kernel_size=1, strides=1, padding=\"same\")(mod)\n", + " mod = BatchNormalization()(mod)\n", + " mod = Activation('relu')(mod)\n", + " mod = Flatten()(mod)\n", + " mod = Dense(256)(mod)\n", + " mod = Activation('relu')(mod)\n", + " mod = Dense(1)(mod)\n", + " mod = Activation('tanh',name='v')(mod)\n", + " return mod\n", + "\n", + "h = x = Input(shape=(11,11,18))\n", + "h = ConvBlock(h)\n", + "for i in range(3):\n", + " h = ResidualBlock(h)\n", + "p = PolicyHead(h)\n", + "v = ValueHead(h)\n", + "model = Model(x, [p, v])\n", + "model.summary()\n", + "model.compile(optimizer='adam', loss=['sparse_categorical_crossentropy', 'mse'], loss_weights=[1, 10], metrics={'p': 'accuracy'})" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 594333 samples, validate on 95623 samples\n", + "Epoch 1/10\n", + "594333/594333 [==============================] - 1263s 2ms/step - loss: 2.6285 - p_loss: 1.3796 - v_loss: 0.1249 - p_acc: 0.4511 - val_loss: 2.7722 - val_p_loss: 0.8412 - val_v_loss: 0.1931 - val_p_acc: 0.6122\n", + "Epoch 2/10\n", + "594333/594333 [==============================] - 1259s 2ms/step - loss: 1.4321 - p_loss: 0.7752 - v_loss: 0.0657 - p_acc: 0.6346 - val_loss: 2.8289 - val_p_loss: 0.7384 - val_v_loss: 0.2090 - val_p_acc: 0.6484\n", + "Epoch 3/10\n", + "594333/594333 [==============================] - 1261s 2ms/step - loss: 1.1408 - p_loss: 0.7070 - v_loss: 0.0434 - p_acc: 0.6562 - val_loss: 2.8035 - val_p_loss: 0.7012 - val_v_loss: 0.2102 - val_p_acc: 0.6604\n", + "Epoch 4/10\n", + "594333/594333 [==============================] - 1263s 2ms/step - loss: 0.9821 - p_loss: 0.6719 - v_loss: 0.0310 - p_acc: 0.6694 - val_loss: 2.7501 - val_p_loss: 0.6809 - val_v_loss: 0.2069 - val_p_acc: 0.6660\n", + "Epoch 5/10\n", + "594333/594333 [==============================] - 1271s 2ms/step - loss: 0.8873 - p_loss: 0.6493 - v_loss: 0.0238 - p_acc: 0.6804 - val_loss: 2.8450 - val_p_loss: 0.6613 - val_v_loss: 0.2184 - val_p_acc: 0.6732\n", + "Epoch 6/10\n", + "594333/594333 [==============================] - 1281s 2ms/step - loss: 0.8250 - p_loss: 0.6334 - v_loss: 0.0192 - p_acc: 0.6882 - val_loss: 2.7277 - val_p_loss: 0.6603 - val_v_loss: 0.2067 - val_p_acc: 0.6741\n", + "Epoch 7/10\n", + "594333/594333 [==============================] - 1272s 2ms/step - loss: 0.7777 - p_loss: 0.6178 - v_loss: 0.0160 - p_acc: 0.6989 - val_loss: 2.7051 - val_p_loss: 0.6595 - val_v_loss: 0.2046 - val_p_acc: 0.6726\n", + "Epoch 8/10\n", + "594333/594333 [==============================] - 1259s 2ms/step - loss: 0.7405 - p_loss: 0.6021 - v_loss: 0.0138 - p_acc: 0.7090 - val_loss: 2.6416 - val_p_loss: 0.6597 - val_v_loss: 0.1982 - val_p_acc: 0.6717\n", + "Epoch 9/10\n", + "594333/594333 [==============================] - 1263s 2ms/step - loss: 0.7073 - p_loss: 0.5847 - v_loss: 0.0123 - p_acc: 0.7208 - val_loss: 2.6725 - val_p_loss: 0.6739 - val_v_loss: 0.1999 - val_p_acc: 0.6705\n", + "Epoch 10/10\n", + "594333/594333 [==============================] - 1272s 2ms/step - loss: 0.6754 - p_loss: 0.5653 - v_loss: 0.0110 - p_acc: 0.7338 - val_loss: 2.6304 - val_p_loss: 0.6822 - val_v_loss: 0.1948 - val_p_acc: 0.6683\n" + ] + } + ], + "source": [ + "history = model.fit(x_train, [p_train, v_train], batch_size=128, epochs=10, validation_data=(x_test, [p_test, v_test]))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,'Value MSE')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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uCHon7LWduQqqfRAXpfzg8AMa+32YNdHRERERI5PLasi0h/cAaxSUBURERHpPdoa+EREpM8wxuzBDZrR6fnzRERERCR41A1YREREREREehx1AxYREREREZEeR2FVREREREREepwed89qamqqzcrKCnY1RESkj1izZk2xtTYt2PXozXRuFhGRrtTRc3OPC6tZWVmsXt3elFMiIiKdY4zZG+w69HY6N4uISFfq6LlZ3YBFRERERESkx1FYFRERERERkR5HYVVERERERER6nB53z2pb6uvrycvLo6amJthV6VOioqLIzMwkPDw82FUREREREQkqZY6ud7J5o1eE1by8POLj48nKysIYE+zq9AnWWkpKSsjLy2PEiBHBro6IiIiISFApc3StrsgbvaIbcE1NDSkpKfpL04WMMaSkpOjKkYiIiIgIyhxdrSvyRq8Iq4D+0nQDfaciIiIiIs30+7hrnez32WvCajCVlJQwffp0pk+fzqBBg8jIyGh6X1dX16EybrnlFrZu3drNNRURERERkd5ImeNoveKe1WBLSUlh7dq1ANx7773ExcVx1113tdjGWou1lpCQtvP/448/3u31FBERERGR3kmZ42hqWT0JO3bsYPLkyXz5y19mxowZFBQUcPvtt5Odnc2kSZO47777mrY9++yzWbt2LT6fj6SkJO6++26mTZvGWWedxcGDB4N4FCIiIiIi0lP158zR61pWf/ivTeTkV3RpmROHJPCDSyed0L45OTk8/vjj/OY3vwHgwQcfJDk5GZ/Px4IFC1iyZAkTJ05ssU95eTnz5s3jwQcf5M4772Tp0qXcfffdJ30cIiIiIiJy8pQ5ega1rJ6kUaNGcfrppze9f+aZZ5gxYwYzZsxg8+bN5OTkHLVPdHQ0ixcvBmDmzJns2bPnVFVXRKTH8/sta/aWsvVAZbCrIiJ9lbVwcDNUHgh2TUQ6pL9mjl7XsnqiVyO6S2xsbNPr7du388gjj/Dxxx+TlJTEjTfe2OZQzREREU2vQ0ND8fl8p6SuIiI9ld9v+WRfKS9uKODljQcoKK/h6pmZ/OzqacGumoj0JTUVsOEvsOZxOLABTCiMvwiyb4UR86Gd+wCl/1Hm6Bl6XVjtySoqKoiPjychIYGCggJWrFjBokWLgl0tEZEeye+3rNlXyovrXUA9UFFDRGgIc8em8e1F41g4YWCwqygifYG1sP8TF1A3Pgf1VTBwCiz+GZTnwqdPweZ/wYARkH0LTP8sxKYGu9Yi7epPmUNhtQvNmDGDiRMnMnnyZEaOHMmcOXOCXSURkR6lwW9ZvecQyzcU8NLGAxysrCUiLIR5Y9O4e8p4Fk5IJz4qPNjVFJG+oKbca0V9wrWihsfClCUw82YYMgMa53889x7IeR5WL4VXvw9v3A8TL3etrcPOat5OpIfoT5nDWGuDXYcWsrOz7erVq1ss27x5MxMmTAhSjfo2fbci0t0a/JZVAQG1yAuo88emcfHUwZw7vnsDqjFmjbU2u9s+oB9o69ws0iNZC/vXeK2of3OtqIOmwMxbYMrVEJVw7P0PbobVj8O6ZVBbDmnjXWidei1EJ52aY5Cg0e/i7tHW99rRc7NaVkVEpMs1+C0f73YB9eVNLqBGhoWwYFw6F3kBNS5SpyAR6SI15bD+WVjzBygMbEW9BYac1vHW0fQJcNFP4bx7YdPfXGvrS9+GV38Akz/jgmvGDLW2ipwi+qUgIiJdwtfgdwF1YwEvbyyk+HAtUeFeQJ3iAmqsAqqIdJXGVtTVj7tgWV8Fg6bCJb+AyUuO34p6LBExcNqN7pG/1rXUrv8LrH3KfUb2ra6lNjKu645HRI6iXw0iInLCfA1+Ptp9iBc3FLBi4wFKjtQRHR7KuePTWTxlEOeOTycmQqcaEelC1WXN96IWbvRaUa9296JmzOj6zxsyHYY8Auf/CDY8C6uWwgvfgFe+B1OvccF10OSu/1wRUVgVEZHO8TX4+XCXC6ivbAoIqBPSuXjKYOaPS1NAFZGuZS3krXYBdeNz4KtubkWdcjVExnd/HaIS4PTbIPsLkLfKdRH+9ClY/XvInOVC66QrIDy6++si0k/o14SIiBxXfYOfD3aWsHxDASs2HaC0qp6YCNeC6gJqOtERocGupoj0NdVl3r2oT8DBTRARB9Ou9Ub0PS04dTIGhs5yjwt/DOueccH1H1+Gl+92U99k3wKpY4JTP5E+RGFVRETaVN/g5/2dJSxfX8CKnAOUVdUTGxHKwgkDuWjKIOaPSycqXAFVRLqYta7lcs0TbkRfXzUMng6XPOwGTToVragdFZMMZ/0bnPkV2POOC60f/xY+fBSyznGhdfylEBYR7JqK9Eohwa5AbzF//nxWrFjRYtnDDz/MV77ylXb3iYtzN93n5+ezZMmSdss93nQADz/8MFVVVU3vL7roIsrKyjpadRGRDqvz+Vm59SDf/us6Tn/gNW5a+jEvbihg3tg0fvu5maz53vn88vrTWDR5sIKqiHSt6jL46DH49Rz4/fmQ80/Xinr7m/Clt1zw60lBNZAxMGIuXP0E3LkZFv4AyvbCX2+FX0yE1+6F0j1BrqT0dMobR1PLagddf/31LFu2jAsvvLBp2bJly/jZz3523H2HDBnCX//61xP+7Icffpgbb7yRmJgYAJYvX37CZYmItFbn8/PejmJe3FDAqzmFlFfXEx8ZxnkTB7J48iDmjk1TMBXpav4GqDsC9dVQ7z3XVbkRbeurAtY1vg9YV1/tQltCBiRmNj/iBkFoL/tpZy3kfuxaUTf93bWiDjkNLn3ETRXTU8PpscSlwzl3wpxvwM43XGvre4/Auw/D6IXu3tYxF/a+PyvpdsobR9O/kg5asmQJ99xzD7W1tURGRrJnzx7y8/OZPn06CxcupLS0lPr6eu6//34uv/zyFvvu2bOHSy65hI0bN1JdXc0tt9xCTk4OEyZMoLq6umm7O+64g1WrVlFdXc2SJUv44Q9/yC9/+Uvy8/NZsGABqamprFy5kqysLFavXk1qaioPPfQQS5cuBeC2227jG9/4Bnv27GHx4sWcffbZvP/++2RkZPDPf/6T6Gjd8C8iTp3Pz7s7inhx/QFezTlARY2P+Mgwzp84kIumDOacsalEhimgSj9lLTTUn1iIbHN9G+U01HWyUgbCY9zgPeExUFvu5hZtsUkoxA+GRC/EJmRA4lAvzHqvowf0jDlCq0sD7kXN8e5Fvc67F3V6sGvXNUJCYMx57lG+Hz75I3zyB1h2A8QPgZk3wYzPQ8KQYNdUegjljaP1vrD60t1wYEPXljloCix+8JibpKSkMGvWLF5++WUuv/xyli1bxrXXXkt0dDR///vfSUhIoLi4mDPPPJPLLrsM086J4Ne//jUxMTGsX7+e9evXM2NG8xDrDzzwAMnJyTQ0NLBw4ULWr1/P17/+dR566CFWrlxJampqi7LWrFnD448/zkcffYS1ljPOOIN58+YxYMAAtm/fzjPPPMPvfvc7rrnmGp577jluvPHGk/+uRKTXOlzr4+1tRbyWU8irmwuprPERH+UC6sVTBnP2GAVU6cesha0vwRs/gqKtYBs6t78JcVOoRMR4oTLGex3tAmJ4dMt1TevbeB0eDRGxXjD1ygyLOjpk1lRAxX4XhMpzvdd57rH/E9j8r6NDcVh0QHjNhITMlmE2IcN9XnewFnI/CmhFrfFaUX/ptaL24TlLEzNgwXdg7rdg28uutfXN/4a3fgrjFrsuziPPdQFXeoYgZA7ljaP1vrAaRI1N841/eZYuXYq1lu9+97u8/fbbhISEsH//fgoLCxk0aFCbZbz99tt8/etfB2Dq1KlMnTq1ad2zzz7LY489hs/no6CggJycnBbrW3v33Xe58soriY2NBeCqq67inXfe4bLLLmPEiBFMn+6uTM6cOZM9e/Z00bcgIr3J/rJqXt9cyKs5hXy06xB1DX6SYsK5YOIgLp46iDmjFVBFyP/UzZm55x1IGQNz/t0Lj7GtgmNMyxAZGEBDI059i2VUgnukT2h7vd8PVcXNAbY8zwu0uS7gbn8NDhcCtuV+0cnN4bWphfYkuhtXl8K6P7uQWrQZIuJh+g0w46a+04raUaFhMOES9zi0230nnz4FW16ApOEutE6/EeLSgl1TCRLljZZ6X1g9Tgtod7riiiu48847+eSTT6iurmbGjBk88cQTFBUVsWbNGsLDw8nKyqKmpuaY5bR1FWT37t38/Oc/Z9WqVQwYMICbb775uOVYa9tdFxkZ2fQ6NDS0RfO/iPRdfr9lY345r+UU8trmg+QUVAAwIjWWm+dksXB8OjOHDyAsVFfvRSjPg9fvg/V/hpgUuOjnrhtqaHiwa9Y1QkLc/ZNx6ZAxo+1tfHVQme+1zuZBRWOw3Q+le2Hve210Nw5x3ViP6m4c0Fobk+xaUVc/Djn/8FpRZ8Bl/wuTrurbragdlTwCzv8hLPiuawVf84QbiOmNB2DiZe7e1uFzeka37f4oSJlDeaOl3hdWgyguLo758+dz6623cv311wNQXl5Oeno64eHhrFy5kr179x6zjLlz5/L000+zYMECNm7cyPr16wGoqKggNjaWxMRECgsLeemll5g/fz4A8fHxVFZWHtUsP3fuXG6++WbuvvturLX8/e9/58knn+z6AxeRHq2mvoH3dxbz2uaDvL65kMKKWkIMZA9P5juLx3PexIGMStMPQ5EmNRXw7i/gw//nuqae/R/uEZUY7JqdemERMCDLPdpzIt2NQyPcsoh4N+/ozJtg8LTuPJLeKyzSTckzZYnrgr7mCVj7NGx8DlLHwvDZrrU7JtldVIn2nmO8ZZGJ6j7chyhvtKSw2knXX389V111FcuWLQPgs5/9LJdeeinZ2dlMnz6d8ePHH3P/O+64g1tuuYWpU6cyffp0Zs2aBcC0adM47bTTmDRpEiNHjmTOnDlN+9x+++0sXryYwYMHs3LlyqblM2bM4Oabb24q47bbbuO0005Tl1+RfqCospaVWw7y2uZC3tleTHV9A7ERocwdm8Z5EwayYHw6ybGa10+khQYffPIErPxv1z12yjWw8HuQNCzYNevZOtvduDHMpo1TK2pnpY2DRf8NC7/v7uv95EnYshyqD4Hf1/Y+JsTdF90iyA5oFWpTWgbeqCSNRtyDKW80M8dq2g2G7Oxs23oeoM2bNzNhQjv/QcpJ0Xcr0jtYa9l+8DCvbS7ktZxCPs0tw1oYnBjFeRMGct7EgZw5Mln3n7bBGLPGWpsd7Hr0Zm2dm3sVa2HbCnj1e1C8zXWtvOD+9rvGivQ01kJtBVQdcsG1qvFR4r0vaXtdQ237ZUYlufB6VKgd0HYrbnSya4nvw/S7uHu09b129NysSyoiIj1UfYOfVXsO8VqOa0Hdd8hN1j0lI5FvLBzLwgnpTBqS0O5ogCICFKyDV+6B3W9Dymi47k8w7iLdByi9izGum3pUIjCiY/tY66ZJai/IVge8PnzATSFUdchNtdSeiHjXatu6pTZ1DGTOgvSJarGVLqW/TSIiPUh5dT1vedPLvLn1IBU1PiLCQpgzKoUvzRvJwvEDGZQYFexqivR85fvhjfth3TOupWjxz9xIq31l8CSR4zHGjV4dEdu5ru71NS2DbFPLbWnLVtyqEji0E44UQ91ht294rOuxMHSWC6+Zp0NsSvccn/QLCqsiIkGWe6iKV3MKeX2Lm17G57ekxEZw4aRBLJwwkHPGpBIbqf+uRTqkthLefRg+eBSsH+Z8Hc75Zv8cPEnkRIRHQfgQSBjSse2thdI9kLca8j6G3I/dv8HGuYqTR7nQOvR0tb5Kp/WavynWWnV162I97X5lkf7C77eszSvj9c2FvJZzkK2FlQCMSY/jtnNGcv7EdKYPHUBoiP7PE+mwBh98+kdY+WM4UgSTl7hBagYMD3bNRPo2Y9w0PMkjYOrVblldlZu/OO9jyF0FO1+H9W6woJ7e+qrM0bVONm/0irAaFRVFSUkJKSkp+svTRay1lJSUEBWl7oQip0J1XQPv7ijmtZxCXt9ykOLDtYSGGE7PGsA9F0/gvAkDyUqNDXY1pRcxxiwCHgFCgf+z1j7Yav2dwG2ADygCbrXW7vXW3QTc4216v7X2D6es4l3NWtj+qhs8qWgLDDsLrv8zZM4Mds1E+q+IGMia4x4Q0Pq6yrW85vXM1ldljq7VFXmjV4TVzMxM8vLyKCoqCnZV+pSoqCgyMzODXQ2RPutgRQ2vbznIazmFvLujmFqfn/jIMOaNS+P8iQOZPzadxBjdPyedZ4wJBR4FzgfygFXGmOettTkBm30KZFtrq4wxdwA/Ba41xiQDPwCyAQus8fYtPbVH0QUK1nuDJ70FySPh2qdg/CUaPEmkp2nR+nqNW1Z3BPLX9qjWV2WOrneyeaNXhNXw8HBGjOjgyGciIkHi91s2H6jgjc1u9N51eeUAZA6I5vpZwzh/4kBOz0omIkyTt8tJmwXssNbuAjDGLAMuB5rCqrV2ZcD2HwI3eq8vBF611h7y9n0VWAQ8cwrq3TUq8t3gSWv/BNFJsOgnkH1rn59WQ6RPiYjtfOvrUC+4Dp0FaRO6vPVVmaPn6RVhVUSkJ7LWsqv4CO/vLOGDncV8sLOE0qp6AKYPTeJbF45j4YR0xg2MV3ci6WoZQG7A+zzgjGNs/wXgpWPsm9GltesutYfhvUfg/f91P2Bnf80NnhSdFOyaicjJarf19VMvvK6GHa+5Eb6h59772jhlUE2Fmxu3pgJqy5vf11a2WlcBNeVueWwaDJwI6ZPcc+pYCIsM9hEFlcKqiEgn5JVWeeG0hPd3FlNY4SZcH5IYxbnjBzJndApnj04lPUH3g0u3auvqR5ujWBhjbsR1+Z3XmX2NMbcDtwMMG9aJaS+6g78BPn0S3ngAjhyEyZ/xBk/KCm69RKR7RcRC1tnuAZ1vfU2fCCGhHf88a900PG2GyYo2lnvhMzCM1lQ016ddBiITICqh+Tk2DSoLYNeb4HcXvgkJc/NDp09sGWITh0FI/+ilpbAqInIMBytr+KApnJaw71AVACmxEZw1KoXZo1KZPSqF4Skxaj2VUykPGBrwPhPIb72RMeY84L+Aedba2oB957fa983W+1prHwMeA8jOzg7e8PHbX3ODJx3MgaFnwvXPQGZ20KojIkF03NbXVW7AtbZaXyPijhE4vee6Sjfl1THrEBIQNBPdc0ImpCccHUAjE9y0WU3v493riLj2w2ZDPZTsgMJN7v+9whzYvxo2/a15m4g4SJ/ghdhJzc8xySf/HfcwpqdNX5KdnW1Xr14d7GqISD9VXlXPB7tct973d5aw/aCb6Dw+KowzR6Yw2wuoYwfGKZz2EsaYNdbaPpVujDFhwDZgIbAfWAXcYK3dFLDNacBfgUXW2u0By5OBNcAMb9EnwMzGe1jbEpRz84GNLqTufAMGjIDzfwgTLtPgSSJybG21vh7Y6Fo7Q8KOESTbe05sfh8Z71p7g/H/UE2FG/E8MMQe3ATVAWPjxQ3yWmADQmzaeDd3bg/T0XOzWlZFpF87Uutj1Z6eacS/AAAgAElEQVRDTS2nG/PLsRaiwkM4PSuZz8zMZPaoFCYNSdS8p9JjWGt9xpivAitwU9cstdZuMsbcB6y21j4P/AyIA/7iXVjZZ629zFp7yBjzI1zABbjvWEH1lKsogJX3w6dPe4MnPQjZX9DgSSLSMW21vtbXABbConrvBa+oBNdCPHRW8zJrofKAC62FOV6I3QQf/w4avM40JsR1jw7sRpw+0V0E7AVdidWyKiL9Sk19A5/uK2tqOV2bW4bPbwkPNZw2bEBTy+n0oUkatbeP6Istq6faKTk31x2B934J7/8S/D6YdTvMvQuiB3Tv54qI9DUNPji06+gQW7qHpiEKwmNcq2uLEDsJ4tJOSRW7tGW1AxOP/wJY4L2NAdKttUneur4z8biI9Dq+Bj/r95c3DYi0ek8ptT4/IQamZCbxxbkjmT0qhezhyURHdGIQBhHpGv4GWPu0Gzzp8AGYdCUs/IFrFRERkc4LDYO0se4x6crm5XVH4OCWgBC7Cba+DJ8+1bxNbFqre2EnummCImJO/XHQgbDakYnHrbX/EbD914DTvNd9Z+JxEekV/H7LlgOVvO9NJfPR7kMcrvUBMH5QPDecMYw5o1KZNTKZhKjwINdWpJ/b8Tq88j33gylzFlz7ZMsubiIi0nUiYiFzpnsEOnzw6HthVz8OvmpvA69rdfpEmHyVG5H9FOlIy+pxJx5v5XpcQIW+MPG4iPRox5rrdERqLJdNH8LsUSmcOTKF1Lj+PVeZSI9RmAOv3AM7X3fTz1z9B5h4ee+9l0xEpDeLS3ePUQual/kbXLfhphDrPRfvOKVV60hY7fDE48aY4cAI4I1j7Ns7Jh4XkR6rvblOB3tznc4elcJZo1IYkhQd5JqKSAuVB2DlA67LWWQCXPhjOP22fj/pvYhIjxMSCimj3GPiZc3LT/F4Rx0Jqx2eeBy4DvirtU0z4fa+icdFpMcpr6rnvZ3FvLO9iPd2tJzr9MxRbjqZOaNSNdepSE/mq4XfzoWqQ3DGHW7wpD44J6CISJ92in9ndSSsdmjicc91wL+12nd+q33fbL1Tj5l4XER6hPoGP+tyy3h7ezFvbytifV4ZfgtxkWGcOTKZm2dnMXt0CmPT4wnRdDIivUNYJFz0cxg0GZJHBrs2IiLSC3QkrK4CxhhjRuAmHr8OuKH1RsaYccAA4IOAxSuAHxtjGsedvwD4zknVWET6pL0lR3h7ezHvbCvig50lVNb6CDEwNTOJry4YzdyxaUwbmkR4qKaTEem1AruSiYiIHMdxw2oHJx4HN7DSMhswcWuPn3hcRIKmoqaeD3aW8M72It7ZXszeEte1NyMpmkumDeacMWnMHpVCUkxEkGsqIiIiIsHQoXlWrbXLgeWtln2/1ft729l3KbD0BOsnIn1Eg9+yLq+Md7a5e08/zS2jwW+JiQjlrJEp3DpnBOeMSWVEaqzuOxURERGRjoVVEZETkVdaxTvbXTh9d3sxFTU+jIEpGYl8ed5IzhmTxoxhA4gIU9deEREREWlJYVVEusyRWl+Lrr27io8AMCghikWTB3HOmDTmjE4lOVZde0VERETk2BRWReSE+f2WjfnlvOON2vvJvlLqGyxR4SGcOTKFz545nLljUhmdHqeuvSIiIiLSKQqrItIpBeXVTeH0vR3FlFbVAzBpSAJfOHskc8ekMjNrAJFhoUGuqYiIiIj0ZgqrInJMVXU+Ptp9qGlgpO0HDwOQFh/JgvHpzB2TxtljUkmNiwxyTUVERESkL1FYFZEW/H7L5gMVTa2nq/eUUtfgJzIshFkjkrkmeyjnjE1l3MB4de0VERERkW6jsCrSz9U3+NleeJgN+8v4YGcJ7+4opvhwHQDjB8Vz0+zhzB2bxulZyUSFq2uviIiIiJwaCqsi/Uidz8+2wko27C9no/fYfKCSOp8fgJTYCM4Zk8o5XtfegQlRQa6xiIiIiPRXCqsifVRNfQNbD1SyMd+F0g37y9l6oJL6BgtAfFQYk4ckctNZw5mckciUjESyUmIJCVHXXhEREREJPoVVkT6gpr6BnIIKNnmhdMP+CrYXVuLzu2CaGB3OlIxEbj17BFO8YDp0QIyCqYiIiIj0WAqrIr1MVZ2PnPwKr7XUPe8oOkyDF0yTYyOYnJHIgnFpTMlIZHJGIpkDojUYkoiIiIj0KgqrIj3Y4Vofm/aXs7EpnJazq+gwXi4lNS6SKRkJXDBpYFNX3sGJUQqmIiIiItLrKayK9BAVNfVs3F/Opv0VbgCk/HJ2Fx/BesF0YEIkUzISuXjKYNeVNzOR9PhIBVMRERER6ZMUVkWCoKyqjk35Fd79peVs2l/OnpKqpvVDEqOYnJHIFdMzmJKRyKSMBNLjNTKviIiIiPQfCqsi3azW18CavaV8uq/MTReTX07uoeqm9ZkDopmSkcjV2UOZnJHI5CEJpMRFBrHGIiIiIiLBp7Aq0g32lVTx1raDvLWtiPd3llBV1wDA8JQYpmYmccOs4d7gRwkkxUQEubYiIiIiIj2PwqpIF6iq8/HRrkO8ta2It7YVsbv4CADDkmNYMjOTeWPTyM5KJjE6PMg1FRERERHpHRRWRU6AtZbtBw/z1lYXTj/ec4g6n5+o8BBmj0rl5tlZzBubRlZqbLCrKiIiIiLSKymsinRQeXU97+8obmo9LSivAWDswDhuOms488amk501gKjw0CDXVERERESk91NYFWmH32/ZlF/RdO/pJ/vKaPBb4iPDOHtMKv++MI25Y9MYkhQd7KqKiIiIiPQ5CqsiAUoO1/LOdtd6+va2IkqO1AEwJSORO+aNYt64NKYPTSI8NCTINRURERER6dsUVqVf8zX4WZtb1tS1d8P+cqyF5NgI5o5JZd64NM4Zk0bqqZ5Kxt8AvlpoqIOGeu+59SNgua+NZQ310NBWGfVe2a23rYOQMAiPbvWIafkcdox1jY+waAhRoBcRERGRE6ewKv1OQXk1b3vh9J3txVTW+AgxMGPYAO48byzzxqUxeUgiISHmxD/E74eyvVC4EQ5shIOboKq07aDZ1jLr77oDbhQSBqEREBruPUcGvI6A0DAXkuurvUcV+Grc84kIi2oOsmFRrQJtYMiNaif4xrQso2lZRECdA+ofonuFRURERPoShVXp82p9DazaXdp07+m2wsMADEqI4uIpg5k7No05o1JJjDnBaWXqjkBhDhRucMG0cJN71FV6GxhIGQVxgyAiFkIHuJAVFnl04GozSAasby+ohbazvHH7kPATb+m01gutXoBteq5p9b6NkNvWuvoaqC5ttawafNUnVr9GJqT5WNv8Tlsva295q9chndi2sdywKO8R2fI5JAzMSVwEEREREelHFFalT9pTfKSpa+8HO0uorm8gIjSEWSOSuXrmUOaNS2NMehymM8HBWijP9QLpRjiwwT0f2g1Yt01kAgycDNOug0GTYeAUSJ8AETHdcpynhDHNLaIkd9/n+P0u5LYZdAMCr68W/PVtd2M+6rWvnW7TtVBb2XKZv51tu5IJaTvEthdu29wuYFl4dOf2UeuziIiI9CIKq9InVNX5+GBnSVNA3Vviuq5mpcRwTXYm88alcebIFGIiOvhXvq4KDm52YbSxK2/hJqgtb94meaQLplMbg+lkSBqmlrMTFRLiQn1EDN0aijvD2jZCbP1xAnJAIPbVBDzXuFblFsvaeK4pb7XcC+j11TRdFDlRIWHNATYiBiITISoBIuPdhZbI+FbvE9pYn+ieQ0+wJ4KIiIhIBymsSq9VVlXHik0HeGF9AR/tOkRdg5/o8FBmj0rhC2ePYO6YNLJSY49diLVQsb+5tbQxmB7a2XzfaEQcDJwEU5Y0h9L0iRAZ1/0HKcFlTHPXXo7zd6m7NQbnNkNuq2WNLdDtBuNq1329psK1MFfsh9ot3vsK9znHExbdRrgNCLNHhd/Eo7ePiNNAXCIiItIuhVXpVcqr63k1p5AX1ufz7vZifH7LsOQYbpo9nPnj0snOGkBkWDtdHetroGhzQDDd5Lry1pQ1b5M0HAZNgcmf8YLpJEjK0g9qCb7A4BwZ332f03iPcm1lc3itrQh4X9m8rMX7Sjh8sOX747YEm2O06sbDqAUw6cruO1YRERHp0RRWpcerrKnn9c0HeWF9Pm9vK6auwU9GUjRfOHsEl0wdwuSMhJb3nloLlQda3ldauAmKt4NtcNuEx7jW0UlXuJbSQVPc+6iE4BykSE8ReI9yXPqJl+P3Q93hNoJueRvBt9J1f66thKoSKN3j1sckK6yKiIj0Ywqr0iNV1fmaAurKrUXU+fwMSojic2cN55Kpg5k+NMkF1JoKKFjr7i89sNGNyFu4yf3gbZQ4zLWQTri0OZgOyNJgMyLdKSTEXfzRBSARERE5QQqr0mPU1DewcstBXthQwBubD1Jd30BafCQ3z0zl8mG1TIgsIuTQp/DJLnh1p7uv9EhRcwFhUW7k3XEXuUA60OvGG50UvIMSEREREZETorAqQVXra+CtrUW8sm43O7esZ6Avn0mRRdyaVsaYsIPEV+Vi1h2AdQE7xQ1y85aOXeSek0dB2nj3Wq2lIiIiIiJ9gsKqnDr1NVC6m/qiHezdtp6ivTmElu5mCgVcYA5BCBCBG5OlNh3iRsGQ8yBlpAukySPdQ6PwioiIiIj0eQqr0rV8tW5wlBKvm673bEt2QkU+Bks4MBpIJp6KmGGYgfNoyJpIaOqo5lCq+9xERERERPo1hVXpPF8dlO1rEUabnsvzmucnBeojkigIG8L6qpFsqz+LA2FDGDRiIjNPy+bMSSNJbm+aGRERERER6dcUVqV9DT7I/chN/xIYSMtym6eAAYhMdF11M2dhp17HTv8gXi+M48+7wtlVEUlMRCgLJwzkkqmD+crYNKLCFVBFREREROTYFFalpZoK2Pk6bFkO21+BmjK3PCLeBdIhM2DK1c3ddVNG4Y9K5tO8Mv61roDlHxRwsLKWqPAQzh2fzl1Th7BgXDrREQqoIiIiIiLScQqrAuX7Yety2PoS7HkHGuogOhnGLXbTwAw7E2LTwJimXay1rMsr54WV+SzfsI788hoiwkKYPzaNi6cO5rwJA4mN1F8vERERERE5MUoT/ZG1rmvv1pdg64tQ4M0LkzwSZt0O4y+GzFkQGtZqN8um/ApeWF/AixvyyT1UTXioYe6YNO66cBznTxxIfFR4EA5IRERERET6GoXV/sJXB3vf9QLqS1CeCxjIPB3Ou9e1oKaObdF6Ci6gbjlQyYvrC3hhfT57SqoIDTHMGZ3K184dw4UTB5EYo4AqIiIiIiJdS2G1L6sugx2vwZYX3XNtBYRFw6gFMO8/YeyFEJfe7u7vbC/iJy9vYeP+CkIMnDUqhS/NG8WFkwaRHBtxCg9ERERERET6G4XVvqZ0b3P33r3vg9/n7jedeLnr3jtiHkTEHLOILQcq+PHyLby9rYjMAdHcd/kkFk8eTFp85Ck6CBERERER6e8UVns7vx8K1jYPkFS40S1PHQezv+a692ZkQ0jIcYsqrKjhf17Zyl/X5BEXGcZ/XTSBz88eTqTmQhURERERkVNMYbU3qq9xo/ZueRG2vQyVBWBCYNhZcMH9LqCmjOpwcUdqffz27V387u1d+Px+bpkzgq+dO5qkGHX1FRERERGR4OhQWDXGLAIeAUKB/7PWPtjGNtcA9wIWWGetvcFb3gBs8DbbZ629rAvq3f9UHYJtK1wL6s43oO4whMfC6IUunI69EGKSO1Wkr8HPs6vzeOjVbRQfruXiqYP59oXjGJ4S200HISIiIiIi0jHHDavGmFDgUeB8IA9YZYx53lqbE7DNGOA7wBxrbakxJnDUnmpr7fQurnf/ULKzuXvvvg/A+iF+MEy9xgXUrHMgPKrTxVprWbn1IP+9fAvbDx4me/gAHvv8TGYMG9ANByEiIiIiItJ5HWlZnQXssNbuAjDGLAMuB3ICtvki8Ki1thTAWnuwqyvaL/j9sH+1C6hblkPxVrd84GQ455suoA6e3qH7T9uzcX85P16+mfd3lpCVEsNvbpzBhZMGYVpNWSMiIiIiIhJMHQmrGUBuwPs84IxW24wFMMa8h+sqfK+19mVvXZQxZjXgAx601v6j9QcYY24HbgcYNmxYpw6g16urgl1vuoC67WU4UgQhYTB8DmTfCuMWwYCsk/6Y/WXV/M+Krfzt0/0MiAnn3ksncsMZw4kIO/HgKyIiIiIi0l06ElbbanKzbZQzBpgPZALvGGMmW2vLgGHW2nxjzEjgDWPMBmvtzhaFWfsY8BhAdnZ267L7Jl8tLL8L1v8FfNUQmQCjz3PTy4xeCNFd0yW3oqaeX7+5k9+/uxuAL88bxR3zR5EYHd4l5YuIiIiIiHSHjoTVPGBowPtMIL+NbT601tYDu40xW3HhdZW1Nh/AWrvLGPMmcBqwk/6sthKWfRZ2vwUzb4aJV7iW1LCuG323vsHPnz7axyOvb+fQkTquPC2Db14wlswBx55jVUREREREpCfoSFhdBYwxxowA9gPXATe02uYfwPXAE8aYVFy34F3GmAFAlbW21ls+B/hpl9W+N6o6BE8vgfy1cMVvYPr1XVq8tZZXcgp58KUt7C4+wpkjk/mviyYyJTOxSz9HRERERESkOx03rFprfcaYrwIrcPejLrXWbjLG3AesttY+7627wBiTAzQA37LWlhhjZgO/Ncb4gRDcPas57XxU31eRD09eCYd2w7VPwfiLurT4T/eV8uPlm1m1p5RRabH8/qZszh2frsGTRERERESk1+nQPKvW2uXA8lbLvh/w2gJ3eo/Abd4Hppx8NfuAkp3w5BVQVQo3PgcjzumyonMPVfGTl7fwwvoCUuMieODKyVybPZSwUA2eJCIiIiIivVOHwqqcpAMb4MmrwDbAzf+CIad1SbFlVXX86o0d/PGDvYSEwNfPHc3t80YRF6k/VhERERER6d2Uarrbvg/h6WsgMg4+9yKkjT3pImt9DTz5wV7+940dVNTUs2RGJt+8YByDEqO6oMIiItIbGGMWAY/gbtH5P2vtg63WzwUeBqYC11lr/xqwrgHY4L3dZ6297NTUWkREpOMUVrvT9lfhz5+DxAz43D8gaejx9zkGay0vbijgJy9vIfdQNeeMSeU7iycwcUhCF1VYRER6A2NMKPAocD5uRP5VxpjnW40LsQ+4GbirjSKqrbXTu72iIiIiJ0Fhtbts+Cv8/UuQPhFu/BvEpZ1Ucav2HOKBFzezNreM8YPi+cOts5g39uTKFBGRXmsWsMNauwvAGLMMuBxoCqvW2j3eOn8wKigiInKyFFa7w6rfw4vfhOGz4fpnIOrEp43ZVXSYn7y8hRWbChmYEMlPPzOVz8zMJDREI/yKiPRjGUBuwPs84IxO7B9ljFkN+HAj9f+j9QbGmNuB2wGGDRt2ElUVERE5MQqrXclaeOd/4I0fwdhFcPUTEB59QkUdOlLHL1/fzlMf7iUiLIQ7zx/LbeeMICZCf2QiIkJbVyxtJ/YfZq3NN8aMBN4wxmyw1u5sUZi1jwGPAWRnZ3embBERkS6h5NNVrIVX7oEPfgVTr4XLH4XQ8E4XU1PfwOPv7eH/rdzBkTof180axjfOG0N6vAZPEhGRJnlA4EAImUB+R3e21uZ7z7uMMW8CpwE7j7mTiIjIKaaw2hUafPCvf4e1T8GsL8GiByGkc3Oc+v2Wf67bz89e3kp+eQ0Lx6dz9+LxjBkY302VFhGRXmwVMMYYMwLYD1wH3NCRHY0xA4Aqa22tMSYVmAP8tNtqKiIicoIUVk9WfQ089wXY8gLM/w7M+08wnbuf9P2dxfx4+WY27q9g0pAEfn71NGaPTu2mCouISG9nrfUZY74KrMBNXbPUWrvJGHMfsNpa+7wx5nTg78AA4FJjzA+ttZOACcBvvYGXQnD3rOa081EiIiJBo7B6MmorYdkNsPttWPQTOPPLndp9V9FhHnhxM69vOciQxCh+ce00Lp+WQYgGTxIRkeOw1i4Hlrda9v2A16tw3YNb7/c+MKXbKygiInKSFFZPVNUheOozULAOrvwtTLuu00Xc9ofVFFXW8p+LxnPLnCyiwkO7oaIiIiIiIiK9j8LqiSjfD09eCaV74LqnYdziThdxsLKGXcVHuOfiCdx2zsiur6OIiIiIiEgvprDaWSU74Y9XQHUpfO5vkHX2CRWzLrccgOlDk7qydiIiIiIiIn2CwmpnFKyHp65y09Tc/AIMmX7CRa3NLSU0xDA5I7ELKygiIiIiItI3dG5+lf5s7wfwxCUQGgm3vnxSQRVcy+r4QfG6T1VERERERKQNCqsdse0Vd49qXLoLqqljTqo4v9+yLrdMXYBFRERERETaobB6PBv+Csuuh7SxLqgmDT3pIncVH6Gy1qewKiIiIiIi0g6F1WP5+Hfw3G0w9Ey46QWITe2SYtfmlgEaXElERERERKQ9GmCpLdbC2z+HlffDuItgyVIIj+6y4tfllhEXGcaotLguK1NERERERKQvUVhtze+HV+6BDx+FqdfB5Y9CaNd+TWtzy5iamUhIiOnSckVERERERPoKdQMO1OCD57/qguoZX4Yrft3lQbWmvoHNBRXqAiwiIiIiInIMalltVF8Dz30BtrwA878L874NputbPjflV+DzW6YprIqIiIiIiLRLYRWgthKeuR72vAOLfwZn3N5tH9U4uNJpCqsiIiIiIiLtUlg9UgJPfwYK1sNVv4Op13Trx63LLWNwYhTpCVHd+jkiIiIiIiK9Wf8Oq+X74ckroGwfXPcnGLeo2z9ybW6Z7lcVERERERE5jv47wFLxDlh6IVQegBv/dkqC6qEjdew7VKX7VUVERERERI6jf7asFqyDJ69yr2/6FwyZfko+dp13v6paVkVERERERI6t/7Ws7n0fnrgEwqPh1hWnLKiC6wIcYmBKRuIp+0wREREREZHeqH+F1W0r4MkrIX4Q3PoypI4+pR+/NreMsQPjiY3snw3aIiIiIiIiHdV/wur6v8CyGyB9AtzyMiRmntKPt9ayLq+MaZnqAiwiIiIiInI8/SOsfvw7+NsXYdhZ7h7V2JRTXoW9JVWUVdUzfZjCqoiIiIiIyPH07f6o1sLbP4OVD8C4i2HJUggPzvym6/Lc4EpqWRURERERETm+vhtW/X5Y8V346Ncw7Qa47H8hNHiH++m+MqLDQxk7MC5odRAREREREekt+mZYbfDB81+Fdc/AmV+BCx6AkOD2eF6XV8aUjETCQvtHz2sREREREZGT0XeTU20lLLgHLvxx0INqnc/PpvwK3a8qIiIiIiLSQX2zZTU0DK55MughtdGWAxXU+fy6X1VERERERKSDekaa6w49JKiCm18VUMuqiIiIiIhIB/WcRNeHrc0tIy0+kiGJwRmJWEREREREpLdRWD0F1uaWMS0zCWNMsKsiIiIiIiLSKyisdrPy6np2FR3hNHUBFhGRfqy+wc9Dr2zlb5/kBbsqIiLSSyisdrP1ee5+VQ2uJCIi/VlYiOGt7cU89Oo26hv8wa6OiIj0Agqr3WydN7jS1KGJQa6JiIhI8Bhj+NqC0eSVVvP82vxgV0dERHoBhdVutja3jFFpsSREhQe7KiIiIkG1cEI6EwYn8OibO2jw22BXR0REergOhVVjzCJjzFZjzA5jzN3tbHONMSbHGLPJGPOngOU3GWO2e4+buqrivYG1lrW5ZUwfOiDYVREREQk6YwxfXTCaXUVHeGljQbCrIyIiPdxxw6oxJhR4FFgMTASuN8ZMbLXNGOA7wBxr7STgG97yZOAHwBnALOAHxph+k9z2l1VTfLiO6eoCLCIiAsCiyYMYlRbLr97YgV+tqyIicgwdaVmdBeyw1u6y1tYBy4DLW23zReBRa20pgLX2oLf8QuBVa+0hb92rwKKuqXrPt9a7X1UtqyIiIk5oiOHfFoxmy4FKXt9y8Pg7iIhIv9WRsJoB5Aa8z/OWBRoLjDXGvGeM+dAYs6gT+/ZZ63LLiAgLYdyg+GBXRUREpMe4bNoQhiZH86s3tmOtWldFRKRtHQmrpo1lrc8sYcAYYD5wPfB/xpikDu6LMeZ2Y8xqY8zqoqKiDlSpd1ibW8bkIQlEhGkcKxERkUZhoSF8Zf5o1uWV88724mBXR0REeqiOpKg8YGjA+0yg9ZjzecA/rbX11trdwFZceO3IvlhrH7PWZltrs9PS0jpT/x7L1+Bnw/5ypg3V/KoiIiKtXTUjg8GJUfzqjR3BroqIiPRQHQmrq4AxxpgRxpgI4Drg+Vbb/ANYAGCMScV1C94FrAAuMMYM8AZWusBb1udtLaykpt7PdIVVERGRo0SGhfKluSP5eM8hPtpVEuzqiIhID3TcsGqt9QFfxYXMzcCz1tpNxpj7jDGXeZutAEqMMTnASuBb1toSa+0h4Ee4wLsKuM9b1uetyy0HUFgVERFpx3WzhpEaF8GvVqp1VUREjhbWkY2stcuB5a2WfT/gtQXu9B6t910KLD25avY+a3NLGRATzrDkmGBXRUREpEeKCg/li+eM5L9f2sKn+0o5bZhGzxcRkWYa+aebrMt196sa09YYUyIiIgLw2TOHkxQTzqNqXRURkVYUVrvB4Vof2w5WqguwiIjIccRFhnHrnBG8tvkgm/LLg10dERHpQRRWu8GGvHKs/f/t3Xt81PWd7/H3JzOTTO4JIZBAEkIAUQQTCioXL9VWq7WFdm13tZdVW9d2K7rntOfs1p49ddd2L92zu71pL2pte9qqbW13vdTVWrW1UkFRJ3IrcpUJhGuYhNxv3/1jJhAwgYFM+M3l9Xw88mDmN78Jb+aB/Hzn+/t+v2IlYAAA4nDDkloV5vj1ree3eh0FAJBEKKvjIBSOSJIaqiirAACcTHFuQH++ZJqeXNesLfsOex0HAJAkKKvjoDEc0bSyPJXmZ3sdBQCAlPCJpdMV9PsYXQUAHEFZHQehcIT5qgAAnIKyghx99MIaPdq4W28d7PA6DgAgCVBWE0KGpoMAACAASURBVGxPa7f2tHVTVgEAOEV/cUmdfFmm7/yO0VUAAGU14Ybmq7K4EgAAp2ZyUVB/trBaj7zapN2RLq/jAAA8RllNsMamiAI+05zKIq+jAACQcj51aZ2ck+59YZvXUQAAHqOsJlhoZ0TnVBYpGPB5HQUAgJRTVZqnD86fqode3ql9h7u9jgMA8BBlNYEGBp3W7mplvioAAGPwl++cob6BQX3v99u9jgIA8BBlNYG27m9Xe0+/6tlfFQCA01ZXXqD3nTdFP1r1lg519HodBwDgEcpqAg0trtRQQ1kFAGAsbr1spjp7B/T9lYyuAkCmoqwmUCgcUWHQr+ll+V5HAQAgpc2uKNR7zp2sH/xhh9q6+7yOAwDwAGU1gUI7I2qoLlFWlnkdBQCAlLfisllq6+7Xj156y+soAAAPUFYTpKt3QJv2Hma+KgAACTKvqljvnF2u7724XZ29/V7HAQCcYZTVBFm3u1UDg46VgAEASKDbLp+plo5ePbh6p9dRAABnGGU1QRpjiyvVU1YBAEiYBdMmaHFdme59YZu6+wa8jgMAOIMoqwnyejiiqSW5Ki/M8ToKAABp5bbLZ2rf4R79/NUmr6MAAM4gymqCNIYj3AIMAMA4WDyjTO+oKdF3frtVfQODXscBAJwhlNUEONDeo6ZDXZRVAMAZY2ZXmdkmM9tiZp8f4fVLzOw1M+s3sw8d99oNZrY59nXDmUt9esxMt10+S7siXfqP13d5HQcAcIZQVhOA+aoAgDPJzHyS7pF0taQ5kq43sznHnbZT0o2SHjzuvRMk3SnpQkkXSLrTzErHO/NYvXN2uc6dUqRvPb9FA4PO6zgAgDOAspoAoXBEvizT3KlFXkcBAGSGCyRtcc5tc871SnpY0vLhJzjndjjn3pB0/H2z75H0jHOuxTl3SNIzkq46E6HHIjq6OlM7DnbqiTd2ex0HAHAGUFYTIBSO6KzJhcrL9nsdBQCQGaZKCg973hQ7Nt7v9dSVcyo0a1KB7nl+iwYZXQWAtEdZHaPBQcfiSgCAM81GOBZve4vrvWZ2i5mtMbM1+/fvP6Vw4yUry7Ti8pl6c2+7fr1hr9dxAADjjLI6RjsOdqitu18N1cVeRwEAZI4mSdXDnldJivfe2Lje65y71zm30Dm3sLy8/LSDJto18ypVW5anu5/fLOcYXQWAdEZZHaNQbHGlhuqkX5sCAJA+XpE0y8ymm1m2pOskPRbne5+WdKWZlcYWVroydiwl+H1Z+sw7Z2rdrjb99s3kGPEFAIwPyuoYNYYjys/2aeakAq+jAAAyhHOuX9IKRUvmRkk/c86tN7O7zGyZJJnZ+WbWJOnDkr5rZutj722R9CVFC+8rku6KHUsZH5g/VVNLcvXNZxldBYB0xopAYxQKRzSvqli+rJGmAAEAMD6cc09KevK4Y18c9vgVRW/xHem9D0h6YFwDjqNsf5Y+fWmd/u+j6/XStoNaMmOi15EAAOOAkdUx6Okf0IbmNm4BBgDgDPvwwmqVF+bo7ue2eB0FADBOKKtjsGF3m/oGHIsrAQBwhgUDPn3qkjr9YetBvfpWSt3FDACIE2V1DBpZXAkAAM985MIaleYFGF0FgDRFWR2DUDiiyUU5qigOeh0FAICMk5ft180X1+n5Tfu1bler13EAAAlGWR2DxqZWNVSXeB0DAICM9fHF01QY9DO6CgBpiLJ6miKdvdp+oEP1lFUAADxTFAzopiW1emr9Hr2597DXcQAACURZPU2NTdHbjRhZBQDAWzctna68bJ/ueZ7RVQBIJ5TV0xTaGZGZNG8qKwEDAOCl0vxsfXzRND3euFvbD3R4HQcAkCCU1dMUCh/SrEkFKgwGvI4CAEDG++TF0xXwZenbv2V0FQDSBWX1NDjn1NjUqvoqbgEGACAZTCoM6voLavTL13ap6VCn13EAAAlAWT0N4ZYutXT0qqGGsgoAQLK45ZI6mUnf/d02r6MAABKAsnoaQk0RSWJkFQCAJDKlJFcfWlCln64Ja29bt9dxAABjRFk9DaGdEQUDWZpdUeh1FAAAMMxfXjpTA4NO973A6CoApDrK6mlobIpo7pRiBXx8fAAAJJOasjwtr5+in6zeqYPtPV7HAQCMAW3rFPUNDGrdrlb2VwUAIEl95rIZ6u4f0AMrt3sdBQAwBnGVVTO7ysw2mdkWM/v8CK/faGb7zSwU+7p52GsDw44/lsjwXti057B6+gdVT1kFACApzZxUqPfOrdQP//CWWjv7vI4DADhNJy2rZuaTdI+kqyXNkXS9mc0Z4dSfOucaYl/3DzveNez4ssTE9s7r4ejiSoysAgCQvG69bKbae/r1w5d2eB0FAHCa4hlZvUDSFufcNudcr6SHJS0f31jJqzEcUVl+tqpKc72OAgAARjFnSpHefc4kPbByu9p7+r2OAwA4DfGU1amSwsOeN8WOHe9aM3vDzB4xs+phx4NmtsbMVpnZB0b6Dczsltg5a/bv3x9/eg+EwhE1VJfIzLyOAgAATuDWy2Yq0tmnn6x6y+soAIDTEE9ZHamVueOePy6p1jl3nqTfSPrhsNdqnHMLJX1E0tfMbMbbvplz9zrnFjrnFpaXl8cZ/cxr6+7T1v3t3AIMAEAKmF9TqotnTdR9v9+m7r4Br+MAAE5RPGW1SdLwkdIqSbuHn+CcO+icG1of/j5JC4a9tjv26zZJv5U0fwx5PbW2qVXOicWVAABIESsum6kD7b16+OWdXkcBAJyieMrqK5Jmmdl0M8uWdJ2kY1b1NbPKYU+XSdoYO15qZjmxxxMlLZW0IRHBvRCKLa5UX0VZBQAgFVxYV6YLaifouy9sU08/o6sAkEpOWladc/2SVkh6WtES+jPn3Hozu8vMhlb3vd3M1ptZo6TbJd0YO36OpDWx489L+mfnXEqX1bqJ+SrOC3gdBQAAxGnF5TPV3NqtX762y+soAIBT4I/nJOfck5KePO7YF4c9vkPSHSO87w+S5o0xY1JwzikUjujimRO9jgIAAE7BxbMmqr6qWN/67RZ9eEGV/L64tpkHAHiMf63j1Nzarf2He5ivCgBAijEzrbh8lsItXXqscffJ3wAASAqU1Tg1xuarshIwAACp511nT9LZFYW65/ktGhg8flMDAEAyoqzGKRSOKNuXpbMrC72OAgAATlFWlmnF5TO1dX+Hnlq3x+s4AIA4UFbjFApHNGdKkXL8Pq+jAACA03D13ErVlefrm89tlnOMrgJAsqOsxmFg0GntrlZuAQYAIIX5sky3vnOm/rjnsJ7duM/rOACAk6CsxmHzvsPq7B2grAIAkOKWNUxR9YRcffP5LYyuAkCSo6zGIbQzurgSKwEDAJDaAr4s/eWlM9UYjmjlloNexwEAnABlNQ6hcETFuQHVluV5HQUAAIzRtQumqqIoqG8+t9nrKACAE6CsxiEUjqi+ukRm5nUUAAAwRjl+nz51aZ1Wb2/Ry9tbvI4DABgFZfUkOnr69ebew8xXBQAgjVx3fo0mFmTr7ue3eB0FADAKyupJrNvVqkEnNVQXex0FAAAkSG62TzdfXKcX3tyvxnDE6zgAgBFQVk8iFLuA1VcxsgoAQDr52KJpKs4NMLoKAEmKsnoSjU0RVU/IVVlBjtdRAABAAhXk+PWJpdP1zIa92tjc5nUcAMBxKKsnEdoZUUN1qdcxAADAOLhxSa0Kcvy6h9FVAEg6lNUT2NfWrd2t3aqvYr4qAADpqDgvoD9fPE2/WtusrfvbvY4DABiGsnoCQ/NV59cwXxUAgHT1yYumK8efpW89v9XrKACAYSirJ9DYFJE/y3TuFEZWAQBIV2UFOfrohdP0n6FdCrd0eh0HABBDWT2BUDiisysLFQz4vI4CAADG0S2X1Mlnpm//jtFVAEgWlNVRDA46vRFuVUM1twADAJDuJhcF9afnV+mRNU1qbu3yOg4AQJTVUW070K7DPf3srwoAQIb41CUzNOic7vjlWh3u7vM6DgBkPMrqKELhVkksrgQAQKaonpCnO98/R7/ffEDL716pN/ce9joSAGQ0yuooQuFDKszxq25igddRAADAGfLxxbV68OYL1dbdrw/cs1KPN+72OhIAZCzK6igaw606r7pYWVnmdRQAAHAGXVhXpl/dfpHmVBbptode198/vl59A4NexwKAjENZHUF334A2NrcxXxUAgAw1uSioh25ZpE8sna7vr9yh6+9dpb1t3V7HAoCMQlkdwfrdbeofdKwEDABABgv4svTF98/RN6+frw3NbbrmGy9q1baDXscCgIxBWR1BKByRJMoqAADQ++un6NFbl6oo16+P3r9a972wTc45r2MBQNqjrI6gMRzRlOKgJhUFvY4CAACSwKzJhXr01qW6cs5k/cOTG3Xrg6+pvaff61gAkNYoqyMIhSOqZ1QVAAAMUxgM6FsffYf+z3vP0dPr92rZ3S9qM9vbAMC4oawep6WjVztbOrkFGAAAvI2Z6S8uqdNPbr5QbV39Ws72NgAwbiirx2mMzVdlZBUAAIxm0XHb29z1+Aa2twGABKOsHuf1cERZJs2bWux1FAAAkMSGtre5aWmtHli5XR+5b5X2sb0NACQMZfU4jeGIzppcqPwcv9dRAABAkgv4snTn+8/VN66fr3W72vTeb7yo1WxvAwAJQVkdxjmnxqYI81UBAMApWVY/RY+uWKqioF8fYXsbAEgIyuowbx3sVKSzj/mqAADglJ01uVCPrliqK85hexsASATK6jCh2OJKjKwCAIDTURgM6Nsfe4fuuPpsPbVuj5bf/aK27GN7GwA4HZTVYULhiHIDPs2aVOB1FAAAkKLMTJ+6dIZ+cvMitXb1adndK/XEG2xvAwCnirI6TCgc0byqYvl9fCwAAGBsFs8o0xO3XaxzKou04kG2twGAU0Uri+ntH9SG3W3cAgwAABKmojioh/5ikW5cwvY2AHCqKKsxG5vb1DswSFkFAAAJle3P0t8tO1dfv65B63a16ZpvvqiXt7d4HQsAkh5lNaaxicWVAACpw8yuMrNNZrbFzD4/wus5ZvbT2Ourzaw2drzWzLrMLBT7+s6Zzp6pljdM1X/eulSFOX5df98q3f97trcBgBOhrMaEdkZUXpijyuKg11EAADghM/NJukfS1ZLmSLrezOYcd9onJR1yzs2U9FVJXxn22lbnXEPs69NnJDQkSbMrotvbvPucSfryrzZqxUOvs70NAIyCshoTaoqoobpEZuZ1FAAATuYCSVucc9ucc72SHpa0/Lhzlkv6YezxI5LeZVzkkkJhMKDvfGyB7rj6bP3X2mZ94J6VbG8DACOgrEpq7ezTtv0d3AIMAEgVUyWFhz1vih0b8RznXL+kVkllsdemm9nrZvY7M7t4pN/AzG4xszVmtmb//v2JTY8j29v8+OYLFens1fK7V+rJtc1exwKApBJXWY1jXsyNZrZ/2PyXm4e9doOZbY593ZDI8Inyxi7mqwIAUspII6THT34c7ZxmSTXOufmSPivpQTMretuJzt3rnFvonFtYXl4+5sAY2ZIZE/XEbRdrdkWhPvOT1/TlJ9jeBgCGnLSsxjkvRpJ+Omz+y/2x906QdKekCxW9ZelOMytNWPoECe2MyEyaV1XsdRQAAOLRJKl62PMqSbtHO8fM/JKKJbU453qccwclyTn3qqStks4a98QYVUVxUA/fslg3LqnV/S9u10fvW619h9neBgDiGVmNZ17MaN4j6RnnXItz7pCkZyRddXpRx09jU0QzygtUFAx4HQUAgHi8ImmWmU03s2xJ10l67LhzHpM0dEfThyQ955xzZlYe+0G0zKxO0ixJ285Qboxi+PY2a3e16ppvvKhXdrC9DYDMFk9ZjWdejCRda2ZvmNkjZjb009543+sZ55xC4Yjqq7gFGACQGmJzUFdIelrSRkk/c86tN7O7zGxZ7LTvSSozsy2K3u47NI3nEklvmFmjogsvfdo5RytKEkPb2xTk+HX9vav0vRe3s70NgIzlj+OceObFPC7pIedcj5l9WtHVBy+P870ys1sk3SJJNTU1cURKnF2RLh1o71VDDWUVAJA6nHNPSnryuGNfHPa4W9KHR3jfLyT9YtwD4rQNbW/zv3/eqC89sUGv7zykr1x7nvJz4vnfNgBIH/GMrJ50Xoxz7qBzrif29D5JC+J9b+z9ni3iEArHFldiZBUAACSJotj2Np+/+mw9ubZZy+9ZqS372r2OBQBnVDxl9aTzYsysctjTZYrekiRFb0+60sxKYwsrXRk7ljQawxFl+7N0dmWh11EAAACOMDN9+tIZ+vEnL9Shjl4tv/tFtrcBkFFOWlbjnBdzu5mtj81/uV3SjbH3tkj6kqKF9xVJdyXbvJhQOKK5U4oU8LHlLAAASD5LZk7UE7dfpLNi29v8w682qJ/tbQBkgLgmP8QxL+YOSXeM8t4HJD0whozjpn9gUGt3teojF0zzOgoAAMCoKotz9dNbFuvLv9qg+36/Xb/ZuE83LJ6mDy2sVgFzWQGkqYweTty097C6+wZVX83+qgAAILll+7N01/K5uvfjC1SSF9DfPb5Bi/7xWf394+u140CH1/EAIOEy+kdxQ4srza8u9TgJAABAfK48t0JXnluhUDiiH6zcrh+veks/+MMOXT57km5cWquLZk6U2UgbMgBAasnokdXGcEQT8rNVPSHX6ygAAACnpKG6RF+7br5W/s3luu3yWWpsiujj33tZV3z1Bf141Vvq7O33OiIAjElGl9VQOKL6qmJ++ggAAFLWpKKgPnvFWVr5+cv1bx+uVzCQpb/9z3Va9I/P6h+f3KhwS6fXEQHgtGTsbcDtPf3avK9d751XefKTAQAAklyO36drF1TpT94xVa/tPKQHVu7Q917crvt/v01XzJmsG5dM16K6CfyQHkDKyNiy+kZTRM5Fb6EBAABIF2amBdMmaMG0CWpu7dKPXnpLD728U0+v36uzKwp109JaLW+YqmDA53VUADihjL0NuDHcKkmqr6KsAgCA9FRZnKu/vupsvXTHu/SVa+dJkv7mF2u16J+e1Vee+qN2R7o8TggAo8vYkdVQ+JBqy/JUmp/tdRQAAIBxFQz49Gfn1+hPF1Zr9fYWfX/ldn33d1t17wvbdNW5Fbppaa0WTCvlFmEASSVjy2pjuFWL6iZ4HQMAAOCMMTMtqivToroyhVs69aNVb+nhl3fqV2ubNXdqkW5aMl3vq69Ujp9bhAF4LyNvA97T2q09bd2qZ74qAADIUNUT8vSF956jVV94l778gbnq7hvU537eqKX//Jz+/debtK+t2+uIADJcRo6shsIRSSyuBAAAkJft18cWTdNHL6zRyi0H9f2V2/XN57foW7/dqmvOq9RNS6fz/0wAPJGxZTXgM51TWeR1FAAAgKRgZrpo1kRdNGuidhzo0A9f2qGfr2nSo6Hdaqgu0U1La3X13Epl+zPyxjwAHsjIf20awxHNqSxiyXYAAIAR1E7M153vP1ervvAu/f2yc9Xa1ae/ejiki77ynL7x7GYdaO/xOiKADJBxZXVg0OmNpgjzVQEAAE6iIMevG5bU6tnPXqrv33S+zq4s0r8/86aW/NNz+tzPGrVuV6vXEQGksYy7DXjr/nZ19A4w9wIAACBOWVmmy2ZP0mWzJ2nLvnb9/5d26JFXm/SL15p0fm2pblwyXe85d7L8vowbBwEwjjKurIZ2RhdXYmQVAADg1M2cVKC7ls/V566crZ+vCeuHL+3QrQ++psrioD6+eJquP7+GfewBJETmldWmiIqCfk0vy/c6CgAAQMoqzg3o5ovrdNPS6Xruj/v0gz9s1788tUlf/81mfXD+VC1vmKr5NSWsEQLgtGVeWd0Zna+alWVeRwEAAEh5vizTFXMm64o5k7Vpz2H94A879B+vN+nhV8LK9mdpQU2pFtWVafGMMtVXFyvHT3kFEJ+MKqtdvQPatPewPnPODK+jAAAApJ3ZFYX6pz+Zpzvee7Ze3tail7Yd1KptB/W1Z9/UV38j5fiztGBaqRbXlWnRjDLVV5WwFQ6AUWVUWV23u1UDg071VcxXBQAAGC9FwYDePWey3j1nsiQp0tmrl7e3aFWswP7bM29Kz0jBQJYWTpugxTPKtKhugs6rKlGARZoAxGRUWW0Ms7gSAADAmVaSl60rz63QledWSJIOdfRq9fYWrYqNvP6/pzdJkvKyfdGR1xllWlRXpnlTiymvQAbLqLL6ejiiqSW5Ki/M8ToKAABAxirNz9ZVcyt01dxoeW3p6NXqWHF9adtB/ctT0fKan+3TwtoJR+a8zp1SxPY4QAbJqLLaGI6ooYZRVQAAgGQyIT9bV8+r1NXzKiVJB9p7tHrb0ZHXrzz1R0lSQY5f59ceXbDp3CnF8rFoJpC2MqasHmjvUdOhLt2wuNbrKAAAADiBiQU5uua8Sl1zXrS87j/co9XbD+qlrdHy+vym/ZKkwhy/Lph+dOT1nMoiyiuQRjKmrIZ2RuerMrIKAACQWsoLc/S+86bofedNkSTta+vWqu0temnrQa3edlDP/nGfJKko6NcF06OLNS2eUaZzKorYrhBIYRlTVhubIvJlmeZOKfY6CgAAAMZgUlFQy+qnaFl9tLzuae0+ZuT1Nxv3SpKKcwO6MDbyuqiuTGdXFFJegRSSMWU1FI5o9uRC5WazETUAAEA6qSgOannDVC1vmCpJam7tis533RrdKufXG6LltSQvWl6H9nk9axLlFUhmGVFWBwedGsMRXRO7dQQAAADpq7I4Vx+cX6UPzq+SJO2KdGlVbNR11faDenp9tLwGA1maUV6gmZMKNLO8QLMmRx9PK8tnyxwgCWREWd1+sENt3f2az/6qAAAAGWdqSa6uXVClaxdEy2u4pVOrt7foj81t2ryvXWt2HNKjod1HzvdnmWon5mvWpFiRjX3NKC9QMMBdesCZkhFltTHM4koAAACIqp6Qp+oJeccc6+jp17b9Hdq877C27GvXln3t2rTnsH69Ya8GBp0kyUyqLs3TzEkFmjWpQDOGFdmiYMCLPwqQ1jKirIbCEeVn+zSjvMDrKAAAAEhC+Tl+zasq1ryqYxfj7Okf0I4Dndqyr/2YIvvi5gPqHRg8ct7kohzNmlQYHYGNldmZkwpUlp8tM+bFAqcjI8pqYzii86pK2HcLAAAApyTH79PsikLNriiUVHnkeP/AoMKHuo6U1837Dmvrvnb9fE1YHb0DR84rzQvERl8Lj4zCzppUoMriICUWOIm0L6vdfQPa0NymT15U53UUAAAApAm/L0vTJ+Zr+sR8XTFn8pHjzjk1t3Zrc6zERr8O67/WNSvS2XfkvPxs37BR2KNFtmZCHgMsQEzal9WNzW3qG3BqYHElAAAAjDMz05SSXE0pydWlZ5UfOe6c08GO3tgobLu2xkZjV245oF++tuvIedn+LNVNzD+mvFYW56qyOKiK4iALPCGjpH1ZDQ0trkRZBQAAgEfMTBMLcjSxIEeL6sqOea2tu2/YKGz0q7Epol+tbZZzx36fCfnZqigKqrI4qMqSoCqLc6PPY48rKbRII2lfVhvDEVUURX8SBQAAACSbomBA76gp1TtqSo853t03oN2RLjW3dqu5tVt7Wru0u7Vbe1q7tbu1W6/uPHTMrcVDSvMCqijO1ZTYaGxlcfCY0dnK4lzlZlNokfzSvqyGwhHVVxef/EQAAAAgiQQDPtWVF6juBDtadPUOaE9bt5pjpXZPW7d2R7q0J1ZwX9t5SIdGKLQleQFVFAU1pSQ3WmCLgqosGV5og8rLTvuqgCSX1n8DI5292nGwU392fo3XUQAAAICEy832HVnoaTTdfQOx0dijJbZ52ONQOKKWjt63va84NxAblQ2qIjYyOzRKW1Ec1JQSCi3GV1r/7Rqar8rIKgAAADJVMOBT7cR81Z6k0O5tO1pkm4duN450a09bl9buatWB9rcX2qKgXxMLc1Sal63SvIBKjvn16OMJ+UcfZ/uzxvOPizSS1mW1MdwqM+m8KhZXAgAAAEYTDPg0rSxf08pOXGj3tfUcKbNDxfZgR68inb3aHenW+t1tOtTZq+6+wVG/T362L1pm8wMqzcuOltlhRbc0P/vo47xsleQFVJDjZ1/aDJTWZTUUPqRZkwpUkJPWf0wAAABg3AUDPtWU5ammLO+k53b3DehQZ68OdfQp0tmrQ519OtQZLbUtR45Fj4dbOnWos0+tXW+fWzsk4LPjRm2PFt3hpXbCsKJbnBuQ38cobipL2xbnnFNjU6vefc4kr6MAAAAAGSUY8MVWIM6N+z0Dg06tXX2xkntswT3UGSu4HdFj2w906LXOiCKdveobcKN+z6KgX6X52SoKRkdnC4N+FQT9KsyJ/lqQEzj6PHasMOhXYex4QY6f25Y9lLZlNdzSpZaOXtWzvyoAAACQ9HxZpgn50fmtKo/vPc45dfQO6FBHryKxchstuH1q6ThadA9396m9p187WzrV3tOv9p5+He7u18Dg6EV3SLY/a1i59cdKbyBafIcdLxz2ekGs8A6V44Icv3L8WdzKfIrStqyGmqKLKzVQVgEAAIC0ZGZHCmL1hFN7r3NO3X2DOtzTp/buaIFt7+7X4div0ULbd8zzodd3R7qOvt7dr/44Sm/AZ8PKbeDYAhz0Kz/bp7xsv/KyfcrL9il32OOh47nZPuVn+5UbOx5I89uc4yqrZnaVpK9L8km63zn3z6Oc9yFJP5d0vnNujZnVStooaVPslFXOuU+PNXQ8QjsjCgayNHty4Zn47QAAAACkEDNTbqwAThpDZXDOqad/8EiZHRq1jY7gRsvs4WFl9+jrfdp3uFtb90ePd/T2n3BhqpEEfKbcgE/5OUcLbF4g+jg/x6fcwMiFd+Rjx57ry/J+FPikZdXMfJLukXSFpCZJr5jZY865DcedVyjpdkmrj/sWW51zDQnKG7fGpojmTS1mUjUAAACAcWNmCgZ8CgZ8mliQM6bvNTjo1NU3oI7efnX1Dqjzk+8CGwAABi1JREFUyFe/OnsHhh3rP/Ja19DjvgF19kQfH+rs1a5I9PyO2Ou9/adWhLP9Wco7biT3Aw1T9YmLpo/pz3gq4hlZvUDSFufcNkkys4clLZe04bjzviTpXyT9r4QmPE3TJ+ZrRnmB1zEAAAAAIC5ZWab8HL/yx2E3k/6BQXX1HVuARy6/Ixzriz7OCZzZgcB4PoWpksLDnjdJunD4CWY2X1K1c+4JMzu+rE43s9cltUn6W+fc74//DczsFkm3SFJNTc0pxB/dv364PiHfBwAAAABSnd+XpUJflgqDAa+jxC2eajzSzcpHZhCbWZakr0r63AjnNUuqcc7Nl/RZSQ+aWdHbvplz9zrnFjrnFpaXx7n0FwAAAAAgbcVTVpskVQ97XiVp97DnhZLmSvqtme2QtEjSY2a20DnX45w7KEnOuVclbZV0ViKCAwAAAADSVzxl9RVJs8xsupllS7pO0mNDLzrnWp1zE51ztc65WkmrJC2LrQZcHlugSWZWJ2mWpG0J/1MAAAAAANLKSeesOuf6zWyFpKcV3brmAefcejO7S9Ia59xjJ3j7JZLuMrN+SQOSPu2ca0lEcAAAAABA+oprmSnn3JOSnjzu2BdHOfedwx7/QtIvxpAPAAAAAJCB2IQUAAAAAJB0KKsAAAAAgKRDWQUAAAAAJB3KKgAAAAAg6VBWAQAAAABJh7IKAAAAAEg6lFUAAAAAQNKhrAIAAAAAko4557zOcAwz2y/prQR9u4mSDiToe2UyPsfE4HNMDD7HxMikz3Gac67c6xCpjGtzUuJzTAw+x8Tgc0yMTPoc47o2J11ZTSQzW+OcW+h1jlTH55gYfI6JweeYGHyO8Ap/9xKDzzEx+BwTg88xMfgc347bgAEAAAAASYeyCgAAAABIOuleVu/1OkCa4HNMDD7HxOBzTAw+R3iFv3uJweeYGHyOicHnmBh8jsdJ6zmrAAAAAIDUlO4jqwAAAACAFJSWZdXMrjKzTWa2xcw+73WeVGRm1Wb2vJltNLP1ZvZXXmdKZWbmM7PXzewJr7OkKjMrMbNHzOyPsb+Xi73OlIrM7H/G/pteZ2YPmVnQ60zIDFybx45rc2JxbR47rs2JwbV5dGlXVs3MJ+keSVdLmiPpejOb422qlNQv6XPOuXMkLZJ0K5/jmPyVpI1eh0hxX5f0lHPubEn14vM8ZWY2VdLtkhY65+ZK8km6zttUyARcmxOGa3NicW0eO67NY8S1+cTSrqxKukDSFufcNudcr6SHJS33OFPKcc41O+deiz0+rOg/PlO9TZWazKxK0jWS7vc6S6oysyJJl0j6niQ553qdcxFvU6Usv6RcM/NLypO02+M8yAxcmxOAa3PicG0eO67NCcW1eRTpWFanSgoPe94k/iEfEzOrlTRf0mpvk6Ssr0n6a0mDXgdJYXWS9kv6fuyWrfvNLN/rUKnGObdL0r9K2impWVKrc+7X3qZChuDanGBcm8eMa/PYcW1OAK7NJ5aOZdVGOMaSx6fJzAok/ULS/3DOtXmdJ9WY2fsk7XPOvep1lhTnl/QOSd92zs2X1CGJOW+nyMxKFR3Nmi5piqR8M/uYt6mQIbg2JxDX5rHh2pwwXJsTgGvziaVjWW2SVD3seZUYSj8tZhZQ9GL4E+fcL73Ok6KWSlpmZjsUve3tcjP7sbeRUlKTpCbn3NAIwiOKXiBxat4tabtzbr9zrk/SLyUt8TgTMgPX5gTh2pwQXJsTg2tzYnBtPoF0LKuvSJplZtPNLFvRCcqPeZwp5ZiZKToHYaNz7t+9zpOqnHN3OOeqnHO1iv5dfM45x0/LTpFzbo+ksJnNjh16l6QNHkZKVTslLTKzvNh/4+8Si2HgzODanABcmxODa3NicG1OGK7NJ+D3OkCiOef6zWyFpKcVXU3rAefceo9jpaKlkj4uaa2ZhWLHvuCce9LDTMhst0n6Sex/dLdJusnjPCnHObfazB6R9Jqiq4q+Luleb1MhE3BtThiuzUg2XJvHiGvziZlzTBkBAAAAACSXdLwNGAAAAACQ4iirAAAAAICkQ1kFAAAAACQdyioAAAAAIOlQVgEAAAAASYeyCgAAAABIOpRVAAAAAEDSoawCAAAAAJLOfwP/nvGRfpsBowAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16,6))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(history.history['p_acc'])\n", + "plt.plot(history.history['val_p_acc'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Action prediction accuracy\")\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(history.history['v_loss'])\n", + "plt.plot(history.history['val_v_loss'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Value MSE\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy train: 0.7605870782877613\n", + "Accuracy test: 0.6682701860431067\n", + "Explained variance train: 0.9296615093133133\n", + "Explained variance test: -0.278033390090739\n" + ] + } + ], + "source": [ + "p_train_pred, v_train_pred = model.predict(x_train)\n", + "p_test_pred, v_test_pred = model.predict(x_test)\n", + "act_train_pred = np.argmax(p_train_pred, axis=1)\n", + "act_test_pred = np.argmax(p_test_pred, axis=1)\n", + "print(\"Accuracy train:\", accuracy_score(p_train, act_train_pred))\n", + "print(\"Accuracy test:\", accuracy_score(p_test, act_test_pred))\n", + "print(\"Explained variance train:\", explained_variance_score(v_train, v_train_pred))\n", + "print(\"Explained variance test:\", explained_variance_score(v_test, v_test_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('AGZ.h5')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (pommer)", + "language": "python", + "name": "pommer" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/Clean.ipynb b/imitation/Clean.ipynb new file mode 100644 index 0000000..7d16cde --- /dev/null +++ b/imitation/Clean.ipynb @@ -0,0 +1,469 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "data = np.load(\"valid_100K_disc0.99.npz\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262, 11, 11, 18)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_observations = data['observations']\n", + "all_observations.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262,)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_actions = data['actions']\n", + "all_actions.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262,)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_rewards = data['rewards']\n", + "all_rewards.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "15509" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obs_stuck = np.all(all_observations[1:] == all_observations[:-1], axis=(1,2,3))\n", + "sum(obs_stuck)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13419" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obs_stuck2 = np.logical_and(obs_stuck[:-1], obs_stuck[1:])\n", + "sum(obs_stuck2)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12657" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obs_stuck3 = np.logical_and(obs_stuck[:-2], np.logical_and(obs_stuck[1:-1], obs_stuck[2:]))\n", + "sum(obs_stuck3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12329" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obs_stuck4 = np.logical_and(obs_stuck[:-3], np.logical_and(obs_stuck[1:-2], np.logical_and(obs_stuck[2:-1], obs_stuck[3:])))\n", + "sum(obs_stuck4)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "52496" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "act_stuck2 = (all_actions[:-1] == all_actions[1:])\n", + "sum(act_stuck2)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13394" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stuck2 = np.logical_and(obs_stuck2, act_stuck2[:-1])\n", + "sum(stuck2)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "36767" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "act_stuck3 = np.logical_and(all_actions[:-2] == all_actions[1:-1], all_actions[:-2] == all_actions[2:])\n", + "sum(act_stuck3)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12639" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stuck3 = np.logical_and(obs_stuck3, act_stuck3[:-1])\n", + "sum(stuck3)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "30329" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "act_stuck4 = \\\n", + " np.logical_and(\n", + " np.logical_and(\n", + " all_actions[:-3] == all_actions[1:-2], \n", + " all_actions[:-3] == all_actions[2:-1]), \n", + " all_actions[:-3] == all_actions[3:])\n", + "sum(act_stuck4)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12315" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stuck4 = np.logical_and(obs_stuck4, act_stuck4[:-1])\n", + "sum(stuck4)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "ind = np.where(stuck3)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([4851, 2835, 1355, 2012, 1586, 0])" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.histogram(all_actions[ind], bins=range(7))[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([26224, 20963, 18259, 19520, 19438, 3858])" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.histogram(all_actions, bins=range(7))[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(95623,)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cleaned_actions = np.delete(all_actions, ind, axis=0)\n", + "cleaned_actions.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([21373, 18128, 16904, 17508, 17852, 3858])" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.histogram(cleaned_actions, bins=range(7))[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(95623, 11, 11, 18)" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cleaned_observations = np.delete(all_observations, ind, axis=0)\n", + "cleaned_observations.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(95623,)" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cleaned_rewards = np.delete(all_rewards, ind, axis=0)\n", + "cleaned_rewards.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "np.savez_compressed(\"valid_100K_disc0.99_cleaned.npz\", observations=cleaned_observations, actions=cleaned_actions, rewards=cleaned_rewards)" + ] + }, + { + "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.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/Conv model.ipynb b/imitation/Conv model.ipynb new file mode 100644 index 0000000..4c41636 --- /dev/null +++ b/imitation/Conv model.ipynb @@ -0,0 +1,294 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from keras.models import Model, load_model\n", + "from keras.layers import Input, Conv2D, Flatten, Dense\n", + "from keras.callbacks import ModelCheckpoint, EarlyStopping\n", + "import tensorflow as tf\n", + "import keras.backend as K\n", + "from sklearn.metrics import explained_variance_score, accuracy_score\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# make sure TF does not allocate all memory\n", + "config = tf.ConfigProto()\n", + "config.gpu_options.allow_growth = True\n", + "K.set_session(tf.Session(config=config))" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((594333, 11, 11, 18), (594333,), (594333,))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('simple_600K_disc0.99_cleaned.npz')\n", + "x_train = data['observations']\n", + "p_train = data['actions']\n", + "v_train = data['rewards']\n", + "x_train.shape, p_train.shape, v_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((95623, 11, 11, 18), (95623,), (95623,))" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('valid_100K_disc0.99_cleaned.npz')\n", + "x_test = data['observations']\n", + "p_test = data['actions']\n", + "v_test = data['rewards']\n", + "x_test.shape, p_test.shape, v_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "__________________________________________________________________________________________________\n", + "Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + "input_15 (InputLayer) (None, 11, 11, 18) 0 \n", + "__________________________________________________________________________________________________\n", + "conv2d_43 (Conv2D) (None, 11, 11, 256) 41728 input_15[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_44 (Conv2D) (None, 11, 11, 256) 590080 conv2d_43[0][0] \n", + "__________________________________________________________________________________________________\n", + "conv2d_45 (Conv2D) (None, 11, 11, 256) 590080 conv2d_44[0][0] \n", + "__________________________________________________________________________________________________\n", + "flatten_15 (Flatten) (None, 30976) 0 conv2d_45[0][0] \n", + "__________________________________________________________________________________________________\n", + "p (Dense) (None, 6) 185862 flatten_15[0][0] \n", + "__________________________________________________________________________________________________\n", + "v (Dense) (None, 1) 30977 flatten_15[0][0] \n", + "==================================================================================================\n", + "Total params: 1,438,727\n", + "Trainable params: 1,438,727\n", + "Non-trainable params: 0\n", + "__________________________________________________________________________________________________\n" + ] + } + ], + "source": [ + "c = x = Input(shape=(11,11,18))\n", + "c = Conv2D(filters=256, kernel_size=3, strides=1, activation=\"relu\", padding=\"same\")(c)\n", + "c = Conv2D(filters=256, kernel_size=3, strides=1, activation=\"relu\", padding=\"same\")(c)\n", + "c = Conv2D(filters=256, kernel_size=3, strides=1, activation=\"relu\", padding=\"same\")(c)\n", + "h = Flatten()(c)\n", + "#h = Dense(128, activation='relu')(h)\n", + "p = Dense(6, activation=\"softmax\", name='p')(h)\n", + "#h = Dense(128, activation='relu')(h)\n", + "v = Dense(1, activation=\"tanh\", name='v')(h)\n", + "model = Model(x, [p, v])\n", + "model.summary()\n", + "model.compile(optimizer='adam', loss=['sparse_categorical_crossentropy', 'mse'], loss_weights=[1, 0], metrics={'p': 'accuracy'})" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "callbacks = [\n", + " ModelCheckpoint('conv.h5', monitor='val_p_acc', verbose=1, save_best_only=True, mode='max'),\n", + " EarlyStopping(monitor='val_p_acc', min_delta=0.001, patience=5, verbose=1, mode='max')\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 594333 samples, validate on 95623 samples\n", + "Epoch 1/10\n", + "594333/594333 [==============================] - 188s 316us/step - loss: 0.9410 - p_loss: 0.9410 - v_loss: 0.1741 - p_acc: 0.5675 - val_loss: 0.7122 - val_p_loss: 0.7122 - val_v_loss: 0.1774 - val_p_acc: 0.6569\n", + "\n", + "Epoch 00001: val_p_acc improved from -inf to 0.65693, saving model to conv.h5\n", + "Epoch 2/10\n", + "594333/594333 [==============================] - 185s 312us/step - loss: 0.6879 - p_loss: 0.6879 - v_loss: 0.1767 - p_acc: 0.6606 - val_loss: 0.6690 - val_p_loss: 0.6690 - val_v_loss: 0.1769 - val_p_acc: 0.6687\n", + "\n", + "Epoch 00002: val_p_acc improved from 0.65693 to 0.66874, saving model to conv.h5\n", + "Epoch 3/10\n", + "594333/594333 [==============================] - 185s 311us/step - loss: 0.6586 - p_loss: 0.6586 - v_loss: 0.1778 - p_acc: 0.6723 - val_loss: 0.6630 - val_p_loss: 0.6630 - val_v_loss: 0.1778 - val_p_acc: 0.6714\n", + "\n", + "Epoch 00003: val_p_acc improved from 0.66874 to 0.67145, saving model to conv.h5\n", + "Epoch 4/10\n", + "594333/594333 [==============================] - 185s 312us/step - loss: 0.6431 - p_loss: 0.6431 - v_loss: 0.1787 - p_acc: 0.6796 - val_loss: 0.6505 - val_p_loss: 0.6505 - val_v_loss: 0.1784 - val_p_acc: 0.6752\n", + "\n", + "Epoch 00004: val_p_acc improved from 0.67145 to 0.67515, saving model to conv.h5\n", + "Epoch 5/10\n", + "594333/594333 [==============================] - 185s 312us/step - loss: 0.6323 - p_loss: 0.6323 - v_loss: 0.1797 - p_acc: 0.6853 - val_loss: 0.6551 - val_p_loss: 0.6551 - val_v_loss: 0.1795 - val_p_acc: 0.6752\n", + "\n", + "Epoch 00005: val_p_acc improved from 0.67515 to 0.67517, saving model to conv.h5\n", + "Epoch 6/10\n", + "594333/594333 [==============================] - 184s 310us/step - loss: 0.6224 - p_loss: 0.6224 - v_loss: 0.1802 - p_acc: 0.6916 - val_loss: 0.6527 - val_p_loss: 0.6527 - val_v_loss: 0.1808 - val_p_acc: 0.6764\n", + "\n", + "Epoch 00006: val_p_acc improved from 0.67517 to 0.67637, saving model to conv.h5\n", + "Epoch 7/10\n", + "594333/594333 [==============================] - 184s 309us/step - loss: 0.6127 - p_loss: 0.6127 - v_loss: 0.1815 - p_acc: 0.6980 - val_loss: 0.6527 - val_p_loss: 0.6527 - val_v_loss: 0.1793 - val_p_acc: 0.6729\n", + "\n", + "Epoch 00007: val_p_acc did not improve from 0.67637\n", + "Epoch 8/10\n", + "594333/594333 [==============================] - 184s 309us/step - loss: 0.6019 - p_loss: 0.6019 - v_loss: 0.1821 - p_acc: 0.7047 - val_loss: 0.6612 - val_p_loss: 0.6612 - val_v_loss: 0.1815 - val_p_acc: 0.6749\n", + "\n", + "Epoch 00008: val_p_acc did not improve from 0.67637\n", + "Epoch 9/10\n", + "594333/594333 [==============================] - 184s 309us/step - loss: 0.5900 - p_loss: 0.5900 - v_loss: 0.1830 - p_acc: 0.7123 - val_loss: 0.6723 - val_p_loss: 0.6723 - val_v_loss: 0.1820 - val_p_acc: 0.6716\n", + "\n", + "Epoch 00009: val_p_acc did not improve from 0.67637\n", + "Epoch 10/10\n", + "594333/594333 [==============================] - 184s 309us/step - loss: 0.5767 - p_loss: 0.5767 - v_loss: 0.1854 - p_acc: 0.7196 - val_loss: 0.6801 - val_p_loss: 0.6801 - val_v_loss: 0.1843 - val_p_acc: 0.6700\n", + "\n", + "Epoch 00010: val_p_acc did not improve from 0.67637\n" + ] + } + ], + "source": [ + "history = model.fit(x_train, [p_train, v_train], batch_size=512, epochs=10, validation_data=(x_test, [p_test, v_test]), callbacks=callbacks)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,'Value MSE')" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16,6))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(history.history['p_acc'])\n", + "plt.plot(history.history['val_p_acc'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Action prediction accuracy\")\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(history.history['v_loss'])\n", + "plt.plot(history.history['val_v_loss'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Value MSE\")" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy train: 0.7048102662985228\n", + "Accuracy test: 0.6763749307175052\n", + "Explained variance train: -0.04325305576853089\n", + "Explained variance test: -0.04068448877452058\n" + ] + } + ], + "source": [ + "model = load_model('conv.h5')\n", + "p_train_pred, v_train_pred = model.predict(x_train, batch_size=2048)\n", + "p_test_pred, v_test_pred = model.predict(x_test, batch_size=2048)\n", + "act_train_pred = np.argmax(p_train_pred, axis=1)\n", + "act_test_pred = np.argmax(p_test_pred, axis=1)\n", + "print(\"Accuracy train:\", accuracy_score(p_train, act_train_pred))\n", + "print(\"Accuracy test:\", accuracy_score(p_test, act_test_pred))\n", + "print(\"Explained variance train:\", explained_variance_score(v_train, v_train_pred))\n", + "print(\"Explained variance test:\", explained_variance_score(v_test, v_test_pred))" + ] + }, + { + "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.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/Discount.ipynb b/imitation/Discount.ipynb new file mode 100644 index 0000000..0d14691 --- /dev/null +++ b/imitation/Discount.ipynb @@ -0,0 +1,161 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "data = np.load(\"valid_100K.npz\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262, 11, 11, 18)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "observations = data['observations']\n", + "observations.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262,)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "actions = data['actions']\n", + "actions.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(108262,)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rewards = data['rewards']\n", + "rewards.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "discount = 0.99\n", + "disc_rewards = []\n", + "for r in reversed(rewards):\n", + " if r != 0:\n", + " rew = r\n", + " disc_rewards.insert(0, rew)\n", + " rew *= discount" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "np.savez_compressed(\"valid_100K_disc0.99.npz\", observations=observations, actions=actions, rewards=disc_rewards)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "discount = 1\n", + "disc_rewards = []\n", + "for r in reversed(rewards):\n", + " if r != 0:\n", + " rew = r\n", + " disc_rewards.insert(0, rew)\n", + " rew *= discount" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "np.savez_compressed(\"valid_100K_disc1.npz\", observations=observations, actions=actions, rewards=disc_rewards)" + ] + }, + { + "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.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/Fully connected model.ipynb b/imitation/Fully connected model.ipynb new file mode 100644 index 0000000..1f904ef --- /dev/null +++ b/imitation/Fully connected model.ipynb @@ -0,0 +1,240 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from keras.models import Model\n", + "from keras.layers import Input, Flatten, Dense\n", + "import tensorflow as tf\n", + "import keras.backend as K\n", + "from sklearn.metrics import explained_variance_score\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# make sure TF does not allocate all memory\n", + "config = tf.ConfigProto()\n", + "config.gpu_options.allow_growth = True\n", + "K.set_session(tf.Session(config=config))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((594333, 11, 11, 18), (594333,), (594333,))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('simple_600K_disc0.99_cleaned.npz')\n", + "x_train = data['observations']\n", + "p_train = data['actions']\n", + "v_train = data['rewards']\n", + "x_train.shape, p_train.shape, v_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((95623, 11, 11, 18), (95623,), (95623,))" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('valid_100K_disc0.99_cleaned.npz')\n", + "x_test = data['observations']\n", + "p_test = data['actions']\n", + "v_test = data['rewards']\n", + "x_test.shape, p_test.shape, v_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "__________________________________________________________________________________________________\n", + "Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + "input_1 (InputLayer) (None, 11, 11, 18) 0 \n", + "__________________________________________________________________________________________________\n", + "flatten_1 (Flatten) (None, 2178) 0 input_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "dense_1 (Dense) (None, 128) 278912 flatten_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "dense_2 (Dense) (None, 128) 16512 dense_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "dense_3 (Dense) (None, 128) 16512 dense_2[0][0] \n", + "__________________________________________________________________________________________________\n", + "p (Dense) (None, 6) 774 dense_2[0][0] \n", + "__________________________________________________________________________________________________\n", + "v (Dense) (None, 1) 129 dense_3[0][0] \n", + "==================================================================================================\n", + "Total params: 312,839\n", + "Trainable params: 312,839\n", + "Non-trainable params: 0\n", + "__________________________________________________________________________________________________\n" + ] + } + ], + "source": [ + "x = Input(shape=(11,11,18))\n", + "h = Flatten()(x)\n", + "h = Dense(128)(h)\n", + "h = Dense(128)(h)\n", + "p = Dense(6, activation=\"softmax\", name='p')(h)\n", + "h = Dense(128)(h)\n", + "v = Dense(1, activation=\"tanh\", name='v')(h)\n", + "model = Model(x, [p, v])\n", + "model.summary()\n", + "model.compile(optimizer='adam', loss=['sparse_categorical_crossentropy', 'mse'], metrics={'p': 'accuracy'})" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 594333 samples, validate on 95623 samples\n", + "Epoch 1/10\n", + "594333/594333 [==============================] - 23s 39us/step - loss: 1.6708 - p_loss: 1.5147 - v_loss: 0.1561 - p_acc: 0.3642 - val_loss: 1.6407 - val_p_loss: 1.4869 - val_v_loss: 0.1538 - val_p_acc: 0.3847\n", + "Epoch 2/10\n", + "594333/594333 [==============================] - 22s 38us/step - loss: 1.6097 - p_loss: 1.4652 - v_loss: 0.1444 - p_acc: 0.3871 - val_loss: 1.6128 - val_p_loss: 1.4660 - val_v_loss: 0.1467 - val_p_acc: 0.3838\n", + "Epoch 3/10\n", + "594333/594333 [==============================] - 22s 38us/step - loss: 1.5957 - p_loss: 1.4522 - v_loss: 0.1435 - p_acc: 0.3922 - val_loss: 1.6149 - val_p_loss: 1.4664 - val_v_loss: 0.1485 - val_p_acc: 0.3915\n", + "Epoch 4/10\n", + "594333/594333 [==============================] - 22s 38us/step - loss: 1.5872 - p_loss: 1.4444 - v_loss: 0.1428 - p_acc: 0.3948 - val_loss: 1.6454 - val_p_loss: 1.4987 - val_v_loss: 0.1468 - val_p_acc: 0.3796\n", + "Epoch 5/10\n", + "594333/594333 [==============================] - 22s 38us/step - loss: 1.5820 - p_loss: 1.4396 - v_loss: 0.1425 - p_acc: 0.3963 - val_loss: 1.5944 - val_p_loss: 1.4486 - val_v_loss: 0.1458 - val_p_acc: 0.3890\n", + "Epoch 6/10\n", + "594333/594333 [==============================] - 23s 38us/step - loss: 1.5779 - p_loss: 1.4358 - v_loss: 0.1421 - p_acc: 0.3978 - val_loss: 1.6073 - val_p_loss: 1.4606 - val_v_loss: 0.1467 - val_p_acc: 0.3887\n", + "Epoch 7/10\n", + "594333/594333 [==============================] - 23s 38us/step - loss: 1.5755 - p_loss: 1.4336 - v_loss: 0.1419 - p_acc: 0.3984 - val_loss: 1.5918 - val_p_loss: 1.4465 - val_v_loss: 0.1454 - val_p_acc: 0.3963\n", + "Epoch 8/10\n", + "594333/594333 [==============================] - 23s 38us/step - loss: 1.5729 - p_loss: 1.4312 - v_loss: 0.1417 - p_acc: 0.3997 - val_loss: 1.5935 - val_p_loss: 1.4477 - val_v_loss: 0.1458 - val_p_acc: 0.3897\n", + "Epoch 9/10\n", + "594333/594333 [==============================] - 23s 38us/step - loss: 1.5711 - p_loss: 1.4295 - v_loss: 0.1415 - p_acc: 0.4003 - val_loss: 1.6120 - val_p_loss: 1.4627 - val_v_loss: 0.1493 - val_p_acc: 0.3903\n", + "Epoch 10/10\n", + "594333/594333 [==============================] - 23s 38us/step - loss: 1.5708 - p_loss: 1.4293 - v_loss: 0.1415 - p_acc: 0.3997 - val_loss: 1.5930 - val_p_loss: 1.4465 - val_v_loss: 0.1466 - val_p_acc: 0.3916\n" + ] + } + ], + "source": [ + "history = model.fit(x_train, [p_train, v_train], batch_size=128, epochs=10, validation_data=(x_test, [p_test, v_test]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,'Value MSE')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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JZeQl5dXtt0NN9zA0KFD6devH3fccQcADz/8MFu2bGHMmDGMGTMGgK5du7Jz504A7r//fvr370///v158MEHy47Xp08fpkyZQr9+/Tj99NPLHUekKSsqLmFJVg5PfLyG7z+7gEF3vc+5j3zK799azvpdBzh7YAceujSTeT8fx8zbRvOHC07gvMyOSmJFGlDv1DhWZe8/Yi5hEZHmTPlG5ZpWj+zbt8O2r+u2zdQTYOI9Va5OTk5m+PDhvPPOO5x33nlMnz6dSy65hOjoaF577TXi4+PZuXMnI0eO5Nxzz61ySoG//e1vxMTEsGTJEpYsWcLgwYPL1t19990kJSVRXFzMuHHjWLJkCTfffDP3338/s2bNok2bNuXaWrRoEc888wzz5s3DOceIESM47bTTaN26NatWreKll17iySef5OKLL+bVV1/lyiuvrJvPSiSEFBWX8G3AM64L1u9hf2mPa9tYzsnswMjuyYzslkSKklWRkJDeLo5DRSVs2HWA7m1bBTscEZEjKd8AQiPfaFqJbJCUdveX/mFNmzYN5xw///nP+fjjjwkLC2Pz5s1kZ2eTmppaaRsff/wxN998MwADBgxgwIABZetefvllnnjiCYqKiti6dStLly4tt76iOXPm8N3vfpfY2FgALrjgAj755BPOPfdcunXrRmZmJgBDhgxh/fr1dfQpiATX0RLXHm1jOc9PXEcocRUJWb1T4wGv4JMSWRGRw5RvHKlpJbJHuZNRn84//3xuvfVWvvjiC/Ly8hg8eDDPPvssO3bsYNGiRURERNC1a1fy8/OP2k5ld0/WrVvHfffdx4IFC2jdujWTJk2qth3nqh6S1bJly7LX4eHhGlosjYpzjt0HCtiw+yAbdx1kw66DbNx9kI27D7Bsa27liWv3JFLilLiKNAY9U1phBsu35XJm//bBDkdE5EjKN4DQyDeaViIbJK1atWL06NF8//vf57LLLgNg7969pKSkEBERwaxZs9iwYcNR2zj11FN54YUXGDNmDN988w1LliwBYN++fcTGxpKQkEB2djZvv/02o0ePBiAuLo7c3NwjuvpPPfVUJk2axO23345zjtdee43nn3++7k9cpB4UFZewJSefjbsPsmH3gbKEdcPug2zafbAsWS2VGh9FWnIM5w/yEtfh3ZS4ijRW0ZHhdEmKUcEnEZEKlG8cSYlsHbnsssu4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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16,6))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(history.history['p_acc'])\n", + "plt.plot(history.history['val_p_acc'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Action prediction accuracy\")\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(history.history['v_loss'])\n", + "plt.plot(history.history['val_v_loss'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Value MSE\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('dense.h5')" + ] + }, + { + "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.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/Linear model.ipynb b/imitation/Linear model.ipynb new file mode 100644 index 0000000..c7a9a0d --- /dev/null +++ b/imitation/Linear model.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tambet/.conda/envs/pommer/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", + " from ._conv import register_converters as _register_converters\n", + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from keras.models import Model\n", + "from keras.layers import Input, Flatten, Dense\n", + "import tensorflow as tf\n", + "import keras.backend as K\n", + "from sklearn.metrics import explained_variance_score\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# make sure TF does not allocate all memory\n", + "config = tf.ConfigProto()\n", + "config.gpu_options.allow_growth = True\n", + "K.set_session(tf.Session(config=config))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((594333, 11, 11, 18), (594333,), (594333,))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('simple_600K_disc0.99_cleaned.npz')\n", + "x_train = data['observations']\n", + "p_train = data['actions']\n", + "v_train = data['rewards']\n", + "x_train.shape, p_train.shape, v_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((95623, 11, 11, 18), (95623,), (95623,))" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = np.load('valid_100K_disc0.99_cleaned.npz')\n", + "x_test = data['observations']\n", + "p_test = data['actions']\n", + "v_test = data['rewards']\n", + "x_test.shape, p_test.shape, v_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "__________________________________________________________________________________________________\n", + "Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + "input_1 (InputLayer) (None, 11, 11, 18) 0 \n", + "__________________________________________________________________________________________________\n", + "flatten_1 (Flatten) (None, 2178) 0 input_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "p (Dense) (None, 6) 13074 flatten_1[0][0] \n", + "__________________________________________________________________________________________________\n", + "v (Dense) (None, 1) 2179 flatten_1[0][0] \n", + "==================================================================================================\n", + "Total params: 15,253\n", + "Trainable params: 15,253\n", + "Non-trainable params: 0\n", + "__________________________________________________________________________________________________\n" + ] + } + ], + "source": [ + "x = Input(shape=(11,11,18))\n", + "h = Flatten()(x)\n", + "p = Dense(6, activation=\"softmax\", name='p')(h)\n", + "v = Dense(1, activation=\"tanh\", name='v')(h)\n", + "model = Model(x, [p, v])\n", + "model.summary()\n", + "model.compile(optimizer='adam', loss=['sparse_categorical_crossentropy', 'mse'], loss_weights=[1, 10], metrics={'p': 'accuracy'})" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 594333 samples, validate on 95623 samples\n", + "Epoch 1/10\n", + "594333/594333 [==============================] - 17s 29us/step - loss: 3.0279 - p_loss: 1.5010 - v_loss: 0.1527 - p_acc: 0.3666 - val_loss: 3.0192 - val_p_loss: 1.4721 - val_v_loss: 0.1547 - val_p_acc: 0.3762\n", + "Epoch 2/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9657 - p_loss: 1.4512 - v_loss: 0.1514 - p_acc: 0.3903 - val_loss: 3.0443 - val_p_loss: 1.5404 - val_v_loss: 0.1504 - val_p_acc: 0.3683\n", + "Epoch 3/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9579 - p_loss: 1.4466 - v_loss: 0.1511 - p_acc: 0.3921 - val_loss: 3.5232 - val_p_loss: 1.5417 - val_v_loss: 0.1981 - val_p_acc: 0.3512\n", + "Epoch 4/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9666 - p_loss: 1.4457 - v_loss: 0.1521 - p_acc: 0.3922 - val_loss: 3.3368 - val_p_loss: 1.4831 - val_v_loss: 0.1854 - val_p_acc: 0.3801\n", + "Epoch 5/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9504 - p_loss: 1.4443 - v_loss: 0.1506 - p_acc: 0.3935 - val_loss: 3.0418 - val_p_loss: 1.4385 - val_v_loss: 0.1603 - val_p_acc: 0.3945\n", + "Epoch 6/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9540 - p_loss: 1.4445 - v_loss: 0.1510 - p_acc: 0.3931 - val_loss: 2.9814 - val_p_loss: 1.4604 - val_v_loss: 0.1521 - val_p_acc: 0.3867\n", + "Epoch 7/10\n", + "594333/594333 [==============================] - 17s 28us/step - loss: 2.9521 - p_loss: 1.4444 - v_loss: 0.1508 - p_acc: 0.3936 - val_loss: 3.0240 - val_p_loss: 1.4668 - val_v_loss: 0.1557 - val_p_acc: 0.3847\n", + "Epoch 8/10\n", + "594333/594333 [==============================] - 16s 27us/step - loss: 2.9516 - p_loss: 1.4428 - v_loss: 0.1509 - p_acc: 0.3936 - val_loss: 2.9462 - val_p_loss: 1.4515 - val_v_loss: 0.1495 - val_p_acc: 0.3905\n", + "Epoch 9/10\n", + "594333/594333 [==============================] - 16s 28us/step - loss: 2.9529 - p_loss: 1.4439 - v_loss: 0.1509 - p_acc: 0.3931 - val_loss: 3.0163 - val_p_loss: 1.4730 - val_v_loss: 0.1543 - val_p_acc: 0.3770\n", + "Epoch 10/10\n", + "594333/594333 [==============================] - 16s 28us/step - loss: 2.9568 - p_loss: 1.4442 - v_loss: 0.1513 - p_acc: 0.3934 - val_loss: 3.1297 - val_p_loss: 1.5114 - val_v_loss: 0.1618 - val_p_acc: 0.3631\n" + ] + } + ], + "source": [ + "history = model.fit(x_train, [p_train, v_train], batch_size=128, epochs=10, validation_data=(x_test, [p_test, v_test]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,'Value MSE')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16,6))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(history.history['p_acc'])\n", + "plt.plot(history.history['val_p_acc'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Action prediction accuracy\")\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(history.history['v_loss'])\n", + "plt.plot(history.history['val_v_loss'])\n", + "plt.legend(['Train', 'Validation'])\n", + "plt.title(\"Value MSE\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Explained variance train: 0.012845516329725748\n", + "Explained variance test: -0.005572327426227375\n" + ] + } + ], + "source": [ + "_, v_train_pred = model.predict(x_train)\n", + "_, v_test_pred = model.predict(x_test)\n", + "print(\"Explained variance train:\", explained_variance_score(v_train, v_train_pred))\n", + "print(\"Explained variance test:\", explained_variance_score(v_test, v_test_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('linear.h5')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (pommer)", + "language": "python", + "name": "pommer" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/imitation/collect_simple.py b/imitation/collect_simple.py new file mode 100644 index 0000000..13c68ed --- /dev/null +++ b/imitation/collect_simple.py @@ -0,0 +1,87 @@ +import pommerman +from pommerman import agents +import numpy as np +import argparse +from copy import deepcopy + + +def featurize(obs): + # TODO: history of n moves? + board = obs['board'] + + # convert board items into bitmaps + maps = [board == i for i in range(10)] + maps.append(obs['bomb_blast_strength']) + maps.append(obs['bomb_life']) + + # duplicate ammo, blast_strength and can_kick over entire map + maps.append(np.full(board.shape, obs['ammo'])) + maps.append(np.full(board.shape, obs['blast_strength'])) + maps.append(np.full(board.shape, obs['can_kick'])) + + # add my position as bitmap + position = np.zeros(board.shape) + position[obs['position']] = 1 + maps.append(position) + + # add teammate + if obs['teammate'] is not None: + maps.append(board == obs['teammate'].value) + else: + maps.append(np.zeros(board.shape)) + + # add enemies + enemies = [board == e.value for e in obs['enemies']] + maps.append(np.any(enemies, axis=0)) + + return np.stack(maps, axis=2) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--num_episodes', type=int, default=1000) + parser.add_argument('--render', action="store_true", default=False) + parser.add_argument('out_file') + args = parser.parse_args() + + # Create a set of agents (exactly four) + agent_list = [ + agents.SimpleAgent(), + agents.SimpleAgent(), + agents.SimpleAgent(), + agents.SimpleAgent(), + ] + + # Make the "Free-For-All" environment using the agent list + env = pommerman.make('PommeFFACompetition-v0', agent_list) + + observations = [[], [], [], []] + actions = [[], [], [], []] + rewards = [[], [], [], []] + + # Run the episodes just like OpenAI Gym + for i in range(args.num_episodes): + obs = env.reset() + done = False + reward = [0, 0, 0, 0] + t = 0 + while not done: + if args.render: + env.render() + action = env.act(obs) + new_obs, new_reward, done, info = env.step(action) + for j in range(4): + if reward[j] == 0: + observations[j].append(featurize(obs[j])) + actions[j].append(action[j]) + rewards[j].append(new_reward[j]) + obs = deepcopy(new_obs) + reward = deepcopy(new_reward) + t += 1 + print("Episode:", i + 1, "Max length:", t, "Rewards:", reward) + env.close() + + np.savez_compressed(args.out_file, + observations=sum(observations, []), + actions=sum(actions, []), + rewards=sum(rewards, [])) diff --git a/imitation/eval_model.py b/imitation/eval_model.py new file mode 100644 index 0000000..e997b9f --- /dev/null +++ b/imitation/eval_model.py @@ -0,0 +1,122 @@ +import pommerman +from pommerman import agents +import numpy as np +import time +from keras.models import load_model +import keras.backend as K +import tensorflow as tf +import argparse + + +def featurize(obs): + # TODO: history of n moves? + board = obs['board'] + + # convert board items into bitmaps + maps = [board == i for i in range(10)] + maps.append(obs['bomb_blast_strength']) + maps.append(obs['bomb_life']) + + # duplicate ammo, blast_strength and can_kick over entire map + maps.append(np.full(board.shape, obs['ammo'])) + maps.append(np.full(board.shape, obs['blast_strength'])) + maps.append(np.full(board.shape, obs['can_kick'])) + + # add my position as bitmap + position = np.zeros(board.shape) + position[obs['position']] = 1 + maps.append(position) + + # add teammate + if obs['teammate'] is not None: + maps.append(board == obs['teammate'].value) + else: + maps.append(np.zeros(board.shape)) + + # add enemies + enemies = [board == e.value for e in obs['enemies']] + maps.append(np.any(enemies, axis=0)) + + return np.stack(maps, axis=2) + + +class KerasAgent(agents.BaseAgent): + def __init__(self, model_file): + super().__init__() + self.model = load_model(model_file) + + def act(self, obs, action_space): + feat = featurize(obs) + probs, values = self.model.predict(feat[np.newaxis]) + action = np.argmax(probs[0]) + #print("Action:", action) + return action + + +def eval_model(agent_id, model_file, num_episodes): + # Create a set of agents (exactly four) + agent_list = [ + agents.SimpleAgent(), + agents.SimpleAgent(), + agents.SimpleAgent(), + ] + agent_list.insert(agent_id, KerasAgent(model_file)) + + # Make the "Free-For-All" environment using the agent list + env = pommerman.make('PommeFFACompetition-v0', agent_list) + + rewards = [] + lengths = [] + start_time = time.time() + # Run the episodes just like OpenAI Gym + for i_episode in range(num_episodes): + state = env.reset() + done = False + lens = [None] * 4 + t = 0 + while not done: + if args.render: + env.render() + actions = env.act(state) + state, reward, done, info = env.step(actions) + for j in range(4): + if lens[j] is None and reward[j] != 0: + lens[j] = t + t += 1 + rewards.append(reward) + lengths.append(lens) + print('Episode ', i_episode, "reward:", reward[agent_id], "length:", lens[agent_id]) + elapsed = time.time() - start_time + env.close() + return rewards, lengths, elapsed + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('model_file') + parser.add_argument('--num_episodes', type=int, default=400) + parser.add_argument('--render', action='store_true', default=False) + args = parser.parse_args() + + # make sure TF does not allocate all memory + config = tf.ConfigProto() + config.gpu_options.allow_growth = True + K.set_session(tf.Session(config=config)) + + rewards0, lengths0, elapsed0 = eval_model(0, args.model_file, args.num_episodes // 4) + rewards1, lengths1, elapsed1 = eval_model(1, args.model_file, args.num_episodes // 4) + rewards2, lengths2, elapsed2 = eval_model(2, args.model_file, args.num_episodes // 4) + rewards3, lengths3, elapsed3 = eval_model(3, args.model_file, args.num_episodes // 4) + + rewards = [(r0[0], r1[1], r2[2], r3[3]) for r0, r1, r2, r3 in zip(rewards0, rewards1, rewards2, rewards3)] + lengths = [(l0[0], l1[1], l2[2], l3[3]) for l0, l1, l2, l3 in zip(lengths0, lengths1, lengths2, lengths3)] + + print("Average reward:", np.mean(rewards)) + print("Average length:", np.mean(lengths)) + + print("Average rewards per position:", np.mean(rewards, axis=0)) + print("Average lengths per position:", np.mean(lengths, axis=0)) + + elapsed = elapsed0 + elapsed1 + elapsed2 + elapsed3 + total_timesteps = np.sum(np.max(np.concatenate([lengths0, lengths1, lengths2, lengths3], axis=0), axis=1)) + print("Time per timestep:", elapsed / total_timesteps) diff --git a/mcts/mcts_agent.py b/mcts/mcts_agent.py new file mode 100644 index 0000000..7462b29 --- /dev/null +++ b/mcts/mcts_agent.py @@ -0,0 +1,234 @@ +import argparse +import multiprocessing +from queue import Empty +import numpy as np +import time + +import pommerman +from pommerman.agents import BaseAgent, SimpleAgent +from pommerman import constants + + +NUM_AGENTS = 4 +NUM_ACTIONS = len(constants.Action) +NUM_CHANNELS = 18 + + +def argmax_tiebreaking(Q): + # find the best action with random tie-breaking + idx = np.flatnonzero(np.isclose(Q, np.max(Q))) + assert len(idx) > 0, str(Q) + return np.random.choice(idx) + + +class MCTSNode(object): + def __init__(self, p): + # values for 6 actions + self.Q = np.zeros(NUM_ACTIONS) + self.W = np.zeros(NUM_ACTIONS) + self.N = np.zeros(NUM_ACTIONS, dtype=np.uint32) + assert p.shape == (NUM_ACTIONS,) + self.P = p + + def action(self): + U = args.mcts_c_puct * self.P * np.sqrt(np.sum(self.N)) / (1 + self.N) + return argmax_tiebreaking(self.Q + U) + + def update(self, action, reward): + self.W[action] += reward + self.N[action] += 1 + self.Q[action] = self.W[action] / self.N[action] + + def probs(self, temperature=1): + if temperature == 0: + p = np.zeros(NUM_ACTIONS) + p[argmax_tiebreaking(self.N)] = 1 + return p + else: + Nt = self.N ** (1.0 / temperature) + return Nt / np.sum(Nt) + + +class MCTSAgent(BaseAgent): + def __init__(self, agent_id=0): + super().__init__() + self.agent_id = agent_id + self.env = self.make_env() + self.reset_tree() + + def make_env(self): + agents = [] + for agent_id in range(NUM_AGENTS): + if agent_id == self.agent_id: + agents.append(self) + else: + agents.append(SimpleAgent()) + + return pommerman.make('PommeFFACompetition-v0', agents) + + def reset_tree(self): + self.tree = {} + + def search(self, root, num_iters, temperature=1): + # remember current game state + self.env._init_game_state = root + + for i in range(num_iters): + # restore game state to root node + obs = self.env.reset() + # serialize game state + state = str(self.env.get_json_info()) + + trace = [] + done = False + while not done: + if state in self.tree: + node = self.tree[state] + # choose actions based on Q + U + action = node.action() + trace.append((node, action)) + else: + # use unfiform distribution for probs + probs = np.ones(NUM_ACTIONS) / NUM_ACTIONS + + # use current rewards for values + rewards = self.env._get_rewards() + reward = rewards[self.agent_id] + + # add new node to the tree + self.tree[state] = MCTSNode(probs) + + # stop at leaf node + break + + # ensure we are not called recursively + assert self.env.training_agent == self.agent_id + # make other agents act + actions = self.env.act(obs) + # add my action to list of actions + actions.insert(self.agent_id, action) + # step environment forward + obs, rewards, done, info = self.env.step(actions) + reward = rewards[self.agent_id] + + # fetch next state + state = str(self.env.get_json_info()) + + # update tree nodes with rollout results + for node, action in reversed(trace): + node.update(action, reward) + reward *= args.discount + + # reset env back where we were + self.env.set_json_info() + self.env._init_game_state = None + # return action probabilities + state = str(root) + return self.tree[state].probs(temperature) + + def rollout(self): + # reset search tree in the beginning of each rollout + self.reset_tree() + + # guarantees that we are not called recursively + # and episode ends when this agent dies + self.env.training_agent = self.agent_id + obs = self.env.reset() + + length = 0 + done = False + while not done: + if args.render: + self.env.render() + + root = self.env.get_json_info() + # do Monte-Carlo tree search + pi = self.search(root, args.mcts_iters, args.temperature) + # sample action from probabilities + action = np.random.choice(NUM_ACTIONS, p=pi) + + # ensure we are not called recursively + assert self.env.training_agent == self.agent_id + # make other agents act + actions = self.env.act(obs) + # add my action to list of actions + actions.insert(self.agent_id, action) + # step environment + obs, rewards, done, info = self.env.step(actions) + assert self == self.env._agents[self.agent_id] + length += 1 + print("Agent:", self.agent_id, "Step:", length, "Actions:", [constants.Action(a).name for a in actions], "Probs:", [round(p, 2) for p in pi], "Rewards:", rewards, "Done:", done) + + reward = rewards[self.agent_id] + return length, reward, rewards + + def act(self, obs, action_space): + # TODO + assert False + + +def runner(id, num_episodes, fifo, _args): + # make args accessible to MCTSAgent + global args + args = _args + # make sure agents play at all positions + agent_id = id % NUM_AGENTS + agent = MCTSAgent(agent_id=agent_id) + + for i in range(num_episodes): + # do rollout + start_time = time.time() + length, reward, rewards = agent.rollout() + elapsed = time.time() - start_time + # add data samples to log + fifo.put((length, reward, rewards, agent_id, elapsed)) + + +def logger(fifo): + all_rewards = [] + all_lengths = [] + all_elapsed = [] + for i in range(args.num_episodes): + try: + # wait for a new trajectory + length, reward, rewards, agent_id, elapsed = fifo.get() + except Empty: + # just ignore empty fifos + continue + + print("Episode:", i, "Reward:", reward, "Length:", length, "Rewards:", rewards, "Agent:", agent_id, "Time per step:", elapsed / length) + all_rewards.append(reward) + all_lengths.append(length) + all_elapsed.append(elapsed) + + print("Average reward:", np.mean(all_rewards)) + print("Average length:", np.mean(all_lengths)) + print("Time per timestep:", np.sum(all_elapsed) / np.sum(all_lengths)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('--render', action="store_true", default=False) + parser.add_argument('--num_episodes', type=int, default=400) + # runner params + parser.add_argument('--num_runners', type=int, default=4) + parser.add_argument('--max_steps', type=int, default=constants.MAX_STEPS) + # MCTS params + parser.add_argument('--mcts_iters', type=int, default=10) + parser.add_argument('--mcts_c_puct', type=float, default=1.0) + # RL params + parser.add_argument('--discount', type=float, default=0.99) + parser.add_argument('--temperature', type=float, default=0) + args = parser.parse_args() + + # use spawn method for starting subprocesses + ctx = multiprocessing.get_context('spawn') + + # create fifos and processes for all runners + fifo = ctx.Queue() + for i in range(args.num_runners): + process = ctx.Process(target=runner, args=(i, args.num_episodes // args.num_runners, fifo, args)) + process.start() + + # do logging in the main process + logger(fifo)