diff --git a/Barite_50_Data.h5 b/Barite_50_Data.h5 deleted file mode 100644 index 91ec8d7..0000000 --- a/Barite_50_Data.h5 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:925b9e7a484e38bb0ba3ffb9f487854e471b476379f3d1c1adc08112f49f3eeb -size 13021031 diff --git a/Barite_50_Data_inference.h5 b/Barite_50_Data_inference.h5 deleted file mode 100644 index 4a8c6ee..0000000 --- a/Barite_50_Data_inference.h5 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:03523c238f6afe6585a7c93110fee1f3b1f52da6a262d62fe0184646b5a48798 -size 168757224 diff --git a/Barite_50_Data_training.h5 b/Barite_50_Data_training.h5 deleted file mode 100644 index 182d286..0000000 --- a/Barite_50_Data_training.h5 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c35aae40ae8bbe153a59cdaa5ac687769f1c00e7482b4925602179093a9767f -size 329314569 diff --git a/POET_Training.ipynb b/POET_Training.ipynb deleted file mode 100644 index 56fe545..0000000 --- a/POET_Training.ipynb +++ /dev/null @@ -1,2097 +0,0 @@ -{ - "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": "stdout", - "output_type": "stream", - "text": [ - "Running Keras in version 3.8.0\n" - ] - } - ], - "source": [ - "import keras\n", - "from keras.layers import Dense, Dropout, Input,BatchNormalization\n", - "import tensorflow as tf\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", - "from importlib import reload\n", - "set_config(transform_output = \"pandas\")" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define parameters" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "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.Huber()\n", - "\n", - "sample_fraction = 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setup the model" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Model: \"sequential\"\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1mModel: \"sequential\"\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
-       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
-       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense (Dense)                   │ (None, 128)            │         1,152 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_1 (Dense)                 │ (None, 128)            │        16,512 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_2 (Dense)                 │ (None, 8)              │         1,032 │\n",
-       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
-       "
\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 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,152\u001b[0m │\n", - "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_1 (\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_2 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m8\u001b[0m) │ \u001b[38;5;34m1,032\u001b[0m │\n", - "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Total params: 18,696 (73.03 KB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m18,696\u001b[0m (73.03 KB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Trainable params: 18,696 (73.03 KB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m18,696\u001b[0m (73.03 KB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Non-trainable params: 0 (0.00 B)\n",
-       "
\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 = (8,), dtype = \"float32\"),\n", - " keras.layers.Dense(units = 128, activation = \"linear\", dtype = \"float32\"),\n", - " # Dropout(0.2),\n", - " keras.layers.Dense(units = 128, activation = \"elu\", dtype = \"float32\"),\n", - " keras.layers.Dense(units = 8, dtype = \"float32\")\n", - " ]\n", - ")\n", - "\n", - "model_simple.compile(optimizer=optimizer_simple, loss = loss)\n", - "model_simple.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Model: \"sequential_1\"\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1mModel: \"sequential_1\"\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
-       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
-       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense_3 (Dense)                 │ (None, 512)            │         4,608 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_4 (Dense)                 │ (None, 1024)           │       525,312 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_5 (Dense)                 │ (None, 512)            │       524,800 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_6 (Dense)                 │ (None, 8)              │         4,104 │\n",
-       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
-       "
\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_3 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m4,608\u001b[0m │\n", - "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_4 (\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_5 (\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_6 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m8\u001b[0m) │ \u001b[38;5;34m4,104\u001b[0m │\n", - "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Total params: 1,058,824 (4.04 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m1,058,824\u001b[0m (4.04 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Trainable params: 1,058,824 (4.04 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m1,058,824\u001b[0m (4.04 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Non-trainable params: 0 (0.00 B)\n",
-       "
\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=(8,), 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(8, dtype=dtype)\n", - " ])\n", - "\n", - "model_large.compile(optimizer=optimizer_large, loss = loss)\n", - "model_large.summary()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Model: \"sequential_2\"\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1mModel: \"sequential_2\"\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
-       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
-       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense_7 (Dense)                 │ (None, 128)            │         1,152 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_8 (Dense)                 │ (None, 256)            │        33,024 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_9 (Dense)                 │ (None, 512)            │       131,584 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_10 (Dense)                │ (None, 256)            │       131,328 │\n",
-       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_11 (Dense)                │ (None, 8)              │         2,056 │\n",
-       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
-       "
\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_7 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,152\u001b[0m │\n", - "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_8 (\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_9 (\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_10 (\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_11 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m8\u001b[0m) │ \u001b[38;5;34m2,056\u001b[0m │\n", - "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Total params: 299,144 (1.14 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m299,144\u001b[0m (1.14 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Trainable params: 299,144 (1.14 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m299,144\u001b[0m (1.14 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Non-trainable params: 0 (0.00 B)\n",
-       "
\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=(8,), 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(8, 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": 7, - "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": 8, - "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": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# os.chdir('/mnt/beegfs/home/signer/projects/model-training')\n", - "# data_file = h5py.File(\"barite_50_ai_20k.h5\")\n", - "data_file = h5py.File(\"barite_50_4_corner.h5\")\n", - "\n", - "design = data_file[\"design\"]\n", - "results = data_file[\"result\"]\n", - "\n", - "df_design = pd.DataFrame(np.array(design[\"data\"]).transpose(), columns = np.array(design[\"names\"].asstr()))\n", - "df_results = pd.DataFrame(np.array(results[\"data\"]).transpose(), columns = np.array(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": 10, - "metadata": {}, - "outputs": [], - "source": [ - "species_columns = ['H', 'O', 'Ba', 'Cl', 'S', 'Sr', 'Barite', 'Celestite']" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/hannessigner/miniconda3/envs/ai/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.9521309523809524\n", - "Amount class 1 before: 0.04786904761904762\n", - "Using Oversampling\n", - "Amount class 0 after: 0.5\n", - "Amount class 1 after: 0.5\n" - ] - } - ], - "source": [ - "preprocess = preprocessing(func_dict_in=func_dict_in, func_dict_out=func_dict_out)\n", - "X, y = preprocess.cluster(df_design[species_columns], df_results[species_columns])\n", - "# X, y = preprocess.funcTranform(X, y)\n", - "\n", - "X_train, X_test, y_train, y_test = preprocess.split(X, y, ratio = 0.2)\n", - "X_train, y_train = preprocess.balancer(X_train, y_train, strategy = \"over\")\n", - "preprocess.scale_fit(X_train, y_train, scaling = \"global\")\n", - "X_train, X_test, y_train, y_test = preprocess.scale_transform(X_train, X_test, y_train, y_test)\n", - "X_train, X_val, y_train, y_val = preprocess.split(X_train, y_train, ratio = 0.1)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "timestep=250\n", - "plt.imshow(np.array(X[\"Barite\"][(timestep*2500):(timestep*2500+2500)]).reshape(50,50), origin='lower')\n", - "plt.contour(np.array(X[\"Class\"][(timestep*2500):(timestep*2500+2500)]).reshape(50,50), origin='lower', colors='red')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Custom Loss function" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "column_dict = {\"Ba\": X.columns.get_loc(\"Ba\"), \"Barite\":X.columns.get_loc(\"Barite\"), \"Sr\":X.columns.get_loc(\"Sr\"), \"Celestite\":X.columns.get_loc(\"Celestite\"), \"H\":X.columns.get_loc(\"H\"), \"H\":X.columns.get_loc(\"H\"), \"O\":X.columns.get_loc(\"O\")}" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "def custom_loss(preprocess, column_dict, h1, h2, h3, h4):\n", - " # extract the scaling parameters\n", - " scale_X = tf.convert_to_tensor(preprocess.scaler_X.scale_, dtype=tf.float32)\n", - " min_X = tf.convert_to_tensor(preprocess.scaler_X.min_, dtype=tf.float32)\n", - " scale_y = tf.convert_to_tensor(preprocess.scaler_y.scale_, dtype=tf.float32)\n", - " min_y = tf.convert_to_tensor(preprocess.scaler_y.min_, dtype=tf.float32)\n", - "\n", - " def loss(results, predicted):\n", - " \n", - " # inverse min/max scaling\n", - " predicted_inverse = predicted #* scale_y + min_y\n", - " results_inverse = results #* scale_X + min_X\n", - "\n", - " # mass balance\n", - " dBa = tf.keras.backend.abs(\n", - " (predicted_inverse[:, column_dict[\"Ba\"]] + predicted_inverse[:, column_dict[\"Barite\"]]) -\n", - " (results_inverse[:, column_dict[\"Ba\"]] + results_inverse[:, column_dict[\"Barite\"]])\n", - " )\n", - " dSr = tf.keras.backend.abs(\n", - " (predicted_inverse[:, column_dict[\"Sr\"]] + predicted_inverse[:, column_dict[\"Celestite\"]]) -\n", - " (results_inverse[:, column_dict[\"Sr\"]] + results_inverse[:, column_dict[\"Celestite\"]])\n", - " )\n", - " \n", - " # H/O ratio has to be 2\n", - " h2o_ratio = tf.keras.backend.abs(\n", - " (predicted_inverse[:, column_dict[\"H\"]] / predicted_inverse[:, column_dict[\"O\"]]) - 2\n", - " )\n", - "\n", - " # huber loss\n", - " huber_loss = tf.keras.losses.Huber()(results, predicted)\n", - " \n", - " # total loss\n", - " total_loss = h1 * huber_loss + h2 * dBa + h3 * dSr #+ h4 * h2o_ratio**2\n", - " # total_loss = huber_loss\n", - " return total_loss\n", - "\n", - " return loss" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "model_simple.compile(optimizer=optimizer_simple, loss=custom_loss(preprocess, column_dict, 1, 1, 1, 1))#custom_loss(preprocess, column_dict))\n", - "model_large.compile(optimizer=optimizer_large, loss=custom_loss(preprocess, column_dict, 1, 1, 1, 1))#custom_loss(preprocess, column_dict))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Train the model" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "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.loc[:, X_train.columns != \"Class\"], \n", - " y_train.loc[:, y_train.columns != \"Class\"], \n", - " batch_size=batch_size, \n", - " epochs=100, \n", - " validation_data=(X_val.loc[:, X_val.columns != \"Class\"], y_val.loc[:, y_val.columns != \"Class\"]),\n", - " callbacks=[callback])\n", - " \n", - "\n", - " end = time.time()\n", - "\n", - " print(\"Training took {} seconds\".format(end - start))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0073 - val_loss: 0.0025\n", - "Epoch 2/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 0.0043 - val_loss: 0.0035\n", - "Epoch 3/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0035 - val_loss: 0.0029\n", - "Epoch 4/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0031 - val_loss: 0.0030\n", - "Epoch 5/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0031 - val_loss: 0.0017\n", - "Epoch 6/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0025 - val_loss: 0.0019\n", - "Epoch 7/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0024 - val_loss: 0.0018\n", - "Epoch 8/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0021 - val_loss: 0.0013\n", - "Epoch 9/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 0.0020 - val_loss: 0.0023\n", - "Epoch 10/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 0.0019 - val_loss: 0.0012\n", - "Epoch 11/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0017 - val_loss: 0.0010\n", - "Epoch 12/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 0.0016 - val_loss: 0.0011\n", - "Epoch 13/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0014 - val_loss: 0.0024\n", - "Epoch 14/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 0.0013 - val_loss: 0.0010\n", - "Epoch 15/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0013 - val_loss: 0.0013\n", - "Epoch 16/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 0.0011 - val_loss: 7.8773e-04\n", - "Epoch 17/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 9.8307e-04 - val_loss: 9.4317e-04\n", - "Epoch 18/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 0.0011 - val_loss: 7.2556e-04\n", - "Epoch 19/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 8.6145e-04 - val_loss: 0.0012\n", - "Epoch 20/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 8.7931e-04 - val_loss: 7.9255e-04\n", - "Epoch 21/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 8.1421e-04 - val_loss: 8.6545e-04\n", - "Epoch 22/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 8.0980e-04 - val_loss: 8.0041e-04\n", - "Epoch 23/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 7.0201e-04 - val_loss: 7.4177e-04\n", - "Epoch 24/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 7.1057e-04 - val_loss: 8.0948e-04\n", - "Epoch 25/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 6.5622e-04 - val_loss: 7.4124e-04\n", - "Epoch 26/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 6.3500e-04 - val_loss: 5.9376e-04\n", - "Epoch 27/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 5.9934e-04 - val_loss: 6.4478e-04\n", - "Epoch 28/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 5.8949e-04 - val_loss: 7.3300e-04\n", - "Epoch 29/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.7806e-04 - val_loss: 6.7011e-04\n", - "Epoch 30/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 5.6589e-04 - val_loss: 5.5847e-04\n", - "Epoch 31/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.3306e-04 - val_loss: 5.4670e-04\n", - "Epoch 32/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.2881e-04 - val_loss: 6.1837e-04\n", - "Epoch 33/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.1513e-04 - val_loss: 4.9995e-04\n", - "Epoch 34/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.0624e-04 - val_loss: 5.4048e-04\n", - "Epoch 35/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 5.0185e-04 - val_loss: 5.5650e-04\n", - "Epoch 36/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.9359e-04 - val_loss: 4.8311e-04\n", - "Epoch 37/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.7914e-04 - val_loss: 4.7833e-04\n", - "Epoch 38/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.7096e-04 - val_loss: 4.5319e-04\n", - "Epoch 39/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 4.6474e-04 - val_loss: 5.0544e-04\n", - "Epoch 40/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.6506e-04 - val_loss: 4.3838e-04\n", - "Epoch 41/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.5502e-04 - val_loss: 4.6796e-04\n", - "Epoch 42/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.5163e-04 - val_loss: 4.4342e-04\n", - "Epoch 43/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 4.4623e-04 - val_loss: 4.4409e-04\n", - "Epoch 44/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 4.4326e-04 - val_loss: 4.6563e-04\n", - "Epoch 45/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 10ms/step - loss: 4.3963e-04 - val_loss: 4.4313e-04\n", - "Epoch 46/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.3694e-04 - val_loss: 4.4041e-04\n", - "Epoch 47/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.3481e-04 - val_loss: 4.6735e-04\n", - "Epoch 48/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 12ms/step - loss: 4.3270e-04 - val_loss: 4.5155e-04\n", - "Epoch 49/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 12ms/step - loss: 4.2641e-04 - val_loss: 4.2664e-04\n", - "Epoch 50/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.2606e-04 - val_loss: 4.1384e-04\n", - "Epoch 51/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m980s\u001b[0m 581ms/step - loss: 4.2314e-04 - val_loss: 4.3865e-04\n", - "Epoch 52/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.2277e-04 - val_loss: 4.4696e-04\n", - "Epoch 53/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.2034e-04 - val_loss: 4.1750e-04\n", - "Epoch 54/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m65s\u001b[0m 39ms/step - loss: 4.1834e-04 - val_loss: 4.2273e-04\n", - "Epoch 55/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - loss: 4.1589e-04 - val_loss: 4.1261e-04\n", - "Epoch 56/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - loss: 4.1487e-04 - val_loss: 4.4959e-04\n", - "Epoch 57/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - loss: 4.1586e-04 - val_loss: 4.1003e-04\n", - "Epoch 58/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m157s\u001b[0m 93ms/step - loss: 4.1412e-04 - val_loss: 4.1569e-04\n", - "Epoch 59/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 12ms/step - loss: 4.1268e-04 - val_loss: 4.0756e-04\n", - "Epoch 60/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 12ms/step - loss: 4.1062e-04 - val_loss: 4.1501e-04\n", - "Epoch 61/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m23s\u001b[0m 14ms/step - loss: 4.0971e-04 - val_loss: 4.1436e-04\n", - "Epoch 62/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m25s\u001b[0m 15ms/step - loss: 4.0963e-04 - val_loss: 4.0847e-04\n", - "Epoch 63/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m29s\u001b[0m 17ms/step - loss: 4.0908e-04 - val_loss: 4.1114e-04\n", - "Epoch 64/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m32s\u001b[0m 19ms/step - loss: 4.0847e-04 - val_loss: 4.0660e-04\n", - "Epoch 65/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m36s\u001b[0m 21ms/step - loss: 4.0808e-04 - val_loss: 4.0996e-04\n", - "Epoch 66/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 22ms/step - loss: 4.0698e-04 - val_loss: 4.0384e-04\n", - "Epoch 67/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 23ms/step - loss: 4.0676e-04 - val_loss: 4.0728e-04\n", - "Epoch 68/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 23ms/step - loss: 4.0539e-04 - val_loss: 4.0679e-04\n", - "Epoch 69/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 23ms/step - loss: 4.0455e-04 - val_loss: 4.0366e-04\n", - "Epoch 70/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 23ms/step - loss: 4.0342e-04 - val_loss: 4.0677e-04\n", - "Epoch 71/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 23ms/step - loss: 4.0365e-04 - val_loss: 4.0675e-04\n", - "Epoch 72/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m48s\u001b[0m 28ms/step - loss: 4.0370e-04 - val_loss: 4.0298e-04\n", - "Epoch 73/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m67s\u001b[0m 40ms/step - loss: 4.0327e-04 - val_loss: 4.0212e-04\n", - "Epoch 74/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0230e-04 - val_loss: 4.0181e-04\n", - "Epoch 75/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0186e-04 - val_loss: 4.0174e-04\n", - "Epoch 76/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0194e-04 - val_loss: 4.0180e-04\n", - "Epoch 77/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0250e-04 - val_loss: 4.0450e-04\n", - "Epoch 78/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m64s\u001b[0m 38ms/step - loss: 4.0166e-04 - val_loss: 4.0060e-04\n", - "Epoch 79/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0279e-04 - val_loss: 4.0026e-04\n", - "Epoch 80/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m65s\u001b[0m 38ms/step - loss: 4.0156e-04 - val_loss: 4.0022e-04\n", - "Epoch 81/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0187e-04 - val_loss: 4.0012e-04\n", - "Epoch 82/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m66s\u001b[0m 39ms/step - loss: 4.0070e-04 - val_loss: 4.0000e-04\n", - "Epoch 83/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m70s\u001b[0m 42ms/step - loss: 3.9981e-04 - val_loss: 3.9985e-04\n", - "Epoch 84/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m50s\u001b[0m 30ms/step - loss: 4.0303e-04 - val_loss: 4.0034e-04\n", - "Epoch 85/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 3.9996e-04 - val_loss: 3.9949e-04\n", - "Epoch 86/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.0223e-04 - val_loss: 3.9965e-04\n", - "Epoch 87/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.0010e-04 - val_loss: 4.0027e-04\n", - "Epoch 88/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 3.9915e-04 - val_loss: 3.9899e-04\n", - "Epoch 89/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.0031e-04 - val_loss: 3.9913e-04\n", - "Epoch 90/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.0037e-04 - val_loss: 3.9903e-04\n", - "Epoch 91/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.0011e-04 - val_loss: 3.9930e-04\n", - "Epoch 92/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 3.9916e-04 - val_loss: 3.9924e-04\n", - "Epoch 93/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 3.9930e-04 - val_loss: 3.9885e-04\n", - "Epoch 94/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.0009e-04 - val_loss: 3.9866e-04\n", - "Epoch 95/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 3.9961e-04 - val_loss: 3.9870e-04\n", - "Epoch 96/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.0012e-04 - val_loss: 3.9863e-04\n", - "Epoch 97/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 11ms/step - loss: 4.0073e-04 - val_loss: 3.9872e-04\n", - "Epoch 98/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 4.0112e-04 - val_loss: 3.9862e-04\n", - "Epoch 99/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - loss: 3.9970e-04 - val_loss: 3.9864e-04\n", - "Epoch 100/100\n", - "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - loss: 4.0060e-04 - val_loss: 3.9856e-04\n", - "Training took 3712.1917679309845 seconds\n" - ] - } - ], - "source": [ - "model_training(model_large)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Test Mass Balance" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "def mass_balance(model, X, preprocess):\n", - " \n", - " # predict the chemistry\n", - " columns = X.iloc[:, X.columns != \"Class\"].columns\n", - " prediction = pd.DataFrame(model.predict(X[columns]), columns=columns)\n", - " # backtransform min/max\n", - " X = pd.DataFrame(preprocess.scaler_X.inverse_transform(X.iloc[:, X.columns != \"Class\"]), columns=columns)\n", - " prediction = pd.DataFrame(preprocess.scaler_y.inverse_transform(prediction), columns=columns)\n", - " \n", - " # calculate mass balance\n", - " dBa = np.abs((prediction[\"Ba\"] + prediction[\"Barite\"]) - (X[\"Ba\"] + X[\"Barite\"]))\n", - " print(dBa.min())\n", - " dSr = np.abs((prediction[\"Sr\"] + prediction[\"Celestite\"]) - (X[\"Sr\"] + X[\"Celestite\"]))\n", - " print(dSr.min())\n", - " return dBa, dSr" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 664us/step\n", - "1.1719081515317378e-08\n", - "4.366040862180398e-11\n" - ] - } - ], - "source": [ - "dBa, dSr = mass_balance(model_large, X_test, preprocess)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [], - "source": [ - "mass_balance_results = dBa + dSr" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.0004126984126984127" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(mass_balance_results[mass_balance_results < 1e-5]) / len(mass_balance_results)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1571 9.777670e-06\n", - "4804 6.682305e-06\n", - "9522 5.360124e-06\n", - "19062 7.792255e-06\n", - "20931 7.635390e-06\n", - "25699 8.067375e-06\n", - "26621 9.558936e-06\n", - "27291 3.264182e-06\n", - "28758 9.788952e-06\n", - "30798 9.144786e-06\n", - "30868 8.206085e-06\n", - "33577 5.763282e-06\n", - "35603 7.277309e-06\n", - "36166 8.139519e-07\n", - "37063 7.179245e-06\n", - "43690 9.914585e-06\n", - "43815 9.545191e-06\n", - "44262 6.470130e-06\n", - "44943 6.567906e-06\n", - "52627 8.729186e-06\n", - "55763 4.385958e-06\n", - "57566 3.628730e-06\n", - "60090 9.793098e-06\n", - "62479 4.789578e-06\n", - "63477 7.146393e-06\n", - "64471 7.182930e-06\n", - "66959 6.616205e-06\n", - "67640 8.551544e-06\n", - "68503 9.501419e-06\n", - "70704 9.920509e-06\n", - "75976 5.456992e-06\n", - "76018 5.254534e-06\n", - "78582 4.474446e-06\n", - "81150 7.195583e-06\n", - "87159 5.605938e-06\n", - "89481 5.571020e-06\n", - "91118 8.934794e-06\n", - "91502 9.652786e-06\n", - "92207 9.917967e-06\n", - "94182 9.915878e-06\n", - "94506 4.791335e-06\n", - "95973 6.741278e-06\n", - "99816 7.449719e-06\n", - "101503 5.096865e-06\n", - "105575 3.955416e-06\n", - "107682 5.253287e-06\n", - "107940 5.935249e-06\n", - "115812 9.169740e-06\n", - "116353 5.333948e-06\n", - "120035 9.495618e-06\n", - "120275 5.560308e-06\n", - "124877 8.157624e-06\n", - "dtype: float64" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mass_balance_results[mass_balance_results < 1e-5]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Optimizing with Optuna" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "import optuna\n", - "\n", - "def create_model(model, preprocess, h1, h2, h3, h4):\n", - " \n", - " model.compile(optimizer=optimizer_simple, loss=custom_loss(preprocess, column_dict, h1, h2, h3, h4))\n", - " \n", - " return model\n", - "\n", - "\n", - "def objective(trial, preprocess, X_train, y_train, X_val, y_val, X_test, y_test):\n", - " h1 = trial.suggest_float(\"h1\", 0.1, 100)\n", - " h2 = trial.suggest_float(\"h2\", 0.1, 100)\n", - " h3 = trial.suggest_float(\"h3\", 0.1, 100)\n", - " h4 = trial.suggest_float(\"h4\", 0.1, 100)\n", - " \n", - " model = create_model(model_simple, preprocess, h1, h2, h3, h4)\n", - " \n", - " callback = keras.callbacks.EarlyStopping(monitor='loss', patience=3)\n", - " history = model.fit(X_train.loc[:, X_train.columns != \"Class\"], \n", - " y_train.loc[:, y_train.columns != \"Class\"], \n", - " batch_size=batch_size, \n", - " epochs=50, \n", - " validation_data=(X_val.loc[:, X_val.columns != \"Class\"], y_val.loc[:, y_val.columns != \"Class\"]),\n", - " callbacks=[callback])\n", - " \n", - " mass_balance_results = mass_balance(model, X_test, preprocess)\n", - " \n", - " loss = len(mass_balance_results[mass_balance_results < 1e-5]) / len(mass_balance_results)\n", - "\n", - " return loss" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:06:24,572] A new study created in memory with name: no-name-585ded5e-6499-4f70-9577-49339316366a\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12377019392.0000 - val_loss: 43404600.0000\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 36439708.0000 - val_loss: 19609912.0000\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 15841922.0000 - val_loss: 7256873.5000\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 5500834.0000 - val_loss: 1881962.5000\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1413300.5000 - val_loss: 617048.8125\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 496590.9375 - val_loss: 194345.2812\n", - "Epoch 7/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 139668.2969 - val_loss: 31873.9043\n", - "Epoch 8/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 21170.1543 - val_loss: 4920.2520\n", - "Epoch 9/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 4156.0869 - val_loss: 3427.2729\n", - "Epoch 10/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 3414.1331 - val_loss: 3416.1082\n", - "Epoch 11/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 3416.9729 - val_loss: 3429.7239\n", - "Epoch 12/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 3412.4482 - val_loss: 3435.3306\n", - "Epoch 13/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 3425.5073 - val_loss: 3403.7925\n", - "Epoch 14/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 3425.9592 - val_loss: 3423.5193\n", - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 296us/step\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:06:49,285] Trial 0 finished with value: 0.0 and parameters: {'h1': 72.40785703177082, 'h2': 25.825548427085515, 'h3': 61.927211067692724, 'h4': 19.232336897801325}. Best is trial 0 with value: 0.0.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2791.0564 - val_loss: 2618.3965\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2622.5496 - val_loss: 2616.2480\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2620.7339 - val_loss: 2631.9077\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2650.9636 - val_loss: 2814.0315\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2722.9919 - val_loss: 2598.4248\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2778.1111 - val_loss: 2559.9062\n", - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 291us/step\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:07:00,296] Trial 1 finished with value: 0.0 and parameters: {'h1': 55.156241799815355, 'h2': 78.4033434954878, 'h3': 95.18824024469184, 'h4': 14.82240562501995}. Best is trial 0 with value: 0.0.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 7852.1719 - val_loss: 2412.7383\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2426.0986 - val_loss: 2597.7363\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2473.9902 - val_loss: 2277.7488\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2471.1829 - val_loss: 2443.7427\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2402.8818 - val_loss: 2218.1780\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2367.2834 - val_loss: 2218.3396\n", - "Epoch 7/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2340.9314 - val_loss: 2119.3755\n", - "Epoch 8/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 2219.4814 - val_loss: 2298.2070\n", - "Epoch 9/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2155.6299 - val_loss: 2612.8733\n", - "Epoch 10/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2100.1267 - val_loss: 2046.4711\n", - "Epoch 11/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 2001.3557 - val_loss: 2211.9299\n", - "Epoch 12/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1971.5155 - val_loss: 1997.1703\n", - "Epoch 13/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1947.2655 - val_loss: 1892.0009\n", - "Epoch 14/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1915.1980 - val_loss: 1860.9949\n", - "Epoch 15/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1882.3663 - val_loss: 1861.6248\n", - "Epoch 16/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1869.7008 - val_loss: 1896.9276\n", - "Epoch 17/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1883.5923 - val_loss: 1915.4973\n", - "Epoch 18/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1871.5115 - val_loss: 1837.4102\n", - "Epoch 19/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1877.5151 - val_loss: 1879.3440\n", - "Epoch 20/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1862.3589 - val_loss: 1957.3567\n", - "Epoch 21/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1845.3960 - val_loss: 1814.5060\n", - "Epoch 22/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1835.3391 - val_loss: 1809.6317\n", - "Epoch 23/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1838.9376 - val_loss: 1833.8245\n", - "Epoch 24/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1831.4557 - val_loss: 1886.3599\n", - "Epoch 25/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1833.6478 - val_loss: 1800.0344\n", - "Epoch 26/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1833.5480 - val_loss: 1797.0282\n", - "Epoch 27/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1819.1056 - val_loss: 1794.1648\n", - "Epoch 28/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1812.3524 - val_loss: 1881.1871\n", - "Epoch 29/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1805.2583 - val_loss: 1802.8263\n", - "Epoch 30/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1808.2974 - val_loss: 1777.7633\n", - "Epoch 31/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1792.2367 - val_loss: 1791.2937\n", - "Epoch 32/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1789.2295 - val_loss: 1778.8715\n", - "Epoch 33/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1772.3083 - val_loss: 1778.3553\n", - "Epoch 34/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1781.2627 - val_loss: 1760.8132\n", - "Epoch 35/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1783.0363 - val_loss: 1763.7234\n", - "Epoch 36/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1765.7679 - val_loss: 1752.7267\n", - "Epoch 37/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1761.1954 - val_loss: 1762.8220\n", - "Epoch 38/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1762.9722 - val_loss: 1747.1544\n", - "Epoch 39/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1753.7981 - val_loss: 1763.1051\n", - "Epoch 40/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1752.4087 - val_loss: 1739.5280\n", - "Epoch 41/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1748.3682 - val_loss: 1728.5411\n", - "Epoch 42/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1739.5088 - val_loss: 1729.1458\n", - "Epoch 43/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1736.5480 - val_loss: 1724.7151\n", - "Epoch 44/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1740.2578 - val_loss: 1734.8917\n", - "Epoch 45/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1730.3800 - val_loss: 1736.1029\n", - "Epoch 46/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1714.5963 - val_loss: 1715.0453\n", - "Epoch 47/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1717.4546 - val_loss: 1771.3018\n", - "Epoch 48/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1712.6161 - val_loss: 1711.4847\n", - "Epoch 49/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1702.8785 - val_loss: 1712.8119\n", - "Epoch 50/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1711.1716 - val_loss: 1700.8627\n", - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 296us/step\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:08:19,362] Trial 2 finished with value: 0.0 and parameters: {'h1': 32.18807766864932, 'h2': 32.38115474529778, 'h3': 82.71542742505292, 'h4': 21.39993663591346}. Best is trial 0 with value: 0.0.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1814.5203 - val_loss: 1661.1248\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1621.0743 - val_loss: 1503.6709\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1466.0696 - val_loss: 1357.3704\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1319.6273 - val_loss: 1204.6761\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1164.8816 - val_loss: 1049.8190\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1012.0715 - val_loss: 900.6155\n", - "Epoch 7/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 866.8824 - val_loss: 782.1039\n", - "Epoch 8/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 765.9833 - val_loss: 752.7275\n", - "Epoch 9/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 752.8401 - val_loss: 751.8625\n", - "Epoch 10/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 752.4477 - val_loss: 755.2651\n", - "Epoch 11/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 752.4553 - val_loss: 750.9076\n", - "Epoch 12/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 752.6575 - val_loss: 751.2373\n", - "Epoch 13/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 751.5120 - val_loss: 750.2513\n", - "Epoch 14/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 750.1327 - val_loss: 749.1887\n", - "Epoch 15/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 750.2402 - val_loss: 748.8613\n", - "Epoch 16/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 751.2623 - val_loss: 748.6445\n", - "Epoch 17/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 750.6178 - val_loss: 748.5185\n", - "Epoch 18/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 749.1051 - val_loss: 748.1081\n", - "Epoch 19/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 749.3755 - val_loss: 747.6932\n", - "Epoch 20/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 748.1135 - val_loss: 747.2830\n", - "Epoch 21/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 747.3423 - val_loss: 747.2092\n", - "Epoch 22/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 747.1829 - val_loss: 747.7263\n", - "Epoch 23/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 747.6171 - val_loss: 746.8931\n", - "Epoch 24/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 746.1934 - val_loss: 746.4072\n", - "Epoch 25/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 747.4377 - val_loss: 746.0536\n", - "Epoch 26/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 747.3806 - val_loss: 745.7092\n", - "Epoch 27/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 746.1663 - val_loss: 745.9564\n", - "Epoch 28/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 746.9430 - val_loss: 745.2064\n", - "Epoch 29/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.6080 - val_loss: 745.0362\n", - "Epoch 30/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 745.1031 - val_loss: 745.5790\n", - "Epoch 31/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.9517 - val_loss: 746.2484\n", - "Epoch 32/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 745.3198 - val_loss: 744.7700\n", - "Epoch 33/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 746.6561 - val_loss: 744.3752\n", - "Epoch 34/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.4594 - val_loss: 744.5372\n", - "Epoch 35/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 745.4088 - val_loss: 744.5147\n", - "Epoch 36/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 745.0701 - val_loss: 743.8632\n", - "Epoch 37/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.1857 - val_loss: 744.3721\n", - "Epoch 38/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.1999 - val_loss: 743.6331\n", - "Epoch 39/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.2258 - val_loss: 743.9576\n", - "Epoch 40/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.8534 - val_loss: 743.3392\n", - "Epoch 41/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 744.1964 - val_loss: 743.3118\n", - "Epoch 42/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.2463 - val_loss: 744.1565\n", - "Epoch 43/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.7304 - val_loss: 742.9604\n", - "Epoch 44/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 742.8326 - val_loss: 743.0219\n", - "Epoch 45/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.7935 - val_loss: 742.7424\n", - "Epoch 46/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 742.9843 - val_loss: 742.6505\n", - "Epoch 47/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 741.9490 - val_loss: 742.4158\n", - "Epoch 48/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 741.9554 - val_loss: 742.6078\n", - "Epoch 49/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.1502 - val_loss: 742.2740\n", - "Epoch 50/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 743.5102 - val_loss: 742.0992\n", - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 290us/step\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:09:41,637] Trial 3 finished with value: 0.0 and parameters: {'h1': 51.147323536824445, 'h2': 56.78563118722674, 'h3': 31.302312703064025, 'h4': 0.2323539329544047}. Best is trial 0 with value: 0.0.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 27736.6758 - val_loss: 25335.9141\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 24856.6797 - val_loss: 23624.0430\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 23591.7324 - val_loss: 22455.3379\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 22087.6445 - val_loss: 21249.2285\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 21055.1582 - val_loss: 20346.3613\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 20397.3496 - val_loss: 19634.5000\n", - "Epoch 7/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 19168.5645 - val_loss: 18746.1426\n", - "Epoch 8/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 18433.6738 - val_loss: 18086.1094\n", - "Epoch 9/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 17888.7070 - val_loss: 17506.1172\n", - "Epoch 10/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 17398.0664 - val_loss: 16952.9180\n", - "Epoch 11/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 16835.0117 - val_loss: 16448.4297\n", - "Epoch 12/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 16369.1172 - val_loss: 15983.9541\n", - "Epoch 13/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 15914.9648 - val_loss: 15574.0117\n", - "Epoch 14/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 15417.1514 - val_loss: 15182.9922\n", - "Epoch 15/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 14972.8398 - val_loss: 14841.6963\n", - "Epoch 16/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 14821.4219 - val_loss: 14586.0078\n", - "Epoch 17/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 14475.7656 - val_loss: 14208.0049\n", - "Epoch 18/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 14218.5225 - val_loss: 13965.6191\n", - "Epoch 19/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 14080.0352 - val_loss: 13686.0967\n", - "Epoch 20/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 13640.7412 - val_loss: 13432.9609\n", - "Epoch 21/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 13297.7139 - val_loss: 13222.0645\n", - "Epoch 22/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 13205.2559 - val_loss: 13020.1660\n", - "Epoch 23/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 13046.4668 - val_loss: 12839.4688\n", - "Epoch 24/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12915.7373 - val_loss: 12695.6348\n", - "Epoch 25/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12565.1816 - val_loss: 12489.5596\n", - "Epoch 26/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12385.2871 - val_loss: 12334.8535\n", - "Epoch 27/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12441.1230 - val_loss: 12193.6494\n", - "Epoch 28/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12110.5723 - val_loss: 12051.1250\n", - "Epoch 29/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 12140.8193 - val_loss: 11922.8623\n", - "Epoch 30/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11870.8330 - val_loss: 11813.3994\n", - "Epoch 31/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11781.4502 - val_loss: 11694.6562\n", - "Epoch 32/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11774.9316 - val_loss: 11599.8086\n", - "Epoch 33/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11517.6182 - val_loss: 11493.0459\n", - "Epoch 34/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11443.8252 - val_loss: 11402.4766\n", - "Epoch 35/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11502.7910 - val_loss: 11311.7754\n", - "Epoch 36/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11410.6387 - val_loss: 11226.0420\n", - "Epoch 37/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11144.2510 - val_loss: 11152.2734\n", - "Epoch 38/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10994.5703 - val_loss: 11074.9717\n", - "Epoch 39/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11061.8809 - val_loss: 11009.4912\n", - "Epoch 40/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10965.7441 - val_loss: 10939.0264\n", - "Epoch 41/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 11017.5010 - val_loss: 10882.1914\n", - "Epoch 42/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10908.1650 - val_loss: 10822.1357\n", - "Epoch 43/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10795.5361 - val_loss: 10765.4912\n", - "Epoch 44/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10588.0283 - val_loss: 10712.4141\n", - "Epoch 45/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10675.9863 - val_loss: 10659.5850\n", - "Epoch 46/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10741.0137 - val_loss: 10615.9727\n", - "Epoch 47/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10552.5371 - val_loss: 10568.0938\n", - "Epoch 48/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10671.9209 - val_loss: 10526.0469\n", - "Epoch 49/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10479.7158 - val_loss: 10484.8340\n", - "Epoch 50/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 10387.6152 - val_loss: 10451.1416\n", - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 313us/step\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[I 2025-02-17 00:11:09,995] Trial 4 finished with value: 0.0 and parameters: {'h1': 61.30953008699103, 'h2': 93.9200835460014, 'h3': 57.8376987539652, 'h4': 82.3346527788174}. Best is trial 0 with value: 0.0.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8271.6963 - val_loss: 8311.1768\n", - "Epoch 2/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8371.5420 - val_loss: 8275.3896\n", - "Epoch 3/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8377.3896 - val_loss: 8246.3291\n", - "Epoch 4/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8375.9121 - val_loss: 8216.7363\n", - "Epoch 5/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8269.5869 - val_loss: 8189.8159\n", - "Epoch 6/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8172.8184 - val_loss: 8167.1416\n", - "Epoch 7/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8084.1265 - val_loss: 8137.8125\n", - "Epoch 8/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8089.8613 - val_loss: 8119.4287\n", - "Epoch 9/50\n", - "\u001b[1m886/886\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 8135.9199 - val_loss: 8094.7837\n", - "Epoch 10/50\n", - "\u001b[1m610/886\u001b[0m \u001b[32m━━━━━━━━━━━━━\u001b[0m\u001b[37m━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - loss: 8253.8984" - ] - } - ], - "source": [ - "study = optuna.create_study(direction=\"maximize\")\n", - "study.optimize(lambda trial: objective(trial, preprocess, X_train, y_train, X_val, y_val, X_test, y_test), n_trials=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Percentage of cells that pass the mass balance condition\n", - "\n", - "small_modell_20_epochs = 0.0031088911088911087\n", - "\n", - "large_modell_20_epochs = 0.022793206793206792" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step \n" - ] - }, - { - "data": { - "image/png": "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4Dpyc9ddd7Fq1aocV4B+/vnneHh43NJUAyaTiWbNmvHOO+/g6+tr88lje/fuzeHDh60u1rhRcXw2hREWFkajRo1wdnbmrbfeIiQkhL/97W/Fuo/ySj1LUmz27t1LRkYGYO4+X7x4MStWrODee++lRo0aAPTp04e3336bRx55hBEjRnD+/Hn+85//5Po/78KoVasW7u7ufPnllzRo0AAvLy9CQkIICQnho48+onfv3vTs2ZMhQ4ZQpUoV4uPjOXDgANu3b+e///1vntt1dHTk+++/JyIigg4dOjBq1Ci6deuGp6cnf/31F99++y0//vgjFy5cAGDq1Kn06NGDbt268eKLL+Li4sKsWbPYu3cvCxcuLHTvQVhYGP/617947bXXuHLliuVy//379xMXF2eZIPO9995j8ODBxMfH88ADDxAQEMC5c+fYtWsX586dyzds5aVJkyasWbOGH3/8keDgYCpUqHDTf7z79u3LvHnzqF+/Pk2bNmXbtm383//9X44eofw+rxvVq1ePESNG8N577+Hg4EDv3r0tV8NVq1aN559/vtDvLTc9evSgZ8+evPTSSyQmJtKxY0fL1XAtWrRg0KBBVu0ffvhhxowZw8MPP0xqamqOsU4dO3ZkxIgRDB06lK1bt9K5c2c8PT2Jjo5m/fr1NGnShFGjRhVL7WD+vBYvXszs2bNp1aoVDg4OtG7dmoceeogvv/ySu+++m+eee462bdvi7OzMqVOnWL16Nf379+fee++96bFxcXHh4YcfZuzYsaSkpDB79mzL974gdeRm4sSJLF26lG7duvHqq69SqVIlvvzyS3766SemT59e6Ilely5dyqxZsxgwYAA1a9bEMAwWL17MxYsX6dGjR6G2datGjx7NokWL6N+/Py+//DJt27blypUrrF27lr59+9KtW7di+WwKYvz48TRp0oTg4GCioqKYO3cumzdv5qeffiq2ObTKPfuNLZfyIrer4Xx8fIzmzZsbb7/9do4ryebOnWvUq1fPcHV1NWrWrGlMnTrV+PTTTw3AOH78uKVdaGio0adPn1z3eePVcIZhvrKkfv36hrOzc46rRHbt2mU8+OCDRkBAgOHs7GwEBQUZd955p/Hhhx8W6D1evHjReO2114yWLVsaXl5ehrOzs1G9enXjscceM/744w+rtuvWrTPuvPNOw9PT03B3dzfat29v/Pjjj7kes8jISKv12Vf9rF692mr9559/brRp08Zwc3MzvLy8jBYtWuS4kmzt2rVGnz59jEqVKhnOzs5GlSpVjD59+hj//e9/LW1yu4rq+nquP/47d+40OnbsaHh4eBiA5UqcvGo3DMO4cOGC8cQTTxgBAQGGh4eHcccddxjr1q3L9UqevD6vG6+GMwzz1VfTpk0z6tatazg7Oxt+fn7GY489Zpw8edKqXZcuXYxGjRrlqCu3K51yc+XKFeOll14yQkNDDWdnZyM4ONgYNWqUceHChVzbP/LIIwZgdOzYMc9tzp0712jXrp3l+1CrVi3j8ccfN7Zu3XrTuvOS2+cYHx9vPPDAA4avr69hMpmsjmF6errxn//8x2jWrJnlO1S/fn3jH//4h3HkyBFLu/z+zv3444+W11epUsX45z//afz88885vq/51XHj30vDMIw9e/YY/fr1M3x8fAwXFxejWbNmOb7b2X8vrv8uG4ZhHD9+3OqqyoMHDxoPP/ywUatWLcPd3d3w8fEx2rZta8ybN++mxzSvq+GeeuqpHG1z+/cnNxcuXDCee+45o3r16oazs7MREBBg9OnTxzh48KClTUE/m6JeDWcYhjFq1CijevXqhouLi+Hn52fcf//9xu7du2/6OrnGZBg3zAQoIiIiIhYasyQiIiKSD4UlERERkXwoLImIiIjkQ2FJREREJB8KSyIiIiL5UFgSERERyYcmpSwGWVlZnDlzhgoVKpTYLQtERESkeBmGQVJSEiEhIfneVFhhqRicOXMmz/t2iYiISOl28uTJfG98rLBUDLLvLXby5Em8vb3tXI2IiIgURGJiItWqVbvpTYsVlopB9qk3b29vhSUREZEy5mZDaDTAW0RERCQfZS4szZo1ixo1auDm5karVq1Yt25dnm2jo6N55JFHqFevHg4ODowePTpHm3nz5mEymXIsKSkpJfguREREpKwoU2Fp0aJFjB49mvHjx7Njxw46depE7969iYqKyrV9amoq/v7+jB8/nmbNmuW5XW9vb6Kjo60WNze3knobIiIiUoaUqTFLb7/9Nk888QR///vfAZgxYwa//vors2fPZurUqTnah4WF8e677wIwd+7cPLdrMpkICgoqmaKvk5mZSXp6eonvR0qes7Mzjo6O9i5DRERsoMyEpbS0NLZt28bLL79stT4iIoINGzbc0rYvXbpEaGgo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gZODidDKnnatRWFJRERESp3DV8crhfl54uJk37iisCQiIiKlzpGzV6+EC7DveCVQWBIREZFS6NrM3fa9Eg4UlkRERKQUslwJp54lEREREWuGYVw7DWfnaQNAYUlERERKmXNJqSSmZOBgghp+9r0SDhSWREREpJTJPgUXVtkTV6fC39e0uCksiYiISKly+OopuNqlYLwSKCxJKTBp0iSaN29u+XnIkCEMGDDglrZZHNsQERH7KC23OcmmsCR5GjJkCCaTCZPJhLOzMzVr1uTFF1/k8uXLJbrfd999l3nz5hWo7YkTJzCZTOzcubPI2xARkdLlz6sTUtYtBdMGADjZuwAp3Xr16sVnn31Geno669at4+9//zuXL19m9uzZVu3S09NxdnYuln36+PiUim2IiIjtGYbB4VidhpMyxNXVlaCgIKpVq8YjjzzCo48+ypIlSyynzubOnUvNmjVxdXXFMAwSEhIYMWIEAQEBeHt7c+edd7Jr1y6rbb755psEBgZSoUIFnnjiCVJSUqyev/EUWlZWFtOmTaN27dq4urpSvXp1Xn/9dQBq1KgBQIsWLTCZTHTt2jXXbaSmpvLss88SEBCAm5sbd9xxB5GRkZbn16xZg8lk4rfffqN169Z4eHgQHh7OoUOHivFoiojIzZy/nMbF5HRMJqjlr7B0ezIMSLtsn8Uwbrl8d3d30tPTAfjzzz/55ptv+O677yynwfr06UNMTAzLli1j27ZttGzZkrvuuov4+HgAvvnmGyZOnMjrr7/O1q1bCQ4OZtasWfnuc9y4cUybNo0JEyawf/9+vvrqKwIDAwHYsmULACtXriQ6OprFixfnuo2xY8fy3XffMX/+fLZv307t2rXp2bOnpa5s48eP56233mLr1q04OTkxbNiwIh8rEREpvCNXT8FVr+SBm7P9r4QDnYazvfRkeCPEPvv+1xlwKfp8FVu2bOGrr77irrvuAiAtLY0FCxbg7+8PwKpVq9izZw+xsbG4uroC8J///IclS5bw7bffMmLECGbMmMGwYcP4+9//DsC///1vVq5cmaN3KVtSUhLvvvsu77//PoMHDwagVq1a3HHHHQCWfVeuXJmgoKBct5F92nDevHn07t0bgDlz5rBixQo+/fRT/vnPf1ravv7663Tp0gWAl19+mT59+pCSkoKbm1uRj5uIiBTcwZhEAOoElI7xSqCe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z+OsAd4iIiIi+VDPkoiIiEg+FJZERERE8qGwJCIiIpIPhSURERGRfCgslWKzZs2iRo0auLm50apVK9atW2fvksq0SZMmYTKZrJagoCDL84ZhMGnSJEJCQnB3d6dr167s27fPjhWXHb///jv9+vUjJCQEk8nEkiVLrJ4vyLFNTU3lmWeewc/PD09PT+655x5OnTplw3dR+t3sOA8ZMiTHd7x9+/ZWbXScb27q1Km0adOGChUqEBAQwIABAzh06JBVG32ni0dBjnVp+F4rLJVSixYtYvTo0YwfP54dO3bQqVMnevfuTVRUlL1LK9MaNWpEdHS0ZdmzZ4/luenTp/P222/z/vvvExkZSVBQED169LDc+0/ydvnyZZo1a8b777+f6/MFObajR4/m+++/5+uvv2b9+vVcunSJvn37kpmZaau3Uerd7DgD9OrVy+o7vmzZMqvndZxvbu3atTz11FNs2rSJFStWkJGRQUREBJcvX7a00Xe6eBTkWEMp+F4bUiq1bdvWGDlypNW6+vXrGy+//LKdKir7Jk6caDRr1izX57KysoygoCDjzTfftKxLSUkxfHx8jA8//NBGFZYPgPH9999bfi7Isb148aLh7OxsfP3115Y2p0+fNhwcHIxffvnFZrWXJTceZ8MwjMGDBxv9+/fP8zU6zkUTGxtrAMbatWsNw9B3uiTdeKwNo3R8r9WzVAqlpaWxbds2IiIirNZHRESwYcMGO1VVPhw5coSQkBBq1KjBQw89xLFjxwA4fvw4MTExVsfc1dWVLl266JjfooIc223btpGenm7VJiQkhMaNG+v4F9KaNWsICAigbt26DB8+nNjYWMtzOs5Fk5CQAEClSpUAfadL0o3HOpu9v9cKS6VQXFwcmZmZBAYGWq0PDAwkJibGTlWVfe3atePzzz/n119/Zc6cOcTExBAeHs758+ctx1XHvPgV5NjGxMTg4uJCxYoV82wjN9e7d2++/PJLVq1axVtvvUVkZCR33nknqampgI5zURiGwZgxY7jjjjto3LgxoO90ScntWEPp+F47FctWpESYTCarnw3DyLFOCq53796Wx02aNKFDhw7UqlWL+fPnWwYL6piXnKIcWx3/whk4cKDlcePGjWndujWhoaH89NNP3HfffXm+Tsc5b08//TS7d+9m/fr1OZ7Td7p45XWsS8P3Wj1LpZCfnx+Ojo45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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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+y6cnJzw/PPP49NPPy2vt0BERERE+eAY5QqGY5yIiIgqHm6/KyYOvSAiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKREREREQyGJSJiIiIiGQwKBMRERERyWBQJiIiIiKSwaBMRERERCSDQZmIiIiISAaDMhERERGRDAZlIiIiIiIZDMpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCgTEREREclgUCYiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKREREREQyGJSJiIiIiGQwKBMRERERybAu7wYQERGVJYPBgJycnPJuBj2D1Go1lErug3yWMCgTEVGlIIRAbGws7t+/X95NoWeUUqmEv78/1Gp1eTeFSgmDMhERVQrGkOzm5gZbW1soFIrybhI9Q3Jzc3H79m3ExMSgevXqXL6eEQzKRET0zDMYDFJIdnFxKe/m0DPK1dUVt2/fhl6vh0qlKu/mUCngQBoiInrmGcck29ralnNL6FlmHHJhMBjKuSVUWhiUiYio0uDhcHqSuHw9eyp1UM7OzsbFixeh1+vLuylERERE9JSplEE5PT0do0ePhq2tLRo0aICoqCgAwKRJkzBv3rxybh0REdHTY//+/VAoFLxaCFVKlTIoT5s2DX///Tf2798PrVYrlXfp0gUbNmwox5YRERGZGjFiBBQKBRQKBaytrVG9enW89dZbuHfvXrm0Z/Xq1XByciqX1yYqa5XyqhdbtmzBhg0b0KZNG5PxRPXr18c///xTji0jIiIy16NHD6xatQp6vR7nz5/HqFGjcP/+faxfv768m0b0TKuUe5Tv3r0LNzc3s/K0tDQOxCcioqeORqOBh4cHqlWrhm7dumHw4MHYuXOn9PyqVatQr149aLVa1K1bF0uWLJGey87OxoQJE+Dp6QmtVgs/Pz+EhoYCAK5fvw6FQoHIyEip/v3796FQKLB//36zduzfvx8jR45EUlKStJd71qxZAIAlS5agVq1a0Gq1cHd3x8CBA59IXxCVpUq5R7lly5bYvn07Jk6cCODhWarffvstgoKCyrNpRERURoQQyMgpn8t42aisir1j5urVq/jjjz+k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FQuDcgls2LABkydPxvTp0xEREYF27dqhZ8+eiIqKKnC6pKQkDB8+HJ07dy6jlhIRERFRUSmEEKK8G1FRtW7dGs2aNcPSpUulsnr16qF///4IDQ3Nd7ohQ4agVq1asLKywpYtWxAZGWnxayYnJ0On0yEpKQmOjo4laT4RERGVEW6/KybuUS6m7OxsnDx5Et26dTMp79atG44ePZrvdKtWrcI///yDmTNnPukmEhEREVEJWJd3Ayqq+Ph4GAwGuLu7m5S7u7sjNjZWdprLly/j/fffx6FDh2BtbVnXZ2VlISsrS3qcnJxc/EYTERERkcW4R7mEFAqFyWMhhFkZABgMBgwdOhSzZ89G7dq1LZ5/aGgodDqddPPx8Slxm4mIiIiocAzKxVS1alVYWVmZ7T2Oi4sz28sMACkpKThx4gQmTJgAa2trWFtbY86cOfj7779hbW2NvXv3yr7OtGnTkJSUJN2io6OfyPshIiIiIlMcelFMarUazZs3x65duzBgwACpfNeuXejXr59ZfUdHR5w5c8akbMmSJdi7dy9+/vln+Pv7y76ORqOBRqMp3cYTERERUaEYlEtgypQpGDZsGFq0aIGgoCB88803iIqKwtixYwHk7Q2+desWvv/+eyiVSjRs2NBkejc3N2i1WrNyIiIiIip/DMolMHjwYCQkJGDOnDmIiYlBw4YNERYWBl9fXwBATExModdUJiIiIqKnE6+jXMHwOoxEREQVD7ffFRNP5iMiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKREREREQyGJSJiIiIiGQwKBMRERERyWBQJiIiIiKSwaBMRERERCSDQZmIiIiISAaDMhERERGRDAZlIiIiIiIZDMpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCgTEREREclgUCYiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKREREREQyGJSJiIiIiGQwKBMRERERyWBQJiIiIiKSwaBMRERERCSDQZmIiIiISAaDMhERERGRDAZlIiIiIiIZDMpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCiX0JIlS+Dv7w+tVovmzZvj0KFD+dbdvHkzunbtCldXVzg6OiIoKAg7duwow9YSERERkaUYlEtgw4YNmDx5MqZPn46IiAi0a9cOPXv2RFRUlGz9gwcPomvXrggLC8PJkyfRqVMn9O3bFxEREWXcciIiIiIqjEIIIcq7ERVV69at0axZMyxdulQqq1evHvr374/Q0FCL5tGgQQMMHjwYM2bMsKh+cnIydDodkpKS4OjoWKx2ExERUdni9rti4h7lYsrOzsbJkyfRrVs3k/Ju3brh6NGjFs0jNzcXKSkpcHZ2zrdOVlYWkpOTTW5ERERE9OQxKBdTfHw8DAYD3N3dTcrd3d0RGxtr0TwWLFiAtLQ0DBo0KN86oaGh0Ol00s3Hx6dE7SYiIiIiyzAol5BCoTB5LIQwK5Ozfv16zJo1Cxs2bICbm1u+9aZNm4akpCTpFh0dXeI2ExEREVHhrMu7ARVV1apVYWVlZbb3OC4uzmwv8+M2bNiA0aNHY9OmTejSpUuBdTUaDTQaTYnbS0RERERFwz3KxaRWq9G8eXPs2rXLpHzXrl0IDg7Od7r169djxIgR+PHHH9G7d+8n3UwiIiIiKibuUS6BKVOmYNiwYWjRogWCgoLwzTffICoqCmPHjgWQN2zi1q1b+P777wHkheThw4dj0aJFaNOmjbQ32sbGBjqdrtzeBxERERGZY1AugcGDByMhIQFz5sxBTEwMGjZsiLCwMPj6+gIAYmJiTK6pvHz5cuj1eowfPx7jx4+XykNCQrB69eqybj4RERERFYDXUa5geB1GIiKiiofb74qJY5SJiIiIiGQwKBMRERERyWBQJiIiIiKSwaBMRERERCSDQZmIiIiISAaDMhERERGRDAZlIiIiIiIZDMpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCgTEREREclgUCYiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKREREREQyGJSJiIiIiGQwKBMRERERyWBQJiIiIiKSwaBMRERERCSDQZmIiIiISAaDMhERERGRDAZlIiIiIiIZDMpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCgTEREREclgUCYiIiIiksGgTEREREQkg0GZiIiIiEgGgzIRERERkQwGZSIiIiIiGQzKJbRkyRL4+/tDq9WiefPmOHToUIH1Dxw4gObNm0Or1aJGjRpYtmxZGbWUiIiIiIqCQbkENmzYgMmTJ2P69OmIiIhAu3bt0LNnT0RFRcnWv3btGnr16oV27dohIiICH3zwASZNmoRffvmljFtORERERIVRCCFEeTeiomrdujWaNWuGpUuXSmX16tVD//79ERoaalb/3//+N7Zu3YoLFy5IZWPHjsXff/+N8PBwi14zOTkZOp0OSbdvw9HR0byClRWg1T58nJaW/8yUSsDGpnh109OB/BYdhQKwtS1e3YwMIDc3/3bY2RWvbmYmYDCUTl1b27x2A0BWFqDXl05dG5u8fgaA7GwgJ6d06mq1ectFUevm5OTVz49GA1hbF72uXp/XF/lRqwGVquh1DYa8zy4/KlVe/aLWzc3NW9ZKo661dV5fAHnfifT00qlblO891xHydbmOKHpdriPy7lu4jpC230lJ8ttvejoJKpasrCxhZWUlNm/ebFI+adIk0b59e9lp2rVrJyZNmmRStnnzZmFtbS2ys7Nlp8nMzBRJSUnSLTo6WgAQSXmbFfNbr16mM7C1la8HCNGhg2ndqlXzr9uihWldX9/869avb1q3fv386/r6mtZt0SL/ulWrmtbt0CH/ura2pnV79cq/7uNfg4EDC66bmvqwbkhIwXXj4h7WHTeu4LrXrj2sO3VqwXXPnn1Yd+bMguseO/aw7vz5Bdfdt+9h3cWLC667bdvDuqtWFVx348aHdTduLLjuqlUP627bVnDdxYsf1t23r+C68+c/rHvsWMF1Z858WPfs2YLrTp36sO61awXXHTfuYd24uILrhoQ8rJuaWnDdgQOFiYLqch2Rd+M64uGN64i82xNeRyQlJQkAIikpSVDFwaEXxRQfHw+DwQB3d3eTcnd3d8TGxspOExsbK1tfr9cjPj5edprQ0FDodDrp5uPjUzpvgIiIiIgKxKEXxXT79m14e3vj6NGjCAoKkso//vhjrF27Fv/73//MpqlduzZGjhyJadOm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6NnAoRdERBbQ6XRQq9WwtbWFh4eHVL506VI0a9YMn3zyiVS2cuVK+Pj44NKlS6hduzYAoGbNmpg/f77JPB8d7+zv74+PPvoIb731FpYsWQK1Wg2dTgeFQmHyeo/bvXs3Tp8+jWvXrsHHxwcAsHbtWjRo0ADHjx9Hy5YtAQC5ublYvXo1HBwcAADDhg3Dnj178PHHH5esY4iInmHco0xEVAInT57Evn37YG9vL93q1q0LIG8vrlGLFi3Mpt23bx+6du0Kb29vODg4YPjw4UhISEBaWprFr3/hwgX4+PhIIRkA6tevDycnJ1y4cEEq8/Pzk0IyAHh6eiIuLq5I75WIqLLhHmUiohLIzc1F37598emnn5o95+npKd23s7Mzee7GjRvo1asXxo4di48++gjOzs44fPgwRo8ejZycHItfXwgBhUJRaLlKpTJ5XqFQIDc31+LXISKqjBiUiYgspFarYTAYTMqaNWuGX375BX5+frC2tnyVeuLECej1eixYsABKZd7BvY0bNxb6eo+rX78+oqKiEB0dLe1VPn/+PJKSklCvXj2L20NEROY49IKIyEJ+fn7466+/cP36dcTHxyM3Nxfjx49HYmIiXnnlFRw7dgxXr17Fzp07MWrUqAJDbkBAAPR6Pb766itcvXoVa9euxbJly8xeLzU1FXv27EF8fDzS09PN5tOlSxc0btwYr776Kk6dOoVjx45h+PDh6NChg+xwDyIishyDMhGRhaZOnQorKyvUr18frq6uiIqKgpeXF44cOQKDwYDu3bujYcOGePvtt6HT6aQ9xXKaNGmChQsX4tNPP0XDhg2xbt06hIaGmtQJDg7G2LFjMXjwYLi6upqdDAjkDaHYsmULqlSpgvbt26NLly6oUaMGNmzYUOrvn4ioslEIIUR5N4KIiIiI6GnDPcpERERERDIYlImIiIiIZDAoExERERHJYFAmIiIiIpLBoExEREREJINBmYiIiIhIBoMyEREREZEMBmUiIiIiIhkMykREREREMhiUiYiIiIhkMCgTEREREclgUCYiIiIikvH/tW8dvhaw7foAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "species = \"Barite\"\n", - "iterations = 250\n", - "cell_offset = 9\n", - "y_design = []\n", - "y_results = []\n", - "y_differences = []\n", - "\n", - "# if(preprocess.state['log'] == True):\n", - "# df_design_transformed, df_results_transformed = preprocess.funcTranform(df_design[species_columns], df_results[species_columns])\n", - "\n", - "df_design_transformed_scaled = preprocess.scaler_X.transform(df_design[species_columns])\n", - "df_results_transformed_scaled = preprocess.scaler_y.transform(df_results[species_columns])\n", - "\n", - "for i in range(0,iterations):\n", - " idx = i*50*50 + cell_offset-1\n", - " y_design.append(df_design_transformed_scaled.iloc[idx, :])\n", - " y_results.append(df_results_transformed_scaled.iloc[idx,:])\n", - " \n", - "y_design = pd.DataFrame(y_design)\n", - "y_results = pd.DataFrame(y_results)\n", - "\n", - "prediction = model_large.predict(y_design.iloc[:, y_design.columns != \"Class\"])\n", - "prediction = pd.DataFrame(prediction, columns = y_results.columns)\n", - "\n", - "# y_results_back, prediction = preprocess.funcInverse(y_results, prediction)\n", - "\n", - "y_results_back = pd.DataFrame(preprocess.scaler_y.inverse_transform(y_results), columns = species_columns)\n", - "prediction_back = pd.DataFrame(preprocess.scaler_X.inverse_transform(prediction), columns = species_columns)\n", - "\n", - "\n", - "plt.plot(np.arange(0,iterations), y_results_back[species], label = \"Results\")\n", - "plt.plot(np.arange(0,iterations), prediction_back[species], label = \"Prediction\")\n", - "plt.legend()\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel(species)\n", - "plt.title(species+' Concentration over Iterations in cell ' + str(cell_offset))\n", - "plt.legend()\n", - "plt.show()\n", - "\n", - "\n", - "mass_balance = np.abs((prediction_back[\"Ba\"] + prediction_back[\"Barite\"]) - (y_results_back[\"Ba\"] + y_results_back[\"Barite\"])) \\\n", - " + np.abs((prediction_back[\"Sr\"] + prediction_back[\"Celestite\"]) - (y_results_back[\"Sr\"] + y_results_back[\"Celestite\"]))\n", - "plt.plot(np.arange(0,iterations), mass_balance, label = \"Results\")\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel(species)\n", - "plt.title(species+' Absolute Differences between predictions and true values Iterations in cell ' + str(cell_offset))\n", - "plt.axhline(y=1e-5, color='r', linestyle='--', label='Threshold 1e-5')\n", - "plt.legend()\n", - "\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
HOChargeBaClS_6_SrBariteCelestite
0111.01243455.510420-5.285676e-074.536952e-070.0000221.050707e-030.0006250.0010101.717461
1111.01243455.507697-5.292985e-071.091671e-060.0023993.700427e-040.0014880.0017381.716139
2111.01243455.506335-5.311407e-076.816584e-050.0089222.946349e-050.0044450.0048981.708478
3111.01243455.506229-5.326179e-071.435037e-030.0174143.035681e-060.0072810.0087781.698481
4111.01243455.506224-5.354202e-073.264876e-030.0262351.872898e-060.0097640.0126411.688408
..............................
995111.01243455.506217-5.369526e-076.381593e-020.2237701.220403e-070.0320961.7147230.000000
996111.01243455.506217-5.370535e-076.386712e-020.2237891.220029e-070.0320551.7147230.000000
997111.01243455.506217-5.371457e-076.391481e-020.2238071.219644e-070.0320171.7147230.000000
998111.01243455.506217-5.372196e-076.395922e-020.2238261.219672e-070.0319821.7147230.000000
999111.01243455.506217-5.372770e-076.400057e-020.2238441.220142e-070.0319501.7147230.000000
\n", - "

1000 rows × 9 columns

\n", - "
" - ], - "text/plain": [ - " H O Charge Ba Cl \\\n", - "0 111.012434 55.510420 -5.285676e-07 4.536952e-07 0.000022 \n", - "1 111.012434 55.507697 -5.292985e-07 1.091671e-06 0.002399 \n", - "2 111.012434 55.506335 -5.311407e-07 6.816584e-05 0.008922 \n", - "3 111.012434 55.506229 -5.326179e-07 1.435037e-03 0.017414 \n", - "4 111.012434 55.506224 -5.354202e-07 3.264876e-03 0.026235 \n", - ".. ... ... ... ... ... \n", - "995 111.012434 55.506217 -5.369526e-07 6.381593e-02 0.223770 \n", - "996 111.012434 55.506217 -5.370535e-07 6.386712e-02 0.223789 \n", - "997 111.012434 55.506217 -5.371457e-07 6.391481e-02 0.223807 \n", - "998 111.012434 55.506217 -5.372196e-07 6.395922e-02 0.223826 \n", - "999 111.012434 55.506217 -5.372770e-07 6.400057e-02 0.223844 \n", - "\n", - " S_6_ Sr Barite Celestite \n", - "0 1.050707e-03 0.000625 0.001010 1.717461 \n", - "1 3.700427e-04 0.001488 0.001738 1.716139 \n", - "2 2.946349e-05 0.004445 0.004898 1.708478 \n", - "3 3.035681e-06 0.007281 0.008778 1.698481 \n", - "4 1.872898e-06 0.009764 0.012641 1.688408 \n", - ".. ... ... ... ... \n", - "995 1.220403e-07 0.032096 1.714723 0.000000 \n", - "996 1.220029e-07 0.032055 1.714723 0.000000 \n", - "997 1.219644e-07 0.032017 1.714723 0.000000 \n", - "998 1.219672e-07 0.031982 1.714723 0.000000 \n", - "999 1.220142e-07 0.031950 1.714723 0.000000 \n", - "\n", - "[1000 rows x 9 columns]" - ] - }, - "execution_count": 99, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "y" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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16+fU5t3797dbNlgPq+S9NFHHzn1taioSJJ05513trhfMJzXU6dOacCAAVqwYIHL93/729/qhRde0IIFC/TRRx8pOTlZw4cPdzx/05Xi4mJlZ2crJydHu3btUk5OjsaPH69t27b5qxtuaamv1dXV2rFjh2bOnKkdO3Zo9erV+uKLL3Tbbbe1Wm+XLl2cznNZWZliYmL80QWPtHZuJWnkyJFO7S4sLGyxzmA8t5KanJ9XXnlFJpNJY8eObbHejnpu/cZAh3PdddcZkyZNctrWp08fY+rUqS7LP/XUU0afPn2ctj388MPG4MGD/dZGfzl8+LAhydi0aVOzZd59911DknHs2LH2a5gPzJo1yxgwYIDb5UPpvBqGYTz++ONG7969DZvN5vL9YD2vkow1a9Y4XttsNiM5OdmYN2+eY1tNTY0RHx9vLFmypNl6xo8fb4wcOdJp24gRI4y77rrL52321vl9deXDDz80JBlff/11s2VeffVVIz4+3reN8wNX/b3//vuNMWPGeFRPqJzbMWPGGDfffHOLZYLl3PoSI1IdTF1dnbZv366srCyn7VlZWdq6davLfYqLi5uUHzFihD7++GNZrVa/tdUfKisrJUkXXnhhq2WvvvpqpaSk6JZbbtG7777r76b5xP79+5Wamqq0tDTddddd+vLLL5stG0rnta6uTn/5y1/04IMPtvoA72A8r+cqLS1VeXm507mzWCwaNmxYs/+GpebPd0v7dESVlZUymUxKSEhosdzJkyfVq1cvXXzxxfrxj3+skpKS9mmgD7z33nvq3r27rrjiCk2cOFGHDx9usXwonNv/+7//0zvvvKOHHnqo1bLBfG69QZDqYCoqKtTQ0KCkpCSn7UlJSSovL3e5T3l5ucvy9fX1qqio8Ftbfc0wDOXl5emGG25Q//79my2XkpKipUuXatWqVVq9erWuvPJK3XLLLfrXv/7Vjq313KBBg/T6669r/fr1eumll1ReXq4hQ4boyJEjLsuHynmVpLVr1+r48eN64IEHmi0TrOf1fPZ/p578G7bv5+k+HU1NTY2mTp2qe+65p8UH2vbp00fLli3TunXrtHz5csXExOj666/X/v3727G13hk1apTeeOMN/fOf/9Tvf/97ffTRR7r55ptVW1vb7D6hcG5fe+01xcXF6Y477mixXDCfW29FBboBcO38v9oNw2jxL3lX5V1t78geffRRffLJJ9qyZUuL5a688kpdeeWVjteZmZk6ePCgnn/+ed14443+bqbXRo0a5fj+qquuUmZmpnr37q3XXntNeXl5LvcJhfMqSQUFBRo1apRSU1ObLROs57U5nv4b9nafjsJqtequu+6SzWbTokWLWiw7ePBgpwna119/va655hr96U9/0osvvujvprZJdna24/v+/ftr4MCB6tWrl955550WQ0Ywn1tJeuWVV/TTn/601blOwXxuvcWIVAfTrVs3RUZGNvlL5fDhw03+orFLTk52WT4qKkpdu3b1W1t96Ze//KXWrVund999VxdffLHH+w8ePDjo/uLp3LmzrrrqqmbbHQrnVZK+/vprbdy4URMmTPB432A8r/Y7MT35N2zfz9N9Ogqr1arx48ertLRURUVFLY5GuRIREaFrr7026M611DiS2qtXrxbbHsznVpI2b96sffv2efVvOJjPrbsIUh1MdHS0MjIyHHc42RUVFWnIkCEu98nMzGxSfsOGDRo4cKDMZrPf2uoLhmHo0Ucf1erVq/XPf/5TaWlpXtVTUlKilJQUH7fOv2pra7V3795m2x3M5/Vcr776qrp3764f/ehHHu8bjOc1LS1NycnJTueurq5OmzZtavbfsNT8+W5pn47AHqL279+vjRs3ehXyDcPQzp07g+5cS9KRI0d08ODBFtserOfWrqCgQBkZGRowYIDH+wbzuXVboGa5o3krVqwwzGazUVBQYOzZs8eYPHmy0blzZ+Orr74yDMMwpk6dauTk5DjKf/nll0ZsbKwxZcoUY8+ePUZBQYFhNpuNt956K1BdcNsjjzxixMfHG++9955RVlbm+KqurnaUOb+/f/jDH4w1a9YYX3zxhfHpp58aU6dONSQZq1atCkQX3PbEE08Y7733nvHll18aH3zwgfHjH//YiIuLC8nzatfQ0GD07NnTePrpp5u8F8zn9cSJE0ZJSYlRUlJiSDJeeOEFo6SkxHGn2rx584z4+Hhj9erVxu7du427777bSElJMaqqqhx15OTkON2J+/777xuRkZHGvHnzjL179xrz5s0zoqKijA8++KDd+3eulvpqtVqN2267zbj44ouNnTt3Ov0brq2tddRxfl9nz55t/OMf/zD+/e9/GyUlJcbPfvYzIyoqyti2bVsguuikpf6eOHHCeOKJJ4ytW7capaWlxrvvvmtkZmYa3/ve90Lu3NpVVlYasbGxxuLFi13WEUzn1l8IUh3UwoULjV69ehnR0dHGNddc47QcwP33328MGzbMqfx7771nXH311UZ0dLRxySWXNPtD39FIcvn16quvOsqc39/58+cbvXv3NmJiYozExETjhhtuMN555532b7yHsrOzjZSUFMNsNhupqanGHXfcYXz22WeO90PpvNqtX7/ekGTs27evyXvBfF7tSzWc/3X//fcbhtG4BMKsWbOM5ORkw2KxGDfeeKOxe/dupzqGDRvmKG/35ptvGldeeaVhNpuNPn36dIgQ2VJfS0tLm/03/O677zrqOL+vkydPNnr27GlER0cbF110kZGVlWVs3bq1/TvnQkv9ra6uNrKysoyLLrrIMJvNRs+ePY3777/fOHDggFMdoXBu7f785z8bnTp1Mo4fP+6yjmA6t/5iMowzs1cBAADgEeZIAQAAeIkgBQAA4CWCFAAAgJcIUgAAAF4iSAEAAHiJIAUAAOAlghQAAICXCFIAAABeIkgBQDsymUxau3ZtoJsBwEcIUgDCxgMPPCCTydTka+TIkYFuGoAgFRXoBgBAexo5cqReffVVp20WiyVArQEQ7BiRAhBWLBaLkpOTnb4SExMlNV52W7x4sUaNGqVOnTopLS1Nb775ptP+u3fv1s0336xOnTqpa9eu+vnPf66TJ086lXnllVfUr18/WSwWpaSk6NFHH3V6v6KiQj/5yU8UGxuryy+/XOvWrfNvpwH4DUEKAM4xc+ZMjR07Vrt27dK9996ru+++W3v37pUkVVdXa+TIkUpMTNRHH32kN998Uxs3bnQKSosXL9YvfvEL/fznP9fu3bu1bt06XXbZZU7HmDNnjsaPH69PPvlEo0eP1k9/+lMdPXq0XfsJwEcMAAgT999/vxEZGWl07tzZ6evZZ581DMMwJBmTJk1y2mfQoEHGI488YhiGYSxdutRITEw0Tp486Xj/nXfeMSIiIozy8nLDMAwjNTXVmD59erNtkGTMmDHD8frkyZOGyWQy/v73v/usnwDaD3OkAISVH/7wh1q8eLHTtgsvvNDxfWZmptN7mZmZ2rlzpyRp7969GjBggDp37ux4//rrr5fNZtO+fftkMpl06NAh3XLLLS224fvf/77j+86dOysuLk6HDx/2tksAAoggBSCsdO7cucmlttaYTCZJkmEYju9dlenUqZNb9ZnN5ib72mw2j9oEoGNgjhQAnOODDz5o8rpPnz6SpPT0dO3cuVOnTp1yvP/+++8rIiJCV1xxheLi4nTJJZfo//2//9eubQYQOIxIAQgrtbW1Ki8vd9oWFRWlbt26SZLefPNNDRw4UDfccIPeeOMNffjhhyooKJAk/fSnP9WsWbN0//33a/bs2fruu+/0y1/+Ujk5OUpKSpIkzZ49W5MmTVL37t01atQonThxQu+//75++ctftm9HAbQLghSAsPKPf/xDKSkpTtuuvPJKff7555Ia76hbsWKFcnNzlZycrDfeeEPp6emSpNjYWK1fv16PP/64rr32WsXGxmrs2LF64YUXHHXdf//9qqmp0R/+8Af96le/Urdu3TRu3Lj26yCAdmUyDMMIdCMAoCMwmUxas2aNbr/99kA3BUCQYI4UAACAlwhSAAAAXmKOFACcwUwHAJ5iRAoAAMBLBCkAAAAvEaQAAAC8RJACAADwEkEKAADASwQpAAAALxGkAAAAvESQAgAA8NL/D3qRss4b1+VXAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "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": [ - "
" - ] - }, - "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": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m3938/3938\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 827us/step - loss: 70.7642\n" - ] - }, - { - "data": { - "text/plain": [ - "70.69287872314453" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# test on all test data\n", - "model_simple.evaluate(X_test.loc[:, X_test.columns != \"Class\"], y_test.loc[:, y_test.columns != \"Class\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m3747/3747\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 733us/step - loss: 67.2305\n" - ] - }, - { - "data": { - "text/plain": [ - "67.27115631103516" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# test on non-reactive data\n", - "model_simple.evaluate(X_test[X_test['Class'] == 0].iloc[:,X_test.columns != \"Class\"], y_test[X_test['Class'] == 0].iloc[:, y_test.columns != \"Class\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m 1/192\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m2s\u001b[0m 12ms/step - loss: 148.6424" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m192/192\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 749us/step - loss: 139.3093\n" - ] - }, - { - "data": { - "text/plain": [ - "137.7884521484375" - ] - }, - "execution_count": 36, - "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": [ - "## Save the model" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [], - "source": [ - "# Save the model\n", - "model.save(\"Barite_50_Model_additional_species.keras\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "ai", - "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 -} diff --git a/barite_50_4_corner.h5 b/barite_50_4_corner.h5 deleted file mode 100644 index f55a844..0000000 --- a/barite_50_4_corner.h5 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d135c6696d4a0068b442f8e58c77842dcc8c229b79fe9ae0af030cfc3e813bf7 -size 62127814 diff --git a/convert_data.jl b/convert_data.jl deleted file mode 100644 index 3cd3cc9..0000000 --- a/convert_data.jl +++ /dev/null @@ -1,60 +0,0 @@ -using HDF5 -using RData - -using DataFrames - -# Load Training Data -# train_data = load("Barite_50_Data.rds") - -# training_h5_name = "Barite_50_Data.h5" -# h5open(training_h5_name, "w") do fid -# for key in keys(train_data) -# group = create_group(fid, key) -# group["names"] = names(train_data[key]) -# group["data", compress=3] = Matrix(train_data[key]) -# # group = create_group(fid, key) -# # grou["names"] = coln -# end -# end - -# List all .rds files starting with "iter" in a given directory -rds_files = filter(x -> startswith(x, "iter"), readdir("barite_out/")) - -# remove "iter_0.rds" from the list -rds_files = rds_files[2:end] - -big_df_in = DataFrame() -big_df_out = DataFrame() - -for rds_file in rds_files - # Load the RDS file - data = load("barite_out/$rds_file") - # Convert the data to a DataFrame - df_T = DataFrame(data["T"]) - df_C = DataFrame(data["C"]) - # Append the DataFrame to the big DataFrame - append!(big_df_in, df_T) - append!(big_df_out, df_C) -end - -# remove ID, Barite_p1, Celestite_p1 columns -big_df_in = big_df_in[:, Not([:ID, :Barite_p1, :Celestite_p1])] -big_df_out = big_df_out[:, Not([:ID, :Barite_p1, :Celestite_p1])] - -inference_h5_name = "Barite_50_Data_inference.h5" -h5open(inference_h5_name, "w") do fid - fid["names"] = names(big_df_in) - fid["data", compress=9] = Matrix(big_df_in) -end - -training_h5_name = "Barite_50_Data_training.h5" -h5open(training_h5_name, "w") do fid - group_in = create_group(fid, "design") - group_out = create_group(fid, "result") - - group_in["names"] = names(big_df_in) - group_in["data", compress=9] = Matrix(big_df_in) - - group_out["names"] = names(big_df_out) - group_out["data", compress=9] = Matrix(big_df_out) -end \ No newline at end of file diff --git a/loss_1_to_end.png b/loss_1_to_end.png deleted file mode 100644 index fe5b726..0000000 Binary files a/loss_1_to_end.png and /dev/null differ diff --git a/loss_all.png b/loss_all.png deleted file mode 100644 index 9b45cb2..0000000 Binary files a/loss_all.png and /dev/null differ diff --git a/optuna_runs.py b/optuna_runs.py deleted file mode 100644 index 0df7b3f..0000000 --- a/optuna_runs.py +++ /dev/null @@ -1,225 +0,0 @@ -import keras -from keras.layers import Dense, Dropout, Input,BatchNormalization -import tensorflow as tf -import h5py -import numpy as np -import pandas as pd -import time -import sklearn.model_selection as sk -import matplotlib.pyplot as plt -from sklearn.cluster import KMeans -from sklearn.pipeline import Pipeline, make_pipeline -from sklearn.preprocessing import StandardScaler, MinMaxScaler -from imblearn.over_sampling import SMOTE -from imblearn.under_sampling import RandomUnderSampler -from imblearn.over_sampling import RandomOverSampler -from collections import Counter -import os -from preprocessing import * -from sklearn import set_config -from importlib import reload -set_config(transform_output = "pandas") - -dtype = "float32" -activation = "relu" - -lr = 0.001 -batch_size = 512 -epochs = 50 # default 400 epochs - -lr_schedule = keras.optimizers.schedules.ExponentialDecay( - initial_learning_rate=lr, - decay_steps=2000, - decay_rate=0.9, - staircase=True -) - -optimizer_simple = keras.optimizers.Adam(learning_rate=lr_schedule) -optimizer_large = keras.optimizers.Adam(learning_rate=lr_schedule) -optimizer_paper = keras.optimizers.Adam(learning_rate=lr_schedule) - -sample_fraction = 0.8 - -# small model -model_simple = keras.Sequential( - [ - keras.Input(shape = (9,), dtype = "float32"), - keras.layers.Dense(units = 128, activation = "linear", dtype = "float32"), - # Dropout(0.2), - keras.layers.Dense(units = 128, activation = "elu", dtype = "float32"), - keras.layers.Dense(units = 9, dtype = "float32") - ] -) - -def Safelog(val): - # get range of vector - if val > 0: - return np.log10(val) - elif val < 0: - return -np.log10(-val) - else: - return 0 - -def Safeexp(val): - if val > 0: - return -10 ** -val - elif val < 0: - return 10 ** val - else: - return 0 - -# ? Why does the charge is using another logarithm than the other species - -func_dict_in = { - "H" : np.log1p, - "O" : np.log1p, - "Charge" : Safelog, - "H_0_" : np.log1p, - "O_0_" : np.log1p, - "Ba" : np.log1p, - "Cl" : np.log1p, - "S_2_" : np.log1p, - "S_6_" : np.log1p, - "Sr" : np.log1p, - "Barite" : np.log1p, - "Celestite" : np.log1p, -} - -func_dict_out = { - "H" : np.expm1, - "O" : np.expm1, - "Charge" : Safeexp, - "H_0_" : np.expm1, - "O_0_" : np.expm1, - "Ba" : np.expm1, - "Cl" : np.expm1, - "S_2_" : np.expm1, - "S_6_" : np.expm1, - "Sr" : np.expm1, - "Barite" : np.expm1, - "Celestite" : np.expm1, -} - -# os.chdir('/mnt/beegfs/home/signer/projects/model-training') -data_file = h5py.File("barite_50_4_corner.h5") - -design = data_file["design"] -results = data_file["result"] - -df_design = pd.DataFrame(np.array(design["data"]).transpose(), columns = np.array(design["names"].asstr())) -df_results = pd.DataFrame(np.array(results["data"]).transpose(), columns = np.array(results["names"].asstr())) - -data_file.close() - -species_columns = ['H', 'O', 'Charge', 'Ba', 'Cl', 'S', 'Sr', 'Barite', 'Celestite'] - -preprocess = preprocessing(func_dict_in=func_dict_in, func_dict_out=func_dict_out) -X, y = preprocess.cluster(df_design[species_columns], df_results[species_columns]) -# X, y = preprocess.funcTranform(X, y) - -X_train, X_test, y_train, y_test = preprocess.split(X, y, ratio = 0.2) -X_train, y_train = preprocess.balancer(X_train, y_train, strategy = "over") -preprocess.scale_fit(X_train, y_train, scaling = "individual") -X_train, X_test, y_train, y_test = preprocess.scale_transform(X_train, X_test, y_train, y_test) -X_train, X_val, y_train, y_val = preprocess.split(X_train, y_train, ratio = 0.1) - -column_dict = {"Ba": X.columns.get_loc("Ba"), "Barite":X.columns.get_loc("Barite"), "Sr":X.columns.get_loc("Sr"), "Celestite":X.columns.get_loc("Celestite"), "H":X.columns.get_loc("H"), "H":X.columns.get_loc("H"), "O":X.columns.get_loc("O")} - -def custom_loss(preprocess, column_dict, h1, h2, h3, h4): - # extract the scaling parameters - scale_X = tf.convert_to_tensor(preprocess.scaler_X.scale_, dtype=tf.float32) - min_X = tf.convert_to_tensor(preprocess.scaler_X.min_, dtype=tf.float32) - scale_y = tf.convert_to_tensor(preprocess.scaler_y.scale_, dtype=tf.float32) - min_y = tf.convert_to_tensor(preprocess.scaler_y.min_, dtype=tf.float32) - - def loss(results, predicted): - # inverse min/max scaling - predicted_inverse = predicted * scale_X + min_X - results_inverse = results * scale_y + min_y - - # mass balance - dBa = tf.keras.backend.abs( - (predicted_inverse[:, column_dict["Ba"]] + predicted_inverse[:, column_dict["Barite"]]) - - (results_inverse[:, column_dict["Ba"]] + results_inverse[:, column_dict["Barite"]]) - ) - dSr = tf.keras.backend.abs( - (predicted_inverse[:, column_dict["Sr"]] + predicted_inverse[:, column_dict["Celestite"]]) - - (results_inverse[:, column_dict["Sr"]] + results_inverse[:, column_dict["Celestite"]]) - ) - - # H/O ratio has to be 2 - h2o_ratio = tf.keras.backend.abs( - (predicted_inverse[:, column_dict["H"]] / predicted_inverse[:, column_dict["O"]]) - 2 - ) - - # huber loss - huber_loss = tf.keras.losses.Huber()(results, predicted) - - # total loss - total_loss = h1 * huber_loss + h2 * dBa**2 + h3 * dSr**2 #+ h4 * h2o_ratio**2 - - return total_loss - - return loss - -def mass_balance(model, X, preprocess): - - # predict the chemistry - columns = X.iloc[:, X.columns != "Class"].columns - prediction = pd.DataFrame(model.predict(X[columns]), columns=columns) - - # backtransform min/max - X = pd.DataFrame(preprocess.scaler_X.inverse_transform(X.iloc[:, X.columns != "Class"]), columns=columns) - prediction = pd.DataFrame(preprocess.scaler_y.inverse_transform(prediction), columns=columns) - - # calculate mass balance dBa = np.abs((prediction["Ba"] + prediction["Barite"]) - (X["Ba"] + X["Barite"])) - dSr = np.abs((prediction["Sr"] + prediction["Celestite"]) - (X["Sr"] + X["Celestite"])) - - return dBa + dSr - -import optuna - -def create_model(model, preprocess, h1, h2, h3, h4): - - model.compile(optimizer=optimizer_simple, loss=custom_loss(preprocess, column_dict, h1, h2, h3, h4)) - - return model - - -def objective(trial, preprocess, X_train, y_train, X_val, y_val, X_test, y_test): - h1 = trial.suggest_float("h1", 0.1, 10) - h2 = trial.suggest_float("h2", 0.1, 10) - h3 = trial.suggest_float("h3", 0.1, 10) - h4 = trial.suggest_float("h4", 0.1, 10) - - model = create_model(model_simple, preprocess, h1, h2, h3, h4) - - callback = keras.callbacks.EarlyStopping(monitor='loss', patience=3) - history = model.fit(X_train.loc[:, X_train.columns != "Class"], - y_train.loc[:, y_train.columns != "Class"], - batch_size=batch_size, - epochs=50, - validation_data=(X_val.loc[:, X_val.columns != "Class"], y_val.loc[:, y_val.columns != "Class"]), - callbacks=[callback]) - - prediction_loss = model.evaluate(X_test.loc[:, X_test.columns != "Class"], y_test.loc[:, y_test.columns != "Class"]) - mass_balance_results = mass_balance(model, X_test, preprocess) - - mass_balance_ratio = len(mass_balance_results[mass_balance_results < 1e-5]) / len(mass_balance_results) - - return prediction_loss, mass_balance_ratio - -if __name__ == "__main__": - study = optuna.create_study(storage="sqlite:///model_optimization.db", study_name="model_optimization", directions=["minimize", "maximize"]) - study.optimize(lambda trial: objective(trial, preprocess, X_train, y_train, X_val, y_val, X_test, y_test), n_trials=1000) - - print("Number of finished trials: ", len(study.trials)) - - print("Best trial:") - trial = study.best_trial - - print(" Value: ", trial.value) - - print(" Params: ") - for key, value in trial.params.items(): - print(" {}: {}".format(key, value)) \ No newline at end of file diff --git a/preprocessing.py b/preprocessing.py deleted file mode 100644 index 4597334..0000000 --- a/preprocessing.py +++ /dev/null @@ -1,332 +0,0 @@ -import keras -print("Running Keras in version {}".format(keras.__version__)) - -import h5py -import numpy as np -import pandas as pd -import time -import sklearn.model_selection as sk -import matplotlib.pyplot as plt -from sklearn.cluster import KMeans -from imblearn.over_sampling import SMOTE -from imblearn.under_sampling import RandomUnderSampler -from imblearn.over_sampling import RandomOverSampler -from collections import Counter -import os -from sklearn.preprocessing import StandardScaler, MinMaxScaler -from sklearn.base import clone - -# preprocessing pipeline -# - -def Safelog(val): - # get range of vector - if val > 0: - return np.log10(val) - elif val < 0: - return -np.log10(-val) - else: - return 0 - -def Safeexp(val): - if val > 0: - return -10 ** -val - elif val < 0: - return 10 ** val - else: - return 0 - - -class FuncTransform(): - ''' - Class to transform and inverse transform data with given functions. - Transform and inverse transform functions have to be given as dictionaries in the following format: - {'key1': function1, 'key2': function2, ...} - ''' - - def __init__(self, func_transform, func_inverse): - self.func_transform = func_transform - self.func_inverse = func_inverse - - def fit(self, X, y=None): - return self - - def transform(self, X, y=None): - X = X.copy() - for key in X.keys(): - if "Class" not in key: - X[key] = X[key].apply(self.func_transform[key]) - return X - - def fit_transform(self, X, y=None): - self.fit(X) - return self.transform(X, y) - - def inverse_transform(self, X_log): - X_log = X_log.copy() - for key in X_log.keys(): - if "Class" not in key: - X_log[key] = X_log[key].apply(self.func_inverse[key]) - return X_log - - -def clustering(X, n_clusters=2, random_state=42, x_length=50, y_length=50, species='Barite'): - ''' - Function to cluster data with KMeans. - ''' - - class_labels = np.array([]) - grid_length = x_length * y_length - iterations = int(len(X) / grid_length) - - for i in range(0, iterations): - field = np.array(X[species][(i*grid_length):(i*grid_length+grid_length)] - ).reshape(x_length, y_length) - kmeans = KMeans(n_clusters=n_clusters, random_state=random_state).fit( - field.reshape(-1, 1)) - - class_labels = np.append(class_labels.astype(int), kmeans.labels_) - - if("Class" in X.columns): - print("Class column already exists") - else: - class_labels_df = pd.DataFrame(class_labels, columns=['Class']) - X_clustered = pd.concat([X, class_labels_df], axis=1) - - return X_clustered - - -def balancer(design, target, strategy, sample_fraction=0.5): - - number_features = (design.columns != "Class").sum() - if("Class" not in design.columns): - if("Class" in target.columns): - classes = target['Class'] - else: - raise Exception("No class column found") - else: - classes = design['Class'] - counter = classes.value_counts() - print("Amount class 0 before:", counter[0] / (counter[0] + counter[1]) ) - print("Amount class 1 before:", counter[1] / (counter[0] + counter[1]) ) - df = pd.concat([design.loc[:,design.columns != "Class"], target.loc[:, target.columns != "Class"], classes], axis=1) - - if strategy == 'smote': - print("Using SMOTE strategy") - smote = SMOTE(sampling_strategy=sample_fraction) - df_resampled, classes_resampled = smote.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df.columns == "Class"]) - - elif strategy == 'over': - print("Using Oversampling") - over = RandomOverSampler() - df_resampled, classes_resampled = over.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df.columns == "Class"]) - - elif strategy == 'under': - print("Using Undersampling") - under = RandomUnderSampler() - df_resampled, classes_resampled = under.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df.columns == "Class"]) - - else: - return design, target - - counter = classes_resampled["Class"].value_counts() - print("Amount class 0 after:", counter[0] / (counter[0] + counter[1]) ) - print("Amount class 1 after:", counter[1] / (counter[0] + counter[1]) ) - - design_resampled = pd.concat([df_resampled.iloc[:,0:number_features], classes_resampled], axis=1) - target_resampled = pd.concat([df_resampled.iloc[:,number_features:], classes_resampled], axis=1) - - return design_resampled, target_resampled - - -def plot_simulation(X, timestep, component='Barite', x_length=50, y_length=50): - grid_length = x_length * y_length - max_iter = int(len(X) / grid_length) - if(timestep >= max_iter): - raise Exception("timestep is not in the simulation range") - - plt.imshow(np.array(X[component][(timestep*grid_length):(timestep*grid_length+grid_length)]).reshape(x_length,y_length), interpolation='bicubic', origin='lower') - - if("Class" in X.columns): - plt.contour(np.array(X['Class'][(timestep*grid_length):(timestep*grid_length+grid_length)]).reshape(x_length,y_length), levels=[0.1], colors='red', origin='lower') - - plt.show() - - -def preprocessing_training(df_design, df_targets, func_dict_in, func_dict_out, sampling, scaling, test_size): - - df_design = clustering(df_design) - df_targets = pd.concat([df_targets, df_design['Class']], axis=1) - - df_design_log = FuncTransform(func_dict_in, func_dict_out).fit_transform(df_design) - df_results_log = FuncTransform(func_dict_in, func_dict_out).fit_transform(df_targets) - - X_train, X_test, y_train, y_test = sk.train_test_split(df_design_log, df_results_log, test_size = test_size, random_state=42) - - X_train, y_train = balancer(X_train, y_train, sampling) - - scaler_X = MinMaxScaler() - scaler_y = MinMaxScaler() - - if scaling == 'individual': - scaler_X.fit(X_train.iloc[:, X_train.columns != "Class"]) - scaler_y.fit(y_train.iloc[:, y_train.columns != "Class"]) - - elif scaling == 'global': - scaler_X.fit(pd.concat([X_train.iloc[:, X_train.columns != "Class"], y_train.iloc[:, y_train.columns != "Class"]], axis=0)) - scaler_y = scaler_X - - X_train = pd.concat([scaler_X.transform(X_train.loc[:, X_train.columns != "Class"]), X_train.loc[:, "Class"]], axis=1) - X_test = pd.concat([scaler_X.transform(X_test.loc[:, X_test.columns != "Class"]), X_test.loc[:, "Class"]], axis=1) - - y_train = pd.concat([scaler_y.transform(y_train.loc[:, y_train.columns != "Class"]), y_train.loc[:, "Class"]], axis=1) - y_test = pd.concat([scaler_y.transform(y_test.loc[:, y_test.columns != "Class"]), y_test.loc[:, "Class"]], axis=1) - - X_train, X_val, y_train, y_val = sk.train_test_split(X_train, y_train, test_size = 0.1) - - return X_train, X_val, X_test, y_train, y_val, y_test, scaler_X, scaler_y - - - -class preprocessing: - - def __init__(self, func_dict_in, func_dict_out, random_state=42): - self.random_state = random_state - self.scaler_X = None - self.scaler_y = None - self.func_dict_in = func_dict_in - self.func_dict_out = func_dict_out - self.state = {"cluster": False, "log": False, "balance": False, "scale": False} - - def funcTranform(self, X, y): - for key in X.keys(): - if "Class" not in key: - X[key] = X[key].apply(self.func_dict_in[key]) - y[key] = y[key].apply(self.func_dict_in[key]) - self.state["log"] = True - - return X, y - - def funcInverse(self, X, y): - - for key in X.keys(): - if "Class" not in key: - X[key] = X[key].apply(self.func_dict_out[key]) - y[key] = y[key].apply(self.func_dict_out[key]) - self.state["log"] = False - return X, y - - def cluster(self, X, y, species='Barite', n_clusters=2, x_length=50, y_length=50): - - class_labels = np.array([]) - grid_length = x_length * y_length - iterations = int(len(X) / grid_length) - - for i in range(0, iterations): - field = np.array(X[species][(i*grid_length):(i*grid_length+grid_length)] - ).reshape(x_length, y_length) - kmeans = KMeans(n_clusters=n_clusters, random_state=self.random_state).fit(field.reshape(-1, 1)) - class_labels = np.append(class_labels.astype(int), kmeans.labels_) - - if ("Class" in X.columns and "Class" in y.columns): - print("Class column already exists") - else: - class_labels_df = pd.DataFrame(class_labels, columns=['Class']) - X = pd.concat([X, class_labels_df], axis=1) - y = pd.concat([y, class_labels_df], axis=1) - self.state["cluster"] = True - - return X, y - - - def balancer(self, X, y, strategy, sample_fraction=0.5): - - number_features = (X.columns != "Class").sum() - if("Class" not in X.columns): - if("Class" in y.columns): - classes = y['Class'] - else: - raise Exception("No class column found") - else: - classes = X['Class'] - counter = classes.value_counts() - print("Amount class 0 before:", counter[0] / (counter[0] + counter[1]) ) - print("Amount class 1 before:", counter[1] / (counter[0] + counter[1]) ) - df = pd.concat([X.loc[:,X.columns != "Class"], y.loc[:, y.columns != "Class"], classes], axis=1) - - if strategy == 'smote': - print("Using SMOTE strategy") - smote = SMOTE(sampling_strategy=sample_fraction) - df_resampled, classes_resampled = smote.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df. columns == "Class"]) - - elif strategy == 'over': - print("Using Oversampling") - over = RandomOverSampler() - df_resampled, classes_resampled = over.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df. columns == "Class"]) - - elif strategy == 'under': - print("Using Undersampling") - under = RandomUnderSampler() - df_resampled, classes_resampled = under.fit_resample(df.loc[:, df.columns != "Class"], df.loc[:, df. columns == "Class"]) - - else: - return X, y - - counter = classes_resampled["Class"].value_counts() - print("Amount class 0 after:", counter[0] / (counter[0] + counter[1]) ) - print("Amount class 1 after:", counter[1] / (counter[0] + counter[1]) ) - - design_resampled = pd.concat([df_resampled.iloc[:,0:number_features], classes_resampled], axis=1) - target_resampled = pd.concat([df_resampled.iloc[:,number_features:], classes_resampled], axis=1) - - self.state['balance'] = True - return design_resampled, target_resampled - - - def scale_fit(self, X, y, scaling): - - if scaling == 'individual': - self.scaler_X = MinMaxScaler() - self.scaler_y = MinMaxScaler() - self.scaler_X.fit(X.iloc[:, X.columns != "Class"]) - self.scaler_y.fit(y.iloc[:, y.columns != "Class"]) - - elif scaling == 'global': - self.scaler_X = MinMaxScaler() - self.scaler_X.fit(pd.concat([X.iloc[:, X.columns != "Class"], y.iloc[:, y.columns != "Class"]], axis=0)) - self.scaler_y = self.scaler_X - - self.state['scale'] = True - - def scale_transform(self, X_train, X_test, y_train, y_test): - X_train = pd.concat([self.scaler_X.transform(X_train.loc[:, X_train.columns != "Class"]), X_train.loc[:, "Class"]], axis=1) - - X_test = pd.concat([self.scaler_X.transform(X_test.loc[:, X_test.columns != "Class"]), X_test.loc[:, "Class"]], axis=1) - - y_train = pd.concat([self.scaler_y.transform(y_train.loc[:, y_train.columns != "Class"]), y_train.loc[:, "Class"]], axis=1) - - y_test = pd.concat([self.scaler_y.transform(y_test.loc[:, y_test.columns != "Class"]), y_test.loc[:, "Class"]], axis=1) - - return X_train, X_test, y_train, y_test - - def scale_inverse(self, X): - - if("Class" in X.columns): - X = pd.concat([self.scaler_X.inverse_transform(X.loc[:, X.columns != "Class"]), X.loc[:, "Class"]], axis=1) - else: - X = self.scaler_X.inverse_transform(X) - - return X - - def split(self, X, y, ratio=0.8): - X_train, y_train, X_test, y_test = sk.train_test_split(X, y, test_size = ratio, random_state=self.random_state) - - return X_train, y_train, X_test, y_test - - - - - - - - \ No newline at end of file diff --git a/src/preprocessing.py b/src/preprocessing.py index 29a4ac5..16679ce 100644 --- a/src/preprocessing.py +++ b/src/preprocessing.py @@ -177,7 +177,6 @@ def mass_balance_metric(preprocess, column_dict, scaler_type="minmax"): (predicted_inverse[:, column_dict["Sr"]] + predicted_inverse[:, column_dict["Celestite"]]) - (results_inverse[:, column_dict["Sr"]] + results_inverse[:, column_dict["Celestite"]]) ) - return tf.reduce_mean(dBa + dSr) return mass_balance