{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Smogseer training at 50 epochs" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import xarray as xr\n", "import numpy as np\n", "from tensorflow import keras\n", "from tensorflow.keras import layers\n", "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n", "from sklearn.impute import SimpleImputer\n", "from tensorflow.keras.models import load_model\n", "import matplotlib.pyplot as plt\n", "from tensorflow.keras.utils import Sequence" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset> Size: 2GB\n", "Dimensions: (time: 366, lat: 291, lon: 512, bnds: 2)\n", "Coordinates:\n", " * lat (lat) float64 2kB 34.36 34.33 34.3 ... 24.97 24.94 24.9\n", " * lon (lon) float64 4kB 68.15 68.19 68.22 ... 84.75 84.79 84.82\n", " * time (time) datetime64[ns] 3kB 2019-01-03T12:00:00 ... 2024-01...\n", " time_bnds (time, bnds) datetime64[ns] 6kB ...\n", "Dimensions without coordinates: bnds\n", "Data variables:\n", " AER_AI_340_380 (time, lat, lon) float32 218MB ...\n", " AER_AI_354_388 (time, lat, lon) float32 218MB ...\n", " CH4 (time, lat, lon) float32 218MB ...\n", " CLOUD_FRACTION (time, lat, lon) float32 218MB ...\n", " CO (time, lat, lon) float32 218MB ...\n", " HCHO (time, lat, lon) float32 218MB ...\n", " NO2 (time, lat, lon) float32 218MB ...\n", " O3 (time, lat, lon) float32 218MB ...\n", " SO2 (time, lat, lon) float32 218MB ...\n", "Attributes:\n", " Conventions: CF-1.7\n", " title: S5PL2 Data Cube Subset\n", " history: [{'program': 'xcube_sh.chunkstore.SentinelHubC...\n", " date_created: 2024-05-02T13:00:01.155492\n", " time_coverage_start: 2019-01-01T00:00:00+00:00\n", " time_coverage_end: 2024-01-05T00:00:00+00:00\n", " time_coverage_duration: P1830DT0H0M0S\n", " time_coverage_resolution: P5DT0H0M0S\n", " geospatial_lon_min: 68.137207\n", " geospatial_lat_min: 24.886436\n", " geospatial_lon_max: 84.836426\n", " geospatial_lat_max: 34.37759367382812
Model: \"smogseer\"\n",
"
\n"
],
"text/plain": [
"\u001b[1mModel: \"smogseer\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", "│ input_layer_1 (InputLayer) │ (None, 1, 291, 512, 6) │ 0 │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_3 │ (None, 1, 291, 512, 6) │ 24 │\n", "│ (BatchNormalization) │ │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv_lstm2d_2 (ConvLSTM2D) │ (None, 1, 291, 512, │ 12,736 │\n", "│ │ 16) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_4 │ (None, 1, 291, 512, │ 64 │\n", "│ (BatchNormalization) │ 16) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv_lstm2d_3 (ConvLSTM2D) │ (None, 1, 291, 512, │ 55,424 │\n", "│ │ 32) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_5 │ (None, 1, 291, 512, │ 128 │\n", "│ (BatchNormalization) │ 32) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv3d_1 (Conv3D) │ (None, 1, 291, 512, 1) │ 865 │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n", "\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", "│ input_layer_1 (\u001b[38;5;33mInputLayer\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, \u001b[38;5;34m6\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_3 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, \u001b[38;5;34m6\u001b[0m) │ \u001b[38;5;34m24\u001b[0m │\n", "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv_lstm2d_2 (\u001b[38;5;33mConvLSTM2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, │ \u001b[38;5;34m12,736\u001b[0m │\n", "│ │ \u001b[38;5;34m16\u001b[0m) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_4 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, │ \u001b[38;5;34m64\u001b[0m │\n", "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ \u001b[38;5;34m16\u001b[0m) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv_lstm2d_3 (\u001b[38;5;33mConvLSTM2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, │ \u001b[38;5;34m55,424\u001b[0m │\n", "│ │ \u001b[38;5;34m32\u001b[0m) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ batch_normalization_5 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, │ \u001b[38;5;34m128\u001b[0m │\n", "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ \u001b[38;5;34m32\u001b[0m) │ │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv3d_1 (\u001b[38;5;33mConv3D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m, \u001b[38;5;34m291\u001b[0m, \u001b[38;5;34m512\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m865\u001b[0m │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Total params: 69,241 (270.47 KB)\n", "\n" ], "text/plain": [ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m69,241\u001b[0m (270.47 KB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Trainable params: 69,133 (270.05 KB)\n", "\n" ], "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m69,133\u001b[0m (270.05 KB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Non-trainable params: 108 (432.00 B)\n", "\n" ], "text/plain": [ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m108\u001b[0m (432.00 B)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m150s\u001b[0m 496ms/step - loss: 0.7337 - mean_squared_error: 0.1448 - val_loss: 0.6862 - val_mean_squared_error: 0.1305 - learning_rate: 1.0000e-05\n", "Epoch 2/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m137s\u001b[0m 469ms/step - loss: 0.7032 - mean_squared_error: 0.1331 - val_loss: 0.6964 - val_mean_squared_error: 0.1351 - learning_rate: 1.0000e-05\n", "Epoch 3/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.6931 - mean_squared_error: 0.1289 - val_loss: 0.7002 - val_mean_squared_error: 0.1363 - learning_rate: 1.0000e-05\n", "Epoch 4/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 472ms/step - loss: 0.6858 - mean_squared_error: 0.1247 - val_loss: 0.6941 - val_mean_squared_error: 0.1334 - learning_rate: 1.0000e-05\n", "Epoch 5/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.6783 - mean_squared_error: 0.1212 - val_loss: 0.6801 - val_mean_squared_error: 0.1267 - learning_rate: 1.0000e-05\n", "Epoch 6/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 478ms/step - loss: 0.6691 - mean_squared_error: 0.1169 - val_loss: 0.6731 - val_mean_squared_error: 0.1232 - learning_rate: 1.0000e-05\n", "Epoch 7/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m141s\u001b[0m 483ms/step - loss: 0.6576 - mean_squared_error: 0.1122 - val_loss: 0.6551 - val_mean_squared_error: 0.1144 - learning_rate: 1.0000e-05\n", "Epoch 8/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 503ms/step - loss: 0.6441 - mean_squared_error: 0.1054 - val_loss: 0.6403 - val_mean_squared_error: 0.1071 - learning_rate: 1.0000e-05\n", "Epoch 9/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m149s\u001b[0m 510ms/step - loss: 0.6289 - mean_squared_error: 0.0970 - val_loss: 0.6240 - val_mean_squared_error: 0.0991 - learning_rate: 1.0000e-05\n", "Epoch 10/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m144s\u001b[0m 492ms/step - loss: 0.6117 - mean_squared_error: 0.0892 - val_loss: 0.6035 - val_mean_squared_error: 0.0891 - learning_rate: 1.0000e-05\n", "Epoch 11/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 485ms/step - loss: 0.5937 - mean_squared_error: 0.0801 - val_loss: 0.5833 - val_mean_squared_error: 0.0794 - learning_rate: 1.0000e-05\n", "Epoch 12/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m137s\u001b[0m 469ms/step - loss: 0.5754 - mean_squared_error: 0.0714 - val_loss: 0.5642 - val_mean_squared_error: 0.0702 - learning_rate: 1.0000e-05\n", "Epoch 13/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 472ms/step - loss: 0.5567 - mean_squared_error: 0.0626 - val_loss: 0.5496 - val_mean_squared_error: 0.0634 - learning_rate: 1.0000e-05\n", "Epoch 14/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.5387 - mean_squared_error: 0.0540 - val_loss: 0.5301 - val_mean_squared_error: 0.0543 - learning_rate: 1.0000e-05\n", "Epoch 15/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m137s\u001b[0m 469ms/step - loss: 0.5220 - mean_squared_error: 0.0461 - val_loss: 0.5103 - val_mean_squared_error: 0.0453 - learning_rate: 1.0000e-05\n", "Epoch 16/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 486ms/step - loss: 0.5051 - mean_squared_error: 0.0391 - val_loss: 0.4963 - val_mean_squared_error: 0.0390 - learning_rate: 1.0000e-05\n", "Epoch 17/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 503ms/step - loss: 0.4907 - mean_squared_error: 0.0324 - val_loss: 0.4815 - val_mean_squared_error: 0.0326 - learning_rate: 1.0000e-05\n", "Epoch 18/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 502ms/step - loss: 0.4774 - mean_squared_error: 0.0263 - val_loss: 0.4664 - val_mean_squared_error: 0.0263 - learning_rate: 1.0000e-05\n", "Epoch 19/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 501ms/step - loss: 0.4648 - mean_squared_error: 0.0214 - val_loss: 0.4584 - val_mean_squared_error: 0.0230 - learning_rate: 1.0000e-05\n", "Epoch 20/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 485ms/step - loss: 0.4539 - mean_squared_error: 0.0169 - val_loss: 0.4452 - val_mean_squared_error: 0.0177 - learning_rate: 1.0000e-05\n", "Epoch 21/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 475ms/step - loss: 0.4444 - mean_squared_error: 0.0133 - val_loss: 0.4366 - val_mean_squared_error: 0.0144 - learning_rate: 1.0000e-05\n", "Epoch 22/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 472ms/step - loss: 0.4362 - mean_squared_error: 0.0103 - val_loss: 0.4267 - val_mean_squared_error: 0.0108 - learning_rate: 1.0000e-05\n", "Epoch 23/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.4303 - mean_squared_error: 0.0077 - val_loss: 0.4232 - val_mean_squared_error: 0.0096 - learning_rate: 1.0000e-05\n", "Epoch 24/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 475ms/step - loss: 0.4241 - mean_squared_error: 0.0058 - val_loss: 0.4167 - val_mean_squared_error: 0.0073 - learning_rate: 1.0000e-05\n", "Epoch 25/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m145s\u001b[0m 497ms/step - loss: 0.4207 - mean_squared_error: 0.0044 - val_loss: 0.4112 - val_mean_squared_error: 0.0054 - learning_rate: 1.0000e-05\n", "Epoch 26/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 502ms/step - loss: 0.4154 - mean_squared_error: 0.0034 - val_loss: 0.4105 - val_mean_squared_error: 0.0052 - learning_rate: 1.0000e-05\n", "Epoch 27/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 499ms/step - loss: 0.4136 - mean_squared_error: 0.0026 - val_loss: 0.4066 - val_mean_squared_error: 0.0040 - learning_rate: 1.0000e-05\n", "Epoch 28/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 500ms/step - loss: 0.4119 - mean_squared_error: 0.0020 - val_loss: 0.4046 - val_mean_squared_error: 0.0033 - learning_rate: 1.0000e-05\n", "Epoch 29/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 476ms/step - loss: 0.4105 - mean_squared_error: 0.0016 - val_loss: 0.4034 - val_mean_squared_error: 0.0030 - learning_rate: 1.0000e-05\n", "Epoch 30/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 474ms/step - loss: 0.4106 - mean_squared_error: 0.0013 - val_loss: 0.4030 - val_mean_squared_error: 0.0029 - learning_rate: 1.0000e-05\n", "Epoch 31/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 472ms/step - loss: 0.4078 - mean_squared_error: 0.0012 - val_loss: 0.4021 - val_mean_squared_error: 0.0026 - learning_rate: 1.0000e-05\n", "Epoch 32/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 471ms/step - loss: 0.4087 - mean_squared_error: 0.0011 - val_loss: 0.4015 - val_mean_squared_error: 0.0024 - learning_rate: 1.0000e-05\n", "Epoch 33/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 475ms/step - loss: 0.4083 - mean_squared_error: 9.7096e-04 - val_loss: 0.4016 - val_mean_squared_error: 0.0024 - learning_rate: 1.0000e-05\n", "Epoch 34/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m141s\u001b[0m 483ms/step - loss: 0.4075 - mean_squared_error: 9.5572e-04 - val_loss: 0.4013 - val_mean_squared_error: 0.0023 - learning_rate: 1.0000e-05\n", "Epoch 35/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 475ms/step - loss: 0.4084 - mean_squared_error: 9.2558e-04 - val_loss: 0.4006 - val_mean_squared_error: 0.0021 - learning_rate: 1.0000e-05\n", "Epoch 36/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m137s\u001b[0m 469ms/step - loss: 0.4088 - mean_squared_error: 8.9947e-04 - val_loss: 0.4008 - val_mean_squared_error: 0.0022 - learning_rate: 1.0000e-05\n", "Epoch 37/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 477ms/step - loss: 0.4081 - mean_squared_error: 8.2714e-04 - val_loss: 0.4005 - val_mean_squared_error: 0.0021 - learning_rate: 1.0000e-05\n", "Epoch 38/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 504ms/step - loss: 0.4093 - mean_squared_error: 8.5030e-04 - val_loss: 0.4005 - val_mean_squared_error: 0.0021 - learning_rate: 1.0000e-05\n", "Epoch 39/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 500ms/step - loss: 0.4090 - mean_squared_error: 8.4955e-04 - val_loss: 0.4002 - val_mean_squared_error: 0.0020 - learning_rate: 1.0000e-05\n", "Epoch 40/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m148s\u001b[0m 507ms/step - loss: 0.4085 - mean_squared_error: 8.1096e-04 - val_loss: 0.4000 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 41/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m140s\u001b[0m 481ms/step - loss: 0.4082 - mean_squared_error: 7.9257e-04 - val_loss: 0.4003 - val_mean_squared_error: 0.0020 - learning_rate: 1.0000e-05\n", "Epoch 42/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.4087 - mean_squared_error: 7.7913e-04 - val_loss: 0.4006 - val_mean_squared_error: 0.0021 - learning_rate: 1.0000e-05\n", "Epoch 43/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 474ms/step - loss: 0.4088 - mean_squared_error: 7.6459e-04 - val_loss: 0.3999 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 44/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.4083 - mean_squared_error: 7.5364e-04 - val_loss: 0.4001 - val_mean_squared_error: 0.0020 - learning_rate: 1.0000e-05\n", "Epoch 45/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 473ms/step - loss: 0.4066 - mean_squared_error: 7.8711e-04 - val_loss: 0.3999 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 46/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m145s\u001b[0m 495ms/step - loss: 0.4093 - mean_squared_error: 7.6262e-04 - val_loss: 0.3998 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 47/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 504ms/step - loss: 0.4076 - mean_squared_error: 7.3529e-04 - val_loss: 0.3997 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 48/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m145s\u001b[0m 496ms/step - loss: 0.4094 - mean_squared_error: 6.9850e-04 - val_loss: 0.3998 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 49/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 503ms/step - loss: 0.4087 - mean_squared_error: 7.1750e-04 - val_loss: 0.3997 - val_mean_squared_error: 0.0019 - learning_rate: 1.0000e-05\n", "Epoch 50/50\n", "\u001b[1m292/292\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 472ms/step - loss: 0.4070 - mean_squared_error: 6.8971e-04 - val_loss: 0.3996 - val_mean_squared_error: 0.0018 - learning_rate: 1.0000e-05\n", "Restoring model weights from the end of the best epoch: 50.\n" ] } ], "source": [ "# Define the model with correct input shape\n", "inp = layers.Input(shape=(1, X_data_clean.shape[2], X_data_clean.shape[3], X_data_clean.shape[4]))\n", "\n", "x = layers.BatchNormalization()(inp)\n", "x = layers.ConvLSTM2D(\n", " filters=16,\n", " kernel_size=(3, 3),\n", " padding=\"same\",\n", " return_sequences=True,\n", " activation=\"tanh\",\n", " recurrent_activation=\"sigmoid\",\n", " kernel_initializer=\"glorot_uniform\"\n", ")(x)\n", "x = layers.BatchNormalization()(x)\n", "x = layers.ConvLSTM2D(\n", " filters=32,\n", " kernel_size=(3, 3),\n", " padding=\"same\",\n", " return_sequences=True,\n", " activation=\"tanh\",\n", " recurrent_activation=\"sigmoid\",\n", " kernel_initializer=\"glorot_uniform\"\n", ")(x)\n", "x = layers.BatchNormalization()(x)\n", "x = layers.Conv3D(\n", " filters=1, kernel_size=(3, 3, 3), activation=\"sigmoid\", padding=\"same\"\n", ")(x)\n", "\n", "model = keras.models.Model(inp, x, name=\"smogseer\")\n", "\n", "# Use a reduced learning rate and gradient clipping\n", "optimizer = keras.optimizers.Adam(learning_rate=1e-5, clipnorm=1.0)\n", "model.compile(\n", " loss=keras.losses.binary_crossentropy,\n", " optimizer=optimizer,\n", " metrics=['mean_squared_error']\n", ")\n", "\n", "# Print the model summary\n", "model.summary()\n", "\n", "# Data Generator Class\n", "\n", "class DataGenerator(Sequence):\n", " def __init__(self, X_data, y_data, batch_size):\n", " self.X_data = X_data\n", " self.y_data = y_data\n", " self.batch_size = batch_size\n", " self.indices = np.arange(X_data.shape[0])\n", " \n", " def __len__(self):\n", " return int(np.ceil(len(self.indices) / self.batch_size))\n", " \n", " def __getitem__(self, index):\n", " batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n", " batch_X = self.X_data[batch_indices]\n", " batch_y = self.y_data[batch_indices]\n", " return batch_X, batch_y\n", "\n", " def on_epoch_end(self):\n", " np.random.shuffle(self.indices)\n", "\n", "batch_size = 1\n", "train_generator = DataGenerator(X_train, y_train, batch_size)\n", "val_generator = DataGenerator(X_val, y_val, batch_size)\n", "\n", "# Define callbacks for monitoring and adjusting learning rate\n", "callbacks = [\n", " keras.callbacks.ReduceLROnPlateau(\n", " monitor='val_loss', factor=0.1, patience=10, verbose=1, min_lr=1e-7\n", " ),\n", " keras.callbacks.EarlyStopping(\n", " monitor='val_loss', patience=15, verbose=1, restore_best_weights=True\n", " ),\n", " keras.callbacks.TensorBoard(log_dir='./logs')\n", "]\n", "\n", "# Train the model using data generators\n", "history = model.fit(train_generator, epochs=50, validation_data=val_generator, callbacks=callbacks)\n", "# Save the model\n", "model.save('smogseer.keras')\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 747ms/step\n", "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 460ms/step - loss: 0.3992 - mean_squared_error: 0.0016\n", "Validation Loss: 0.39958614110946655\n", "Validation Accuracy: 0.0018263210076838732\n" ] } ], "source": [ "## LOAD CHECKPOINTS IF NEEDED\n", "X_val = np.load('X_val.npy')\n", "y_val = np.load('Y_val.npy')\n", "\n", "# Load the model\n", "model = load_model('smogseer50.keras')\n", "\n", "# Run predictions on validation data\n", "predictions = model.predict(X_val)\n", "\n", "# Evaluate the model on validation data\n", "val_loss, val_accuracy = model.evaluate(X_val, y_val)\n", "print(f\"Validation Loss: {val_loss}\")\n", "print(f\"Validation Accuracy: {val_accuracy}\")" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "\n", "# Plot comparisons and training history\n", "\n", "def plot_comparison(y_true, y_pred, index, save_path):\n", " \"\"\"\n", " Plots the ground truth and the predicted output for a given index.\n", " \n", " Parameters:\n", " - y_true: Ground truth data\n", " - y_pred: Predicted data\n", " - index: Index of the sample to plot\n", " - save_path: Path to save the plot\n", " \"\"\"\n", " fig, axes = plt.subplots(1, 2, figsize=(12, 6))\n", "\n", " # Plot ground truth\n", " ax = axes[0]\n", " ax.imshow(y_true[index, 0, :, :, 0], cmap='viridis')\n", " ax.set_title('Ground Truth')\n", " ax.axis('off')\n", "\n", " # Plot prediction\n", " ax = axes[1]\n", " ax.imshow(y_pred[index, 0, :, :, 0], cmap='viridis')\n", " ax.set_title('Prediction')\n", " ax.axis('off')\n", "\n", " plt.tight_layout()\n", " plt.savefig(save_path)\n", " plt.close()\n", "\n", "# Visualize a few samples\n", "num_samples_to_plot = 5\n", "for i in range(num_samples_to_plot):\n", " plot_comparison(y_val, predictions, i, f'comparison_plot_{i}.png')\n", "\n", "# Plot training history\n", "def plot_training_history(history, save_path):\n", " \"\"\"\n", " Plots the training and validation loss and accuracy over epochs.\n", "\n", " Parameters:\n", " - history: Keras History object\n", " - save_path: Path to save the plot\n", " \"\"\"\n", " fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))\n", "\n", " # Plot loss\n", " ax1.plot(history.history['loss'], label='Training Loss')\n", " ax1.plot(history.history['val_loss'], label='Validation Loss')\n", " ax1.set_title('Loss over epochs')\n", " ax1.set_xlabel('Epoch')\n", " ax1.set_ylabel('Loss')\n", " ax1.legend()\n", "\n", " # Plot accuracy\n", " ax2.plot(history.history['mean_squared_error'], label='Training MSE')\n", " ax2.plot(history.history['val_mean_squared_error'], label='Validation MSE')\n", " ax2.set_title('MSE over epochs')\n", " ax2.set_xlabel('Epoch')\n", " ax2.set_ylabel('MSE')\n", " ax2.legend()\n", "\n", " plt.tight_layout()\n", " plt.savefig(save_path)\n", " plt.close()\n", "\n", "# Plot training history\n", "plot_training_history(history, 'training_history_epoch50.png')" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(291, 512)\n", "(291, 512)\n", "(291, 512)\n", "(291, 512)\n", "(291, 512)\n" ] } ], "source": [ "# Visualize a few samples\n", "num_timesteps_to_plot = 5\n", "for i in range(num_timesteps_to_plot):\n", " print(predictions[i, 0, :, :, 0].shape)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Target data range: 0.99998665 1.6277676e-06\n" ] } ], "source": [ "print(\"Target data range: \", predictions.max(), predictions.min())" ] } ], "metadata": { "kernelspec": { "display_name": "venv", "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.9.12" } }, "nbformat": 4, "nbformat_minor": 2 }