mirror of
https://git.gfz-potsdam.de/naaice/model-training.git
synced 2025-12-15 19:48:23 +01:00
976 lines
145 KiB
Plaintext
976 lines
145 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## General Information"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This notebook is used to train a simple neural network model to predict the chemistry in the barite benchmark (50x50 grid). The training data is stored in the repository using **git large file storage** and can be downloaded after the installation of git lfs using the `git lfs pull` command.\n",
|
|
"\n",
|
|
"It is then recommended to create a Python environment using miniconda. The necessary dependencies are contained in `environment.yml` and can be installed using `conda env create -f environment.yml`.\n",
|
|
"\n",
|
|
"The data set is divided into a design and result part and consists of the iterations of a reference simulation. The design part of the data set contains the chemical concentrations at time $t$ and the result part at time $t+1$, which are to be learned by the model."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Setup Libraries"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2025-01-22 15:50:06.981475: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
|
|
"2025-01-22 15:50:07.001765: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
|
|
"To enable the following instructions: SSE4.1 SSE4.2 AVX AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Running Keras in version 3.6.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import keras\n",
|
|
"import h5py\n",
|
|
"import numpy as np\n",
|
|
"import pandas as pd\n",
|
|
"import time\n",
|
|
"import sklearn.model_selection as sk\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from sklearn.cluster import KMeans\n",
|
|
"from sklearn.pipeline import Pipeline, make_pipeline\n",
|
|
"from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
|
|
"from imblearn.over_sampling import SMOTE\n",
|
|
"from imblearn.under_sampling import RandomUnderSampler\n",
|
|
"from imblearn.over_sampling import RandomOverSampler\n",
|
|
"from collections import Counter\n",
|
|
"import os\n",
|
|
"from preprocessing import *\n",
|
|
"from sklearn import set_config\n",
|
|
"set_config(transform_output = \"pandas\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Define parameters"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"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",
|
|
"\n",
|
|
"loss = keras.losses.Huber()\n",
|
|
"\n",
|
|
"sample_fraction = 0.8"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Setup the model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1mModel: \"sequential\"\u001b[0m\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">16,512</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,548</span> │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_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;34m12\u001b[0m) │ \u001b[38;5;34m1,548\u001b[0m │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"model_simple = keras.Sequential(\n",
|
|
" [\n",
|
|
" keras.Input(shape = (12,), dtype = \"float32\"),\n",
|
|
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
|
|
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
|
|
" keras.layers.Dense(units = 12, dtype = \"float32\")\n",
|
|
" ]\n",
|
|
")\n",
|
|
"\n",
|
|
"model_simple.compile(optimizer=optimizer_simple, loss = loss)\n",
|
|
"model_simple.summary()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_1\"</span>\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1mModel: \"sequential_1\"\u001b[0m\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,656</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1024</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">524,800</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_6 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,156</span> │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m6,656\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_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;34m12\u001b[0m) │ \u001b[38;5;34m6,156\u001b[0m │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"model_large = keras.Sequential(\n",
|
|
" [keras.layers.Input(shape=(12,), dtype=dtype),\n",
|
|
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
|
|
" keras.layers.Dense(1024, activation='relu', dtype=dtype),\n",
|
|
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
|
|
" keras.layers.Dense(12, dtype=dtype)\n",
|
|
" ])\n",
|
|
"\n",
|
|
"model_large.compile(optimizer=optimizer_large, loss = loss)\n",
|
|
"model_large.summary()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Define transformer functions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"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": 6,
|
|
"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": 7,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# os.chdir('/mnt/beegfs/home/signer/projects/model-training')\n",
|
|
"data_file = h5py.File(\"Barite_50_Data_training.h5\")\n",
|
|
"\n",
|
|
"design = data_file[\"design\"]\n",
|
|
"results = data_file[\"result\"]\n",
|
|
"\n",
|
|
"df_design = pd.DataFrame(np.array(design[\"data\"]).transpose(), columns = design[\"names\"].asstr())\n",
|
|
"df_results = pd.DataFrame(np.array(results[\"data\"]).transpose(), columns = results[\"names\"].asstr())\n",
|
|
"\n",
|
|
"data_file.close()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/home/signer/bin/miniconda3/envs/training/lib/python3.11/site-packages/sklearn/base.py:1473: ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (2). Possibly due to duplicate points in X.\n",
|
|
" return fit_method(estimator, *args, **kwargs)\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Amount class 0 before: 0.9879169719169719\n",
|
|
"Amount class 1 before: 0.012083028083028084\n"
|
|
]
|
|
},
|
|
{
|
|
"ename": "KeyError",
|
|
"evalue": "'Class'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/pandas/core/indexes/base.py:3805\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 3804\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 3805\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_engine\u001b[38;5;241m.\u001b[39mget_loc(casted_key)\n\u001b[1;32m 3806\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n",
|
|
"File \u001b[0;32mindex.pyx:167\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
|
|
"File \u001b[0;32mindex.pyx:175\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
|
|
"File \u001b[0;32mpandas/_libs/index_class_helper.pxi:70\u001b[0m, in \u001b[0;36mpandas._libs.index.Int64Engine._check_type\u001b[0;34m()\u001b[0m\n",
|
|
"\u001b[0;31mKeyError\u001b[0m: 'Class'",
|
|
"\nThe above exception was the direct cause of the following exception:\n",
|
|
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[9], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m X_train, X_val, X_test, y_train, y_val, y_test \u001b[38;5;241m=\u001b[39m preprocessing(df_design, df_results, func_dict_in, func_dict_out, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124moff\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m0.1\u001b[39m)\n",
|
|
"File \u001b[0;32m~/Documents/model-training/preprocessing.py:164\u001b[0m, in \u001b[0;36mpreprocessing\u001b[0;34m(df_design, df_targets, func_dict_in, func_dict_out, sampling, test_size)\u001b[0m\n\u001b[1;32m 160\u001b[0m df_results_log \u001b[38;5;241m=\u001b[39m FuncTransform(func_dict_in, func_dict_out)\u001b[38;5;241m.\u001b[39mfit_transform(df_targets)\n\u001b[1;32m 162\u001b[0m X_train, X_test, y_train, y_test \u001b[38;5;241m=\u001b[39m sk\u001b[38;5;241m.\u001b[39mtrain_test_split(df_design_log, df_results_log, test_size \u001b[38;5;241m=\u001b[39m test_size, random_state\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m42\u001b[39m)\n\u001b[0;32m--> 164\u001b[0m X_train, y_train \u001b[38;5;241m=\u001b[39m balancer(X_train, y_train, sampling)\n\u001b[1;32m 166\u001b[0m scaler_X \u001b[38;5;241m=\u001b[39m MinMaxScaler()\n\u001b[1;32m 167\u001b[0m scaler_y \u001b[38;5;241m=\u001b[39m MinMaxScaler()\n",
|
|
"File \u001b[0;32m~/Documents/model-training/preprocessing.py:131\u001b[0m, in \u001b[0;36mbalancer\u001b[0;34m(design, target, strategy, sample_fraction)\u001b[0m\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 129\u001b[0m classes_resampled \u001b[38;5;241m=\u001b[39m classes\n\u001b[0;32m--> 131\u001b[0m counter \u001b[38;5;241m=\u001b[39m classes_resampled[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClass\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mvalue_counts()\n\u001b[1;32m 132\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAmount class 0 after:\u001b[39m\u001b[38;5;124m\"\u001b[39m, counter[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;241m/\u001b[39m (counter[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;241m+\u001b[39m counter[\u001b[38;5;241m1\u001b[39m]) )\n\u001b[1;32m 133\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAmount class 1 after:\u001b[39m\u001b[38;5;124m\"\u001b[39m, counter[\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m/\u001b[39m (counter[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;241m+\u001b[39m counter[\u001b[38;5;241m1\u001b[39m]) )\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/pandas/core/series.py:1121\u001b[0m, in \u001b[0;36mSeries.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 1118\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_values[key]\n\u001b[1;32m 1120\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m key_is_scalar:\n\u001b[0;32m-> 1121\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_value(key)\n\u001b[1;32m 1123\u001b[0m \u001b[38;5;66;03m# Convert generator to list before going through hashable part\u001b[39;00m\n\u001b[1;32m 1124\u001b[0m \u001b[38;5;66;03m# (We will iterate through the generator there to check for slices)\u001b[39;00m\n\u001b[1;32m 1125\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_iterator(key):\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/pandas/core/series.py:1237\u001b[0m, in \u001b[0;36mSeries._get_value\u001b[0;34m(self, label, takeable)\u001b[0m\n\u001b[1;32m 1234\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_values[label]\n\u001b[1;32m 1236\u001b[0m \u001b[38;5;66;03m# Similar to Index.get_value, but we do not fall back to positional\u001b[39;00m\n\u001b[0;32m-> 1237\u001b[0m loc \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mindex\u001b[38;5;241m.\u001b[39mget_loc(label)\n\u001b[1;32m 1239\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_integer(loc):\n\u001b[1;32m 1240\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_values[loc]\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/pandas/core/indexes/base.py:3812\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 3807\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(casted_key, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m (\n\u001b[1;32m 3808\u001b[0m \u001b[38;5;28misinstance\u001b[39m(casted_key, abc\u001b[38;5;241m.\u001b[39mIterable)\n\u001b[1;32m 3809\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m casted_key)\n\u001b[1;32m 3810\u001b[0m ):\n\u001b[1;32m 3811\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key)\n\u001b[0;32m-> 3812\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[1;32m 3813\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[1;32m 3814\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[1;32m 3815\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[1;32m 3816\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n\u001b[1;32m 3817\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n",
|
|
"\u001b[0;31mKeyError\u001b[0m: 'Class'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"X_train, X_val, X_test, y_train, y_val, y_test = preprocessing(df_design, df_results, func_dict_in, func_dict_out, \"off\", 0.1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Classify each cell with kmeans"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/home/signer/bin/miniconda3/envs/training/lib/python3.11/site-packages/sklearn/base.py:1473: ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (2). Possibly due to duplicate points in X.\n",
|
|
" return fit_method(estimator, *args, **kwargs)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"df_design = clustering(df_design)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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TCyyRs5oIjqTDsHN9DsCAGa24BH66le/qiAIpk09g4OD06YjSdq7d6+GhoaqS39//4Juz8WH5MbPC0087mRNIqtEgUn/HdpYoUlkjJOxlTu2GsmZND7OaCI8XBUHAHO24IfjMpmM1q5dq56eHn3ve9+rru/p6dG2bdumPT+bzSqbzVY/d5U3/hw+P79780x+t+1ETokSxS79WHaJSnLKO6cLiTTqEo3GsQpJSaVSScVCSfGFvNxYTsmFQC7vVC5ahSUpLiUql2OZuCiXFGWSguRKcq4o54qSi9PfwSRySTz+S83rdwGAxaSskqSJv+eX5a6Bw4cPuyiK3O9//3v38ccfu46ODrdkyRL3z3/+84pf29/f75Tee4GFhYWFZREv/f39V/ybf03eRfv73/++/ve//+nnP/+5PvvsM61evVp//etfdeONN17xa1tbW9Xf36+GhgYZYzQ8PKy2tjb19/ersbHxWmzudYH9dHXYT1eH/XR12E8zc85pZGREra2tV3yuca62jxUNDw+rqalJQ0ND/Jd8Geynq8N+ujrsp6vDfpo/zqYDALwhQgAAb2o+QtlsVs8+++yUK+gwHfvp6rCfrg776eqwn+av5s8JAQCuXzU/CQEArl9ECADgDRECAHhDhAAA3tR8hHzeJrwWHT16VPfff79aW1tljNHrr78+5XHnnPbt26fW1lbV1dVp8+bNOn36tJ+N9aSrq0u33367GhoadMMNN+iBBx7QJ598MuU57Cfp0KFDWrNmjRobG9XY2KgNGzborbfeqj7OPppZV1eXjDHq6OiormNfzV1NR8jXbcJr2ejoqG677TZ1d3fP+PiBAwd08OBBdXd3q6+vTy0tLdqyZYtGRka+4C31p7e3V7t27dL777+vnp4elctlbd26VaOjo9XnsJ+klStXav/+/Tp+/LiOHz+uu+66S9u2bav+8WQfTdfX16cXX3xRa9asmbKefTUP83if0mvu29/+tnv00UenrPvGN77hfvrTn3raotoiyb322mvVz5MkcS0tLW7//v3Vdfl83jU1Nbnf/OY3HrawNgwODjpJrre31znHfrqcZcuWud/97nfsoxmMjIy49vZ219PT4zZt2uSeeOIJ5xz/e5qvmp2Eauk24YvFmTNnNDAwMGWfZbNZbdq06Uu9z4aGhiRJy5cvl8R+mkkcxzp8+LBGR0e1YcMG9tEMdu3apfvuu0/33HPPlPXsq/m5Ju+ivRBme5twqLpfZtpnZ8+e9bFJ3jnn9OSTT+qOO+7Q6tWrJbGfJjt16pQ2bNigfD6vpUuX6rXXXtOtt95a/ePJPkodPnxYH374ofr6+qY9xv+e5qdmIzTuam8Tjgnsswm7d+/WRx99pL///e/THmM/SbfccotOnjypzz//XH/5y1+0Y8cO9fb2Vh9nH0n9/f164okndOTIEeVyuUs+j301NzV7OG62twmH1NLSIknss4rHH39cb775pt59912tXLmyup79NCGTyejmm2/WunXr1NXVpdtuu00vvPAC+2iSDz74QIODg1q7dq3CMFQYhurt7dUvf/lLhWFY3R/sq7mp2QhNvk34ZD09Pdq4caOnraptq1atUktLy5R9ViwW1dvb+6XaZ8457d69W6+++qreeecdrVq1asrj7KdLc86pUCiwjya5++67derUKZ08ebK6rFu3Tg899JBOnjypm266iX01H/6uibiy+dwm/Ho1MjLiTpw44U6cOOEkuYMHD7oTJ064s2fPOuec279/v2tqanKvvvqqO3XqlPvBD37gVqxY4YaHhz1v+Rfnsccec01NTe69995zn332WXW5cOFC9TnsJ+f27t3rjh496s6cOeM++ugj9/TTTztrrTty5Ihzjn10OZOvjnOOfTUfNR0h55z71a9+5W688UaXyWTct771repltl9W77777oz3ct+xY4dzLr1c9Nlnn3UtLS0um826O++80506dcrvRn/BZto/ktxLL71UfQ77ybmHH364+v+tr33ta+7uu++uBsg59tHlXBwh9tXccSsHAIA3NXtOCABw/SNCAABviBAAwBsiBADwhggBALwhQgAAb4gQAMAbIgQA8IYIAQC8IUIAAG+IEADAGyIEAPDm/wObChfBM84L5AAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plot_simulation(df_results, 100)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Split into Training and Testing datsets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 74,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df_design_log = FuncTransform(func_dict_in, func_dict_out).fit_transform(df_design)\n",
|
|
"df_results_log = FuncTransform(func_dict_in, func_dict_out).fit_transform(df_results)\n",
|
|
"\n",
|
|
"X_train, X_test, y_train, y_test = sk.train_test_split(df_design_log, df_results_log, test_size = 0.1, random_state=42)\n",
|
|
"\n",
|
|
"X_train, y_train = balancer(X_train, y_train, 'over')\n",
|
|
"\n",
|
|
"scaler_X = MinMaxScaler()\n",
|
|
"scaler_y = MinMaxScaler()\n",
|
|
"\n",
|
|
"X_train = scaler_X.fit_transform(X_train)\n",
|
|
"X_test = scaler_X.transform(X_test)\n",
|
|
"\n",
|
|
"y_train = scaler_y.fit_transform(y_train)\n",
|
|
"y_test = scaler_y.transform(y_test)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Perform Over and Under Sampling on dataset to balance classes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Define Scaling and Normalization Functions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Preprocess the data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Sample the data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Custom Loss function"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 164,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess):\n",
|
|
" df_result = postprocess(df_result_log, func_dict_out, data_min_log, data_max_log) \n",
|
|
" return keras.losses.Huber + np.sum(((df_result['H'] / df_result['O']) - 2)**2)\n",
|
|
"\n",
|
|
"def loss_wrapper(data_min_log, data_max_log, func_dict_out, postprocess):\n",
|
|
" def loss(df_design_log, df_result_log):\n",
|
|
" return custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess)\n",
|
|
" return loss"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Train the model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 76,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1/50\n",
|
|
"\u001b[1m3520/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 0.0014 - val_loss: 1.6198e-06\n",
|
|
"Epoch 2/50\n",
|
|
"\u001b[1m3520/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.8272e-06 - val_loss: 1.0907e-06\n",
|
|
"Epoch 3/50\n",
|
|
"\u001b[1m3520/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.7458e-06 - val_loss: 8.1786e-07\n",
|
|
"Epoch 4/50\n",
|
|
"\u001b[1m3520/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.5743e-06 - val_loss: 7.5118e-07\n",
|
|
"Epoch 5/50\n",
|
|
"\u001b[1m3520/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 2ms/step - loss: 1.3131e-06 - val_loss: 6.6803e-07\n",
|
|
"Epoch 6/50\n",
|
|
"\u001b[1m2479/3520\u001b[0m \u001b[32m━━━━━━━━━━━━━━\u001b[0m\u001b[37m━━━━━━\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - loss: 1.1443e-06"
|
|
]
|
|
},
|
|
{
|
|
"ename": "KeyboardInterrupt",
|
|
"evalue": "",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[76], line 7\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;66;03m# measure time\u001b[39;00m\n\u001b[1;32m 5\u001b[0m start \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m----> 7\u001b[0m history \u001b[38;5;241m=\u001b[39m model_simple\u001b[38;5;241m.\u001b[39mfit(X_train, \n\u001b[1;32m 8\u001b[0m y_train, \n\u001b[1;32m 9\u001b[0m batch_size \u001b[38;5;241m=\u001b[39m batch_size, \n\u001b[1;32m 10\u001b[0m epochs \u001b[38;5;241m=\u001b[39m epochs, \n\u001b[1;32m 11\u001b[0m validation_data \u001b[38;5;241m=\u001b[39m (X_val, y_val)\n\u001b[1;32m 12\u001b[0m )\n\u001b[1;32m 14\u001b[0m end \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTraining took \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m seconds\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(end \u001b[38;5;241m-\u001b[39m start))\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/keras/src/utils/traceback_utils.py:117\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 115\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 116\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 117\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 119\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/keras/src/backend/tensorflow/trainer.py:320\u001b[0m, in \u001b[0;36mTensorFlowTrainer.fit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m step, iterator \u001b[38;5;129;01min\u001b[39;00m epoch_iterator\u001b[38;5;241m.\u001b[39menumerate_epoch():\n\u001b[1;32m 319\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_begin(step)\n\u001b[0;32m--> 320\u001b[0m logs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrain_function(iterator)\n\u001b[1;32m 321\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_end(step, logs)\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstop_training:\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/util/traceback_utils.py:150\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 148\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 149\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 150\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 151\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 152\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/polymorphic_function.py:833\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 830\u001b[0m compiler \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mxla\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnonXla\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 832\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OptionalXlaContext(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile):\n\u001b[0;32m--> 833\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds)\n\u001b[1;32m 835\u001b[0m new_tracing_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexperimental_get_tracing_count()\n\u001b[1;32m 836\u001b[0m without_tracing \u001b[38;5;241m=\u001b[39m (tracing_count \u001b[38;5;241m==\u001b[39m new_tracing_count)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/polymorphic_function.py:878\u001b[0m, in \u001b[0;36mFunction._call\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 875\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[1;32m 876\u001b[0m \u001b[38;5;66;03m# In this case we have not created variables on the first call. So we can\u001b[39;00m\n\u001b[1;32m 877\u001b[0m \u001b[38;5;66;03m# run the first trace but we should fail if variables are created.\u001b[39;00m\n\u001b[0;32m--> 878\u001b[0m results \u001b[38;5;241m=\u001b[39m tracing_compilation\u001b[38;5;241m.\u001b[39mcall_function(\n\u001b[1;32m 879\u001b[0m args, kwds, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_variable_creation_config\n\u001b[1;32m 880\u001b[0m )\n\u001b[1;32m 881\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_created_variables:\n\u001b[1;32m 882\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreating variables on a non-first call to a function\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 883\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m decorated with tf.function.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/tracing_compilation.py:137\u001b[0m, in \u001b[0;36mcall_function\u001b[0;34m(args, kwargs, tracing_options)\u001b[0m\n\u001b[1;32m 132\u001b[0m function \u001b[38;5;241m=\u001b[39m trace_function(\n\u001b[1;32m 133\u001b[0m args\u001b[38;5;241m=\u001b[39margs, kwargs\u001b[38;5;241m=\u001b[39mkwargs, tracing_options\u001b[38;5;241m=\u001b[39mtracing_options\n\u001b[1;32m 134\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;66;03m# Bind it ourselves to skip unnecessary canonicalization of default call.\u001b[39;00m\n\u001b[0;32m--> 137\u001b[0m bound_args \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mbind(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 138\u001b[0m flat_inputs \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39munpack_inputs(bound_args)\n\u001b[1;32m 139\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m function\u001b[38;5;241m.\u001b[39m_call_flat( \u001b[38;5;66;03m# pylint: disable=protected-access\u001b[39;00m\n\u001b[1;32m 140\u001b[0m flat_inputs, captured_inputs\u001b[38;5;241m=\u001b[39mfunction\u001b[38;5;241m.\u001b[39mcaptured_inputs\n\u001b[1;32m 141\u001b[0m )\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/inspect.py:3195\u001b[0m, in \u001b[0;36mSignature.bind\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3190\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mbind\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m/\u001b[39m, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 3191\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Get a BoundArguments object, that maps the passed `args`\u001b[39;00m\n\u001b[1;32m 3192\u001b[0m \u001b[38;5;124;03m and `kwargs` to the function's signature. Raises `TypeError`\u001b[39;00m\n\u001b[1;32m 3193\u001b[0m \u001b[38;5;124;03m if the passed arguments can not be bound.\u001b[39;00m\n\u001b[1;32m 3194\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 3195\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bind(args, kwargs)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/inspect.py:3133\u001b[0m, in \u001b[0;36mSignature._bind\u001b[0;34m(self, args, kwargs, partial)\u001b[0m\n\u001b[1;32m 3130\u001b[0m arguments[param\u001b[38;5;241m.\u001b[39mname] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mtuple\u001b[39m(values)\n\u001b[1;32m 3131\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[0;32m-> 3133\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m param\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01min\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m param\u001b[38;5;241m.\u001b[39mkind \u001b[38;5;241m!=\u001b[39m _POSITIONAL_ONLY:\n\u001b[1;32m 3134\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[1;32m 3135\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmultiple values for argument \u001b[39m\u001b[38;5;132;01m{arg!r}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 3136\u001b[0m arg\u001b[38;5;241m=\u001b[39mparam\u001b[38;5;241m.\u001b[39mname)) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 3138\u001b[0m arguments[param\u001b[38;5;241m.\u001b[39mname] \u001b[38;5;241m=\u001b[39m arg_val\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/inspect.py:2722\u001b[0m, in \u001b[0;36mParameter.name\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 2719\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_default \u001b[38;5;241m=\u001b[39m state[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_default\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m 2720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_annotation \u001b[38;5;241m=\u001b[39m state[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_annotation\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m-> 2722\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 2723\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mname\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 2724\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_name\n\u001b[1;32m 2726\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 2727\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdefault\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n",
|
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"X_train, X_test, y_train, y_test = sk.train_test_split(pp_design, pp_results, test_size = 0.2)\n",
|
|
"X_train, X_val, y_train, y_val = sk.train_test_split(X_train, y_train, test_size = 0.1)\n",
|
|
"\n",
|
|
" # measure time\n",
|
|
"start = time.time()\n",
|
|
"\n",
|
|
"history = model_simple.fit(X_train, \n",
|
|
" y_train, \n",
|
|
" batch_size = batch_size, \n",
|
|
" epochs = epochs, \n",
|
|
" validation_data = (X_val, y_val)\n",
|
|
")\n",
|
|
"\n",
|
|
"end = time.time()\n",
|
|
"\n",
|
|
"print(\"Training took {} seconds\".format(end - start))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 51,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1/50\n",
|
|
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 0.0018 - val_loss: 1.5623e-06\n",
|
|
"Epoch 2/50\n",
|
|
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.4825e-06 - val_loss: 2.3533e-06\n",
|
|
"Epoch 3/50\n",
|
|
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.5046e-06 - val_loss: 1.4752e-06\n",
|
|
"Epoch 4/50\n",
|
|
"\u001b[1m3960/3960\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 2ms/step - loss: 1.2676e-06 - val_loss: 1.5767e-06\n",
|
|
"Epoch 5/50\n",
|
|
"\u001b[1m2568/3960\u001b[0m \u001b[32m━━━━━━━━━━━━\u001b[0m\u001b[37m━━━━━━━━\u001b[0m \u001b[1m2s\u001b[0m 2ms/step - loss: 1.4503e-06"
|
|
]
|
|
},
|
|
{
|
|
"ename": "KeyboardInterrupt",
|
|
"evalue": "",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[51], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# measure time\u001b[39;00m\n\u001b[1;32m 2\u001b[0m start \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m----> 4\u001b[0m history \u001b[38;5;241m=\u001b[39m model_simple\u001b[38;5;241m.\u001b[39mfit(X_train\u001b[38;5;241m.\u001b[39miloc[:, X_train\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClass\u001b[39m\u001b[38;5;124m\"\u001b[39m], \n\u001b[1;32m 5\u001b[0m y_train\u001b[38;5;241m.\u001b[39miloc[:, y_train\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClass\u001b[39m\u001b[38;5;124m\"\u001b[39m], \n\u001b[1;32m 6\u001b[0m batch_size \u001b[38;5;241m=\u001b[39m batch_size, \n\u001b[1;32m 7\u001b[0m epochs \u001b[38;5;241m=\u001b[39m epochs, \n\u001b[1;32m 8\u001b[0m validation_data \u001b[38;5;241m=\u001b[39m (X_val\u001b[38;5;241m.\u001b[39miloc[:,X_val\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClass\u001b[39m\u001b[38;5;124m\"\u001b[39m], y_val\u001b[38;5;241m.\u001b[39miloc[:, y_val\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClass\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m 9\u001b[0m )\n\u001b[1;32m 11\u001b[0m end \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTraining took \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m seconds\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(end \u001b[38;5;241m-\u001b[39m start))\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/keras/src/utils/traceback_utils.py:117\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 115\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 116\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 117\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 119\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/keras/src/backend/tensorflow/trainer.py:320\u001b[0m, in \u001b[0;36mTensorFlowTrainer.fit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m step, iterator \u001b[38;5;129;01min\u001b[39;00m epoch_iterator\u001b[38;5;241m.\u001b[39menumerate_epoch():\n\u001b[1;32m 319\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_begin(step)\n\u001b[0;32m--> 320\u001b[0m logs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrain_function(iterator)\n\u001b[1;32m 321\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_end(step, logs)\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstop_training:\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/util/traceback_utils.py:150\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 148\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 149\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 150\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 151\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 152\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/polymorphic_function.py:833\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 830\u001b[0m compiler \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mxla\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnonXla\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 832\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OptionalXlaContext(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile):\n\u001b[0;32m--> 833\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds)\n\u001b[1;32m 835\u001b[0m new_tracing_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexperimental_get_tracing_count()\n\u001b[1;32m 836\u001b[0m without_tracing \u001b[38;5;241m=\u001b[39m (tracing_count \u001b[38;5;241m==\u001b[39m new_tracing_count)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/polymorphic_function.py:878\u001b[0m, in \u001b[0;36mFunction._call\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 875\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[1;32m 876\u001b[0m \u001b[38;5;66;03m# In this case we have not created variables on the first call. So we can\u001b[39;00m\n\u001b[1;32m 877\u001b[0m \u001b[38;5;66;03m# run the first trace but we should fail if variables are created.\u001b[39;00m\n\u001b[0;32m--> 878\u001b[0m results \u001b[38;5;241m=\u001b[39m tracing_compilation\u001b[38;5;241m.\u001b[39mcall_function(\n\u001b[1;32m 879\u001b[0m args, kwds, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_variable_creation_config\n\u001b[1;32m 880\u001b[0m )\n\u001b[1;32m 881\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_created_variables:\n\u001b[1;32m 882\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreating variables on a non-first call to a function\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 883\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m decorated with tf.function.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/tracing_compilation.py:139\u001b[0m, in \u001b[0;36mcall_function\u001b[0;34m(args, kwargs, tracing_options)\u001b[0m\n\u001b[1;32m 137\u001b[0m bound_args \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mbind(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 138\u001b[0m flat_inputs \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39munpack_inputs(bound_args)\n\u001b[0;32m--> 139\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m function\u001b[38;5;241m.\u001b[39m_call_flat( \u001b[38;5;66;03m# pylint: disable=protected-access\u001b[39;00m\n\u001b[1;32m 140\u001b[0m flat_inputs, captured_inputs\u001b[38;5;241m=\u001b[39mfunction\u001b[38;5;241m.\u001b[39mcaptured_inputs\n\u001b[1;32m 141\u001b[0m )\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/concrete_function.py:1322\u001b[0m, in \u001b[0;36mConcreteFunction._call_flat\u001b[0;34m(self, tensor_inputs, captured_inputs)\u001b[0m\n\u001b[1;32m 1318\u001b[0m possible_gradient_type \u001b[38;5;241m=\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPossibleTapeGradientTypes(args)\n\u001b[1;32m 1319\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (possible_gradient_type \u001b[38;5;241m==\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPOSSIBLE_GRADIENT_TYPES_NONE\n\u001b[1;32m 1320\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m executing_eagerly):\n\u001b[1;32m 1321\u001b[0m \u001b[38;5;66;03m# No tape is watching; skip to running the function.\u001b[39;00m\n\u001b[0;32m-> 1322\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inference_function\u001b[38;5;241m.\u001b[39mcall_preflattened(args)\n\u001b[1;32m 1323\u001b[0m forward_backward \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_select_forward_and_backward_functions(\n\u001b[1;32m 1324\u001b[0m args,\n\u001b[1;32m 1325\u001b[0m possible_gradient_type,\n\u001b[1;32m 1326\u001b[0m executing_eagerly)\n\u001b[1;32m 1327\u001b[0m forward_function, args_with_tangents \u001b[38;5;241m=\u001b[39m forward_backward\u001b[38;5;241m.\u001b[39mforward()\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/atomic_function.py:216\u001b[0m, in \u001b[0;36mAtomicFunction.call_preflattened\u001b[0;34m(self, args)\u001b[0m\n\u001b[1;32m 214\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall_preflattened\u001b[39m(\u001b[38;5;28mself\u001b[39m, args: Sequence[core\u001b[38;5;241m.\u001b[39mTensor]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[1;32m 215\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Calls with flattened tensor inputs and returns the structured output.\"\"\"\u001b[39;00m\n\u001b[0;32m--> 216\u001b[0m flat_outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcall_flat(\u001b[38;5;241m*\u001b[39margs)\n\u001b[1;32m 217\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mpack_output(flat_outputs)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/polymorphic_function/atomic_function.py:251\u001b[0m, in \u001b[0;36mAtomicFunction.call_flat\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 249\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record\u001b[38;5;241m.\u001b[39mstop_recording():\n\u001b[1;32m 250\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bound_context\u001b[38;5;241m.\u001b[39mexecuting_eagerly():\n\u001b[0;32m--> 251\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bound_context\u001b[38;5;241m.\u001b[39mcall_function(\n\u001b[1;32m 252\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname,\n\u001b[1;32m 253\u001b[0m \u001b[38;5;28mlist\u001b[39m(args),\n\u001b[1;32m 254\u001b[0m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mflat_outputs),\n\u001b[1;32m 255\u001b[0m )\n\u001b[1;32m 256\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 257\u001b[0m outputs \u001b[38;5;241m=\u001b[39m make_call_op_in_graph(\n\u001b[1;32m 258\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 259\u001b[0m \u001b[38;5;28mlist\u001b[39m(args),\n\u001b[1;32m 260\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bound_context\u001b[38;5;241m.\u001b[39mfunction_call_options\u001b[38;5;241m.\u001b[39mas_attrs(),\n\u001b[1;32m 261\u001b[0m )\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/context.py:1552\u001b[0m, in \u001b[0;36mContext.call_function\u001b[0;34m(self, name, tensor_inputs, num_outputs)\u001b[0m\n\u001b[1;32m 1550\u001b[0m cancellation_context \u001b[38;5;241m=\u001b[39m cancellation\u001b[38;5;241m.\u001b[39mcontext()\n\u001b[1;32m 1551\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cancellation_context \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m-> 1552\u001b[0m outputs \u001b[38;5;241m=\u001b[39m execute\u001b[38;5;241m.\u001b[39mexecute(\n\u001b[1;32m 1553\u001b[0m name\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mutf-8\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m 1554\u001b[0m num_outputs\u001b[38;5;241m=\u001b[39mnum_outputs,\n\u001b[1;32m 1555\u001b[0m inputs\u001b[38;5;241m=\u001b[39mtensor_inputs,\n\u001b[1;32m 1556\u001b[0m attrs\u001b[38;5;241m=\u001b[39mattrs,\n\u001b[1;32m 1557\u001b[0m ctx\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1558\u001b[0m )\n\u001b[1;32m 1559\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1560\u001b[0m outputs \u001b[38;5;241m=\u001b[39m execute\u001b[38;5;241m.\u001b[39mexecute_with_cancellation(\n\u001b[1;32m 1561\u001b[0m name\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mutf-8\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m 1562\u001b[0m num_outputs\u001b[38;5;241m=\u001b[39mnum_outputs,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1566\u001b[0m cancellation_manager\u001b[38;5;241m=\u001b[39mcancellation_context,\n\u001b[1;32m 1567\u001b[0m )\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/tensorflow/python/eager/execute.py:53\u001b[0m, in \u001b[0;36mquick_execute\u001b[0;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 52\u001b[0m ctx\u001b[38;5;241m.\u001b[39mensure_initialized()\n\u001b[0;32m---> 53\u001b[0m tensors \u001b[38;5;241m=\u001b[39m pywrap_tfe\u001b[38;5;241m.\u001b[39mTFE_Py_Execute(ctx\u001b[38;5;241m.\u001b[39m_handle, device_name, op_name,\n\u001b[1;32m 54\u001b[0m inputs, attrs, num_outputs)\n\u001b[1;32m 55\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m core\u001b[38;5;241m.\u001b[39m_NotOkStatusException \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
|
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# measure time\n",
|
|
"start = time.time()\n",
|
|
"\n",
|
|
"history = model_simple.fit(X_train.iloc[:, X_train.columns != \"Class\"], \n",
|
|
" y_train.iloc[:, y_train.columns != \"Class\"], \n",
|
|
" batch_size = batch_size, \n",
|
|
" epochs = epochs, \n",
|
|
" validation_data = (X_val.iloc[:,X_val.columns != \"Class\"], y_val.iloc[:, y_val.columns != \"Class\"])\n",
|
|
")\n",
|
|
"\n",
|
|
"end = time.time()\n",
|
|
"\n",
|
|
"print(\"Training took {} seconds\".format(end - start))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plt.plot(history.history[\"loss\"], \"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": 31,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plt.plot(history.history[\"loss\"][1:], \"o-\", label = \"Training Loss\")\n",
|
|
"plt.xlabel(\"Epoch\")\n",
|
|
"# plt.yscale('log')\n",
|
|
"plt.ylabel(\"Loss (Huber)\")\n",
|
|
"plt.grid('on')\n",
|
|
"plt.savefig(\"loss_1_to_end.png\", dpi=300)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Test the model"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m15641/15641\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 331us/step - loss: 3.0422e-06\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2.9736404485447565e-06"
|
|
]
|
|
},
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on all test data\n",
|
|
"model_simple.evaluate(X_test_preprocess.iloc[:,X_test.columns != \"Class\"], y_test_preprocess.iloc[:, y_test.columns != \"Class\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m15451/15451\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 234us/step - loss: 0.0313\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.031290605664253235"
|
|
]
|
|
},
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on non-reactive data\n",
|
|
"model_simple.evaluate(X_test_preprocess[X_test_preprocess['Class'] == 0].iloc[:,:-1], y_test_preprocess[X_test_preprocess['Class'] == 0].iloc[:,:-1])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m190/190\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 295us/step - loss: 0.1246\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.12462512403726578"
|
|
]
|
|
},
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on reactive data\n",
|
|
"model_simple.evaluate(X_test_preprocess[X_test_preprocess['Class'] == 1].iloc[:,:-1], y_test_preprocess[X_test_preprocess['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\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Legacy Code"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"def log_scale(df_design, df_result, func_dict):\n",
|
|
" \n",
|
|
" df_design = df_design.copy()\n",
|
|
" df_result = df_result.copy()\n",
|
|
" \n",
|
|
" for key in df_design.keys():\n",
|
|
" if key != \"Class\":\n",
|
|
" df_design[key] = np.vectorize(func_dict[key])(df_design[key])\n",
|
|
" df_result[key] = np.vectorize(func_dict[key])(df_result[key])\n",
|
|
" \n",
|
|
" return df_design, df_result\n",
|
|
"\n",
|
|
"# Get minimum and maximum values for each column\n",
|
|
"def get_min_max(df_design, df_result):\n",
|
|
" \n",
|
|
" min_vals_des = df_design.min()\n",
|
|
" max_vals_des = df_design.max()\n",
|
|
" \n",
|
|
" min_vals_res = df_result.min()\n",
|
|
" max_vals_res = df_result.max()\n",
|
|
"\n",
|
|
" # minimum of input and output data to get global minimum/maximum\n",
|
|
" data_min = np.minimum(min_vals_des, min_vals_res).to_dict()\n",
|
|
" data_max = np.maximum(max_vals_des, max_vals_res).to_dict()\n",
|
|
"\n",
|
|
" return data_min, data_max\n",
|
|
"\n",
|
|
"df_design_log, df_results_log = log_scale(df_design, df_results, func_dict_in)\n",
|
|
"data_min_log, data_max_log = get_min_max(df_design_log, df_design_log)\n",
|
|
"\n",
|
|
"train_min_log, train_max_log = get_min_max(X_train_log, y_train_log)\n",
|
|
"test_min_log, test_max_log = get_min_max(X_test_log, y_test_log)\n",
|
|
"\n",
|
|
"X_train_preprocess = preprocess(X_train_log, func_dict_in, train_min_log, train_max_log)\n",
|
|
"y_train_preprocess = preprocess(y_train_log, func_dict_in, train_min_log, train_max_log)\n",
|
|
"\n",
|
|
"X_test_preprocess = preprocess(X_test_log, func_dict_in, test_min_log, test_max_log)\n",
|
|
"y_test_preprocess = preprocess(y_test_log, func_dict_in, test_min_log, test_max_log)\n",
|
|
"\n",
|
|
"X_train_log, y_train_log = log_scale(X_train, y_train, func_dict_in)\n",
|
|
"X_test_log, y_test_log = log_scale(X_test, y_test, func_dict_in)\n",
|
|
"\n",
|
|
"\n",
|
|
"def preprocess(data, func_dict, data_min, data_max):\n",
|
|
" data = data.copy()\n",
|
|
" for key in data.keys():\n",
|
|
" if key != \"Class\":\n",
|
|
" data[key] = (data[key] - data_min[key]) / (data_max[key] - data_min[key])\n",
|
|
"\n",
|
|
" return data\n",
|
|
"\n",
|
|
"def postprocess(data, func_dict, data_min, data_max):\n",
|
|
" data = data.copy()\n",
|
|
" for key in data.keys():\n",
|
|
" if key != \"Class\":\n",
|
|
" data[key] = data[key] * (data_max[key] - data_min[key]) + data_min[key]\n",
|
|
" data[key] = np.vectorize(func_dict[key])(data[key])\n",
|
|
" return data\n",
|
|
"\n",
|
|
"X_train, X_val, y_train, y_val = sk.train_test_split(X_train_preprocess, y_train_preprocess, test_size = 0.1)\n",
|
|
"\n",
|
|
"pp_design = preprocess(df_design_log, func_dict_in, data_min_log, data_max_log)\n",
|
|
"pp_results = preprocess(df_results_log, func_dict_in, data_min_log, data_max_log)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "training",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.11"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|