{ "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 a contrived 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. This example is simply intended to show how to build and train a physics guided neural network. " ] }, { "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", "from rex import init_logger\n", "\n", "from phygnn import PhysicsGuidedNeuralNetwork" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "init_logger('phygnn', log_level='INFO', log_file=None)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2.4.0'" ] }, "execution_count": 3, "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": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "((10000, 1), (10000, 2), (10000, 2))" ] }, "execution_count": 4, "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": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0, 0.5, 'y_noise')" ] }, "execution_count": 5, "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": 6, "metadata": {}, "outputs": [], "source": [ "def p_fun_pythag(model, y_true, y_predicted, p):\n", " \"\"\"Example function for loss calculation using physical relationships.\n", " \n", " Parameters\n", " ----------\n", " model : PhysicsGuidedNeuralNetwork\n", " Instance of the phygnn model at the current point in training.\n", " y_true : np.ndarray\n", " Known y values that were given to the phygnn.fit() method.\n", " y_predicted : tf.Tensor\n", " Predicted y values in a 2D tensor based on x values in the\n", " current batch.\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 x-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": [ "# model architecture\n", "\n", "Here we define the model layers using a simple list of kwargs." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "hidden_layers = [{'units': 64},\n", " {'activation': 'relu'},\n", " {'units': 64}, \n", " {'activation': 'relu'},\n", " ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# train 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": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "INFO - 2021-02-02 16:35:28,927 [phygnn.py:773] : Epoch 0 train loss: 1.84e-01 val loss: 2.57e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,021 [phygnn.py:773] : Epoch 1 train loss: 1.16e-01 val loss: 1.28e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,100 [phygnn.py:773] : Epoch 2 train loss: 1.61e-01 val loss: 1.31e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,173 [phygnn.py:773] : Epoch 3 train loss: 1.28e-01 val loss: 1.32e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,251 [phygnn.py:773] : Epoch 4 train loss: 1.07e-01 val loss: 1.13e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,317 [phygnn.py:773] : Epoch 5 train loss: 1.18e-01 val loss: 1.03e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,386 [phygnn.py:773] : Epoch 6 train loss: 1.12e-01 val loss: 1.07e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,457 [phygnn.py:773] : Epoch 7 train loss: 9.82e-02 val loss: 9.88e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,520 [phygnn.py:773] : Epoch 8 train loss: 1.02e-01 val loss: 9.74e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,590 [phygnn.py:773] : Epoch 9 train loss: 1.02e-01 val loss: 9.71e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,659 [phygnn.py:773] : Epoch 10 train loss: 9.91e-02 val loss: 9.81e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,736 [phygnn.py:773] : Epoch 11 train loss: 9.90e-02 val loss: 9.53e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,807 [phygnn.py:773] : Epoch 12 train loss: 1.01e-01 val loss: 9.54e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,873 [phygnn.py:773] : Epoch 13 train loss: 9.79e-02 val loss: 9.48e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:29,941 [phygnn.py:773] : Epoch 14 train loss: 9.87e-02 val loss: 9.43e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,010 [phygnn.py:773] : Epoch 15 train loss: 9.63e-02 val loss: 9.45e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,068 [phygnn.py:773] : Epoch 16 train loss: 9.71e-02 val loss: 9.42e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,130 [phygnn.py:773] : Epoch 17 train loss: 9.69e-02 val loss: 9.38e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,192 [phygnn.py:773] : Epoch 18 train loss: 9.79e-02 val loss: 9.44e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,256 [phygnn.py:773] : Epoch 19 train loss: 9.83e-02 val loss: 9.39e-02 for \"phygnn\"\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", " n_features=2, n_labels=1)\n", "model.fit(x, y_noise, p, n_batch=4, n_epoch=20)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEGCAYAAAB/+QKOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAA9G0lEQVR4nO3deXxU5dnw8d81S/ZJwpoNEFB2RJCwWNy1iktBLe62QrW+Wu1in7YvT+tjq9W3rVrbx6fWrY9aW61bxaLFKiKKWFECArJvIiQsCWsSsmeu949zkgzJJEyWSQJzfT+f+cxZ7nPmyiSZa+5zn/u+RVUxxhhjGvN0dQDGGGO6J0sQxhhjwrIEYYwxJixLEMYYY8KyBGGMMSYsX1cH0FF69+6tAwcO7OowjDHmmLJs2bK9qton3L7jJkEMHDiQvLy8rg7DGGOOKSLyZXP77BKTMcaYsKKaIERkqohsEJHNIjI7zP4fishaEVklIgtE5ISQfQNE5B0RWeeWGRjNWI0xxhwpaglCRLzAo8BFwEjgWhEZ2ajYZ0Cuqo4BXgUeCNn3HPCgqo4AJgKF0YrVGGNMU9Fsg5gIbFbVrQAi8iIwHVhbV0BVF4aUXwLc4JYdCfhUdb5brjSKcRpj2qC6upr8/HwqKiq6OhQTgYSEBPr164ff74/4mGgmiBxgR8h6PjCphfI3AW+5y0OBgyLyGjAIeBeYraq10QjUGNN6+fn5BAIBBg4ciIh0dTimBarKvn37yM/PZ9CgQREf1y0aqUXkBiAXeNDd5APOAH4ETAAGAzPDHHeLiOSJSF5RUVEnRWuMAaioqKBXr16WHI4BIkKvXr1aXduLZoIoAPqHrPdztx1BRM4HfgZMU9VKd3M+sEJVt6pqDfA6cGrjY1X1SVXNVdXcPn3C3sZrjIkiSw7Hjrb8rqKZIJYCQ0RkkIjEAdcAc0MLiMg44Amc5FDY6Nh0Ean71D+XkLaLDlV+EN7/NRQsi8rpjTHmWBW1BOF+878DeBtYB7ysqmtE5F4RmeYWexBIAV4RkRUiMtc9thbn8tICEfkcEOCpaMXK+7+CLz+O2umNMeZYFNU2CFWdp6pDVfVEVb3f3Xa3qtYlgvNVNUNVx7qPaSHHzlfVMap6sqrOVNWqqASZkAa+RCjZFZXTG2Oi4+DBg/zxj39s9XEXX3wxBw8ebLHM3XffzbvvvtvGyMJLSUnp0PN1hm7RSN2lRCCQaQnCmGNMcwmipqamxePmzZtHenp6i2Xuvfdezj///PaEd1w4bsZiapfUbCjZ3dVRGHPMuueNNazdWdyh5xyZncrPvzaq2f2zZ89my5YtjB07Fr/fT0JCAj169GD9+vVs3LiRyy67jB07dlBRUcH3v/99brnlFqBh3LbS0lIuuugiTj/9dP7973+Tk5PDP/7xDxITE5k5cyaXXnopM2bMYODAgdx444288cYbVFdX88orrzB8+HCKioq47rrr2LlzJ6eddhrz589n2bJl9O7du8WfS1X5yU9+wltvvYWIcNddd3H11Veza9curr76aoqLi6mpqeGxxx7jK1/5CjfddBN5eXmICN/61re48847O/R9bonVIMBqEMYcg379619z4oknsmLFCh588EGWL1/Of//3f7Nx40YAnn76aZYtW0ZeXh6PPPII+/bta3KOTZs2cfvtt7NmzRrS09P5+9//Hva1evfuzfLly7ntttt46KGHALjnnns499xzWbNmDTNmzGD79u0Rxf3aa6+xYsUKVq5cybvvvsuPf/xjdu3axQsvvMCFF15Yv2/s2LGsWLGCgoICVq9ezeeff86sWbPa+G61jdUgAAJZUDwPVJ1LTsaYVmnpm35nmThx4hGdwB555BHmzJkDwI4dO9i0aRO9evU64phBgwYxduxYAMaPH8+2bdvCnvuKK66oL/Paa68BsHjx4vrzT506lR49ekQU5+LFi7n22mvxer1kZGRw1llnsXTpUiZMmMC3vvUtqqurueyyyxg7diyDBw9m69atfPe73+WSSy7hggsuiPj96AhWgwAnQdSUQ8Whro7EGNNGycnJ9cvvv/8+7777Lh9//DErV65k3LhxYTuJxcfH1y97vd5m2y/qyrVUpr3OPPNMFi1aRE5ODjNnzuS5556jR48erFy5krPPPpvHH3+cm2++OSqv3RxLEOBcYgJrhzDmGBIIBCgpKQm779ChQ/To0YOkpCTWr1/PkiVLOvz1p0yZwssvvwzAO++8w4EDByI67owzzuCll16itraWoqIiFi1axMSJE/nyyy/JyMjg29/+NjfffDPLly9n7969BINBvv71r3PfffexfPnyDv85WmKXmMCpQQCU7IS+w7s2FmNMRHr16sWUKVMYPXo0iYmJZGRk1O+bOnUqjz/+OCNGjGDYsGFMnjy5w1//5z//Oddeey1/+ctfOO2008jMzCQQCBz1uMsvv5yPP/6YU045BRHhgQceIDMzkz//+c88+OCD+P1+UlJSeO655ygoKGDWrFkEg0EAfvWrX3X4z9ESUdVOfcFoyc3N1TbPKLd/KzwyDi57DMZe17GBGXOcWrduHSNGjOjqMLpMZWUlXq8Xn8/Hxx9/zG233caKFSu6OqwWhfudicgyVc0NV95qENBQgyje2bVxGGOOGdu3b+eqq64iGAwSFxfHU09Fb7CHrmIJAsCfCAnp1gZhjInYkCFD+Oyzz47Ytm/fPs4777wmZRcsWNDkDqpjgSWIOoEs6wthjGmXXr16dfvLTK1hdzHVsc5yxhhzBEsQdWy4DWOMOYIliDqBTCdBuLeTGWNMrLMEUSeQBVoLh23qUmOMAUsQDeo7y1k7hDHHo7r5GHbu3MmMGTPCljn77LM5Wn+q3//+95SVldWvRzK/RGvMnDmTV199tcPO1x5RTRAiMlVENojIZhGZHWb/D0VkrYisEpEFInJCo/2pIpIvIn+IZpxASIKwdghjjmfZ2dnt+gBunCAimV/iWBW121xFxAs8CnwVyAeWishcVQ2dW/ozIFdVy0TkNuAB4OqQ/b8EFkUrxiPUj8dkneWMabW3ZsPuzzv2nJknw0W/bnb37Nmz6d+/P7fffjsAv/jFL/D5fCxcuJADBw5QXV3Nfffdx/Tp0484btu2bVx66aWsXr2a8vJyZs2axcqVKxk+fDjl5eX15W677TaWLl1KeXk5M2bM4J577uGRRx5h586dnHPOOfTu3ZuFCxfWzy/Ru3dvHn74YZ5++mkAbr75Zn7wgx+wbdu2ZuedOJoFCxbwox/9iJqaGiZMmMBjjz1GfHw8s2fPZu7cufh8Pi644AIeeughXnnlFe655x68Xi9paWksWtT+j85o1iAmAptVdas7XeiLwBG/KVVdqKp1qXgJ0K9un4iMBzKAd6IYY4OUDECsBmHMMeLqq6+uHywP4OWXX+bGG29kzpw5LF++nIULF/If//EftDSc0GOPPUZSUhLr1q3jnnvuYdmyZfX77r//fvLy8li1ahUffPABq1at4nvf+x7Z2dksXLiQhQsXHnGuZcuW8cwzz/DJJ5+wZMkSnnrqqfqOdJHOOxGqoqKCmTNn8tJLL/H555/XTyK0b98+5syZw5o1a1i1ahV33XUX4MyC9/bbb7Ny5Urmzp3bqveyOdHsKJcD7AhZzwcmtVD+JuAtABHxAL8FbgCanfdPRG4BbgEYMGBA+6L1+iClr7VBGNMWLXzTj5Zx48ZRWFjIzp07KSoqokePHmRmZnLnnXeyaNEiPB4PBQUF7Nmzh8zMzLDnWLRoEd/73vcAGDNmDGPGjKnf9/LLL/Pkk09SU1PDrl27WLt27RH7G1u8eDGXX355/bDjV1xxBR9++CHTpk2LeN6JUBs2bGDQoEEMHToUgBtvvJFHH32UO+64g4SEBG666SYuvfRSLr30UsAZXXbmzJlcddVV9fNXtFe3aKQWkRuAXOBBd9N3gHmqmt/Scar6pKrmqmpunz592h9IIBOKLUEYc6y48sorefXVV3nppZe4+uqref755ykqKmLZsmWsWLGCjIyMsPNAHM0XX3zBQw89xIIFC1i1ahWXXHJJm85TJ9J5JyLh8/n49NNPmTFjBm+++SZTp04F4PHHH+e+++5jx44djB8/PuwMeq0VzQRRAPQPWe/nbjuCiJwP/AyYpqqV7ubTgDtEZBvwEPBNEYn+V5SAdZYz5lhy9dVX8+KLL/Lqq69y5ZVXcujQIfr27Yvf72fhwoV8+eWXLR5/5pln8sILLwCwevVqVq1aBUBxcTHJycmkpaWxZ88e3nrrrfpjmpuH4owzzuD111+nrKyMw4cPM2fOHM4444w2/2zDhg1j27ZtbN68GYC//OUvnHXWWZSWlnLo0CEuvvhifve737Fy5UoAtmzZwqRJk7j33nvp06cPO3bsaOn0EYnmJaalwBARGYSTGK4BjhhLW0TGAU8AU1W1sG67ql4fUmYmTkN2k7ugOlwgE/KXRv1ljDEdY9SoUZSUlJCTk0NWVhbXX389X/va1zj55JPJzc1l+PCW53e57bbbmDVrFiNGjGDEiBGMHz8egFNOOYVx48YxfPhw+vfvz5QpU+qPueWWW5g6dWp9W0SdU089lZkzZzJx4kTAaaQeN25cRJeTwklISOCZZ57hyiuvrG+kvvXWW9m/fz/Tp0+noqICVeXhhx8G4Mc//jGbNm1CVTnvvPM45ZRT2vS6oaI6H4SIXAz8HvACT6vq/SJyL5CnqnNF5F3gZKDuus52VZ3W6BwzcRLEHS29Vrvmg6jz/m/g/f8HdxWCL/7o5Y2JYbE+H8SxqFvNB6Gq84B5jbbdHbLcbAN0SJlngWc7OrawUt2+EKV7IL2djd7GGHOMs+G+Q4V2lrMEYYyJottvv52PPvroiG3f//73mTVrVhdF1JQliFB1neVsZjljIqKqiEhXh3FMevTRRzv19drSnNAtbnPtNgLZzrPdyWTMUSUkJLBv3742ffCYzqWq7Nu3j4SEhFYdZzWIUEk9weO3znLGRKBfv37k5+dTVGQjIB8LEhIS6Nev39ELhrAEEUrEph41JkJ+v59BgwZ1dRgmiuwSU2OpliCMMQYsQTRVN7OcMcbEOEsQjQWybTwmY4zBEkRTgUyoKoHKpmOtGGNMLLEE0ZjNLGeMMYAliKZSbW5qY4wBSxBNWQ3CGGMASxBN2XAbxhgDWIJoKj4AcQGrQRhjYp4liHACmdYGYYyJeVFNECIyVUQ2iMhmEWkyI5yI/FBE1orIKhFZICInuNvHisjHIrLG3Xd1NONswhKEMcZEL0GIiBd4FLgIGAlcKyIjGxX7DGe2uDHAq8AD7vYy4JuqOgqYCvxeRNKjFWsTqdmWIIwxMS+aNYiJwGZV3aqqVcCLwPTQAqq6UFXL3NUlQD93+0ZV3eQu7wQKgT5RjPVIdcNt2DDGxpgYFs0EkQPsCFnPd7c15ybgrcYbRWQiEAdsCbPvFhHJE5G8Dh1yOJAFtVVQtr/jzmmMMceYbtFILSI3ALnAg422ZwF/AWaparDxcar6pKrmqmpunz4dWMEIWGc5Y4yJZoIoAPqHrPdztx1BRM4HfgZMU9XKkO2pwD+Bn6nqkijG2ZR1ljPGmKgmiKXAEBEZJCJxwDXA3NACIjIOeAInORSGbI8D5gDPqeqrUYwxvLrOciXWWc4YE7uiliBUtQa4A3gbWAe8rKprROReEZnmFnsQSAFeEZEVIlKXQK4CzgRmuttXiMjYaMXaRH2CsBqEMSZ2RXXKUVWdB8xrtO3ukOXzmznur8Bfoxlbi3zxkNTL2iCMMTGtWzRSd0uBLJs4yBgT0yxBNCdgc1MbY2KbJYjm2NzUxpgYZwmiOYEsOFwItTVdHYkxxnQJSxDNSc0CDTpJwhhjYpAliOZYb2pjTIyzBNGc+pnlLEEYY2KTJYjmBLKdZ6tBGGNilCWI5iT3BvHanUzGmJhlCaI5Hq/NLGeMiWmWIFpiCcIYE8MsQbTEhtswxsQwSxAtseE2jDExzBJESwKZUHEQqsu7OhJjjOl0liBaYp3ljDExLKoJQkSmisgGEdksIrPD7P+hiKwVkVUiskBETgjZd6OIbHIfN0Yzzmal2tSjxpjYFbUEISJe4FHgImAkcK2IjGxU7DMgV1XHAK8CD7jH9gR+DkwCJgI/F5Ee0Yq1WVaDMMbEsGjWICYCm1V1q6pWAS8C00MLqOpCVS1zV5cA/dzlC4H5qrpfVQ8A84GpUYw1PBtuwxgTw6KZIHKAHSHr+e625twEvNWaY0XkFhHJE5G8oqKidoYbRkI6+BKtBmGMiUndopFaRG4AcoEHW3Ocqj6pqrmqmtunT59oBGYTBxljYlY0E0QB0D9kvZ+77Qgicj7wM2Caqla25thOYX0hjDExKpoJYikwREQGiUgccA0wN7SAiIwDnsBJDqEz87wNXCAiPdzG6QvcbZ0v1RKEMSY2RS1BqGoNcAfOB/s64GVVXSMi94rINLfYg0AK8IqIrBCRue6x+4Ff4iSZpcC97rbOF8hyLjGpdsnLG2NMV/FF8+SqOg+Y12jb3SHL57dw7NPA09GLLkKBTKgug4pDkJje1dEYY0yn6RaN1N1awDrLGWNikyWIo7HOcsaYGGUJ4mjqOstZgjDGxBhLEEdjNQhjTIyyBHE0cUmQkGZtEMaYmGMJIhKBLCje2dVRGGNMp7IEEYm6vhDGGBNDLEFEwhKEMSYGWYKIRCATSndDMNjVkRhjTKexBBGJ1GwI1kDZ3q6OxBhjOo0liEhYXwhjTAyyBBGJQLbzbDPLGWNiSMwnCFVlx/4yDhyuar6Q1SCMMTEo5hNEwcFyznhgIW9+3sKHf0pfQOxOJmNMTIn5BJGTnkh6kp+1Ow81X8jrd5JEiXWWM8bEjqgmCBGZKiIbRGSziMwOs/9MEVkuIjUiMqPRvgdEZI2IrBORR0REohQjo7JTWV1Q3HJBm5vaGBNjIkoQIpIsIh53eaiITBMR/1GO8QKPAhcBI4FrRWRko2LbgZnAC42O/QowBRgDjAYmAGdFEmtbjMpOY8PuEqprW+jnEMiyRmpjTEyJtAaxCEgQkRzgHeAbwLNHOWYisFlVt6pqFfAiMD20gKpuU9VVQONPZgUSgDggHvADeyKMtdVGZadSVRtk057S5gsFbG5qY0xsiTRBiKqWAVcAf1TVK4FRRzkmB9gRsp7vbjsqVf0YWAjsch9vq+q6JkGJ3CIieSKSV1RUFMmpwxqVnQbAmpbaIQJZTke5mhbudjLGmONIxAlCRE4Drgf+6W7zRickEJGTgBFAP5ykcq6InNG4nKo+qaq5qprbp0+fNr/eoN7JJMV5WbOzhXaIultdS60dwhgTGyJNED8A/hOYo6prRGQwzjf8lhQA/UPW+7nbInE5sERVS1W1FHgLOC3CY1vN6xFGZKW2XINIdTvLWUO1MSZGRJQgVPUDVZ2mqr9xG6v3qur3jnLYUmCIiAwSkTjgGmBuhHFtB84SEZ/bGH4W0OQSU0canZ3K2p3FBIMavoB1ljPGxJhI72J6QURSRSQZWA2sFZEft3SMqtYAdwBv43y4v+zWPu4VkWnueSeISD5wJfCEiKxxD38V2AJ8DqwEVqrqG234+SI2KjuNw1W1bNt3OHyBuqlH7U4mY0yM8EVYbqSqFovI9TiXe2YDy4AHWzpIVecB8xptuztkeSnOpafGx9UC/yfC2DrEyOxUANbsLGZwn5SmBZJ6gcdvNQhjTMyItA3C717quQyYq6rVOLeiHjeGZgTwe4XVzbVDiNjEQcaYmBJpgngC2AYkA4tE5ATgKF2Pjy1xPg9DMwKsPdqdTDbchjEmRkTaSP2Iquao6sXq+BI4J8qxdbrR2WmsLjiEajOVo1SrQRhjYkekjdRpIvJwXac0EfktTm3iuDIqJ5UDZdXsOlQRvoBdYjLGxJBILzE9DZQAV7mPYuCZaAXVVRp6VDdzmSmQCZXFUNnCkBzGGHOciDRBnKiqP3fHVdqqqvcAg6MZWFcYkRVABFYXNNNQHbDOcsaY2BFpgigXkdPrVkRkClAenZC6TlKcj8G9k1uuQYDd6mqMiQmR9oO4FXhORNLc9QPAjdEJqWuNzknj0y/2h99Z11nOEoQxJgZEehfTSlU9BWd+hjGqOg44N6qRdZFR2ansOlTBvtLKpjtTLUEYY2JHq2aUU9ViVa27/vLDKMTT5Ua31FAdH4C4FGuDMMbEhPZMORqVKUC7WuiQG2EFsqDYOssZY45/7UkQx9VQG3XSk+Lo1yOx+aG/bW5qY0yMaLGRWkRKCJ8IBEiMSkTdwKjs1JZrEDs+6dyAjDGmC7SYIFQ10FmBdCejstN4e80eSiqqCST4j9xZN9yGqjOAnzHGHKfac4npuDU6x2mHWLerpOnOQBbUVkL5gU6OyhhjOpcliDAahtwI0w5hneWMMTEiqglCRKaKyAYR2Swis8PsP1NElotIjYjMaLRvgIi8IyLrRGStiAyMZqyh+gbi6Z0Sz+qCMO0QdcNtdODMctv2Hqa6Nthh5zPGmI4QtQQhIl7gUeAiYCRwrYiMbFRsOzATeCHMKZ4DHlTVEcBEoDBasTYmIm5DdfRrEEUllVzwu0X8z4JNHXI+Y4zpKNGsQUwENruD+1UBLwLTQwuo6jZVXQUc8fXZTSQ+VZ3vlitV1bIoxtrE6JxUNheWUlFde+SODk4Q728opKo2yAuf7qCqxmoRxpjuI5oJIgfYEbKe726LxFDgoIi8JiKficiDbo3kCCJyS90cFUVFRR0QcoNR2WnUBJWNexo1VPvinfmpOyxBFOH1CHtLK5m/dk+HnNMYYzpCd22k9gFnAD8CJuAMLT6zcSFVfVJVc1U1t0+fPh0awKiWelR30MRB1bVBFm0s4vJxOeSkJ/LCp1+2+5zGGNNRopkgCoD+Iev93G2RyAdWuJenaoDXgVM7NryWDeiZRCDBF35uiEBmhwy3sezLA5RU1nD+iL5cN2kAH23ex9Yim4zIGNM9RDNBLAWGiMggEYkDrgHmtuLYdBGpqxacC6yNQozNEhFGZjXTo7qDahALNxTi9wpTTurNlbn98HmEv326vd3nNcaYjhC1BOF+878DeBtYB7ysqmtE5F4RmQYgIhNEJB+4EnhCRNa4x9biXF5aICKf4wzt8VS0Ym3O6Jw01u0qpqbxLaiBLDhcCLU17Tr/wvWFTBjYk0CCn76BBC4YlcEry/KbNowbY0wXiHTCoDZR1XnAvEbb7g5ZXopz6SncsfNx5p/oMqOyU6msCbJ172GGZoSMOhLIBA06SSI1u03nzj9QxsY9pVw5vuEq3PWTTmDe57v51+rdXDYu0vZ8Y4yJju7aSN0tjM5xelQ3aYeoSwrtuJNp4Qbnrqtzhvet33ba4F4M6p3M859YY7UxputZgmjB4N7JxPs8Tdsh6vtCtL0d4v31hfTvmciJfZLrt3k8wrUT+7N02wE27A4zDpQxxnQiSxAt8Hk9DM8K06O6bm7qNt7JVFFdy0db9nLusL5IoxFhZ4zvT5zXwwtWizDGdDFLEEcx2p0bQjVkWozkPiDeNtcglmzdR0V1kLNDLi/V6Zkcx8UnZ/LaZwWUVbWvEdwYY9rDEsRRjMpOo6Sihh37yxs2eryQktHmBPH+hiIS/B5OG9wr7P7rJ59ASUUNb660EWONMV3HEsRR1M0NsbrJZaZMKGn9JSZV5b31hXzlxN4k+JuMHgJA7gk9GNI3xRqrjTFdyhLEUQzNCOD1SNN2iNTsNtUgtu49zPb9ZZwzrPmhQUSE6ycNYGX+ofA9uY0xphNYgjiKBL+XIX1Tms4NEchs022uC9c7o5afPaxp+0Ooy0/tR4Lfw/OfWM9qY0zXsAQRgVHZaeFvdS0/ANXl4Q9qxsINhQzpm0L/nkktlktL9DPtlGz+saKAkorq1oZsjDHtZgkiAqOyU9lbWklhcUXDxrqZ5Vpxmam0soZPv9jPuWHuXgrnukknUFZVy+sr2j8woDHGtJYliAjU96gObYdoQ2e5xZv2Ul2rR728VOeUfmmMyk7l+SVfHnmbrTHGdAJLEBEYkeWMw7QmtB2ifriNyL/dv7+hkEC8j9yBPSIq7zRWn8D63SUs334w4tcxxpiOYAkiAoEEP4N6J7erBqGqLNxQyBlDe+P3Rv62TxubTUq8jxessdoY08ksQURoZHajuSES0sGXEPGdTGt3FbOnuJJzIry8VCcl3sf0sdm8uWonB8uqWnWsMca0hyWICI3OTiP/QHnDh7SIMyZTcWQJou721rNa6P/QnOsnnUBlTZC/L490Qj5jjGm/qCYIEZkqIhtEZLOIzA6z/0wRWS4iNSIyI8z+VBHJF5E/RDPOSNTNUb02tBbRipnlFm4oYky/NPoGElr92iOzUxk3IJ3nP7HGamNM54laghARL/AocBEwErhWREY2KrYdmAm80MxpfgksilaMrVGXIJq0Q0RwienA4So+234g4ruXwrl+0glsLTrMJ1/sb/M5jDGmNaJZg5gIbFbVrapaBbwITA8toKrbVHUVEGx8sIiMBzKAd6IYY8R6pcSTlZZwZDtEaraTII7yrX7RpiKCSsT9H8K5dEwWqQk+61ltjOk00UwQOcCOkPV8d9tRiYgH+C3OvNQtlbtFRPJEJK+oqKjNgUZqVOOG6kAmVJdBZXHzBwHvrS+kV3IcY9z+FG2R4Pfy9fH9+NfqXewtrWzzeYwxJlLdtZH6O8A8Vc1vqZCqPqmquaqa26dP6xt/W2tUdhpbikob5mmomziohXaI2qDywcYizhraB49Hmi0XiesnDaC6Vnklr8W3xRhjOkQ0E0QB0D9kvZ+7LRKnAXeIyDbgIeCbIvLrjg2v9UZlp6IK63a504FGMLPcih0HOVhWfcTc0211Ut8Akwb15G+fbicYtMZqY0x0RTNBLAWGiMggEYkDrgHmRnKgql6vqgNUdSDOZabnVLXJXVCdrW7IjfqhvyPoLLdwfSFej3DmkI6p4Vw/+QS27y9j8ea9HXI+Y4xpTtQShKrWAHcAbwPrgJdVdY2I3Csi0wBEZIKI5ANXAk+IyJpoxdMRstIS6JHkbxhyo/4SU/M1iIUbChk/oAdpSf4OieHCURn0TI6zyYSMMVHni+bJVXUeMK/RtrtDlpfiXHpq6RzPAs9GIbxWExFGZac13OoalwQJac3WIPYUV7BmZzE/mTqsw2KI93m5Mrcff/rwC/YUV5CR2vp+FcYYE4nu2kjdbY3KSWXjnhKqatw7cwNZzfaFeH+D03u6Pbe3hnPdxAHUBpWXlu44emFjjGkjSxCtNCo7jepaZVNhXUN1ZrPDbby3vpCstASGZQQ6NIYTeiVzxpDe/O3T7dTUNulCYowxHcISRCuNdntUN7RDhJ+buqomyOJNezlneF9E2nd7azjXT+xP8aEDfPzZKti7+aid9YwxprWi2gZxPBrYK5nkOK97J1N/pwZRuhuCQfA05Nu8bfs5XFV79NFbVZ3bZEv3QMVBqDgE5QePunxhxSGmJtTAm+55cm+CSx/u+B/YGBOzLEG0kscjjMxOZfXOkDuZgjVQthdSGpLBe+sLifN6mHJSryNPUFoIBcth53LY+ZmzXNbMLasePySmOw3hCemQ1BN6DoKEdCQxnUXbq5i3uYL/OqWE5Lz/hSFfhWEXReXnNsbEHksQbTAqO42X83ZQG1S8qXW3uu46IkEs3FDIOQPjSNrxoZMMCpbDzhVQ7PaCFg/0GQ5Dp0L2WEjr15AI6pKCP8kZVrwZJx4s5+XfvEdGYAB3ZqyBud+F2z6GlOj3KjfGHP8sQbTByOxUyqpq+WLvYU6q6wuxbwtUlcHO5Rz+YilPHfqYwSW74S/uQT0Hw4DJkHMqZI+DzDEQn9KuOHLSEzlnWF+eX7aHO256HP+fzoU3vgfXvNBiYjHGmEhYgmiD0dkNPapPGuT2pn51VkOB+Aw2aX96TJ5JjyGTnISQGNk81K11/eQBLHg2j38V9uRr5/8c3v4pLH8Oxt8YldczxsQOSxBtMCQjhTivhzU7i5l+ynA4/Yfg8dXXDr7zyna27y9j4dSzox7LWUP7clLfFH7zr/Wc/4NbSNz4L/jXf8LA06HXiVF/fWPM8ctuc20Dv9fDsMyAcyeTCJz/czj3ZzDsIsrj+/Dx1n2tnnu6rbwe4ZfTR5N/oJw/vL8FLnsMvD6YcyvU1nRKDMaY45MliDaqmxui8RSgH2/dS1VNkHOGd15D8Wkn9uKKcTk8uWgrmyvT4JKHIf9TWPy7TovBGHP8sQTRRqNy0jhYVk3BwfIjtr+3vpCkOC8TB/Xs1Hh+eskIEv1e7np9NTr66zD66/DBr527p4wxpg0sQbRR3RzVoTPMqSoL1xcx5aTexPu8nRpP75R4fjJ1OEu27uf1FQVwyW8hJQNeu8W5u8oYY1rJEkQbjchMxSOwpuBQ/bZNhaUUHCzv8MH5InXdxAGc0j+d+/+5jkOaApf9EfZtgvl3H/1gY4xpxBJEGyXGeTmxT8oRNYiF653RW88e1jUd1Twe4f7LRrP/cBUPvrMeBp8Nk2+HpU/Bpne7JCZjzLErqglCRKaKyAYR2SwiTWaEE5EzRWS5iNSIyIyQ7WNF5GMRWSMiq0Tk6mjG2VajslMb5obAaX8YkZVKVlpil8U0OieNb542kOc/2c6KHQfhvLuhzwj4x3fg8L4ui8sYc+yJWoIQES/wKHARMBK4VkRGNiq2HZgJvNBoexnwTVUdBUwFfi8i6dGKta1G56Sxp7iSvaWVFFdUk/flAc7potpDqP+4YCh9UuK56/XPqfXGw9efgrL98Ob3bdRXY0zEolmDmAhsVtWtqloFvAhMDy2gqttUdRUQbLR9o6pucpd3AoVA13/yNjIypKF68aa91Aa1y9ofQgUS/PzXpSNZXVDMXz7eBpknw7l3wbo3YOXfujo8Y8wxIpoJIgcInfIs393WKiIyEYgDtoTZd4uI5IlIXlFRUZsDbatR7pAbqwsO8d76QtIS/Yztn97pcYRz6ZgszhjSm9++s5HC4gr4yndhwFdg3k/gwLauDs8Ycwzo1o3UIpKFM9zdLFVtMnWaqj6pqrmqmtunT+dXMNIS/fTvmcjqgkO8v6GIM4f2weftHm+piHDv9NFU1gb55T/XgccLlz/u7JxzGwRruzZAY0y3F81PswKgf8h6P3dbREQkFfgn8DNVXdLBsXWY0dlpLFhfyN7SSs7txN7TkRjUO5nbzjqRN1bu5MNNRdDjBLj4Qdj+b/j3Ix3yGhXVtTzxwRZeXrqDw5U2tIcxx5NoJoilwBARGSQiccA1wNxIDnTLzwGeU9VXoxhju43KTqWqJogInDmkeyUIgNvOPpGBvZK4+x9rqKyphVOugRHT4L37YdfKdp17T3EF1zy5hF+9tZ6f/H0VE+9/l9l/X8Vn2w80GYLEGHPsiVqCUNUa4A7gbWAd8LKqrhGRe0VkGoCITBCRfOBK4AkRWeMefhVwJjBTRFa4j7HRirU96tohxvZPp1dKfBdH01SC38u900fzxd7DPPHBVmdwwa/9NyT1cnpZV5cf/SRhLN9+gK/9z2I27inh8RtO5e+3ncYlY7L4x4qdXP7Hf3Ph7xfxv4u/YP/hqg7+iYwxnUWOl296ubm5mpeX1+mvW1RSyeRfLeCHXx3K7eec1OmvH6nbX1jO/LV7mH/nmZzQKxk2vwt//TpM/g5M/VWrzvVK3g5+Nmc1GWnxPPXNXIZnptbvK6mo5s1Vu3hp6Q5W7DhInNfDV0dlcM2E/kw5sTcej01kZEx3IiLLVDU37D5LEO23ZuchTuqb0unjL7XGnuIKzvvtB4w/oQfPzpqAiMC8H8OnT8I3XocTzznqOWpqg9w/bx3PfLSNKSf14g/XnkqP5Lhmy6/fXcxLS3cw57MCDpZVk5OeyFW5/bkytx/Z6V3XmdAY08AShAHg6cVfcO+ba/nj9ady8clZziB+T54FlaVw20eQ1PwItAcOV3H7C8v595Z9fGvKIH568fCI79iqrKnlnTV7eGnpDhZv3lvfXnPNhP6cNyKDOF/3uPPLmFhkCcIATg1g2h8+Yv/hKt79j7NIiffBzs/gT+dDr5Pgymeh74gmx63fXcy3n8tjz6FK7r98NFfm9m968gjt2F/GK3k7eDkvn93FFfRKjuOKU3P49pmD6RtIaMdPZ4xpi5YShH11iyE+r4f7Lh/NnpIKfjd/o7Mxexxc/6ozFMeT58CyZ48YjuNfq3dxxR//TWV1kBf/z+R2JQeA/j2T+OEFw/ho9rk8M2sCEwb25JmPtnHNE0vYW1rZrnMbYzqWJYgYc+qAHlwzYQDP/nsba+tGoj3xHLh1MQyYBG98H/5+E8HyQzw8fyO3/nU5QzMCvPHd0zl1QI8Oi8PrEc4Z1pfHvzGev90ymZ2Hyrnx6U8prqjusNcwxrSPJYgY9H+nDiM90c9dr39OMOjWFgIZcMMcOPe/0DWvs/e3k1n43tt8/dR+vHjLZDJSo3f5Z8LAnjx2w3g27C7h5j/nUVFtvbyN6Q4sQcSg9KQ4/vPiESzffpCX8kKGy/J42DbyNu5Mup+a6kpeT/gFD/VfTEInNCKfM6wvD189lqXb9vOd55dTXdtkZBVjTCezBBGjvn5qDhMH9eTXb61nn3vtf9HGIqb9YTHvl5/IjqvewTv0AuTtn8LfrnXaKKJs2inZ/HL6aN5bX8iPXlnZULsxxnQJSxAxSkS477LRHK6s4VdvredPH25l5jOfkpWWyNzbT2fSqJPgmhdg6m9gywJ4/HT48uOox3XD5BP48YXD+MeKnfzijTU2ZIcxXcjX1QGYrjM0I8DNZwzm8Q+ckdSnjsrkt1edQnK8+2chApNvdRqvX5kFz14C5/wnnP5DZ3TY9ji8z0k8m9+FbR/BgMlw4f+DQAbfOftEisureWLRVtIT/fzwgmHt/EmNMW1hCSLGfe+8k1iz8xCTBvXkO2efFH4ojOxx8H8WwZt3wnv3wRcfwhVPOQ3bkQrWOn0uNs2HzfOhYDmgzphQ/Sc5kxltmg/n/xwZP4vZFw3nYFk1j7y3mdREPzefMbjDfmZjTGSso5yJnCp89hdn0qH4FLj8CTjpvObLH94Lmxc4CWHzAijfDwjkjIchX4WTvgrZY53ayN7N8M874YtF0G8ifO331PYZyXf/tpx5n+/mgRljuKqdfTCMMU1ZT2rTsQrXOZecitbB6XfCOT8Dr9+pJRQsa6gl7FyBU0voDSed7ySFE89tfkgPVVj5Irz9U6gshq98l8op/8HNL6zlo817+eP145k6OrMzf1JjjnuWIEzHqyqDf82G5X92vvGn94ct70H5ARAP5OS6tYTzIWsseFpxP8ThfTD/bljxV0g/gYqpD3Hde8msLijmmVkTmHJS76j9WMbEGksQJno+fxXe/CH44t1awvkw+JwWB/6L2BcfOu0e+zZRNeIKbiy4jJUH43n+5kmM68Be3W1RXRukrKqW8qpayqtryUiNJynOmvTMsafLEoSITAX+G/ACf1LVXzfafybwe2AMcE3o7HEiciNwl7t6n6r+uaXXsgTRhWprnFpDa2oJkaqphMW/gw9/S9CXyG/1Ol6oPpuXbp3C0IxAu06tqny5r4yPt+5jT3EF5VW1lNU/auoTQFl1w/LhyhrKq2uprj3y/8bnEUbnpDFpUE8mDupJ7gk9SUvytys+YzpDlyQIEfECG4GvAvk4U5Beq6prQ8oMBFKBHwFz6xKEiPQE8oBcQIFlwHhVPdDc61mCOM7t3eTUJrZ9yEoZxq+9t/LAd66hf8+kVp3mwOEqPtqyl4827+XDTXvJP9Awo168z0NSnJekOB+JcV6S4rwk+r0kx7vrfndbnI/kOK9bxkeC38OWolI+/WI/K3ccoqrWmYJ2eGZqfcKYMLAnfQJdP+OgqlJYUsnGPSVs2F3Cpj2lbCwsIS3Rz+TBvZg8uBejs1MjHsrdHPtaShDRrBNPBDar6lY3iBeB6UB9glDVbe6+xuMqXAjMV9X97v75wFTgb1GM13RnvYfAjW/Ayr8x6l8/5bmKH/HiYx9x4a0P0bdX85ebKqprWfblARZv3sviTXtZvfMQqhCI9zH5xF58+4zBnD6kNwN7JePtgNnuKqprWbHjIJ9+sZ9Pv9jPS0t38Oy/twEwuE/yEQmjX4/WJbfW2n+4ykkChQ3JYMOeEg6VNwyI2DM5jiF9U9ixv4z3NxQBkBLvI3dgD0sYJqoJIgcIGeiHfGBSO47NaVxIRG4BbgEYMGBA26I0xw4RGHsdviEXsu/1n/CNTa+y89HFHP76/5A86gIAgkFl3e7i+hrC0m37qagO4vMI4wak84PzhnL6kF6c0i89Kh96CX5v/QcrOG0VqwsO1SeMf67axd8+df60c9ITmegmjOz0RDwCXhE8HsHrETwCHqlbDn0+crvHI+w+VM6G3aVs3FNS/9hb2jAfeCDBx7CMAJeMyWJo3xSGZgYYmhGgd8g86oUlFXyydT+ffLGPJVv38+u31gOQHOcld2BP9+fqyeicNPyWMGJCNC8xzQCmqurN7vo3gEmqekeYss8Cb4ZcYvoRkKCq97nr/wWUq+pDzb2eXWKKPZ9/+AbJ7/6YwbKLw4lZFGpPtlQE2FGTxm7tiaZmkd1vMEOHDGHMiBGkBNK6OmSCQWXDnpL6hPHJ1n1UHT7AYRKopf1T1ibFeRmSEWBo3xSGZQYYkhFgWEaAjNR4Z5rZVigqqXSTxT4+2bqfTYWlQMsJIxhUSqtqKKmooaSimuJy57mkoobikOfG29MS/YzISmV4ZoCRWakM6p1stRacS4JVtUEqa4JUVNdSWR2ksqaWimpnW2V1LZU1QZLivExyv5S0VlddYioAQns29XO3RXrs2Y2Ofb9DojLHjZPP+BrvpJ7MC688yIjSbfTzHeLkuJ2c5fscf81hKAc2uY95QHwaBDIhNQsC2e6z+4gPOHdieeOcZ19Cw3L9c3zLDfGqUF0GZfucToJl+53lkIenbB8jyvYzomwfN5btQ4P7kIRaan2JHO51MqW9x1LceyzFPU+hPDGDYFCpDSq1qs6yKkGlyfbeKfEMywyQk54Yvjd8G/QJxHPpmGwuHZMNOAnj0y/2Ownji3385l8NNYz0pDiKK6oprazhaN8543weUhN8pCb4CST4SEnwsftQBR9t3lvf+B/n8zA0I4XhmamMyEplRGaA4Vmp9GxhDvTuprKmloNl1e6jigNl1Rwqd54P1i0fruZgeRWHK2udBFATmgCc9Ui+w4/tn87rt0/p8J8hmjUIH04j9Xk4H/hLgetUdU2Yss9yZA2iJ07D9KlukeU4jdTNDilqNYjYtSr/IHE+D8MyAg3fkitLoGQ3FO+Ekl3u824o2QnFu5zl0t0QrGndi3l8TqLwxR35XJcYairCHyceZ1iR+kfPhuXEHnAoH/KXwq5VEHTbCFJznF7n/XKh3wSnP0lcdNstWmNvaWV9LaiksobUBD+pCT4CCX5SE53nQEgiqFtP8IevKVXVBNlSVMr63cWs21XCul3Oc+hMgxmp8Q1JIyvACLe24fd6UFVKK2sorqihuLyaQ+XVFJdX16/X1VwO1S837KsJBvF5PHg9gs8r+DyCz+PB53Uu5fkb7fN6PPjdfT6PUFUbdD/snWRwsKya8hbmNfF7hfSkONIT/aQn+UmO95Hg85Lg9xBf9+z3kuBznuNDnhPq1kOW0xL9DO6T0qbfY1fe5noxzm2sXuBpVb1fRO4F8lR1rohMAOYAPYAKYLeqjnKP/RbwU/dU96vqMy29liUI02rBIBwuchJIValzS21tlfNcUwm1lUdua/Jc2VA2LuXID/3GySAhPbLbgGsqYffnTrLIz4OCPDiwzdknXsgY6SSLnFwncfQaEp3bi7uRopJK1u8uZn1d0thdwubCkobahtdDYpyXkopqjjZCfCDeR2qim7gS/U5SS/QR5/VQE1RqaoPUuLWz6lqlNhh0t7vbgkFq3fWakH1xPg89kvykJcbRI8n50E9PiiMt0U+PpDjSk/zOcrKTFJLivK2+5Bct1lHOmGNZaZEzhEn+UidhFCx3hiIB57JZzqmQkgEaDHnUus/asC1Y26hMyMPrd5JcXLLz8Cc3LMclu/uSQpYblfMndWqiqqoJsnVvaX3SqKiuJS3Rf8SHvvPsrKcl+klJ8HXInWrHG0sQxhxPgkHYu9FJFnW1jIpi5zJW6MPjdZclZLu3aTkRqK2GqsNOTaq6rGG5Nbzx4E9wkoUvAfyJzsOX6G6vW67b7pb1Jzhx1FY7l/yCNc0sVzudMuuWg7XuvmrneG+ck+i8cS0sN7c/zomnrv3Jn+Cu121LDGmbOkrTbV1bVNXhIx/VdctlzntbddgtV+ocU/d6oa/tTzzy9VtaP1pczeiqRmpjTDR4PNB3uPMYd0P0XicYhJryph90jT/cKkuhutwpW13hbK+pcLZVlzvLZfsblXGXa6vCv7bHBx6/8yHu8TrLHp/zIVi/HLIPdc5VW93oudFyRxBvyAezm0A06H7wu+8Lrfji7Ut0ElxNuXOetsgZD99+r23HtsAShDEmPI+n4VJStARrnWSBNiQFj9ep1XQ0VbdG0ihx1FQ6yzUVIY9KN4lVNqzXhKxXVxy5XTwNl9/8SY0uzzV32a7u0lxIo31tdcjrljeKo4X15OgMYGkJwhjTdTxeZ26RziDiXlbyA1FMeu1RH1/3cHzf/mCMMabNLEEYY4wJyxKEMcaYsCxBGGOMCcsShDHGmLAsQRhjjAnLEoQxxpiwLEEYY4wJ67gZi0lEioAv23GK3sDeDgonGiy+9rH42sfia5/uHN8Jqton3I7jJkG0l4jkNTdgVXdg8bWPxdc+Fl/7dPf4mmOXmIwxxoRlCcIYY0xYliAaPNnVARyFxdc+Fl/7WHzt093jC8vaIIwxxoRlNQhjjDFhWYIwxhgTVkwlCBGZKiIbRGSziMwOsz9eRF5y938iIgM7Mbb+IrJQRNaKyBoR+X6YMmeLyCERWeE+7u6s+EJi2CYin7uv32QScHE84r6Hq0Tk1E6MbVjIe7NCRIpF5AeNynTqeygiT4tIoYisDtnWU0Tmi8gm97lHM8fe6JbZJCI3dmJ8D4rIevf3N0dE0ps5tsW/hSjG9wsRKQj5HV7czLEt/r9HMb6XQmLbJiIrmjk26u9fu6lqTDwAL7AFGAzEASuBkY3KfAd43F2+BnipE+PLAk51lwPAxjDxnQ282cXv4zagdwv7LwbeAgSYDHzShb/v3TidgLrsPQTOBE4FVodsewCY7S7PBn4T5riewFb3uYe73KOT4rsA8LnLvwkXXyR/C1GM7xfAjyL4/bf4/x6t+Brt/y1wd1e9f+19xFINYiKwWVW3qmoV8CIwvVGZ6cCf3eVXgfNEojE5blOquktVl7vLJcA6IKczXruDTQeeU8cSIF1EsrogjvOALarant717aaqi4D9jTaH/p39GbgszKEXAvNVdb+qHgDmA1M7Iz5VfUdVa9zVJUC/jn7dSDXz/kUikv/3dmspPvez4yrgbx39up0llhJEDrAjZD2fph/A9WXcf5BDQK9OiS6Ee2lrHPBJmN2nichKEXlLREZ1bmQAKPCOiCwTkVvC7I/kfe4M19D8P2ZXv4cZqrrLXd4NZIQp013ex2/h1AjDOdrfQjTd4V4Ce7qZS3Td4f07A9ijqpua2d+V719EYilBHBNEJAX4O/ADVS1utHs5ziWTU4D/AV7v5PAATlfVU4GLgNtF5MwuiKFFIhIHTANeCbO7O7yH9dS51tAt7zUXkZ8BNcDzzRTpqr+Fx4ATgbHALpzLON3RtbRce+j2/0uxlCAKgP4h6/3cbWHLiIgPSAP2dUp0zmv6cZLD86r6WuP9qlqsqqXu8jzALyK9Oys+93UL3OdCYA5OVT5UJO9ztF0ELFfVPY13dIf3ENhTd9nNfS4MU6ZL30cRmQlcClzvJrEmIvhbiApV3aOqtaoaBJ5q5nW7+v3zAVcALzVXpqvev9aIpQSxFBgiIoPcb5jXAHMblZkL1N0tMgN4r7l/jo7mXq/8X2Cdqj7cTJnMujYREZmI8/vrzASWLCKBumWcxszVjYrNBb7p3s00GTgUcjmlszT7za2r30NX6N/ZjcA/wpR5G7hARHq4l1AucLdFnYhMBX4CTFPVsmbKRPK3EK34Qtu0Lm/mdSP5f4+m84H1qpofbmdXvn+t0tWt5J35wLnDZiPO3Q0/c7fdi/OPAJCAc1liM/ApMLgTYzsd51LDKmCF+7gYuBW41S1zB7AG546MJcBXOvn9G+y+9ko3jrr3MDRGAR513+PPgdxOjjEZ5wM/LWRbl72HOIlqF1CNcx38Jpx2rQXAJuBdoKdbNhf4U8ix33L/FjcDszoxvs041+/r/g7r7uzLBua19LfQSfH9xf3bWoXzoZ/VOD53vcn/e2fE525/tu5vLqRsp79/7X3YUBvGGGPCiqVLTMYYY1rBEoQxxpiwLEEYY4wJyxKEMcaYsCxBGGOMCcsShDHdgDvK7JtdHYcxoSxBGGOMCcsShDGtICI3iMin7hj+T4iIV0RKReR34szjsUBE+rhlx4rIkpB5FXq4208SkXfdAQOXi8iJ7ulTRORVdy6G5ztrJGFjmmMJwpgIicgI4GpgiqqOBWqB63F6b+ep6ijgA+Dn7iHPAf9XVcfg9Pyt2/488Kg6AwZ+BacnLjgj+P4AGInT03ZKlH8kY1rk6+oAjDmGnAeMB5a6X+4TcQbaC9IwKNtfgddEJA1IV9UP3O1/Bl5xx9/JUdU5AKpaAeCe71N1x+5xZyEbCCyO+k9lTDMsQRgTOQH+rKr/ecRGkf9qVK6t49dUhizXYv+fpovZJSZjIrcAmCEifaF+bukTcP6PZrhlrgMWq+oh4ICInOFu/wbwgTqzBeaLyGXuOeJFJKkzfwhjImXfUIyJkKquFZG7cGYB8+CM4Hk7cBiY6O4rxGmnAGco78fdBLAVmOVu/wbwhIjc657jyk78MYyJmI3makw7iUipqqZ0dRzGdDS7xGSMMSYsq0EYY4wJy2oQxhhjwrIEYYwxJixLEMYYY8KyBGGMMSYsSxDGGGPC+v/0iW2GAqrdeAAAAABJRU5ErkJggg==\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.104\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 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": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "INFO - 2021-02-02 16:35:30,802 [phygnn.py:773] : Epoch 0 train loss: 1.87e-01 val loss: 2.74e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,871 [phygnn.py:773] : Epoch 1 train loss: 8.40e-02 val loss: 1.34e-01 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,937 [phygnn.py:773] : Epoch 2 train loss: 1.35e-01 val loss: 9.75e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:30,998 [phygnn.py:773] : Epoch 3 train loss: 1.15e-01 val loss: 9.35e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,063 [phygnn.py:773] : Epoch 4 train loss: 9.33e-02 val loss: 8.51e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,127 [phygnn.py:773] : Epoch 5 train loss: 6.79e-02 val loss: 5.95e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,203 [phygnn.py:773] : Epoch 6 train loss: 7.08e-02 val loss: 4.92e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,277 [phygnn.py:773] : Epoch 7 train loss: 4.89e-02 val loss: 4.68e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,354 [phygnn.py:773] : Epoch 8 train loss: 4.64e-02 val loss: 5.34e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,443 [phygnn.py:773] : Epoch 9 train loss: 4.07e-02 val loss: 3.80e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,521 [phygnn.py:773] : Epoch 10 train loss: 3.65e-02 val loss: 3.84e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,597 [phygnn.py:773] : Epoch 11 train loss: 3.55e-02 val loss: 4.19e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,682 [phygnn.py:773] : Epoch 12 train loss: 3.77e-02 val loss: 3.61e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,763 [phygnn.py:773] : Epoch 13 train loss: 3.41e-02 val loss: 3.82e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,842 [phygnn.py:773] : Epoch 14 train loss: 3.59e-02 val loss: 3.43e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:31,922 [phygnn.py:773] : Epoch 15 train loss: 3.66e-02 val loss: 3.32e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:32,000 [phygnn.py:773] : Epoch 16 train loss: 3.21e-02 val loss: 3.17e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:32,083 [phygnn.py:773] : Epoch 17 train loss: 3.29e-02 val loss: 3.49e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:32,166 [phygnn.py:773] : Epoch 18 train loss: 3.58e-02 val loss: 3.27e-02 for \"phygnn\"\n", "INFO - 2021-02-02 16:35:32,234 [phygnn.py:773] : Epoch 19 train loss: 3.61e-02 val loss: 3.67e-02 for \"phygnn\"\n" ] } ], "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", " n_features=2, n_labels=1)\n", "model.fit(x, y_noise, p, n_batch=4, n_epoch=20)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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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.015\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 loss function example\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": 12, "metadata": {}, "outputs": [], "source": [ "def p_fun_bad(model, y_true, y_predicted, 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": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ERROR - 2021-02-02 16:35:32,909 [phygnn.py:491] : 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[0;31m----------------------------------------------------\u001b[0m", "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mloss_weights\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m n_features=2, n_labels=1)\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_noise\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/code/phygnn/phygnn/phygnn.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, p, n_batch, n_epoch, shuffle, validation_split, p_kwargs, run_preflight, return_diagnostics)\u001b[0m\n\u001b[1;32m 756\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 757\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_loss_weights\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mrun_preflight\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 758\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpreflight_p_fun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_val\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_val\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp_val\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 759\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 760\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/code/phygnn/phygnn/phygnn.py\u001b[0m in \u001b[0;36mpreflight_p_fun\u001b[0;34m(self, x, y_true, p, p_kwargs)\u001b[0m\n\u001b[1;32m 490\u001b[0m 'Please use only tensor math in the p_fun.')\n\u001b[1;32m 491\u001b[0m \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merror\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0memsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 492\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0memsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 493\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'p_fun passed preflight check.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mRuntimeError\u001b[0m: The input p_fun was not differentiable! Please use only tensor math in the p_fun." ] } ], "source": [ "model = PhysicsGuidedNeuralNetwork(p_fun=p_fun_bad, \n", " hidden_layers=hidden_layers, \n", " loss_weights=(0.5, 0.5),\n", " n_features=2, n_labels=1)\n", "model.fit(x, y_noise, p)" ] }, { "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.8.5" } }, "nbformat": 4, "nbformat_minor": 2 }