mirror of
https://git.gfz-potsdam.de/naaice/model-training.git
synced 2025-12-15 19:58:22 +01:00
1018 lines
123 KiB
Plaintext
1018 lines
123 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-15 16:24:49.275664: 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-15 16:24:49.404820: 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",
|
|
"print(\"Running Keras in version {}\".format(keras.__version__))\n",
|
|
"\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 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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Define parameters"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 141,
|
|
"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": 142,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_5\"</span>\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1mModel: \"sequential_5\"\u001b[0m\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_17 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_18 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">16,512</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_19 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,548</span> │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_17 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_18 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m16,512\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_19 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m1,548\u001b[0m │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">19,724</span> (77.05 KB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 KB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"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": 143,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_6\"</span>\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1mModel: \"sequential_6\"\u001b[0m\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_20 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,656</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_21 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1024</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_22 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">524,800</span> │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_23 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,156</span> │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
|
|
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
|
|
"│ dense_20 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m6,656\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_21 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1024\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_22 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m524,800\u001b[0m │\n",
|
|
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
|
|
"│ dense_23 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m6,156\u001b[0m │\n",
|
|
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">1,062,924</span> (4.05 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"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 some functions and helper classes"
|
|
]
|
|
},
|
|
{
|
|
"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\n"
|
|
]
|
|
},
|
|
{
|
|
"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": 42,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# os.chdir('/mnt/beegfs/home/signer/projects/model-training')\n",
|
|
"data_file = h5py.File(\"Barite_50_Data_training.h5\")\n",
|
|
"\n",
|
|
"design = data_file[\"design\"]\n",
|
|
"results = data_file[\"result\"]\n",
|
|
"\n",
|
|
"df_design = pd.DataFrame(np.array(design[\"data\"]).transpose(), columns = design[\"names\"].asstr())\n",
|
|
"df_results = pd.DataFrame(np.array(results[\"data\"]).transpose(), columns = results[\"names\"].asstr())\n",
|
|
"\n",
|
|
"data_file.close()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Classify each cell with kmeans"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 43,
|
|
"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": [
|
|
"# widget with slider for the index\n",
|
|
"\n",
|
|
"class_label_design = np.array([])\n",
|
|
"class_label_result = np.array([])\n",
|
|
"\n",
|
|
"\n",
|
|
"i = 1000\n",
|
|
"for i in range(0,1001):\n",
|
|
" field_design = np.array(df_design['Barite'][(i*2500):(i*2500+2500)]).reshape(50,50)\n",
|
|
" field_result = np.array(df_results['Barite'][(i*2500):(i*2500+2500)]).reshape(50,50)\n",
|
|
" \n",
|
|
" kmeans_design = KMeans(n_clusters=2, random_state=0).fit(field_design.reshape(-1,1))\n",
|
|
" kmeans_result = KMeans(n_clusters=2, random_state=0).fit(field_result.reshape(-1,1))\n",
|
|
" \n",
|
|
" class_label_design = np.append(class_label_design.astype(int), kmeans_design.labels_)\n",
|
|
" class_label_result = np.append(class_label_result.astype(int), kmeans_result.labels_)\n",
|
|
" \n",
|
|
"\n",
|
|
"\n",
|
|
"class_label_design = pd.DataFrame(class_label_design, columns = [\"Class\"])\n",
|
|
"class_label_result = pd.DataFrame(class_label_result, columns = [\"Class\"])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 44,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if(\"Class\" in df_design.columns and \"Class\" in df_results.columns):\n",
|
|
" print(\"Class column already exists\")\n",
|
|
"else:\n",
|
|
" df_design = pd.concat([df_design, class_label_design], axis=1)\n",
|
|
" df_results = pd.concat([df_results, class_label_design], axis=1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 45,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Amount class 0: 0.9879380619380619\n",
|
|
"Amount class 1: 0.012061938061938062\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"counter = Counter(df_design.iloc[:,-1])\n",
|
|
"print(\"Amount class 0:\", counter[0] / (counter[0] + counter[1]) )\n",
|
|
"print(\"Amount class 1:\", counter[1] / (counter[0] + counter[1]) )\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<matplotlib.contour.QuadContourSet at 0x7c17915fe310>"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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Bw/q5Zdf1uHDh897jX+f5qdtI9RwqY8JxzT22bR7771Xr7zyin7wgx+c9xr7SXrPe96jY8eO6c0339Q//MM/6K677tLQ0FDzdfaRNDw8rPvuu0+HDh1SsVh8y/exry5P207HzfUx4ZD6+vokiX1W9+lPf1pPP/20nn32Wa1bt665nv00rVAo6Nprr9WNN96ogYEBXX/99frqV7/KPmrx0ksv6fTp07rhhhsUhqHCMNTQ0JD+7M/+TGEYNvcH++rytG2EWh8T3mpwcFA333yzp61qbxs2bFBfX9+MfVatVjU0NLSs9plzTvfee6+efPJJPfPMM9qwYcOM19lPb805p0qlwj5qceutt+r48eM6duxYc7nxxht155136tixY3rnO9/JvpoPf+dEXNx8HhO+VI2Pj7ujR4+6o0ePOklu//797ujRo+7UqVPOOeceffRRVyqV3JNPPumOHz/ufu/3fs+tXbvWjY2Ned7yt8+nPvUpVyqV3HPPPedef/315jI5Odl8D/vJuT179rjnn3/enTx50r3yyivuc5/7nLPWukOHDjnn2EcX0np2nHPsq/lo6wg559yf//mfu2uuucYVCgX3vve9r3ma7XL17LPPzvos97vuuss5l58u+vDDD7u+vj4Xx7H7wAc+4I4fP+53o99ms+0fSe4b3/hG8z3sJ+c+8YlPNP+3dfXVV7tbb721GSDn2EcXcm6E2FeXj0c5AAC8adtjQgCApY8IAQC8IUIAAG+IEADAGyIEAPCGCAEAvCFCAABviBAAwBsiBADwhggBALwhQgAAb4gQAMCb/w89oIZdSjvIlgAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"i=800\n",
|
|
"\n",
|
|
"plt.imshow(np.array(df_results['Barite'][(i*2500):(i*2500+2500)]).reshape(50,50), interpolation='bicubic', origin='lower')\n",
|
|
"plt.contour(np.array(df_results['Class'][(i*2500):(i*2500+2500)]).reshape(50,50), levels=[0.1], colors='red', origin='lower')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Split into Training and Testing datsets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 126,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"X_train, X_test, y_train, y_test = sk.train_test_split(df_design, df_results, test_size = 0.2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Perform Over and Under Sampling on dataset to balance classes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 109,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def balancer(design, target, strategy, sample_fraction=0.5):\n",
|
|
" counter = Counter(design.iloc[:,-1])\n",
|
|
" print(\"Amount class 0 before:\", counter[0] / (counter[0] + counter[1]) )\n",
|
|
" print(\"Amount class 1 before:\", counter[1] / (counter[0] + counter[1]) )\n",
|
|
" \n",
|
|
" number_features = (df_design.columns != \"Class\").sum()\n",
|
|
" if(\"Class\" not in design.columns):\n",
|
|
" if(\"Class\" in target.columns):\n",
|
|
" classes = target['Class']\n",
|
|
" else:\n",
|
|
" raise(\"No class column found\")\n",
|
|
" else:\n",
|
|
" classes = design['Class']\n",
|
|
" df = pd.concat([design.loc[:,design.columns != \"Class\"], target.loc[:, design.columns != \"Class\"], classes], axis=1)\n",
|
|
" \n",
|
|
" if strategy == 'smote':\n",
|
|
" print(\"Using SMOTE strategy\")\n",
|
|
" smote = SMOTE(sampling_strategy=sample_fraction)\n",
|
|
" df_resampled, classes_resampled = smote.fit_resample(df.loc[:, df.columns != \"Class\"], df.loc[:, df.columns == \"Class\"])\n",
|
|
" \n",
|
|
" elif strategy == 'over':\n",
|
|
" print(\"Using Oversampling\")\n",
|
|
" over = RandomOverSampler()\n",
|
|
" df_resampled, classes_resampled = over.fit_resample(df.loc[:, df.columns != \"Class\"], df.loc[:, df.columns == \"Class\"])\n",
|
|
" \n",
|
|
" elif strategy == 'under':\n",
|
|
" print(\"Using Undersampling\")\n",
|
|
" under = RandomUnderSampler()\n",
|
|
" df_resampled, classes_resampled = under.fit_resample(df.loc[:, df.columns != \"Class\"], df.loc[:, df.columns == \"Class\"])\n",
|
|
"\n",
|
|
" counter = Counter(classes_resampled[\"Class\"])\n",
|
|
" print(\"Amount class 0 after:\", counter[0] / (counter[0] + counter[1]) )\n",
|
|
" print(\"Amount class 1 after:\", counter[1] / (counter[0] + counter[1]) )\n",
|
|
" \n",
|
|
" design_resampled = pd.concat([df_resampled.iloc[:,0:number_features], classes_resampled], axis=1)\n",
|
|
" target_resampled = pd.concat([df_resampled.iloc[:,number_features:], classes_resampled], axis=1)\n",
|
|
" \n",
|
|
" return design_resampled, target_resampled "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 127,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Amount class 0 before: 0.9878911088911089\n",
|
|
"Amount class 1 before: 0.012108891108891108\n",
|
|
"Using Oversampling\n",
|
|
"Amount class 0 after: 0.5\n",
|
|
"Amount class 1 after: 0.5\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"X_train, y_train = balancer(X_train, y_train, 'over')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Define Scaling and Normalization Functions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 87,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 88,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"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[88], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m df_design_log, df_results_log \u001b[38;5;241m=\u001b[39m log_scale(df_design, df_results, func_dict_in)\n\u001b[1;32m 2\u001b[0m data_min_log, data_max_log \u001b[38;5;241m=\u001b[39m get_min_max(df_design_log, df_results_log)\n",
|
|
"Cell \u001b[0;32mIn[87], line 8\u001b[0m, in \u001b[0;36mlog_scale\u001b[0;34m(df_design, df_result, func_dict)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m df_design\u001b[38;5;241m.\u001b[39mkeys():\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \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[0;32m----> 8\u001b[0m df_design[key] \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mvectorize(func_dict[key])(df_design[key])\n\u001b[1;32m 9\u001b[0m df_result[key] \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mvectorize(func_dict[key])(df_result[key])\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m df_design, df_result\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/numpy/lib/function_base.py:2372\u001b[0m, in \u001b[0;36mvectorize.__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 2369\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_init_stage_2(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 2370\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\n\u001b[0;32m-> 2372\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_as_normal(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/numpy/lib/function_base.py:2365\u001b[0m, in \u001b[0;36mvectorize._call_as_normal\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 2362\u001b[0m vargs \u001b[38;5;241m=\u001b[39m [args[_i] \u001b[38;5;28;01mfor\u001b[39;00m _i \u001b[38;5;129;01min\u001b[39;00m inds]\n\u001b[1;32m 2363\u001b[0m vargs\u001b[38;5;241m.\u001b[39mextend([kwargs[_n] \u001b[38;5;28;01mfor\u001b[39;00m _n \u001b[38;5;129;01min\u001b[39;00m names])\n\u001b[0;32m-> 2365\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_vectorize_call(func\u001b[38;5;241m=\u001b[39mfunc, args\u001b[38;5;241m=\u001b[39mvargs)\n",
|
|
"File \u001b[0;32m~/bin/miniconda3/envs/training/lib/python3.11/site-packages/numpy/lib/function_base.py:2455\u001b[0m, in \u001b[0;36mvectorize._vectorize_call\u001b[0;34m(self, func, args)\u001b[0m\n\u001b[1;32m 2452\u001b[0m \u001b[38;5;66;03m# Convert args to object arrays first\u001b[39;00m\n\u001b[1;32m 2453\u001b[0m inputs \u001b[38;5;241m=\u001b[39m [asanyarray(a, dtype\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mobject\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m args]\n\u001b[0;32m-> 2455\u001b[0m outputs \u001b[38;5;241m=\u001b[39m ufunc(\u001b[38;5;241m*\u001b[39minputs)\n\u001b[1;32m 2457\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ufunc\u001b[38;5;241m.\u001b[39mnout \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 2458\u001b[0m res \u001b[38;5;241m=\u001b[39m asanyarray(outputs, dtype\u001b[38;5;241m=\u001b[39motypes[\u001b[38;5;241m0\u001b[39m])\n",
|
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"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_results_log)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 128,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 129,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 114,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Preprocess the data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 130,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Sample the data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 131,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"X_train, X_val, y_train, y_val = sk.train_test_split(X_train_preprocess, y_train_preprocess, test_size = 0.1)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Custom Loss function"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": 144,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1/5\n",
|
|
"\u001b[1m6954/6954\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 0.0014 - val_loss: 1.9722e-05\n",
|
|
"Epoch 2/5\n",
|
|
"\u001b[1m6954/6954\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 2ms/step - loss: 1.8605e-05 - val_loss: 1.6460e-05\n",
|
|
"Epoch 3/5\n",
|
|
"\u001b[1m6954/6954\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 2ms/step - loss: 1.7344e-05 - val_loss: 1.8609e-05\n",
|
|
"Epoch 4/5\n",
|
|
"\u001b[1m6954/6954\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 1.6938e-05 - val_loss: 1.6669e-05\n",
|
|
"Epoch 5/5\n",
|
|
"\u001b[1m6954/6954\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 2ms/step - loss: 1.6373e-05 - val_loss: 1.5985e-05\n",
|
|
"Training took 63.22352385520935 seconds\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# measure time\n",
|
|
"start = time.time()\n",
|
|
"\n",
|
|
"history = model_simple.fit(X_train.iloc[:, :-1], \n",
|
|
" y_train.iloc[:, :-1], \n",
|
|
" batch_size = batch_size, \n",
|
|
" epochs = 5, \n",
|
|
" validation_data = (X_val.iloc[:,:-1], y_val.iloc[:, :-1])\n",
|
|
")\n",
|
|
"\n",
|
|
"end = time.time()\n",
|
|
"\n",
|
|
"print(\"Training took {} seconds\".format(end - start))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 145,
|
|
"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": 146,
|
|
"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": 152,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m15641/15641\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 1ms/step - loss: 0.0904\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.09046255797147751"
|
|
]
|
|
},
|
|
"execution_count": 152,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on all test data\n",
|
|
"model_large.evaluate(X_test_preprocess.iloc[:,:-1], y_test_preprocess.iloc[:, :-1])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 153,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m15455/15455\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 996us/step - loss: 0.0902\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.0901983454823494"
|
|
]
|
|
},
|
|
"execution_count": 153,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on non-reactive data\n",
|
|
"model_large.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": 155,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[1m186/186\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 1ms/step - loss: 0.1127\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.11247223615646362"
|
|
]
|
|
},
|
|
"execution_count": 155,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# test on reactive data\n",
|
|
"model_large.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\")"
|
|
]
|
|
}
|
|
],
|
|
"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
|
|
}
|