EntropyTrainer-checkpoint.ipynb 134 KB
 steffen.schotthoefer committed Aug 05, 2020 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 { "cells": [ { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Ufb5Oc9LHkOd" }, "source": [ "# Test NN for Entropy Closure #\n", "\n", "Test Data is generated from RTSN code" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Zs9ZGENoItzq" }, "source": [ "Load all needed modules" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Imports\n", "import pandas as pd\n", "import random # for generating random numbers\n", "import numpy as np\n", "import tensorflow as tf\n", "from tensorflow import keras\n", "import matplotlib.pyplot as plt # MATLAB like plotting routines\n", "from sklearn.preprocessing import normalize" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Z9bPtTIHIxnR" }, "source": [ "Load and preprocess Training Data" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 78, "resources": { "http://localhost:8080/nbextensions/google.colab/files.js": { "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7CgpmdW5jdGlvbiBfdXBsb2FkRmlsZXMoaW5wdXRJZCwgb3V0cHV0SWQpIHsKICBjb25zdCBzdGVwcyA9IHVwbG9hZEZpbGVzU3RlcChpbnB1dElkLCBvdXRwdXRJZCk7CiAgY29uc3Qgb3V0cHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG91dHB1dElkKTsKICAvLyBDYWNoZSBzdGVwcyBvbiB0aGUgb3V0cHV0RWxlbWVudCB0byBtYWtlIGl0IGF2YWlsYWJsZSBmb3IgdGhlIG5leHQgY2FsbAogIC8vIHRvIHVwbG9hZEZpbGVzQ29udGludWUgZnJvbSBQeXRob24uCiAgb3V0cHV0RWxlbWVudC5zdGVwcyA9IHN0ZXBzOwoKICByZXR1cm4gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpOwp9CgovLyBUaGlzIGlzIHJvdWdobHkgYW4gYXN5bmMgZ2VuZXJhdG9yIChub3Qgc3VwcG9ydGVkIGluIHRoZSBicm93c2VyIHlldCksCi8vIHdoZXJlIHRoZXJlIGFyZSBtdWx0aXBsZSBhc3luY2hyb25vdXMgc3RlcHMgYW5kIHRoZSBQeXRob24gc2lkZSBpcyBnb2luZwovLyB0byBwb2xsIGZvciBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcC4KLy8gVGhpcyB1c2VzIGEgUHJvbWlzZSB0byBibG9jayB0aGUgcHl0aG9uIHNpZGUgb24gY29tcGxldGlvbiBvZiBlYWNoIHN0ZXAsCi8vIHRoZW4gcGFzc2VzIHRoZSByZXN1bHQgb2YgdGhlIHByZXZpb3VzIHN0ZXAgYXMgdGhlIGlucHV0IHRvIHRoZSBuZXh0IHN0ZXAuCmZ1bmN0aW9uIF91cGxvYWRGaWxlc0NvbnRpbnVlKG91dHB1dElkKSB7CiAgY29uc3Qgb3V0cHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG91dHB1dElkKTsKICBjb25zdCBzdGVwcyA9IG91dHB1dEVsZW1lbnQuc3RlcHM7CgogIGNvbnN0IG5leHQgPSBzdGVwcy5uZXh0KG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSk7CiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXh0LnZhbHVlLnByb21pc2UpLnRoZW4oKHZhbHVlKSA9PiB7CiAgICAvLyBDYWNoZSB0aGUgbGFzdCBwcm9taXNlIHZhbHVlIHRvIG1ha2UgaXQgYXZhaWxhYmxlIHRvIHRoZSBuZXh0CiAgICAvLyBzdGVwIG9mIHRoZSBnZW5lcmF0b3IuCiAgICBvdXRwdXRFbGVtZW50Lmxhc3RQcm9taXNlVmFsdWUgPSB2YWx1ZTsKICAgIHJldHVybiBuZXh0LnZhbHVlLnJlc3BvbnNlOwogIH0pOwp9CgovKioKICogR2VuZXJhdG9yIGZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBiZXR3ZWVuIGVhY2ggYXN5bmMgc3RlcCBvZiB0aGUgdXBsb2FkCiAqIHByb2Nlc3MuCiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIGlucHV0IGZpbGUgcGlja2VyIGVsZW1lbnQuCiAqIEBwYXJhbSB7c3RyaW5nfSBvdXRwdXRJZCBFbGVtZW50IElEIG9mIHRoZSBvdXRwdXQgZGlzcGxheS4KICogQHJldHVybiB7IUl0ZXJhYmxlPCFPYmplY3Q+fSBJdGVyYWJsZSBvZiBuZXh0IHN0ZXBzLgogKi8KZnVuY3Rpb24qIHVwbG9hZEZpbGVzU3RlcChpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IGlucHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlucHV0SWQpOwogIGlucHV0RWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlOwoKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIG91dHB1dEVsZW1lbnQuaW5uZXJIVE1MID0gJyc7CgogIGNvbnN0IHBpY2tlZFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgaW5wdXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7CiAgICAgIHJlc29sdmUoZS50YXJnZXQuZmlsZXMpOwogICAgfSk7CiAgfSk7CgogIGNvbnN0IGNhbmNlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpOwogIGlucHV0RWxlbWVudC5wYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKGNhbmNlbCk7CiAgY2FuY2VsLnRleHRDb250ZW50ID0gJ0NhbmNlbCB1cGxvYWQnOwogIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgY2FuY2VsLm9uY2xpY2sgPSAoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9OwogIH0pOwoKICAvLyBXYWl0IGZvciB0aGUgdXNlciB0byBwaWNrIHRoZSBmaWxlcy4KICBjb25zdCBmaWxlcyA9IHlpZWxkIHsKICAgIHByb21pc2U6IFByb21pc2UucmFjZShbcGlja2VkUHJvbWlzZSwgY2FuY2VsUHJvbWlzZV0pLAogICAgcmVzcG9uc2U6IHsKICAgICAgYWN0aW9uOiAnc3RhcnRpbmcnLAogICAgfQogIH07CgogIGNhbmNlbC5yZW1vdmUoKTsKCiAgLy8gRGlzYWJsZSB0aGUgaW5wdXQgZWxlbWVudCBzaW5jZSBmdXJ0aGVyIHBpY2tzIGFyZSBub3QgYWxsb3dlZC4KICBpbnB1dEVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlOwoKICBpZiAoIWZpbGVzKSB7CiAgICByZXR1cm4gewogICAgICByZXNwb25zZTogewogICAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgICAgfQogICAgfTsKICB9CgogIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykgewogICAgY29uc3QgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpOwogICAgbGkuYXBwZW5kKHNwYW4oZmlsZS5uYW1lLCB7Zm9udFdlaWdodDogJ2JvbGQnfSkpOwogICAgbGkuYXBwZW5kKHNwYW4oCiAgICAgICAgYCgke2ZpbGUudHlwZSB8fCAnbi9hJ30pIC0gJHtmaWxlLnNpemV9IGJ5dGVzLCBgICsKICAgICAgICBgbGFzdCBtb2RpZmllZDogJHsKICAgICAgICAgICAgZmlsZS5sYXN0TW9kaWZpZWREYXRlID8gZmlsZS5sYXN0TW9kaWZpZWREYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ24vYSd9IC0gYCkpOwogICAgY29uc3QgcGVyY2VudCA9IHNwYW4oJzAlIGRvbmUnKTsKICAgIGxpLmFwcGVuZENoaWxkKHBlcmNlbnQpOwoKICAgIG91dHB1dEVsZW1lbnQuYXBwZW5kQ2hpbGQobGkpOwoKICAgIGNvbnN0IGZpbGVEYXRhUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgICAgIHJlYWRlci5vbmxvYWQgPSAoZSkgPT4gewogICAgICAgIHJlc29sdmUoZS50YXJnZXQucmVzdWx0KTsKICAgICAgfTsKICAgICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGUpOwogICAgfSk7CiAgICAvLyBXYWl0IGZvciB0aGUgZGF0YSB0byBiZSByZWFkeS4KICAgIGxldCBmaWxlRGF0YSA9IHlpZWxkIHsKICAgICAgcHJvbWlzZTogZmlsZURhdGFQcm9taXNlLAogICAgICByZXNwb25zZTogewogICAgICAgIGFjdGlvbjogJ2NvbnRpbnVlJywKICAgICAgfQogICAgfTsKCiAgICAvLyBVc2UgYSBjaHVua2VkIHNlbmRpbmcgdG8gYXZvaWQgbWVzc2FnZSBzaXplIGxpbWl0cy4gU2VlIGIvNjIxMTU2NjAuCiAgICBsZXQgcG9zaXRpb24gPSAwOwogICAgd2hpbGUgKHBvc2l0aW9uIDwgZmlsZURhdGEuYnl0ZUxlbmd0aCkgewogICAgICBjb25zdCBsZW5ndGggPSBNYXRoLm1pbihmaWxlRGF0YS5ieXRlTGVuZ3RoIC0gcG9zaXRpb24sIE1BWF9QQVlMT0FEX1NJWkUpOwogICAgICBjb25zdCBjaHVuayA9IG5ldyBVaW50OEFycmF5KGZpbGVEYXRhLCBwb3NpdGlvbiwgbGVuZ3RoKTsKICAgICAgcG9zaXRpb24gKz0gbGVuZ3RoOwoKICAgICAgY29uc3QgYmFzZTY0ID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNodW5rKSk7CiAgICAgIHlpZWxkIHsKICAgICAgICByZXNwb25zZTogewogICAgICAgICAgYWN0aW9uOiAnYXBwZW5kJywKICAgICAgICAgIGZpbGU6IGZpbGUubmFtZSwKICAgICAgICAgIGRhdGE6IGJhc2U2NCwKICAgICAgICB9LAogICAgICB9OwogICAgICBwZXJjZW50LnRleHRDb250ZW50ID0KICAgICAgICAgIGAke01hdGgucm91bmQoKHBvc2l0aW9uIC8gZmlsZURhdGEuYnl0ZUxlbmd0aCkgKiAxMDApfSUgZG9uZWA7CiAgICB9CiAgfQoKICAvLyBBbGwgZG9uZS4KICB5aWVsZCB7CiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICB9CiAgfTsKfQoKc2NvcGUuZ29vZ2xlID0gc2NvcGUuZ29vZ2xlIHx8IHt9OwpzY29wZS5nb29nbGUuY29sYWIgPSBzY29wZS5nb29nbGUuY29sYWIgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYi5fZmlsZXMgPSB7CiAgX3VwbG9hZEZpbGVzLAogIF91cGxvYWRGaWxlc0NvbnRpbnVlLAp9Owp9KShzZWxmKTsK", "headers": [ [ "content-type", "application/javascript" ] ], "ok": true, "status": 200, "status_text": "OK" } } }, "colab_type": "code", "id": "tbAk6wxEJt8J", "outputId": "43ee9205-39a1-4f74-dd6a-1a2ce5c89030" }, "outputs": [], "source": [ "def preprocess_data(filename):\n", " # reading csv file\n", " dataFrameInput = pd.read_csv(filename) #outputs a dataframe object\n", "\n", " idx = 0\n", " xDataList = list()\n", " yDataList = list()\n", " data = dataFrameInput.values # numpy array\n", "\n", " ## Somehow t = 0 has an odd number of elements, just cut it out\n", "\n", " for row in data:\n", " if (row[2] > 0):\n", " if (idx % 2 == 0):\n", " xDataList.append(row)\n", " else:\n", " yDataList.append(row)\n", "\n", " idx = idx + 1\n", "\n", " # merge the lists\n", " DataList = list()\n", " for rowX, rowY in zip(xDataList, yDataList):\n", " DataList.append([rowX, rowY])\n", "\n", " # Shuffle data\n", "\n", " random.shuffle(DataList)\n", "\n", " DataArray = np.asarray(DataList)\n", " #print(DataArray.shape)\n", "\n", " # Strip off header information, i.e. the first 3 cols\n", " DataArraySlim = DataArray[:, :, 3:]\n", " #print(DataArraySlim.shape)\n", "\n",  Steffen Schotthöfer committed Aug 06, 2020 115  " '''\n",  steffen.schotthoefer committed Aug 05, 2020 116 117 118 119 120 121 122 123 124 125 126  " # split in train and test data (ratio 4:1)\n", " DataTrain = DataArraySlim[:4 * int(DataArraySlim.shape[0] / 5)]\n", " DataTest = DataArraySlim[4 * int(DataArraySlim.shape[0] / 5):]\n", "\n", " # Split in x (input) and y (output) data\n", " xDataTrain = DataTrain[:, 0, :]\n", " yDataTrain = DataTrain[:, 1, :]\n", " xDataTest = DataTest[:, 0, :]\n", " yDataTest = DataTest[:, 1, :]\n", "\n", " #Normalize Input\n",  Steffen Schotthöfer committed Aug 06, 2020 127 128 129 130 131 132 133 134 135 136 137 138  " #xDataTrain = normalize(xDataTrain, axis=1, norm='l1')\n", " #xDataTest = normalize(xDataTest, axis=1, norm='l1')\n", " \n", " '''\n", " \n", " return DataArraySlim\n", "\n", "def split_data(Data, ratio): # 0_v - \\alpha(\\theta) \\cdot u$\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Easiest case \n", "$\\alpha, u\\in\\mathbb{R}$\n", "\n", "Entropy$\\eta(\\alpha\\cdot m) = exp(\\alpha\\cdot m)$\n", "\n", "Spherical harmonics basis for$M_0$:$ m_0 = \\sqrt{\\left(\\frac{1}{4\\pi}\\right)}\$" ] }, { "cell_type": "code",  Steffen Schotthöfer committed Aug 06, 2020 563  "execution_count": 12,  steffen.schotthoefer committed Aug 05, 2020 564 565  "metadata": {}, "outputs": [  Steffen Schotthöfer committed Aug 06, 2020 566 567 568 569 570 571 572  { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(37.846815845621244, shape=(), dtype=float64)\n" ] },  steffen.schotthoefer committed Aug 05, 2020 573 574  { "data": {  Steffen Schotthöfer committed Aug 06, 2020 575  "image/png": "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\n",  steffen.schotthoefer committed Aug 05, 2020 576 577 578 579 580 581 582 583 584 585 586  "text/plain": [ "