{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# PhyGNN Test with Pythagorean's Theorem\n", "\n", "In this example test we create a dataset with pythagorean's theorem `a^2 + b^2 = c^2` where `a` and `b` are input features and we are trying to predict `c`. We train on a noisy and biased `c` dataset resulting in a predictably biased neural network. We then train with an augmented loss function that includes 80% weight on the predicted vs. physical calculation of `c`. The neural network loses its bias and is able to predict much more accurately. \n", "\n", "Obviously this is an idealized situation where we know the solution for `c`, but the physical loss function can be created using whatever benchmark might be applicable to a given physical domain." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import tensorflow as tf\n", "\n", "from phygnn import PhysicsGuidedNeuralNetwork" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2.1.0'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.__version__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Pythag Inputs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we set up the training features and known output values based on the pythagorean theorem." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "((10000, 1), (10000, 2), (10000, 2))" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N = 100\n", "\n", "a = np.linspace(-1, 1, N)\n", "b = np.linspace(-1, 1, N)\n", "a, b = np.meshgrid(a, b)\n", "\n", "a = np.expand_dims(a.flatten(), axis=1)\n", "b = np.expand_dims(b.flatten(), axis=1)\n", "\n", "y = np.sqrt(a ** 2 + b ** 2)\n", "x = np.hstack((a, b))\n", "p = x.copy()\n", "\n", "y.shape, x.shape, p.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we make a y_noise dataset which is noisy and systematically biased." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0, 0.5, 'y_noise')" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "y_noise = y * (1 + (np.random.random(y.shape) - 0.5) * 0.5) + 0.1\n", "plt.scatter(y, y_noise)\n", "plt.plot((y.min(), y.max()), (y.min(), y.max()), 'k-')\n", "plt.xlabel('y')\n", "plt.ylabel('y_noise')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Example P_Fun\n", "\n", "This is an example physics loss function that supplements the normal y_predicted vs. y_true neural network loss function." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def p_fun_pythag(y_predicted, y_true, p):\n", " \"\"\"Example function for loss calculation using physical relationships.\n", " \n", " Parameters\n", " ----------\n", " y_predicted : tf.Tensor\n", " Predicted y values in a 2D tensor based on x values in this batch.\n", " y_true : np.ndarray\n", " Known y values that were given to the PhyGNN fit method.\n", " p : np.ndarray\n", " Supplemental physical feature data that can be used to calculate a \n", " y_physical value to compare against y_predicted. The rows in this \n", " array have been carried through the batching process alongside y_true \n", " and the features used to create y_predicted and so can be used 1-to-1 \n", " with the rows in y_predicted and y_true.\n", " \n", " Returns\n", " -------\n", " p_loss : tf.Tensor\n", " A 0D tensor physical loss value.\n", " \"\"\"\n", " \n", " p = tf.convert_to_tensor(p, dtype=tf.float32)\n", " y_physical = tf.sqrt(p[:, 0]**2 + p[:, 1]**2)\n", " y_physical = tf.expand_dims(y_physical, 1)\n", " \n", " p_loss = tf.math.reduce_mean(tf.math.abs(y_predicted - y_physical))\n", " \n", " return p_loss" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# NN Model Structure\n", "\n", "Here we define the model layers using a simple list of kwargs." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "hidden_layers = [{'units': 64, 'activation': 'relu', 'name': 'relu1'},\n", " {'units': 64, 'activation': 'relu', 'name': 'relu2'},\n", " ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Train the Model without P_Fun\n", "\n", "Here we train the model with loss weights (1.0, 0.0) which fully weights the mean absolute error of y_predicted vs. y_noise and does not weight the p_fun calculation at all." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From C:\\Users\\GBUSTER\\AppData\\Local\\Continuum\\anaconda3\\envs\\mlclouds\\lib\\site-packages\\tensorflow_core\\python\\ops\\array_grad.py:563: _EagerTensorBase.cpu (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.identity instead.\n" ] } ], "source": [ "PhysicsGuidedNeuralNetwork.seed(0)\n", "model = PhysicsGuidedNeuralNetwork(p_fun=p_fun_pythag, \n", " hidden_layers=hidden_layers, \n", " loss_weights=(1.0, 0.0), \n", " input_dims=2, output_dims=1)\n", "model.fit(x, y_noise, p, n_batch=4, n_epoch=20)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEKCAYAAAAFJbKyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deXzU1bn48c8zSxKykZAECAm7IAJCiIjWBbSoBdu6oFXQqliVarXW3rY/7XKrte2ttbZ622u12uq1vdal7q24lWrBuhREQBYhgCCBEBK27MvMPL8/vt/AECbJTJJJAvO8X695zXefZ76EPDnnfM85oqoYY4wx0fL0dgDGGGOOLJY4jDHGxMQShzHGmJhY4jDGGBMTSxzGGGNiYonDGGNMTOKaOERkloisF5GNInJbhP2Xi8gq9/WOiEx2tx8rIivCXlUicou77w4R2R6279x4fgdjjDGHknj14xARL7ABOBsoBZYC81R1bdgxpwDrVHWviMwG7lDVkyJcZztwkqpuFZE7gBpVvScugRtjjGlXPEsc04CNqrpZVZuAJ4Hzww9Q1XdUda+7+h5QGOE6M4FNqro1jrEaY4yJki+O1y4AtoWtlwIntXEswDXAKxG2zwWeaLXtJhG5ElgGfCss+USUm5urI0aM6DBgY4wxB33wwQeVqprXens8E4dE2BaxXkxEzsRJHKe12p4EnAd8N2zzA8CP3Wv9GPgl8JUI11wALAAYNmwYy5Yti/0bGGNMAhORiDU98ayqKgWGhq0XAjtaHyQik4DfA+er6u5Wu2cDy1W1vGWDqparalBVQ8DDOFVih1HVh1R1qqpOzcs7LGEaY4zppHgmjqXAGBEZ6ZYc5gIvhR8gIsOA54ArVHVDhGvMo1U1lYjkh61eCKzu1qiNMca0K25VVaoaEJGbgNcAL/CIqq4Rkevd/Q8CPwRygN+KCEBAVacCiEgqzhNZX2116btFpAinqmpLhP3GGGPiKG6P4/YlU6dOVWvjMKZnNDc3U1paSkNDQ2+HYqKUkpJCYWEhfr//kO0i8kHLH/Ph4tk4boxJQKWlpWRkZDBixAjcmgTTh6kqu3fvprS0lJEjR0Z1jg05YozpVg0NDeTk5FjSOEKICDk5OTGVEC1xGGO6nSWNI0us/16JkTjq2+0faIwxJgaJkTjqWncPMcYcrfbt28dvf/vbmM8799xz2bdvX7vH/PCHP+Tvf/97Z0OLKD09vVuv1xMSI3EEm3s7AmNMD2krcQSDwXbPW7hwIVlZWe0ec+edd3LWWWd1Kb6jgSUOY8xR5bbbbmPTpk0UFRVx4okncuaZZ3LZZZdx/PHHA3DBBRdwwgknMGHCBB566KED540YMYLKykq2bNnCcccdx3XXXceECRM455xzqK+vB2D+/Pk888wzB46//fbbKS4u5vjjj+fjjz8GoKKigrPPPpvi4mK++tWvMnz4cCorKzuMW1X5zne+w8SJEzn++ON56qmnACgrK2P69OkUFRUxceJElixZQjAYZP78+QeOvffee7v1HnYkMR7H1SA0VEFKZm9HYkxC+dFf17B2R1W3XnP8kExu/+KENvffddddrF69mhUrVvDWW2/x+c9/ntWrVx941PSRRx5hwIAB1NfXc+KJJ3LRRReRk5NzyDVKSkp44oknePjhh7nkkkt49tln+fKXv3zYZ+Xm5rJ8+XJ++9vfcs899/D73/+eH/3oR3z2s5/lu9/9Lq+++uohyak9zz33HCtWrGDlypVUVlZy4oknMn36dP785z/zuc99ju9///sEg0Hq6upYsWIF27dvZ/VqZ+CMjqrYultilDgAqg4bJssYkwCmTZt2SP+EX//610yePJmTTz6Zbdu2UVJSctg5I0eOpKioCIATTjiBLVu2RLz2nDlzDjvm7bffZu7cuQDMmjWL7OzsqOJ8++23mTdvHl6vl0GDBjFjxgyWLl3KiSeeyKOPPsodd9zBRx99REZGBqNGjWLz5s18/etf59VXXyUzs2f/KE6MEgdA1XYYOK63ozAmobRXMugpaWlpB5bfeust/v73v/Puu++SmprKGWecEbH/QnJy8oFlr9d7oKqqreO8Xi+BQABwqpw6o63zpk+fzuLFi3n55Ze54oor+M53vsOVV17JypUree2117j//vt5+umneeSRRzr1uZ2ROCWO6rLejsAY0wMyMjKorq6OuG///v1kZ2eTmprKxx9/zHvvvdftn3/aaafx9NNPA/D666+zd2903QGmT5/OU089RTAYpKKigsWLFzNt2jS2bt3KwIEDue6667jmmmtYvnw5lZWVhEIhLrroIn784x+zfPnybv8e7UmgEodVVRmTCHJycjj11FOZOHEi/fr1Y9CgQQf2zZo1iwcf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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "MAE: 0.102\n" ] } ], "source": [ "model.history[['training_loss', 'validation_loss']].plot()\n", "plt.ylabel('Loss')\n", "plt.show()\n", "plt.close()\n", "\n", "y_pred = model.predict(x)\n", "plt.scatter(y, y_pred)\n", "plt.plot((y.min(), y.max()), (y.min(), y.max()), 'k-')\n", "plt.xlabel('True')\n", "plt.ylabel('Predicted')\n", "plt.show()\n", "plt.close()\n", "print('MAE: {:.3f}'.format(np.mean(np.abs(y_pred - y))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Train the Model with P_Fun\n", "\n", "Here we train the model with loss weights (0.2, 0.8) which still weights the mean absolute error of y_predicted vs. y_noise but also gives much more weight to the p_fun calculation. We can see by the results that supplementing the pure NN training with a physical estimate of the true value helps the overall model prediction capabilities. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "PhysicsGuidedNeuralNetwork.seed(0)\n", "model = PhysicsGuidedNeuralNetwork(p_fun=p_fun_pythag, \n", " hidden_layers=hidden_layers, \n", " loss_weights=(0.2, 0.8),\n", " input_dims=2, output_dims=1)\n", "model.fit(x, y_noise, p, n_batch=4, n_epoch=20)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEGCAYAAAB/+QKOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3deXxU5b348c83M1nIvrGELBAgCCIQJCyCgtu1aK2opSquoIhSrdbb9ur91dtWW9veanu91p0Wr1apuFG1dadYRNYEQ9j3JQtLyL4nkzy/P84khDCZTJbJMvm+X6+8Zuac55z55hDmO89ynkeMMSillFIt+fV0AEoppXonTRBKKaVc0gShlFLKJU0QSimlXNIEoZRSyiV7TwfQlWJjY83w4cN7OgyllOozMjIyThljBrra51MJYvjw4aSnp/d0GEop1WeIyJHW9mkTk1JKKZc0QSillHJJE4RSSimXfKoPQinVferq6sjJyaG6urqnQ1EeCAoKIiEhAX9/f4+P0QShlOqQnJwcwsLCGD58OCLS0+EoN4wxFBQUkJOTQ3JyssfHaROTUqpDqquriYmJ0eTQB4gIMTEx7a7taYJQSnWYJoe+oyP/Vr6VIBw1PR2BUkr5DN9KELUVPR2BUkr5DN9KEA4dTaFUf1FcXMzzzz/f7uOuuuoqiouL3Zb52c9+xhdffNHR0FwKDQ3t0vN1Bx9LENrEpFR/0VqCqK+vd3vcRx99RGRkpNsyjz/+OJdffnmn4vMFvjXMVWsQSvWIxz7cwc680i4957lDw/n5d8a1uv+RRx7hwIEDpKam4u/vT2hoKHFxcWRmZrJz506uvfZasrOzqa6u5sEHH2Tx4sXA6TnbysvLufLKK7nwwgtZt24d8fHxvP/++wwYMIAFCxZw9dVXM2/ePIYPH84dd9zBhx9+SF1dHW+//TZjxowhPz+fm2++mYKCAqZMmcInn3xCRkYGsbGxbn8vYwz/8R//wccff4yI8Oijj3LjjTdy7NgxbrzxRkpLS3E4HLzwwgvMmDGDu+66i/T0dESEO++8k4ceeqhLr7M7vlWDqK+FBvffHpRSvuG3v/0tI0eOJDMzkyeffJJNmzbxxBNPsHPnTgCWLVtGRkYG6enpPPPMMxQUFJx1jn379nHfffexY8cOIiMjeffdd12+V2xsLFu2bGHJkiU89dRTADz22GNceumlbNmyheuuu46jR496FPd7771HZmYmW7du5YsvvuAnP/kJx44dY/ny5XzrW99q2peamkpmZia5ubls376dbdu2sXDhwg5erY7xrRqEaYDiIxA9oqcjUapfcfdNv7tMnTr1jJvAnnnmGVauXAlAdnY2+/btIyYm5oxjkpOTSU1NBWDy5MkcPnzY5bmvv/76pjLvvfceAGvXrm06/5w5c4iKivIozrVr1zJ//nxsNhuDBw9m9uzZbN68mSlTpnDnnXdSV1fHtddeS2pqKiNGjODgwYP84Ac/4Nvf/jZXXHGF5xekC/hWDQLg1P6ejkAp1QNCQkKann/55Zd88cUXrF+/nq1btzJp0iSXN4kFBgY2PbfZbDgcDpfnbizXvIwxpkNxtnbcrFmzWLNmDfHx8dx222289tprREVFsXXrVi6++GKee+45Fi1a1KH37CjfSxAF+3o6AqVUNwgLC6OsrMzlvpKSEqKioggODmb37t1s2LChy9//wgsv5K233gLgs88+o6ioyKPjZs2axYoVK6ivryc/P581a9YwdepUjhw5wqBBg7j77ru566672LJlC6dOnaKhoYHvfve7/PKXv2TLli1d/nu441tNTH52OKUJQqn+ICYmhpkzZ3LeeecxYMAABg8e3LRvzpw5vPjii0yYMIFzzjmH6dOnd/n7//znP2f+/PmsWLGC2bNnExcXR1hYWJvHXXfddaxfv56JEyciIvzud79jyJAhvPrqqzz55JNNHe6vvfYaubm5LFy4kIaGBgB+85vfdPnv4Y50tJrUG6UNDzfpv5gFC/7e06Eo5fN27drF2LFjezqMHlNTU4PNZsNut7N+/XqWLFlCZmZmT4fllqt/MxHJMMakuSrvWzUIe5DWIJRS3eLo0aPccMMNNDQ0EBAQwNKlS3s6pC7nYwkiEMqPQ3UpBIX3dDRKKR+WkpLCN998c8a2goICLrvssrPKrlq16qwRVH2BjyWIIKDU6qiOn9zT0Sil+pmYmJhe38zUHr41isnuHLKmQ12VUqrTfCtB2AJB/HSoq1JKdQHfShAiEDlMO6qVUqoL+FaCAIhNgQJtYlJKqc7ywQQxGgoOgPPGEqWUgtPrMeTl5TFv3jyXZS6++GLS09Pdnufpp5+msrKy6bUn60u0x4IFC3jnnXe67Hyd4dUEISJzRGSPiOwXkUdc7L9FRLKcP+tEZGKzfYdFZJuIZIqI+3+x5mJGgaMKSnO66LdQSvmSoUOHduoDuGWC8GR9ib7Ka8NcRcQGPAf8G5ADbBaRD4wxO5sVOwTMNsYUiciVwMvAtGb7LzHGnGrXG8emWI+n9kFkUsd/AaWU5z5+BI5v69pzDhkPV/621d0PP/www4YN4/vf/z4Av/jFLxAR1qxZQ1FREXV1dfzqV79i7ty5Zxx3+PBhrr76arZv305VVRULFy5k586djB07lqqqqqZyS5YsYfPmzVRVVTFv3jwee+wxnnnmGfLy8rjkkkuIjY1l9erVTetLxMbG8oc//IFly5YBsGjRIn74wx9y+PDhVtedaMuqVav48Y9/jMPhYMqUKbzwwgsEBgbyyCOP8MEHH2C327niiit46qmnePvtt3nsscew2WxERESwZs2ajlz1M3izBjEV2G+MOWiMqQXeBM74lzLGrDPGNM5wtQFI6PS7xjgThPZDKOXTbrrpJlasWNH0+q233mLhwoWsXLmSLVu2sHr1an70ox+5nXX1hRdeIDg4mKysLH7605+SkZHRtO+JJ54gPT2drKws/vWvf5GVlcUDDzzA0KFDWb16NatXrz7jXBkZGbzyyits3LiRDRs2sHTp0qYb6Txdd6K56upqFixYwIoVK9i2bVvTIkKFhYWsXLmSHTt2kJWVxaOPPgpYq+B9+umnbN26lQ8++KBd17I13rxRLh7IbvY6hzNrBy3dBXzc7LUBPhMRA7xkjHnZ1UEishhYDJCUlAShgyAwXEcyKdWd3HzT95ZJkyZx8uRJ8vLyyM/PJyoqiri4OB566CHWrFmDn58fubm5nDhxgiFDhrg8x5o1a3jggQcAmDBhAhMmTGja99Zbb/Hyyy/jcDg4duwYO3fuPGN/S2vXruW6665rmnb8+uuv56uvvuKaa67xeN2J5vbs2UNycjKjR48G4I477uC5557j/vvvJygoiEWLFvHtb3+bq6++GoCZM2eyYMECbrjhhqb1KzrLmwlCXGxzmcpF5BKsBHFhs80zjTF5IjII+FxEdhtjzqozORPHywBpaWkGEasfQu+FUMrnzZs3j3feeYfjx49z00038cYbb5Cfn09GRgb+/v4MHz7c5ToQzYmc/VF16NAhnnrqKTZv3kxUVBQLFixo8zzuaiot151o3pTV3vPZ7XY2bdrEqlWrePPNN3n22Wf55z//yYsvvsjGjRv5xz/+0bQaXWen9/BmE1MOkNjsdQKQ17KQiEwA/gTMNcY0rQlojMlzPp4EVmI1WXkmNkVrEEr1AzfddBNvvvkm77zzDvPmzaOkpIRBgwbh7+/P6tWrOXLkiNvjZ82axRtvvAHA9u3bycrKAqC0tJSQkBAiIiI4ceIEH398unGjtXUoZs2axd/+9jcqKyupqKhg5cqVXHTRRR3+3caMGcPhw4fZv99qLv/LX/7C7NmzKS8vp6SkhKuuuoqnn366aWqPAwcOMG3aNB5//HFiY2PJzs52d3qPeLMGsRlIEZFkIBe4Cbi5eQERSQLeA24zxuxttj0E8DPGlDmfXwE87vE7x6RA1gqorYCAkLbLK6X6pHHjxlFWVkZ8fDxxcXHccsstfOc73yEtLY3U1FTGjBnj9vglS5awcOFCJkyYQGpqKlOnWt9DJ06cyKRJkxg3bhwjRoxg5syZTccsXryYK6+8kri4uDP6Ic4//3wWLFjQdI5FixYxadIkj5qTXAkKCuKVV17he9/7XlMn9b333kthYSFz586luroaYwz/8z//A8BPfvIT9u3bhzGGyy67jIkTJ7bxDm3z6noQInIV8DRgA5YZY54QkXsBjDEvisifgO8CjWneYYxJE5ERWLUGsJLYcmPME229X1pamklPT4cdK+HtBXDPGojr/EVSSp2tv68H0Rf1qvUgjDEfAR+12PZis+eLgLMWWTXGHAQ6/ske02yoqyYIpZTqEN+a7rtRzEhAdKirUqrXuu+++/j666/P2Pbggw+ycOHCHorobL6ZIPwHQGSidlQr5WXGGJejgFTbnnvuuW59v450J/jeXEyNYlJ0qKtSXhQUFERBQUGHPnhU9zLGUFBQQFBQULuO880aBFhDXb/ZCMZY04ArpbpUQkICOTk55Ofn93QoygNBQUEkJLRvsgrfTRAxo6C2HMqOQfjQno5GKZ/j7+9PcnJyT4ehvMh3m5iaT9qnlFKq3Xw3QTQNdd3rvpxSSimXfDdBhA8F/xAd6qqUUh3kuwlCxLofQpuYlFKqQ3w3QYBzfWpNEEop1RG+nSBiUqA4G+ranlpXKaXUmXw7QcSmAAYKD/Z0JEop1ef0gwSB9kMopVQH+HaCiBllPWo/hFJKtZtvJ4iAEAiPh1M61FUppdrLtxME6PrUSinVQb6fIBrXp9YZJ5VSql18P0HEpEBNKZSf7OlIlFKqT/H9BBGrHdVKKdURvp8gYnSoq1JKdYTvJ4iIRLAH6aR9SinVTr6fIPz8IFon7VNKqfby/QQBOmmfUkp1QP9JEEVHwFHb05EopVSf0T8SREwKmHooOtTTkSilVJ/RPxJE41BX7YdQSimP9Y8EoetTK6VUu/WPBBEUDqGDdairUkq1Q/9IEGDVIrSJSSmlPNZ/EkSszuqqlFLt0X8SREwKVBVBRUFPR6KUUn2CVxOEiMwRkT0isl9EHnGx/xYRyXL+rBORiZ4e226Ny49qLUIppTzitQQhIjbgOeBK4Fxgvoic26LYIWC2MWYC8Evg5XYc2z4xOtRVKaXaw5s1iKnAfmPMQWNMLfAmMLd5AWPMOmNMkfPlBiDB02PbLXIY2AK0BqGUUh7yZoKIB7Kbvc5xbmvNXcDHHTy2bTY7RI/Q9amVUspDdi+eW1xsc7nup4hcgpUgLuzAsYuBxQBJSUnuI4oZpTfLKaWUh7xZg8gBEpu9TgDyWhYSkQnAn4C5xpiC9hwLYIx52RiTZoxJGzhwoPuIYlOg8CDU13n8SyilVH/lzQSxGUgRkWQRCQBuAj5oXkBEkoD3gNuMMXvbc2yHxKRAg8Oa2VUppZRbXmtiMsY4ROR+4FPABiwzxuwQkXud+18EfgbEAM+LCIDDWRtweWyng2o+1LVxAj+llFIuebMPAmPMR8BHLba92Oz5ImCRp8d2WvOhrudc2aWnVkopX9N/7qQGCI6G4Bgd6qqUUh7oXwkCnJP26VBXpZRqS/9LEDppn1JKeaT/JYiYFKjIh6rino5EKaV6NZ9KENV1DW0Xih1tPeriQUop5ZZPJYiKWkfbhRqHuuqkfUop5ZZPJYhKTxJE1HDws2s/hFJKtcGnEkRVbX3bhWz+VpLQOZmUUsotn0oQNY4GSqo8mGdJh7oqpVSbfCpBAGTleDA6KXaUNWlfgwc1DqWU6qd8LkFszfYgQcSkQH0NFB/1fkBKKdVH+VSCCLT7kelJgmiatE+bmZRSqjU+lSAGBNjIzC7BGJdrC50Wo0NdlVKqLT6VIIID7JwqryG3uMp9wZBYCIrQoa5KKeWGbyUIfxsAW7NL3BcUcY5k0gShlFKt8akEEeRvI8DuR2Z2UduFY0drH4RSSrnhUwlCBMYNDW+7BgHWUNeyY1BT5v3AlFKqD/KpBAGQmhjJttwSHPVtTNynHdVKKeWWTyaIqrp69p4od19Qh7oqpZRbPpcgJiZEArR9P0T0CBA/rUEopVQrfC5BDIsJJjLYv+07qu2BEJmkQ12VUqoVPpcgRISJCZFs9WROJp20TymlWuVzCQKsfoi9J8qoqGljfYjYFKsPosGDleiUUqqf8dkE0WBgW24bw11jRoGjCkpzuycwpZTqQzxKECIyUkQCnc8vFpEHRCTSu6F13MREDzuqm0YyaT+EUkq15GkN4l2gXkRGAX8GkoHlXouqk6JDAkiKDm67o7rpXgjth1BKqZY8TRANxhgHcB3wtDHmISDOe2F1XmpiZNs1iLAhEBCmNQillHLB0wRRJyLzgTuAvzu3+XsnpK4xMTGSYyXVnCitbr2QiDXlhq5PrZRSZ/E0QSwELgCeMMYcEpFk4HXvhdV5qZ72Q+hQV6WUcsmjBGGM2WmMecAY81cRiQLCjDG/9XJsnTJuaDh2P2m7HyI2BUpzoLaiewJTSqk+wtNRTF+KSLiIRANbgVdE5A/eDa1zgvxtjI0L96AGMcp6LDjg/aCUUqoP8bSJKcIYUwpcD7xijJkMXN7WQSIyR0T2iMh+EXnExf4xIrJeRGpE5Mct9h0WkW0ikiki6R7GeYaJiRFk5ZTQ0OBmCVId6qqUUi55miDsIhIH3MDpTmq3RMQGPAdcCZwLzBeRc1sUKwQeAJ5q5TSXGGNSjTFpHsZ5hokJkZTXODiQ72Zm1+iR1qP2Qyil1Bk8TRCPA58CB4wxm0VkBNDWV+6pwH5jzEFjTC3wJjC3eQFjzEljzGagrp1xe2RSkgcd1QHBEJGoNQillGrB007qt40xE4wxS5yvDxpjvtvGYfFAdrPXOc5tnjLAZyKSISKL23FckxGxoYQF2j3rh9Bpv5VS6gyedlIniMhKETkpIidE5F0RSWjrMBfb3HQGnGWmMeZ8rCaq+0RkViuxLRaRdBFJz8/PP2Ofn58wITGi7ZldGyftM+0JTymlfJunTUyvAB8AQ7FqAR86t7mTAyQ2e50A5HkamDEmz/l4EliJ1WTlqtzLxpg0Y0zawIEDz9o/MSGS3cfKqK6rb/3NYlKgthzKjnsanlJK+TxPE8RAY8wrxhiH8+f/gLM/jc+0GUgRkWQRCQBuwkoybRKREBEJa3wOXAFs9zDWM6QmRuJoMOzIczOza+NIJr2jWimlmniaIE6JyK0iYnP+3AoUuDvAOXfT/Vid27uAt4wxO0TkXhG5F0BEhohIDvDvwKMikiMi4cBgYK2IbAU2Af8wxnzSkV+w8Y7qb466aWbSoa5KKXUWu4fl7gSeBf4Hqx9hHdb0G24ZYz4CPmqx7cVmz49jNT21VApM9DA2twaFBzE0IoitOW5qEGFDwT9Yh7oqpVQzno5iOmqMucYYM9AYM8gYcy3WTXN9wsTESDKzi1ov4OcHMSO1BqGUUs10ZkW5f++yKLwsNTGS7MIqCsprWi8Uk6JDXZVSqpnOJAhXw1h7pcYV5rLcNTPFpkDxUahzMz24Ukr1I51JEH3mpoHx8RH4CXzj7oa5mBTAQOHBbotLKaV6M7cJQkTKRKTUxU8Z1j0RfUJIoJ3Rg8PcT/0d2zira+eamYwxPP7hTt7cdLRT51FKqZ7mdhSTMSasuwLxtokJkXy68zjGGERctI41TvvdyX6IzOxiln19CID8shruv3SU6/dTSqlerjNNTH1KalIkxZV1HCmodF0gMAzC4qwpNzrh9Q1HCQmwcc3Eofz+8738+qNdGJ3CQynVB3l6H0SfNzHh9Myuw2NDXBeK6dz61MWVtfw9K495kxP45dzziAr2Z+lXhyitcvDr68dj89OahFKq7+g3NYjRg0MZ4G9zP7PrwDFwcheUn+zQe7yTkUONo4Fbpw/Dz0/4xTXj+MGlo1iRns0Df/2GWkdDB6NXSqnu128ShN3mx/j4CPcJYurd0OCAj37S7vM3NBje2HiUycOiGBsXDoCI8KMrzuH/XTWGf2w7xt2vpVNV62bSQKWU6kX6TYIAqx9iZ15p69/kB54Dsx+GnX+DnR7NK9hk3YECDp2q4NbpSWftWzxrJL+5fjxr9uVz+7KNlFZ7ZX0kpZTqUv0qQUxMiKS2voFdx0pbLzTzQRgyAf7xI6gs9Pjcr284QlSwP1eeF+dy//ypSTxz0yS+OVrMzUs3uL+rWymleoF+lSBSnUuQul1AyOYPc5+DqkL49Kcenfd4STWf7zrBDWmJBPnbWi33nYlDWXp7GvtOlHPDS+s5VlLVrviVUqo79asEMTQiiNjQQDLdTf0NEDcBLnwIti6HfZ+3ed4Vm7OpbzDcPO3s5qWWLhkziNfunMqJ0hrmvbCew6cqPA1fKaW6Vb9KECJCamIkmW0tQQow6yfWqKYPH4Tq1pukHPUN/HXTUWaNHsiwmFaGz7YwbUQMf717OlV19cx7cT27j7tp8lJKqR7SrxIEQGpiBAfzKyipbKOj2B5oNTWVHYMvft5qsVW7T3K8tJpbPag9NDc+IYK37pmOzQ9ufGkDW466mY5cKaV6QD9MEFEAZOV6UItISIPp34f0ZXDoK5dFXt9whLiIIC4dM6jdsYwaFMY7984gMtifW/+0ka/3n2r3OZRSylv6XYIYnxAB0HY/RKNLfgrRI+CD+6H2zP6Cw6cq+GrfKeZPTcJu69ilTIwO5u17LiAxKpiFr2zmsx3HO3QepZTqav0uQUQM8GfEwBD3I5maCwiGa56FosPwzyfO2LV801FsfsKNUxI7FdOg8CBW3DOdsUPDWfLGFlZ+k9Op8ymlVFfodwkCrBXmMrOLPZ9Eb/hMmLIINjwP2ZsAqK6r5+30bK44dzCDw4M6HVNkcABvLJrGtORoHlqxlb+sP9zpcyqlVGf02wRxqryW3OJ23Idw+S8gIgHevx/qqvlo2zGKKuu4dfqwLosrNNDOsgVTuHzsYP7r/R08t7pzM8sqpVRn9NsEAbifl6mlwDD4zv/CqT2w5ne8vuEII2JDmDEypktjC/K38cKt53Nt6lCe/HQPf1yl62QrpXpGv0wQY4aEE2D3c7/CnCujLoPUWzFrn6YmO5ObpyV5ZTEgf5sff7ghlevPj+f3n+9l6RpdBlUp1f36zXoQzQXY/Rg3NLx9NYhG3/oVZds/5qmAl4hLXdDlsTXy8xN+990J1NQ18MRHuwjy9+O2C4Z77f2UUqqlflmDAGvivm25JTjq27dGQ5mE8v9qFzJWjhC55XkvRWex2/x4+qbUpj6Jt9Kzvfp+SinVXL9NEJOSIqmua2DvifJ2Hfe3b3L5e+35FI24Btb8zlpgyIv8bX48e/MkLkqJ5eF3s3g/M9er76eUUo36bYJovgSpp4wxvL7hKOfFhxN5/R+sjuv374cG7y4CFORv4+Xb0pg6PJp/f2srn2zXm+mUUt7XbxPEsJhgIoP929VRnXGkiD0nyrh12jAkdCBc+TvITYcNL3gxUsuAABt/XjCFiQkR/OCvW1i9u2PLoiqllKf6bYIQESYmRLarBvH6hiOEBdm5JnWoteG878I534Z//hIKDngp0tNCA+28snAq5wwJ457XM3TuJqWUV/XbBAHW/RB7T5ZRXuNos2xBeQ0fbTvOd89PIDjAOfhLBL79e7AFwgc/gIb2dXh3RMQAf/5y5zSSY0JY9Go6mw97vuqdUkq1R79PEMbAtpySNsu+nZFDbX0Dt7Sc1js8Dub8Go58DRnLvBTpmaJCAnh90TTiIoJY+Mrm9t/PoZRSHujXCWKCc2bXtibua2gwLN94lKnJ0aQMDju7QOotMPJS+PznUHzUG6GeZWBYIG/cPY2oEH9uX7aJnXm66JBSqmt5NUGIyBwR2SMi+0XkERf7x4jIehGpEZEft+fYrhATGkhSdHCbU3+v2ZfP0cLK1uddErGm4QD48Ifg6SSAnRQXMYDli6YTHGDj1j9vZN+Jsm55X6VU/+C1BCEiNuA54ErgXGC+iJzbolgh8ADwVAeO7RITEyPbrEG8vuEosaEBzBk3pPVCkUnWhH4HVkHm8i6N0Z3E6GCW3z0dm59wy5826hrXSqku480axFRgvzHmoDGmFngTmNu8gDHmpDFmM9By/c82j+0qqYmRHCup5kRptcv9ucVV/HP3CW5ISyTA3sblSrsLhs2ET/8T8jKttay7oTaRHBvCG4um4Wgw3Lx0AzlFlV5/T6WU7/PmXEzxQPO5IXKAaV19rIgsBhYDJCW1b11osNaoBuuGuW+5qCG8uekoBpg/1YNz+/nBNX+EF2bCy7Otbf7BEDoYwoa4eRwCwdFWU1UHjR4cxmt3TuXmpRu4eelG3rrnAoZEdH6dCqVU/+XNBOHq087Tr9MeH2uMeRl4GSAtLa3dX9fHDY3A7icuE0RdfQNvbs7mknMGkRgd7NkJY0bCkq8hJx3Kj0PZidOPJ7bD/lVQ66KvwM/fmTAGWwkjbDBEDoPUmyHUs/Wuz4uP4NU7p3Lbnzdx8582sGLxBQwMC/QsbqWUasGbCSIHaL4WZwKQ1w3HtkuQv40xcWEuh4p+tuME+WU13Dq9nTWTmJHWT2tqK6DsOJSfcP1YdAiOroeqQvjytzDlLpj5oEeJYlJSFMsWTOH2ZRu57c8b+evd04kKCWhf/EophXcTxGYgRUSSgVzgJuDmbji23VITI/nbN3nUNxhsfqcrL69vOEJ85ABmj/bsG7zHAkLaTiJg3Z295klrqdPNf/Y4UUxNjuZPt0/hzlc3c/uyTbxx9zTCg/y78BdQSvUHXuukNsY4gPuBT4FdwFvGmB0icq+I3AsgIkNEJAf4d+BREckRkfDWjvVWrBMTIimvcXAw//TMrvtPlrP+YAE3T0s6I2l0q5iRcN2LcH86jLvWShRPT4DPHoXyfLeHXpgSy4u3ns/u46Xc9X+bqXF4d0JBpZTv8ep9EMaYj4wxo40xI40xTzi3vWiMedH5/LgxJsEYE26MiXQ+L23tWG+ZlGTN7PpNs2amNzYewd8m3DglsbXDuk9jorhvM5w7F9Y/B0+PbzNRXDpmML+/IZXNh4t4dOV2TDfdn6GU8g39+k7qRiNiQwkLtDf1Q1TV1vNuRg5zzosjNrQXdfLGjoLrXzozUfyv+xrFNUI0yI0AABnoSURBVBOH8sClo3g7I4c/rz3UzQErpfoyTRBYy3tOSIxomtn1w6w8Sqsd3Npy3qXeoilRbIKx32mWKP7LZaL44eWj+da4wfz6o118uUenCVdKeUYThNPEhEh2Hy+juq6eNzYcIWVQKFOTo3s6LPdiU+D6l5slimddJgo/P+EPN6RyzpBwfrD8G/afbN8qekqp/kkThNPExEjqGwx/3XSUrTkl3DItCenEjWvdyoNEERJoZ+ntkwmw+7Ho1c0UV9b2cNBKqd5OE4TTpESro/r3n+1lgL+N6ycn9HBEHdCYKL6/EcZcfTpRrH0agISoYF66bTK5xVXcv/wbHPXeX79CKdV3aYJwGhQeRFxEEOU1DuamDu3b9w0MHA3fXWolihGXwBc/h01LAUgbHs0T141n7f5T/Oofu3o4UKVUb6YJoplUZy2i1Wm9+5qBo+HGv8DoK+Hj/4A9HwNwQ1oiiy5M5v/WHWb5xu5Zv0Ip1fdogmhmwYzhPHhZCufFR/R0KF3Hzwbz/gxDJsA7d0LeNwD851VjmT16ID97fzsbDhb0cJBKqd5IE0Qz00bE8NC/je7pMLpeQAjc/BYEx8LyG6H4KDY/4Y83T2JYTDBLXs/gaIFOEa6UOpMmiP4ibDDc8hbUVcMb34OqYsKD/PnTHVNoMLDotc2UVbdclkMp1Z9pguhPBo21+iQKDsBbt4GjluTYEJ6/5XwO5Ffw0IpM6ht0Og6llEUTRH8zYra1qNGhNfDhA2AMM0fF8vPvnMsXu07y1Gd7ejpCpVQv4c3pvlVvlTofio/Cl7+GqOFw8SPcNn0Yu4+X8cKXBxg9OJTrJvXB+0CUUl1KE0R/Nfs/oPgIfPkbiExCUm/msWvGcTC/nIff3cbwmBAmJUX1dJRKqR6kTUz9lQhc/TQkz4YPfgAHv8Tf5sfzt0xmcHggi/+SwbGSqp6OUinVgzRB9Gf2ALjhNYhJgRW3w8ldRIcE8Oc7plBZ42DxaxlU1epCQ0r1V5og+rsBkXDL2+AfZA1/LTvO6MFhPDN/EtvzSvjJO1t1oSGl+ilNEAoiE60b6SoLYfkNUFPOZWMH8/CcMfw96xjP/nN/T0eolOoB2kmtLENT4XuvwF9vsqbkuGk598wawd7jZfz+872kDA5lznlxrR5e32CorHVQWVtPRY2Dipp6KmodVNY6KK+pp7LGQUVtPZED/LluUjx+PbXOt1LKY5og1GmjvwVXPQn/+BF88jBy1VP8+vrxHCqo4KEVW3k/M4+K2tMf9hU1VgKoqKmnqs7zvopVu0/whxtSCfK3efGXUUp1liYIdaYpi6DoCKx7BqKGEzTjB7x022Tud65EFxxoJzTQRlRIACEBNudrO8EBNkIC7IQE2gkJtBEcYD2GBDR/beft9Gye+GgXx0s2sPT2NGJ605rfSqkziC91QKalpZn09PSeDqPva2iAdxbCzr/B916Fcdd26ek/3naMH67IJC4iiFcWTiU5NqRLz6+U8pyIZBhj0lzt005qdTY/P7juRUicBivvgexNXXr6K8fHsfzu6ZRWO7j++a/JOFLYpedXSnUNTRDKNf8BcNNfIXyo1XFdcKBLTz95WBTvLZlBZHAA85du5B9Zx7r0/EqpztMEoVoXEgO3vAPGWPdIlHbth/jw2BDeXTKDCfER3Ld8Cy/964Dec6FUL6IJQrkXMxLmvwmlufBsGnz1e2tNiS4SHRLA64um8e3xcfzm49381/vbcdQ3dNn5lVIdpwlCtS1pGixZZ83btOpxeHYKbH/Xqll0gSB/G3+cP4l7Zo3g9Q1HWfyXDCpqHF1ybqVUx2mCUJ6JGQnzl8PtH0BQhHUz3bJvQU5Gl5zez0/4z6vG8strz+PLPSe58eX1nCztupqKUqr9NEGo9hkxG+75F3znGSg8BH+6FN69G0pyuuT0t00fxp/uSONgfgXXPb+OvSfKuuS8Sqn20wSh2s/PBpPvgAe2wIX/Djvfhz+mwT+fgJryTp/+0jGDeeueC6itb+C7L6xj3f5TXRC0Uqq9NEGojgsMg8t/DvdvhnOuhDW/szqyM5dbN9t1wnnxEfztvpnERQRxxyubeDeja2ooTeod1tDdTsaplC/zaoIQkTkiskdE9ovIIy72i4g849yfJSLnN9t3WES2iUimiOjt0b1Z1DBror87P7Pum/jbElh6CRxZ16nTxkcO4O17ZzBleDQ/ensr//vFvs4Ngy3Ohoz/gxW3wu9GwB/Ph5dnw77Pu6zDXSlf4rWpNkTEBuwF/g3IATYD840xO5uVuQr4AXAVMA34X2PMNOe+w0CaMcbj9gWdaqMXaGiA7e/AF7+whsaOvQb+7XGITu7wKWsdDTzyXhbvbcll3uQEfn3deALsHny3qa20ktT+L+DAKji119oengCjLoXYc2DTy9bSq0kXwGU/g2EzOhynUn2Ru6k2vDlZ31RgvzHmoDOIN4G5wM5mZeYCrxkrS20QkUgRiTPG6G21fZWfH0y4AcZcDeufhbX/A3s/gWn3wqwfWyOg2inA7sfvvzeRpOhgnv5iH8dKqnh2/vlEhQScWdAYyN8N+1dZSeHIOqivAXsQDJsJkxfAyMtg4DnWkqsAUxfDN6/Bv56EV66EUZfDpY/C0EmdvxZK9XHerEHMA+YYYxY5X98GTDPG3N+szN+B3xpj1jpfrwIeNsaki8ghoAgwwEvGmJdbeZ/FwGKApKSkyUeOHPHK76M6qDQPVv0Sti6H4FiYcT9EDbcSRVAEBEVaj4Hh1hKobXgnI4dH3s2i3hhGDQxl+lAblwftYnzlJqKOrUXK8qyCsedYH/ajLrWSg/8A9yeurYTNS62EVlUE586FS35qJROlfFhP1SBcrQjTMhu5KzPTGJMnIoOAz0VktzFmzVmFrcTxMlhNTJ0JWHlB+FC47gWYthg++X9W01Nr/IObJQ5n0mj+OiiCeUERTJ1jJ2/fVmJPriV59x5sNFBqgvnEjOdA+Dxqhl1M8shzmJAQyYjYEM8WJwoIhpkPWrWM9c9btZ9dH8LE+TD7YaufRal+xpsJIgdIbPY6AcjztIwxpvHxpIisxGqyOitBqD5i6CRY+BGUHYOqYqgucfHTYntFPhTsP/3aWIsSJQFJCMSfjxn5Y04MvpCMuhFk5pWzNbuYbdtKqMzYCkBYoJ3xCRFMTIxkovNxSHgQIq0kjaAIuOQ/YerdVm1i01LIegvSFsJFP4awwd10wZTqed5sYrJjdVJfBuRidVLfbIzZ0azMt4H7Od1J/YwxZqqIhAB+xpgy5/PPgceNMZ+4e0/tpPZhxkBtxelkETYEgqNdFq1vMBzILyczu5isnGK2Zpew+3gpdfXW3/rAsEAmJkSSmhjBBSNjmZgQgd3WSqd3SS6seRK2vAa2AJh2j1XTaOW9lRcYc7rPSHU5d01MXl0wyDlK6WnABiwzxjwhIvcCGGNeFOtr3LPAHKASWOjsfxgBrHSexg4sN8Y80db7aYJQramuq2fXsVKyckrYml3M1pxiDuRXABAWZGfGyBguTBnIrJRYhsW4WMCo4AB8+VvY9rZ1/8eMB2D6EggM7ebfxEcYY9UYy05A+XE3j8fBNMDwC60BBqMug5hRmjC6UI8liO6mCUK1R1FFLesOFLB2fz5r9p4it7gKgKToYC5MiWVWSiwXjIwlYoD/6YNO7LDuGN/zD6vT/aIfWXeV19dBTRnUllt3k9eWWa9ryp3bys7cX1PmLFN+elvoQBg4xuoYHzjWeowabt253tdUFsKxrdZQ57LjUH7Ceiw7bn3wl58Eh4u5tvyDIXSwVUNsfKyvg4OrofCgVSYiyRp8MPIya+qXDoyMU6dpglCqDcYYDhdU8tU+K1lsOFhAeY0DP4GJiZFcNCqWi0YPJDUxEn+bH2Rvhn8+Dofa0S1mC4CAUKsGEhjmfO587R9i9c/k74HSZneN2wIhdrQzaYw5/RidDDb/1t+rO9VWwLGt1GWnU304HfuxLQyoyD6jiCMgHEKHYIsYgoQOsfpyQoecmQhCB1vXorXaQeEh636WA6vh4L+sBCs2SEg7XbsYOqlvJtQepAlCqXaqq28gM7uYr/bm89X+U2zNLqbBQGignekjYpg1OpYLR8WSXJaOZG+CgJBmH/otEkBAmPVoD/TszatL4dQ+656O/N1W0sjfbd3Q18jP32pqaZk4YkZ6/j7tZIwhv6ScUwe+oeZoOgHHvyGqeDtDag7jhzVlSa6JYWvDSLIaRrBTRnKwfiD5JpIarCHMgXY/EqIGkBAV3OLReh4bGtD6AILm6usgZ7N1z8uBVZCXCRgYEAUjLrYSxshLISLeK9eipxhjKK1ycKqihqKKWkKD7MRHDiAsqONfFjRBKNVJJZV1rDtwiq/2n2LN3nxyiqzmqPjIAcwYGcOkpChSEyMZPTi09Q7vzqqtcCaOPWcmjqJDVju9U409nJqAKGoCIqkNiKI20PpxBEZRFxiNIyiausBo6oOiaRgQRUNAODabHzYR/PwEm59QWlXH0YJyKo7tIehEJrGlOxhes4exHCZQ6gAoNKHs8UshN2QsJdETaIibxMAhiSRGB5MYPYCBoYFU1NaTW1RFTlElOWc8Ws+LKuvO+BVdJZDk2GAmD4tmYJibxFdRYDVDHfinlTTKj1vbB461EsWoS62amH2AlUDtQVYNzINkZIxh74lyvt5/iqycYuw2P0ID7YQE2ggJtFvPA+yEBNoJC7I7t1n7Qpz7bK0MtTbGUF7joLCillPltRSU11BYUUtBRS2nGp+XW68b9zkazv7MDnMmivjIAQxt+gkiIcp6PigsqNUYNEEo1YWMMRwpqOSr/af4am8+mw4XUuz8oAsOsDE+PoLUpEgmJUYyKSmKweFBXfr+ZdV1bM8tZVtuMVk5JezJycdWdJAUySFZjhMtpURLGVGUESNlREkZ0ZQSKK4XYaozNooIo9CEUWTCKCCMKMoZ73eQcLESYbUEcSJkDOWxE2Do+YSOnMbgxNEEBXRupHxFjYPc4rMTR+PzworaprIjBoYwLTmGacnRTE2OZmhkKzc/GgMnd56uXRxZb91RfxaxEoU90LqRsjFx2AOpIYDiWj/yq4UTlVDqsFFj/CEwlEw5l9WO8zhV60+9iw9rVwb42wgNsjclFqDpg7/W4XrCyNBAOzGhAUSHBBATEkhMSAAxoQHEhFrPo0ICKK2qI6+4irziKnKLq8gtriavuIqSqjMTr91PGBIRxFBnEolvlkQuGTNYE4RS3tLYf5GZXUTm0WIys4vZeez0sNq4iCBSEyNJdSaM8fERDAjwrJ28osbBjrxSsnKK2ZZbwracEg6eqmjaHx85gAkJEYxPiGBCfCSjh4RiE6HeGBoacD4a6usbaKitQCpPIVUFSGUhflWF+FUV4FddiK26EHtVIfaaQuzVhRj/EGwJkwkclobET7aasHqgbb+ixsGeE2VsPlTIpkOFbDpcSFm1legSowcwdfjphDEsJth181RtJRxdZ62p7qgGR02zxypw1FBVVcmpohKKSssoKy/H1FURKHWE2OqJ8q8n1F7PAD8H9poSqKsEWwBm+EU4Rl5B2bDLKA0cSnmNg4oaBxW1Dspr6q3nNQ7Kqs/eboxp+qCPCbUSQHRoALEhgU1JIci/49e7vMbRlDTyiqvILapyJpJqcourOF5a3ZTcjvz31ZoglOpO1XX17MgrJTO72PlTRHah9W3c5iecMzisWS0jkhGxodQ4Gth5rISsHCsRZOWWcCC/vGmi2biIIMbHRzgTQiTj4yOIbjkflY+rbzDsPl5qJQvnT4GzljE4PJCpyTFMTY5mWnI0KYNCW+3PKK2uY+PBQr7ef4p1B06x94S1jkl4kNXHNHNULDNHxTByYItz1NfB0Q3W/GJ7P4WCfdb2gWNh9Ldg9BxImAI2b96D3EnVpdQf3UTlga9pOLqRyHs/1gShVE87VV7TVMPIzC5ma3YxZc61t0MD7VTWOmhssRgUFmglgvhIJiREcF58hPs2+H7KGOumyI3OZLHxYCHHnUvVRocEMGV4FFOdzVIlVXV8vf8UXx8oYFuONeggyN+PKcOjmTHSSgjjhka02lbvUsEBZ7L4xJocssFhdZSnXGEljJGXwYBIL/32HirJsZLa0Q2QvcEaqm0aQPxg0Djk+19rglCqt2lw3vH9TXYx23NLiAwOYEK81VzU1f0W/YUxhuzCKjYeKmhKGkcLK5v22/2E1MRIZoyMYcaoWCYlRRJo76Kms+oSq5N876ew7zOoLLCG4Q6bcbp24e2b/BrqrQSQvRGOroejG08Pm/YPgYTJ1tT2idOsmk5QuHZSK6X6r2MlVaQfLiI00M6U5GhCA7uh+aehHnIzTjdFndhubY8ecboZqrFj3BbofAxwdpIHnN7WuL+1JquacshNtxJB9gbr/pxa5zruYXFWIki6AJKmweDxLs+jCUIppXpS8VErUez91Lq50uWoKjfEzzk0N+B04vCzQ9ER5ySWAoPOtRJBYw0hMsmj2oomCKWU6i1qK6DosDWKqr7WOaKq1koaDufPGc9rT4+6qq89c3v0CCshJKR1uK+jp9aDUEop1VJACAwe19NReMRLt3wqpZTq6zRBKKWUckkThFJKKZc0QSillHJJE4RSSimXNEEopZRySROEUkoplzRBKKWUcsmn7qQWkTJgT0/H0Q6xwKmeDqIdNF7v0ni9S+N1bZgxZqCrHb52J/We1m4Z741EJF3j9R6N17s0Xu/qDfFqE5NSSimXNEEopZRyydcSxMs9HUA7abzepfF6l8brXT0er091UiullOo6vlaDUEop1UU0QSillHKpzyUIEZkjIntEZL+IPOJiv4jIM879WSJyfk/E6YwlUURWi8guEdkhIg+6KHOxiJSISKbz52c9EWuzeA6LyDZnLGctz9ebrq8znnOaXbtMESkVkR+2KNOj11hElonISRHZ3mxbtIh8LiL7nI9RrRzr9u+9G+N9UkR2O//NV4qIy+XL2vr76cZ4fyEiuc3+za9q5djecn1XNIv1sIhktnJs915fY0yf+QFswAFgBBAAbAXObVHmKuBjQIDpwMYejDcOON/5PAzY6yLei4G/9/S1bRbPYSDWzf5ec31b+fs4jnXjT6+5xsAs4Hxge7NtvwMecT5/BPjvVn4ft3/v3RjvFYDd+fy/XcXryd9PN8b7C+DHHvy99Irr22L/74Gf9Ybr29dqEFOB/caYg8aYWuBNYG6LMnOB14xlAxApInHdHSiAMeaYMWaL83kZsAuI74lYulCvub4uXAYcMMYc6elAmjPGrAEKW2yeC7zqfP4qcK2LQz35e+9yruI1xnxmjHE4X24AErwdh6daub6e6DXXt5GICHAD8Fdvx+GJvpYg4oHsZq9zOPsD15My3U5EhgOTgI0udl8gIltF5GMR6enFag3wmYhkiMhiF/t75fV1uonW/2P1pmsMMNgYcwysLxLAIBdleuu1vhOrFulKW38/3el+Z5PYslaa8Hrj9b0IOGGM2dfK/m69vn0tQYiLbS3H6XpSpluJSCjwLvBDY0xpi91bsJpEJgJ/BP7W3fG1MNMYcz5wJXCfiMxqsb/XXV8AEQkArgHedrG7t11jT/W6ay0iPwUcwButFGnr76e7vACMBFKBY1jNNi31uusLzMd97aFbr29fSxA5QGKz1wlAXgfKdBsR8cdKDm8YY95rud8YU2qMKXc+/wjwF5HYbg6zeTx5zseTwEqsanhzver6NnMlsMUYc6Lljt52jZ1ONDbNOR9PuijTq661iNwBXA3cYpwN4i158PfTLYwxJ4wx9caYBmBpK3H0tutrB64HVrRWpruvb19LEJuBFBFJdn5jvAn4oEWZD4DbnaNtpgMljVX57uZsT/wzsMsY84dWygxxlkNEpmL9mxR0X5RnxBIiImGNz7E6Jre3KNZrrm8LrX7z6k3XuJkPgDucz+8A3ndRxpO/924hInOAh4FrjDGVrZTx5O+nW7ToF7uulTh6zfV1uhzYbYzJcbWzR65vd/WGd9UP1iiavVijD37q3HYvcK/zuQDPOfdvA9J6MNYLsaqsWUCm8+eqFvHeD+zAGkGxAZjRg/GOcMax1RlTr76+zeIOxvrAj2i2rddcY6zEdQyow/rWehcQA6wC9jkfo51lhwIfNTv2rL/3Hop3P1Z7fePf8Yst423t76eH4v2L8+8zC+tDP643X1/n9v9r/JttVrZHr69OtaGUUsqlvtbEpJRSqptoglBKKeWSJgillFIuaYJQSinlkiYIpZRSLmmCUKoXcM44+/eejkOp5jRBKKWUckkThFLtICK3isgm53z8L4mITUTKReT3IrJFRFaJyEBn2VQR2dBsDYUo5/ZRIvKFc/LALSIy0nn6UBF5x7nuwhuNd38r1VM0QSjlIREZC9yINWFaKlAP3AKEYM0DdT7wL+DnzkNeAx42xkzAuqu3cfsbwHPGmjxwBtZdtWDN9vtD4Fysu2Znev2XUsoNe08HoFQfchkwGdjs/HI/AGuSvQZOT7D2OvCeiEQAkcaYfzm3vwq87ZxLJ94YsxLAGFMN4DzfJuOch8e5othwYK33fy2lXNMEoZTnBHjVGPOfZ2wU+a8W5dzNX+Ou2aim2fN69P+n6mHaxKSU51YB80RkEDStKz0M6//RPGeZm4G1xpgSoEhELnJuvw34l7HWA8kRkWud5wgUkeBu/S2U8pB+Q1HKQ8aYnSLyKNaKXn5Ys3HeB1QA40QkAyjB6qcAaxrvF50J4CCw0Ln9NuAlEXnceY7vdeOvoZTHdDZXpTpJRMqNMaE9HYdSXU2bmJRSSrmkNQillFIuaQ1CKaWUS5oglFJKuaQJQimllEuaIJRSSrmkCUIppZRL/x980O4nqlsWTAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "MAE: 0.012\n" ] } ], "source": [ "model.history[['training_loss', 'validation_loss']].plot()\n", "plt.ylabel('Loss')\n", "plt.show()\n", "plt.close()\n", "\n", "y_pred = model.predict(x)\n", "plt.scatter(y, y_pred)\n", "plt.plot((y.min(), y.max()), (y.min(), y.max()), 'k-')\n", "plt.xlabel('True')\n", "plt.ylabel('Predicted')\n", "plt.show()\n", "plt.close()\n", "print('MAE: {:.3f}'.format(np.mean(np.abs(y_pred - y))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bad Physics Function Test\n", "\n", "Here we see that a p_fun input with numpy operations instead of tensorflow operations cannot be used in PhyGNN. This is because of how the stochastic gradient descent algorithm works in tensorflow. SGD finds the gradient of the loss with respect to the change in node weights. The loss function must be automatically differentiable for this to work. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def p_fun_bad(y_predicted, y_true, p):\n", " \"\"\"This is an example of a poorly formulated p_fun() that uses numpy operations.\"\"\"\n", " \n", " y_physical = p[:, 0]**2 + p[:, 1]**2\n", " p_loss = np.mean(np.abs(y_predicted.numpy() - y_physical))\n", " p_loss = tf.convert_to_tensor(p_loss, dtype=tf.float32)\n", " \n", " return p_loss" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "The input p_fun was not differentiable! Please use only tensor math in the p_fun.\n" ] }, { "ename": "RuntimeError", "evalue": "The input p_fun was not differentiable! Please use only tensor math in the p_fun.", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mloss_weights\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0.5\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0.5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m input_dims=2, output_dims=1)\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_noise\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mn_batch\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mn_epoch\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32mc:\\sandbox\\phygnn\\phygnn\\phygnn.py\u001b[0m in \u001b[0;36mfit\u001b[1;34m(self, x, y, p, n_batch, n_epoch, shuffle, validation_split, p_kwargs, run_preflight, return_diagnostics)\u001b[0m\n\u001b[0;32m 431\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 432\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_loss_weights\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mrun_preflight\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 433\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_p_fun_preflight\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp_kwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 434\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 435\u001b[0m \u001b[0mt0\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32mc:\\sandbox\\phygnn\\phygnn\\phygnn.py\u001b[0m in \u001b[0;36m_p_fun_preflight\u001b[1;34m(self, x, y_true, p, p_kwargs)\u001b[0m\n\u001b[0;32m 256\u001b[0m 'Please use only tensor math in the p_fun.')\n\u001b[0;32m 257\u001b[0m \u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0merror\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0memsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 258\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0memsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 259\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 260\u001b[0m \u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'p_fun passed preflight check.'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mRuntimeError\u001b[0m: The input p_fun was not differentiable! Please use only tensor math in the p_fun." ] } ], "source": [ "PhysicsGuidedNeuralNetwork.seed(0)\n", "model = PhysicsGuidedNeuralNetwork(p_fun=p_fun_bad, \n", " hidden_layers=hidden_layers, \n", " loss_weights=(0.5, 0.5),\n", " input_dims=2, output_dims=1)\n", "model.fit(x, y_noise, p, n_batch=4, n_epoch=20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:mlclouds]", "language": "python", "name": "conda-env-mlclouds-py" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }