model-training/POET_Training.ipynb
2025-02-11 17:17:43 +01:00

1142 lines
139 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## General Information"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is used to train a simple neural network model to predict the chemistry in the barite benchmark (50x50 grid). The training data is stored in the repository using **git large file storage** and can be downloaded after the installation of git lfs using the `git lfs pull` command.\n",
"\n",
"It is then recommended to create a Python environment using miniconda. The necessary dependencies are contained in `environment.yml` and can be installed using `conda env create -f environment.yml`.\n",
"\n",
"The data set is divided into a design and result part and consists of the iterations of a reference simulation. The design part of the data set contains the chemical concentrations at time $t$ and the result part at time $t+1$, which are to be learned by the model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup Libraries"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2025-02-11 15:40:37.253319: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
"2025-02-11 15:40:37.275142: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
"To enable the following instructions: SSE4.1 SSE4.2 AVX AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running Keras in version 3.6.0\n"
]
}
],
"source": [
"import keras\n",
"import h5py\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"import sklearn.model_selection as sk\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.cluster import KMeans\n",
"from sklearn.pipeline import Pipeline, make_pipeline\n",
"from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
"from imblearn.over_sampling import SMOTE\n",
"from imblearn.under_sampling import RandomUnderSampler\n",
"from imblearn.over_sampling import RandomOverSampler\n",
"from collections import Counter\n",
"import os\n",
"from preprocessing import *\n",
"from sklearn import set_config\n",
"set_config(transform_output = \"pandas\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define parameters"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [],
"source": [
"dtype = \"float32\"\n",
"activation = \"relu\"\n",
"\n",
"lr = 0.001\n",
"batch_size = 512\n",
"epochs = 50 # default 400 epochs\n",
"\n",
"lr_schedule = keras.optimizers.schedules.ExponentialDecay(\n",
" initial_learning_rate=lr,\n",
" decay_steps=2000,\n",
" decay_rate=0.9,\n",
" staircase=True\n",
")\n",
"\n",
"optimizer_simple = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"optimizer_large = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"optimizer_paper = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"\n",
"\n",
"loss = keras.losses.MeanSquaredError()\n",
"\n",
"sample_fraction = 0.8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup the model"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_4\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_4\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_17 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_18 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">16,512</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_19 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,548</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_17 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_18 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m16,512\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_19 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m1,548\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# small model\n",
"model_simple = keras.Sequential(\n",
" [\n",
" keras.Input(shape = (12,), dtype = \"float32\"),\n",
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
" keras.layers.Dense(units = 12, dtype = \"float32\")\n",
" ]\n",
")\n",
"\n",
"model_simple.compile(optimizer=optimizer_simple, loss = loss)\n",
"model_simple.summary()"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_5\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_5\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_20 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,656</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_21 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1024</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_22 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">524,800</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_23 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,156</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_20 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m6,656\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_21 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1024\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_22 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m524,800\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_23 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m6,156\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# large model\n",
"model_large = keras.Sequential(\n",
" [keras.layers.Input(shape=(12,), dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(1024, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(12, dtype=dtype)\n",
" ])\n",
"\n",
"model_large.compile(optimizer=optimizer_large, loss = loss)\n",
"model_large.summary()\n"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_6\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_6\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_24 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_25 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">33,024</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_26 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,584</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_27 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,328</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_28 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">3,084</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_24 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_25 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m33,024\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_26 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m131,584\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_27 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m131,328\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_28 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m3,084\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">300,684</span> (1.15 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m300,684\u001b[0m (1.15 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">300,684</span> (1.15 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m300,684\u001b[0m (1.15 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# model from paper\n",
"# (see https://doi.org/10.1007/s11242-022-01779-3 model for the complex chemistry)\n",
"model_paper = keras.Sequential(\n",
" [keras.layers.Input(shape=(12,), dtype=dtype),\n",
" keras.layers.Dense(128, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(256, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(256, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(12, dtype=dtype)\n",
" ])\n",
"\n",
"model_paper.compile(optimizer=optimizer_paper, loss = loss)\n",
"model_paper.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define transformer functions"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [],
"source": [
"def Safelog(val):\n",
" # get range of vector\n",
" if val > 0:\n",
" return np.log10(val)\n",
" elif val < 0:\n",
" return -np.log10(-val)\n",
" else:\n",
" return 0\n",
"\n",
"def Safeexp(val):\n",
" if val > 0:\n",
" return -10 ** -val\n",
" elif val < 0:\n",
" return 10 ** val\n",
" else:\n",
" return 0"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [],
"source": [
"# ? Why does the charge is using another logarithm than the other species\n",
"\n",
"func_dict_in = {\n",
" \"H\" : np.log1p,\n",
" \"O\" : np.log1p,\n",
" \"Charge\" : Safelog,\n",
" \"H_0_\" : np.log1p,\n",
" \"O_0_\" : np.log1p,\n",
" \"Ba\" : np.log1p,\n",
" \"Cl\" : np.log1p,\n",
" \"S_2_\" : np.log1p,\n",
" \"S_6_\" : np.log1p,\n",
" \"Sr\" : np.log1p,\n",
" \"Barite\" : np.log1p,\n",
" \"Celestite\" : np.log1p,\n",
"}\n",
"\n",
"func_dict_out = {\n",
" \"H\" : np.expm1,\n",
" \"O\" : np.expm1,\n",
" \"Charge\" : Safeexp,\n",
" \"H_0_\" : np.expm1,\n",
" \"O_0_\" : np.expm1,\n",
" \"Ba\" : np.expm1,\n",
" \"Cl\" : np.expm1,\n",
" \"S_2_\" : np.expm1,\n",
" \"S_6_\" : np.expm1,\n",
" \"Sr\" : np.expm1,\n",
" \"Barite\" : np.expm1,\n",
" \"Celestite\" : np.expm1,\n",
"}\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Read data from `.h5` file and convert it to a `pandas.DataFrame`"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [],
"source": [
"# os.chdir('/mnt/beegfs/home/signer/projects/model-training')\n",
"data_file = h5py.File(\"Barite_50_Data_training.h5\")\n",
"\n",
"design = data_file[\"design\"]\n",
"results = data_file[\"result\"]\n",
"\n",
"df_design = pd.DataFrame(np.array(design[\"data\"]).transpose(), columns = design[\"names\"].asstr())\n",
"df_results = pd.DataFrame(np.array(results[\"data\"]).transpose(), columns = results[\"names\"].asstr())\n",
"\n",
"data_file.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Preprocess Data\n",
"\n",
"The data are preprocessed in the following way:\n",
"\n",
"1. Label data points in the `design` dataset with `reactive` and `non-reactive` labels using kmeans clustering\n",
"2. Transform `design` and `results` data set into log-scaled data.\n",
"3. Split data into training and test sets.\n",
"4. Learn scaler on training data for `design` and `results` together (option `global`) or individual (option `individual`).\n",
"5. Transform training and test data.\n",
"6. Split training data into training and validation dataset."
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/signer/bin/miniconda3/envs/training/lib/python3.11/site-packages/sklearn/base.py:1473: ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (2). Possibly due to duplicate points in X.\n",
" return fit_method(estimator, *args, **kwargs)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Amount class 0 before: 0.9879169719169719\n",
"Amount class 1 before: 0.012083028083028084\n"
]
}
],
"source": [
"X_train, X_val, X_test, y_train, y_val, y_test, scaler_X, scaler_y = preprocessing_training(df_design, df_results, func_dict_in, func_dict_out, \"off\", 'individual', 0.1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Custom Loss function"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [],
"source": [
"def custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess):\n",
" df_result = postprocess(df_result_log, func_dict_out, data_min_log, data_max_log) \n",
" return keras.losses.Huber + np.sum(((df_result['H'] / df_result['O']) - 2)**2)\n",
"\n",
"def loss_wrapper(data_min_log, data_max_log, func_dict_out, postprocess):\n",
" def loss(df_design_log, df_result_log):\n",
" return custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess)\n",
" return loss"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train the model"
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [],
"source": [
"# measure time\n",
"def model_training(model):\n",
" start = time.time()\n",
" callback = keras.callbacks.EarlyStopping(monitor='loss', patience=3)\n",
" history = model.fit(X_train.iloc[:, X_train.columns != \"Class\"], \n",
" y_train.iloc[:, y_train.columns != \"Class\"], \n",
" batch_size = batch_size, \n",
" epochs = 40, \n",
" validation_data = (X_val.iloc[:, X_val.columns != \"Class\"], y_val.iloc[:, y_val.columns != \"Class\"]),\n",
" callbacks = [callback])\n",
"\n",
" end = time.time()\n",
"\n",
" print(\"Training took {} seconds\".format(end - start))"
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.8876e-06 - val_loss: 1.8770e-06\n",
"Epoch 2/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9907e-06 - val_loss: 1.8834e-06\n",
"Epoch 3/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6876e-06 - val_loss: 1.8772e-06\n",
"Epoch 4/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.5167e-06 - val_loss: 1.8927e-06\n",
"Epoch 5/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 2.0424e-06 - val_loss: 1.8783e-06\n",
"Epoch 6/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.5759e-06 - val_loss: 1.8775e-06\n",
"Epoch 7/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7919e-06 - val_loss: 1.8742e-06\n",
"Epoch 8/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9016e-06 - val_loss: 1.8740e-06\n",
"Epoch 9/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7540e-06 - val_loss: 1.8810e-06\n",
"Epoch 10/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9548e-06 - val_loss: 1.8773e-06\n",
"Epoch 11/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 2.0289e-06 - val_loss: 1.8712e-06\n",
"Epoch 12/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6964e-06 - val_loss: 1.8717e-06\n",
"Epoch 13/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 2.1222e-06 - val_loss: 1.8696e-06\n",
"Epoch 14/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9142e-06 - val_loss: 1.8694e-06\n",
"Epoch 15/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6718e-06 - val_loss: 1.8697e-06\n",
"Epoch 16/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.5208e-06 - val_loss: 1.8694e-06\n",
"Epoch 17/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8481e-06 - val_loss: 1.8691e-06\n",
"Epoch 18/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6943e-06 - val_loss: 1.8693e-06\n",
"Epoch 19/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8389e-06 - val_loss: 1.8690e-06\n",
"Epoch 20/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9054e-06 - val_loss: 1.8691e-06\n",
"Epoch 21/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6646e-06 - val_loss: 1.8702e-06\n",
"Epoch 22/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8724e-06 - val_loss: 1.8692e-06\n",
"Epoch 23/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7165e-06 - val_loss: 1.8690e-06\n",
"Epoch 24/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8717e-06 - val_loss: 1.8690e-06\n",
"Epoch 25/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8996e-06 - val_loss: 1.8690e-06\n",
"Epoch 26/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8146e-06 - val_loss: 1.8691e-06\n",
"Epoch 27/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.9670e-06 - val_loss: 1.8689e-06\n",
"Epoch 28/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7449e-06 - val_loss: 1.8690e-06\n",
"Epoch 29/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 2.0738e-06 - val_loss: 1.8690e-06\n",
"Epoch 30/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 2ms/step - loss: 1.5405e-06 - val_loss: 1.8690e-06\n",
"Epoch 31/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.6470e-06 - val_loss: 1.8692e-06\n",
"Epoch 32/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7679e-06 - val_loss: 1.8690e-06\n",
"Epoch 33/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7011e-06 - val_loss: 1.8690e-06\n",
"Epoch 34/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 2.0628e-06 - val_loss: 1.8690e-06\n",
"Epoch 35/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.7559e-06 - val_loss: 1.8690e-06\n",
"Epoch 36/40\n",
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.8712e-06 - val_loss: 1.8690e-06\n",
"Training took 245.66379165649414 seconds\n"
]
}
],
"source": [
"model_training(model_simple)"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 14ms/step\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAlQAAAHFCAYAAAA0SmdSAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAQlhJREFUeJzt3Xl4VOX5xvF7JpmshAESskGEaJGAQNkqEBdQVm1MtVVUbBClUAuIYSmKVQlaiVALLlQWa0EtFWwVq6gpqSg/kQCREimrVVEQEoIQJoCQ9f39QXOaIQuBAwwD3891zWXmPc/7nufMkM7dM2cmDmOMEQAAAE6b09cNAAAA+DsCFQAAgE0EKgAAAJsIVAAAADYRqAAAAGwiUAEAANhEoAIAALCJQAUAAGATgQoAAMAmAhVwChYuXCiHw+F1a968ufr06aNly5adlX1+/PHHGjx4sFq0aKGgoCC53W4lJydrzpw5OnLkyFnZpy+tXr1aGRkZOnjw4FlZ/y9/+YueeeaZWrc5HA5lZGSclf1eKBwOh8aMGWPd37NnjzIyMpSXl+e7pk7SR0ZGhhwOx7lvChcVAhVwGhYsWKCcnBytXr1a8+fPV0BAgG666Sa98847Z3Q/U6ZM0bXXXqvdu3friSeeUHZ2thYvXqy+ffsqIyNDjzzyyBnd3/lg9erVmjp1qk8CVU5Ojn7xi1+clf1eqPbs2aOpU6eeF4Gqrj5+8YtfKCcn59w3hYtKoK8bAPxRhw4d1L17d+v+oEGD1LRpU7322mu66aabzsg+/vrXv+rxxx/X8OHD9eKLL3r9P+wbbrhBkyZN4kVC0tGjRxUaGnpG1urZs+cZWceflZWVyeFwKDDQty8PR48eVUhIyBk5s9SyZUu1bNnyDHQF1I0zVMAZEBISoqCgILlcLq/xqVOnqkePHmrWrJkaN26srl276qWXXlJD/ib5448/rqZNm+q5556r9UUlIiJCAwYMsO4fO3ZMkydPVmJiooKCgtSiRQuNHj26xpme1q1bKyUlRVlZWeratatCQ0OVlJSkP/3pTzX2sXv3bo0cOVIJCQkKCgpSfHy8br31Vu3du9eqKS4u1sSJE732m56eXuPtyKq3il599VW1a9dOYWFh+uEPf+j1VmlGRoZ+/etfS5ISExOtt1U/+ugjr97ffPNNdenSRSEhIZo6daok6Q9/+IOuvfZaRUdHKzw8XB07dtSMGTNUVlZmrd+nTx+9++67+uabb7zetq3e44lv+W3atEk/+clP1LRpU4WEhKhz5856+eWXvWo++ugjORwOvfbaa/rNb36j+Ph4NW7cWP369dP27dtrPK61WbVqlfr27auIiAiFhYUpOTlZ7777rrX9s88+k8Ph0EsvvVRj7vvvvy+Hw6G3337bGvvPf/6jIUOGKDo6WsHBwWrXrp3+8Ic/1Nr3q6++qgkTJqhFixYKDg7WF1980aCeP/roI/3oRz+SJN1zzz3W41n9Mfz000+VmpqqZs2aKSQkRF26dNHrr7/utU7VW+nLly/Xvffeq+bNmyssLEwlJSX64osvdM8996hNmzYKCwtTixYtdNNNN+nf//53g/uo7S2/yspKzZgxQ0lJSQoODlZ0dLSGDh2qb7/91quuT58+6tChg3Jzc3XNNdcoLCxMl156qZ566ilVVlZ6rffb3/5Wbdu2VWhoqJo0aaJOnTrp2WefbdBjiQuAAdBgCxYsMJLMmjVrTFlZmSktLTW7du0yY8eONU6n02RlZXnVDxs2zLz00ksmOzvbZGdnmyeeeMKEhoaaqVOn1rufPXv2GEnm9ttvb1BflZWVZuDAgSYwMNA8+uijZvny5ebpp5824eHhpkuXLubYsWNWbatWrUzLli1N+/btzSuvvGL+8Y9/mNtuu81IMitXrrTqvv32WxMXF2eioqLMzJkzzT//+U+zZMkSc++995qtW7caY4w5cuSI6dy5s1fNs88+a9xut7n++utNZWWltZ4k07p1a3PllVea119/3bz33numT58+JjAw0Hz55ZfGGGN27dpl7r//fiPJvPnmmyYnJ8fk5OQYj8dj9R4XF2cuvfRS86c//cl8+OGHZt26dcYYY8aNG2fmzJljsrKyzIoVK8ysWbNMVFSUueeee6weNm/ebK666ioTGxtrrZ2Tk+PV45QpU6z727ZtMxEREeayyy4zr7zyinn33XfNnXfeaSSZ6dOnW3UffvihdXx33XWXeffdd81rr71mLrnkEtOmTRtTXl5e7/P30UcfGZfLZbp162aWLFli3nrrLTNgwADjcDjM4sWLrbouXbqYq666qsb8wYMHm+joaFNWVmYdp9vtNh07djSvvPKKWb58uZkwYYJxOp0mIyOjRt8tWrQwt956q3n77bfNsmXLzP79++vs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i091b7zxho4cOWJtPxU33HCDPvzww3o/pZaSkqIvv/xSkZGR1hm76rfWrVuf8n4bclbnRFUvxFVzpeNh8sUXX6x1/Yau3bdvX61YscIKNlVeeeUVhYWFnZGvWQgPD1ePHj305ptvevVVWVmpP//5z2rZsqXXW5wDBgxQixYttGDBAi1YsEAhISG68847re1hYWG67rrrtGHDBnXq1KnW56W2My6nq67nq23btmrTpo0+++yzWnvo3r2719u/dXE4HF7PqyS9++672r17d4P6qM31118vqebvS25urrZu3Xpavy/VNWnSRLfeeqtGjx6tAwcO6Ouvv7a1HvwDZ6iA07Bp0yaVl5dLOv72wZtvvqns7Gzdcsst1v/7//GPf6yZM2dqyJAhGjlypPbv36+nn366xotDXW677TY9+uijeuKJJ7Rt2zYNHz5cl112mb7//nutXbtW8+bN0+23364BAwaof//+GjhwoB588EEVFxfrqquu0saNGzVlyhR16dJFaWlpp3yMjz/+uN5//31de+21evjhh9WxY0cdPHhQWVlZGj9+vJKSkpSenq433nhD1157rcaNG6dOnTqpsrJSO3fu1PLlyzVhwgT16NHjlPbbsWNHSdKzzz6ru+++Wy6XS23btq33xbd///4KCgrSnXfeqUmTJunYsWOaM2eOioqKal3/zTff1Jw5c9StWzc5nU6v7xSrbsqUKVq2bJmuu+46PfbYY2rWrJkWLVqkd999VzNmzJDb7T6lY6tLZmam+vfvr+uuu04TJ05UUFCQXnjhBW3atEmvvfaa15mbgIAADR06VDNnzlTjxo3105/+tEYfzz77rK6++mpdc801+tWvfqXWrVvr0KFD+uKLL/TOO+9Y19ydCZdddplCQ0O1aNEitWvXTo0aNVJ8fLzi4+M1b9483XDDDRo4cKCGDRumFi1a6MCBA9q6dav+9a9/6a9//etJ109JSdHChQuVlJSkTp06af369frd735X48xSfX2cqG3btho5cqSef/55OZ1O3XDDDfr666/16KOPKiEhQePGjTvlx+Gmm26yvp+uefPm+uabb/TMM8+oVatWatOmzSmvBz/k00viAT9T26f83G636dy5s5k5c6bX1xMYY8yf/vQn07ZtWxMcHGwuvfRSk5mZaV566aU6P8VWm5UrV5pbb73VxMXFGZfLZRo3bmx69eplfve733l9Yu7o0aPmwQcfNK1atTIul8vExcWZX/3qV6aoqMhrvVatWpkf//jHNfbTu3dv07t3b6+xXbt2mXvvvdfExsYal8tl4uPjzeDBg83evXutmsOHD5tHHnnEtG3b1gQFBVkf1x83bpwpKCiw6nTCp8Oq93P33Xd7jU2ePNnEx8cbp9NpJJkPP/yw3t6NMeadd94xP/zhD01ISIhp0aKF+fWvf23ef/99r/nGHP9U3K233mqaNGliHA6H16e/dMKn/Iwx5t///re56aabjNvtNkFBQeaHP/xhjU+SVX1a7q9//avX+I4dO+r85NmJPv74Y3P99deb8PBwExoaanr27GneeeedWms///xz699fdnZ2rTU7duww9957r2nRooVxuVymefPmJjk52fz2t789ad/1qe15fO2110xSUpJxuVw1HsPPPvvM+loHl8tlYmNjzfXXX2/mzp1r1VT9Xp34aVFjjCkqKjLDhw830dHRJiwszFx99dXm448/rvXfa1191Pa1CRUVFWb69Onm8ssvNy6Xy0RFRZmf//zn1lctVOndu7e54ooravR19913e31a9Pe//71JTk42UVFRJigoyFxyySVm+PDh5uuvv67v4cQFxGFMA75hEAAAAHXiGioAAACbCFQAAAA2EagAAABsIlABAADYRKACAACwiUAFAABgE1/seY5UVlZqz549ioiIOCt/5gEAAJx5xhgdOnRI8fHxcjrrPg9FoDpH9uzZU+Mv1gMAAP+wa9euev9gPIHqHKn6sxm7du1S48aNfdwNAABoiOLiYiUkJJz0b08SqM6Rqrf5GjduTKACAMDPnOxyHS5KBwAAsIlABQAAYBOBCgAAwCYCFQAAgE0EKgAAAJsIVAAAADYRqAAAAGwiUAEAANhEoAIAALCJQAUAAGCT3wWqF154QYmJiQoJCVG3bt308ccf11u/cuVKdevWTSEhIbr00ks1d+7cGjVvvPGG2rdvr+DgYLVv315Lly61vV8AAHDx8KtAtWTJEqWnp+s3v/mNNmzYoGuuuUY33HCDdu7cWWv9jh07dOONN+qaa67Rhg0b9PDDD2vs2LF64403rJqcnBzdfvvtSktL02effaa0tDQNHjxYa9euPe39AgCAi4vDGGN83URD9ejRQ127dtWcOXOssXbt2unmm29WZmZmjfoHH3xQb7/9trZu3WqN3Xffffrss8+Uk5MjSbr99ttVXFys999/36oZNGiQmjZtqtdee+209lub4uJiud1ueTyeM/fHkY3RQc9BlVZU1r653rknWbqegvr+xZzsH5P//GsDAPibyCZNFBIUeEbXbOjr95nd61lUWlqq9evX66GHHvIaHzBggFavXl3rnJycHA0YMMBrbODAgXrppZdUVlYml8ulnJwcjRs3rkbNM888c9r7laSSkhKVlJRY94uLi096jKes7Hs1eab1mV8XAAA/tGrwRl3dvpVP9u03b/l99913qqioUExMjNd4TEyMCgoKap1TUFBQa315ebm+++67emuq1jyd/UpSZmam3G63dUtISGjYgQIAgNPidDh8tm+/OUNVxXHCg2WMqTF2svoTxxuy5qnud/LkyRo/frx1v7i4+MyHKleY9PCeM7smAAB+KtkV5rN9+02gioqKUkBAQI2zQoWFhTXOHlWJjY2ttT4wMFCRkZH11lSteTr7laTg4GAFBwc37OBOl8MhBYWf3X0AAICT8pu3/IKCgtStWzdlZ2d7jWdnZys5ObnWOb169apRv3z5cnXv3l0ul6vemqo1T2e/AADg4uI3Z6gkafz48UpLS1P37t3Vq1cvzZ8/Xzt37tR9990n6fjbbLt379Yrr7wi6fgn+mbPnq3x48drxIgRysnJ0UsvvWR9ek+SHnjgAV177bWaPn26fvKTn+jvf/+7/vnPf2rVqlUN3i8AALi4+VWguv3227V//349/vjjys/PV4cOHfTee++pVavjV/Tn5+d7fTdUYmKi3nvvPY0bN05/+MMfFB8fr+eee04/+9nPrJrk5GQtXrxYjzzyiB599FFddtllWrJkiXr06NHg/QIAgIubX30PlT87K99DBQAAzqqGvn77zTVUAAAA5ysCFQAAgE0EKgAAAJsIVAAAADYRqAAAAGwiUAEAANhEoAIAALCJQAUAAGATgQoAAMAmAhUAAIBNBCoAAACbCFQAAAA2EagAAABsIlABAADYRKACAACwiUAFAABgE4EKAADAJgIVAACATQQqAAAAmwhUAAAANhGoAAAAbCJQAQAA2ESgAgAAsIlABQAAYBOBCgAAwCYCFQAAgE0EKgAAAJsIVAAAADYRqAAAAGwiUAEAANhEoAIAALCJQAUAAGATgQoAAMAmAhUAAIBNBCoAAACbCFQAAAA2EagA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QMuXL1dISIiv27noVVZWqnv37po2bZokqUuXLtq8ebPmzJlDoPKRJUuW6M9//rP+8pe/6IorrlBeXp7S09MVHx+vu+++29ft+SUClZ+KiopSQEBAjbNRhYWFNc5a4dy5//779fbbb+v//u//1LJlS1+3c9Fav369CgsL1a1bN2usoqJC//d//6fZs2erpKREAQEBPuzw4hIXF6f27dt7jbVr105vvPGGjzrCr3/9az300EO64447JEkdO3bUN998o8zMTALVaeIaKj8VFBSkbt26KTs722s8OztbycnJPurq4mWM0ZgxY/Tmm29qxYoVSkxM9HVLF7W+ffvq3//+t/Ly8qxb9+7ddddddykvL48wdY5dddVVNb5G5PPPP1erVq181BG+//57OZ3eESAgIICvTbCBM1R+bPz48UpLS1P37t3Vq1cvzZ8/Xzt37tR9993n69YuOqNHj9Zf/vIX/f3vf1dERIR15tDtdis0NNTH3V18IiIialy/Fh4ersjISK5r84Fx48YpOTlZ06ZN0+DBg7Vu3TrNnz9f8+fP93VrF62bbrpJTz75pC655BJdccUV2rBhg2bOnKl7773X1635Lb42wc+98MILmjFjhvLz89WhQwfNmjWLj+n7QF3XrS1YsEDDhg07t82gVn369OFrE3xo2bJlmjx5sv7zn/8oMTFR48eP14gRI3zd1kXr0KFDevTRR7V06VIVFhYqPj5ed955px577DEFBQX5uj2/RKACAACwiWuoAAAAbCJQAQAA2ESgAgAAsIlABQAAYBOBCgAAwCYCFQAAgE0EKgAAAJsIVABwjrRu3ZovFgUuUAQqABekYcOG6eabb5Z0/FvS09PTz9m+Fy5cqCZNmtQYz83N1ciRI89ZHwDOHf6WHwA0UGlpqa0/y9G8efMz2A2A8wlnqABc0IYNG6aVK1fq2WeflcPhkMPh0Ndffy1J2rJli2688UY1atRIMTExSktL03fffWfN7dOnj8aMGaPx48crKipK/fv3lyTNnDlTHTt2VHh4uBISEjRq1CgdPnxYkvTRRx/pnnvukcfjsfaXkZEhqeZbfjt37tRPfvITNWrUSI0bN9bgwYO1d+9ea3tGRoY6d+6sV199Va1bt5bb7dYdd9yhQ4cOnd0HDcApI1ABuKA9++yz6tWrl0aMGKH8/Hzl5+crISFB+fn56t27tzp37qxPP/1UWVlZ2rt3rwYPHuw1/+WXX1ZgYKA++eQTzZs3T5LkdDr13HPPadOmTXr55Ze1YsUKTZo0SZKUnJysZ555Ro0bN7b2N3HixBp9GWN0880368CBA1q5cqWys7P15Zdf6vbbb/eq+/LLL/XWW29p2bJlWrZsmVauXKmnnnrqLD1aAE4Xb/kBuKC53W4FBQUpLCxMsbGx1vicOXPUtWtXTZs2zRr705/+pISEBH3++ee6/PLLJUk/+MEPNGPGDK81q1+PlZiYqCeeeEK/+tWv9MILLygoKEhut1sOh8Nrfyf65z//qY0bN2rHjh1KSEiQJL366qu64oorlJubqx/96EeSpMrKSi1cuFARERGSpLS0NH3wwQd68skn7T0wAM4ozlABuCitX79eH374oRo1amTdkpKSJB0/K1Sle/fuNeZ++OGH6t+/v1q0aKGIiAgNHTpU+/fv15EjRxq8/61btyohIcEKU5LUvn17NWnSRFu3brXGWrdubYUpSYqLi1NhYeEpHSuAs48zVAAuSpWVlbrppps0ffr0Gtvi4uKsn8PDw722ffPNN7rxxht133336YknnlCzZs20atUqDR8+XGVlZQ3evzFGDofjpOMul8tru8PhUGVlZYP3A+DcIFABuOAFBQWpoqLCa6xr165644031Lp1awUGNvx/Cj/99FOVl5fr97//vZzO4yf5X3/99ZPu70Tt27fXzp07tWvXLuss1ZYtW+TxeNSuXbsG9wPg/MBbfgAueK1bt9batWv19ddf67vvvlNlZaVGjx6tAwcO6M4779S6dev01Vdfafny5br33nvrDUOXXXaZysvL9fzzz+urr77Sq6++qrlz59bY3+HDh/XBBx/ou+++0/fff19jnX79+qlTp06666679K9//Uvr1q3T0KFD1bt371rfZgRwfiNQAbjgTZw4UQEBAWrfvr2aN2+unTt3Kj4+Xp988okqKio0cOBAdejQQQ888IDcbrd15qk2nTt31syZMzV9+nR16NBBixYtUmZmpldNcnKy7rvvPt1+++1q3rx5jYvapeNv3b311ltq2rSprr32WvXr10+XXnqplixZcsaPH8DZ5zDGGF83AQAA4M84QwUAAGATgQoAAMAmAhUAAIBNBCoAAACbCFQAAAA2EagAAABsIlABAADYRKACAACwiUAFAABgE4EKAADAJgIVAACATQQqAAAAm/4fMTXyCTMHn44AAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f43e0c41750>"
]
},
"execution_count": 102,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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/XrwwQdVVVUliXW60fDwsGpqanT16lXdcccdOn78uO6///70L0/W6Evd3d364IMPNDAwMGMf/z0tzJKN0HW3+jXh+Apr9pW9e/fq7Nmzev/992fsY52k++67T0NDQ/r888/1t7/9Tbt27VIkEknvZ42kaDSqffv2qaenR2vWrJnzONZqfpbsn+Ny/ZpwSMFgUJJYs3979tln9eabb+q9995TWVlZepx1+kpRUZHuvfdebdmyReFwWJs2bdJLL73EGt3g9OnTGhsb0+bNm1VQUKCCggJFIhH95je/UUFBQXo9WKv5WbIRuvFrwm/U29ur2tpao1ktbRUVFQoGgxlrNjExoUgkclutmXNOe/fu1bFjx/Tuu++qoqIiYz/rNDfnnFKpFGt0g23btml4eFhDQ0PpbcuWLdq5c6eGhoZ0zz33sFYLYXdPxM0t5GvCV6pkMunOnDnjzpw54yS5zs5Od+bMGXfhwgXnnHOHDh1yfr/fHTt2zA0PD7sf//jHbuPGjS6RSBjP/OvzzDPPOL/f706ePOkuXryY3r744ov0MayTc62tra6vr8+Njo66s2fPuueff96tWrXK9fT0OOdYo2xuvDvOOdZqIZZ0hJxz7re//a27++67XVFRkfvud7+bvs32dvXee+/N+l3uu3btcs59ebvoCy+84ILBoPN6ve7hhx92w8PDtpP+ms22PpLca6+9lj6GdXLuqaeeSv+/9a1vfctt27YtHSDnWKNs/jNCrNX88VUOAAAzS/Y1IQDAykeEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmPl/qGKdNepT4hUAAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"species = \"Ba\"\n",
"iterations = 10\n",
"cell_offset = 50\n",
"y_design = []\n",
"y_results = []\n",
"for i in range(0,iterations):\n",
" idx = i*50*50 + cell_offset -1\n",
" y_design.append(df_design.iloc[idx, :])\n",
" y_results.append(df_results.iloc[idx,:])\n",
" \n",
"y_design = pd.DataFrame(y_design)\n",
"y_results = pd.DataFrame(y_results)\n",
"plt.plot(np.arange(0,iterations), y_design[species], label = \"Design\")\n",
"plt.plot(np.arange(0,iterations), y_results[species], label = \"Results\")\n",
"\n",
"y = FuncTransform(func_dict_in, func_dict_out).fit_transform(y_design)\n",
"y = scaler_X.transform(y)\n",
"prediction = model_large.predict(y.iloc[:, y.columns != \"Class\"])\n",
"prediction = pd.DataFrame(prediction, columns = y.columns[y.columns != \"Class\"])\n",
"prediction_back = pd.DataFrame(scaler_X.inverse_transform(prediction), columns=prediction.columns)\n",
"prediction_back = FuncTransform(func_dict_out, func_dict_in).inverse_transform(prediction_back.iloc[:, prediction_back.columns != \"Class\"])\n",
"\n",
"plt.plot(np.arange(0,iterations), prediction_back[species], label = \"Prediction\")\n",
"plt.xlabel('Iteration')\n",
"plt.ylabel(species)\n",
"plt.title(species+' Concentration over Iterations')\n",
"plt.show()\n",
"\n",
"timestep = 1000\n",
"plt.imshow(np.array(df_results[species][(timestep*2500):(timestep*2500+2500)]).reshape(50,50), origin='lower')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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p07VRx99pKlTp+qyyy7T+++/b1Uz/NJWW6uqqrRhwwbdfffd2rBhg15++WV9/vnnOv/889stNzMzs8l13rt3r1JSUqxoQkDau7aSNHbs2Cb1fuWVV9osMxavraRm1+fJJ5+UYRi6+OKL2yw3Wq+tZcwEdcopp5jXX399k2P9+vUzb7/99hbP/81vfmP269evybGf/exn5vDhwy2roxX2799vSjJXr17d6jkrV640JZkHDhwIX8VCYObMmebgwYP9Pj9erqnXL37xC/Poo482PR5Pi6/H6nWVZC5evNj33OPxmHl5eeb999/vO1ZTU2NmZWWZjz76aKvlXHbZZebYsWObHDvnnHPMSZMmhbzOwTqyrS1Zt26dKcnctWtXq+fMnz/fzMrKCm3lLNBSe6dNm2ZecMEFAZUTL9f2ggsuMM8888w2z4mVaxtKCdmjUltbqw8//FBjxoxpcnzMmDFas2ZNi+957733mp1/zjnn6IMPPpDb7basrqFWVlYmScrNzW333CFDhig/P19nnXWWVq5caXXVQmLbtm0qKChQnz59NGnSJO3YsaPVc+PlmkoNP9PPPPOMfvzjH7e771UsXtfD7dy5U/v27Wty7ZxOp04//fRWf3+l1q93W++JRmVlZTIMQ9nZ2W2ed/DgQfXu3Vs9e/bUeeedp40bN4angiGwatUqdevWTX379tV1112n/fv3t3l+PFzbb7/9VsuWLdO1117b7rmxfG2DkZBBpbi4WPX19erevXuT4927d9e+fftafM++fftaPL+urk7FxcWW1TWUTNPUjBkzNHLkSA0cOLDV8/Lz8/X444/rpZde0ssvv6zjjjtOZ511lt56660w1jZww4YN09NPP63XXntNTzzxhPbt26cf/ehH+v7771s8Px6uqdeSJUtUWlqqq6++utVzYvW6Hsn7OxrI76/3fYG+J9rU1NTo9ttv1+TJk9vcB6Zfv3566qmntHTpUj333HNKSUnRiBEjtG3btjDWNjjjxo3Ts88+qzfffFN//vOftX79ep155plyuVytviceru2CBQuUkZGhiy66qM3zYvnaBiumNyXsqCP/52maZpv/G23p/JaOR6sbb7xRH3/8sd555502zzvuuON03HHH+Z4XFRVp9+7d+n//7//ptNNOs7qaQRs3bpzv60GDBqmoqEhHH320FixYoBkzZrT4nli/pl7z5s3TuHHjVFBQ0Oo5sXpdWxPo72+w74kWbrdbkyZNksfj0SOPPNLmucOHD28yAXXEiBE68cQT9de//lUPPfSQ1VXtkMsvv9z39cCBAzV06FD17t1by5Yta/Mf8Vi+tpL05JNPasqUKe3ONYnlaxushOxR6dKli+x2e7O0vX///map3CsvL6/F85OSktS5c2fL6hoqN910k5YuXaqVK1cGteP08OHDYy6xp6ena9CgQa3WO9avqdeuXbv0xhtv6Cc/+UnA743F6+q9kyuQ31/v+wJ9T7Rwu9267LLLtHPnTq1YsSLgXXVtNptOPvnkmLvWUkNPYO/evduseyxfW0l6++23tXXr1qB+h2P52vorIYNKcnKyTjrpJN9dEl4rVqzQj370oxbfU1RU1Oz8119/XUOHDpXD4bCsrh1lmqZuvPFGvfzyy3rzzTfVp0+foMrZuHGj8vPzQ1w7a7lcLm3ZsqXVesfqNT3S/Pnz1a1bN5177rkBvzcWr2ufPn2Ul5fX5NrV1tZq9erVrf7+Sq1f77beEw28IWXbtm164403ggrRpmlq06ZNMXetJen777/X7t2726x7rF5br3nz5umkk07S4MGDA35vLF9bv0VqFm+kLVq0yHQ4HOa8efPMzz77zLzlllvM9PR088svvzRN0zRvv/12c+rUqb7zd+zYYaalpZm//OUvzc8++8ycN2+e6XA4zH/84x+RaoJfbrjhBjMrK8tctWqVuXfvXt+jqqrKd86Rbf3LX/5iLl682Pz888/NTz75xLz99ttNSeZLL70UiSb47Ve/+pW5atUqc8eOHebatWvN8847z8zIyIi7a3q4+vp6s1evXuZtt93W7LVYvq4VFRXmxo0bzY0bN5qSzAceeMDcuHGj706X+++/38zKyjJffvllc/PmzeYVV1xh5ufnm+Xl5b4ypk6d2uQuvnfffde02+3m/fffb27ZssW8//77zaSkJHPt2rVhb9/h2mqr2+02zz//fLNnz57mpk2bmvwOu1wuXxlHtnXWrFnm8uXLze3bt5sbN240r7nmGjMpKcl8//33I9HEJtpqb0VFhfmrX/3KXLNmjblz505z5cqVZlFRkdmjR4+4u7ZeZWVlZlpamjl37twWy4ila2uVhA0qpmmaf/vb38zevXubycnJ5oknntjklt1p06aZp59+epPzV61aZQ4ZMsRMTk42jzrqqFZ/sKKJpBYf8+fP951zZFvnzJljHn300WZKSoqZk5Njjhw50ly2bFn4Kx+gyy+/3MzPzzcdDodZUFBgXnTRReann37qez1erunhXnvtNVOSuXXr1mavxfJ19d5KfeRj2rRppmk23KI8c+ZMMy8vz3Q6neZpp51mbt68uUkZp59+uu98rxdffNE87rjjTIfDYfbr1y8qQlpbbd25c2erv8MrV670lXFkW2+55RazV69eZnJystm1a1dzzJgx5po1a8LfuBa01d6qqipzzJgxZteuXU2Hw2H26tXLnDZtmvnVV181KSMerq3XY489ZqamppqlpaUtlhFL19Yq7J4MAACiVkLOUQEAALGBoAIAAKIWQQUAAEQtggoAAIhaBBUAABC1CCoAACBqEVQAAEDUIqgAAICoRVABEFcMw9CSJUsiXQ0AIUJQARAyV199tQzDaPYYO3ZspKsGIEYlRboCAOLL2LFjNX/+/CbHnE5nhGoDINbRowIgpJxOp/Ly8po8cnJyJDUMy8ydO1fjxo1Tamqq+vTpoxdffLHJ+zdv3qwzzzxTqamp6ty5s37605/q4MGDTc558sknNWDAADmdTuXn5+vGG29s8npxcbEuvPBCpaWl6dhjj9XSpUutbTQAyxBUAITV3XffrYsvvlgfffSRrrzySl1xxRXasmWLJKmqqkpjx45VTk6O1q9frxdffFFvvPFGkyAyd+5cTZ8+XT/96U+1efNmLV26VMccc0yTz5g9e7Yuu+wyffzxxxo/frymTJmikpKSsLYTQIhEevtmAPFj2rRppt1uN9PT05s8fve735mmaZqSzOuvv77Je4YNG2becMMNpmma5uOPP27m5OSYBw8e9L2+bNky02azmfv27TNN0zQLCgrMO++8s9U6SDLvuusu3/ODBw+ahmGYr776asjaCSB8mKMCIKTOOOMMzZ07t8mx3Nxc39dFRUVNXisqKtKmTZskSVu2bNHgwYOVnp7ue33EiBHyeDzaunWrDMPQnj17dNZZZ7VZh+OPP973dXp6ujIyMrR///5gmwQggggqAEIqPT292VBMewzDkCSZpun7uqVzUlNT/SrP4XA0e6/H4wmoTgCiA3NUAITV2rVrmz3v16+fJKl///7atGmTKisrfa+/++67stls6tu3rzIyMnTUUUfpP//5T1jrDCBy6FEBEFIul0v79u1rciwpKUldunSRJL344osaOnSoRo4cqWeffVbr1q3TvHnzJElTpkzRzJkzNW3aNM2aNUvfffedbrrpJk2dOlXdu3eXJM2aNUvXX3+9unXrpnHjxqmiokLvvvuubrrppvA2FEBYEFQAhNTy5cuVn5/f5Nhxxx2n//73v5Ia7shZtGiRfv7znysvL0/PPvus+vfvL0lKS0vTa6+9pl/84hc6+eSTlZaWposvvlgPPPCAr6xp06appqZGf/nLX3TrrbeqS5cuuuSSS8LXQABhZZimaUa6EgASg2EYWrx4sSZOnBjpqgCIEcxRAQAAUYugAgAAohZzVACEDSPNAAJFjwoAAIhaBBUAABC1CCoAACBqEVQAAEDUIqgAAICoRVABAABRi6ACAACiFkEFAABELYIKAACIWv8ffjVm25L6Qy0AAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(history.history[\"loss\"], \"o-\", label = \"Training Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"# plt.yscale('log')\n",
"plt.ylabel(\"Loss (Huber)\")\n",
"plt.grid('on')\n",
"\n",
"plt.savefig(\"loss_all.png\", dpi=300)\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(history.history[\"loss\"][1:], \"o-\", label = \"Training Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"# plt.yscale('log')\n",
"plt.ylabel(\"Loss (Huber)\")\n",
"plt.grid('on')\n",
"plt.savefig(\"loss_1_to_end.png\", dpi=300)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test the model"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7821/7821\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 354us/step - loss: 2.4332e-06\n"
]
},
{
"data": {
"text/plain": [
"2.221618160547223e-06"
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on all test data\n",
"model_simple.evaluate(X_test.iloc[:,X_test.columns != \"Class\"], y_test.iloc[:, y_test.columns != \"Class\"])"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7727/7727\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 309us/step - loss: 1.3519e-06\n"
]
},
{
"data": {
"text/plain": [
"1.1662884844554355e-06"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on non-reactive data\n",
"model_simple.evaluate(X_test[X_test['Class'] == 0].iloc[:,:-1], y_test[X_test['Class'] == 0].iloc[:,:-1])"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m94/94\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 347us/step - loss: 8.9877e-05\n"
]
},
{
"data": {
"text/plain": [
"8.905206777853891e-05"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on reactive data\n",
"model_simple.evaluate(X_test[X_test['Class'] == 1].iloc[:,:-1], y_test[X_test['Class'] == 1].iloc[:, :-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Mass Balance"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [],
"source": [
"def mass_balance(model, X, scaler_X, func_dict_in, func_dict_out):\n",
" # backtransform min/max\n",
" columns = X.iloc[:, X.columns != \"Class\"].columns\n",
" X = pd.DataFrame(scaler_X.inverse_transform(X.iloc[:, X.columns != \"Class\"]), columns = columns)\n",
" \n",
" # backtransform log\n",
" X = FuncTransform(func_dict_in, func_dict_out).inverse_transform(X)\n",
" \n",
" # calculate mass balance\n",
" predicton = model.predict(X)\n",
" dBa = np.abs((prediction[\"Ba\"] + prediction[\"Barite\"]) - (X[\"Ba\"] + X[\"Barite\"]))\n",
" dSr = np.abs((prediction[\"Sr\"] + prediction[\"Celestite\"]) - (X[\"Sr\"] + X[\"Celestite\"]))\n",
" \n",
" return dBa + dSr"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7821/7821\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 345us/step\n"
]
}
],
"source": [
"columns = X_test.columns[X_test.columns != \"Class\"]\n",
"prediction = pd.DataFrame(model_simple.predict(X_test[columns]), columns = columns)"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7821/7821\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 357us/step\n"
]
}
],
"source": [
"mass_balance = mass_balance(model_simple, X_test, scaler_X, func_dict_in, func_dict_out)"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1163 0.000526\n",
"1175 0.000948\n",
"2425 0.000854\n",
"3231 0.000993\n",
"3964 0.000145\n",
" ... \n",
"243165 0.000928\n",
"248138 0.000698\n",
"248832 0.000915\n",
"248963 0.000696\n",
"249253 0.000932\n",
"Length: 115, dtype: float64"
]
},
"execution_count": 116,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mass_balance[mass_balance < 0.001]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Save the model"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"# Save the model\n",
"model.save(\"Barite_50_Model_additional_species.keras\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Legacy Code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"def log_scale(df_design, df_result, func_dict):\n",
" \n",
" df_design = df_design.copy()\n",
" df_result = df_result.copy()\n",
" \n",
" for key in df_design.keys():\n",
" if key != \"Class\":\n",
" df_design[key] = np.vectorize(func_dict[key])(df_design[key])\n",
" df_result[key] = np.vectorize(func_dict[key])(df_result[key])\n",
" \n",
" return df_design, df_result\n",
"\n",
"# Get minimum and maximum values for each column\n",
"def get_min_max(df_design, df_result):\n",
" \n",
" min_vals_des = df_design.min()\n",
" max_vals_des = df_design.max()\n",
" \n",
" min_vals_res = df_result.min()\n",
" max_vals_res = df_result.max()\n",
"\n",
" # minimum of input and output data to get global minimum/maximum\n",
" data_min = np.minimum(min_vals_des, min_vals_res).to_dict()\n",
" data_max = np.maximum(max_vals_des, max_vals_res).to_dict()\n",
"\n",
" return data_min, data_max\n",
"\n",
"df_design_log, df_results_log = log_scale(df_design, df_results, func_dict_in)\n",
"data_min_log, data_max_log = get_min_max(df_design_log, df_design_log)\n",
"\n",
"train_min_log, train_max_log = get_min_max(X_train_log, y_train_log)\n",
"test_min_log, test_max_log = get_min_max(X_test_log, y_test_log)\n",
"\n",
"X_train_preprocess = preprocess(X_train_log, func_dict_in, train_min_log, train_max_log)\n",
"y_train_preprocess = preprocess(y_train_log, func_dict_in, train_min_log, train_max_log)\n",
"\n",
"X_test_preprocess = preprocess(X_test_log, func_dict_in, test_min_log, test_max_log)\n",
"y_test_preprocess = preprocess(y_test_log, func_dict_in, test_min_log, test_max_log)\n",
"\n",
"X_train_log, y_train_log = log_scale(X_train, y_train, func_dict_in)\n",
"X_test_log, y_test_log = log_scale(X_test, y_test, func_dict_in)\n",
"\n",
"\n",
"def preprocess(data, func_dict, data_min, data_max):\n",
" data = data.copy()\n",
" for key in data.keys():\n",
" if key != \"Class\":\n",
" data[key] = (data[key] - data_min[key]) / (data_max[key] - data_min[key])\n",
"\n",
" return data\n",
"\n",
"def postprocess(data, func_dict, data_min, data_max):\n",
" data = data.copy()\n",
" for key in data.keys():\n",
" if key != \"Class\":\n",
" data[key] = data[key] * (data_max[key] - data_min[key]) + data_min[key]\n",
" data[key] = np.vectorize(func_dict[key])(data[key])\n",
" return data\n",
"\n",
"X_train, X_val, y_train, y_val = sk.train_test_split(X_train_preprocess, y_train_preprocess, test_size = 0.1)\n",
"\n",
"pp_design = preprocess(df_design_log, func_dict_in, data_min_log, data_max_log)\n",
"pp_results = preprocess(df_results_log, func_dict_in, data_min_log, data_max_log)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "training",
"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.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 2
}