diff --git a/22-06-17-DL/Diamond.ipynb b/22-06-17-DL/Diamond.ipynb new file mode 100644 index 0000000..49e423d --- /dev/null +++ b/22-06-17-DL/Diamond.ipynb @@ -0,0 +1,1421 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Keras.ipynb", + "provenance": [], + "toc_visible": true, + "authorship_tag": "ABX9TyP5ax5jpc8OyTny/ODkjm+l", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "DataSet: https://www.kaggle.com/datasets/shivam2503/diamonds" + ], + "metadata": { + "id": "6e_s7G9AmmF4" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2_wrKy6tmWDP", + "outputId": "edf52db2-65a0-438a-8c35-757d62978ff1" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Archive: ./diamonds.csv.zip\n", + " inflating: diamonds.csv \n" + ] + } + ], + "source": [ + "! unzip ./diamonds.csv.zip" + ] + }, + { + "cell_type": "code", + "source": [ + "import numpy as np\n", + "import pandas as pd" + ], + "metadata": { + "id": "l_YDxihVmtKc" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "df = pd.read_csv('diamonds.csv')\n", + "df.head()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "ZGlvfpy_mybm", + "outputId": "4db65255-4651-4981-e62e-d613a3d51272" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Unnamed: 0 carat cut color clarity depth table price x y \\\n", + "0 1 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 \n", + "1 2 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 \n", + "2 3 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 \n", + "3 4 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 \n", + "4 5 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 \n", + "\n", + " z \n", + "0 2.43 \n", + "1 2.31 \n", + "2 2.31 \n", + "3 2.63 \n", + "4 2.75 " + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0caratcutcolorclaritydepthtablepricexyz
010.23IdealESI261.555.03263.953.982.43
120.21PremiumESI159.861.03263.893.842.31
230.23GoodEVS156.965.03274.054.072.31
340.29PremiumIVS262.458.03344.204.232.63
450.31GoodJSI263.358.03354.344.352.75
\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + " \n", + "
\n", + "
\n", + " " + ] + }, + "metadata": {}, + "execution_count": 4 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df.drop('Unnamed: 0', axis=1, inplace = True)" + ], + "metadata": { + "id": "ggmAfo5qp4Ss" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "df.isna().sum()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3-4KdSBOm3xG", + "outputId": "a29956ec-5be1-4103-c9ff-767d105130f8" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "carat 0\n", + "cut 0\n", + "color 0\n", + "clarity 0\n", + "depth 0\n", + "table 0\n", + "price 0\n", + "x 0\n", + "y 0\n", + "z 0\n", + "dtype: int64" + ] + }, + "metadata": {}, + "execution_count": 17 + } + ] + }, + { + "cell_type": "code", + "source": [ + "df.info()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "GVJ1LszMnLsX", + "outputId": "69c94ea8-a290-4c2a-f83d-ac484458b686" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "RangeIndex: 53940 entries, 0 to 53939\n", + "Data columns (total 10 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 carat 53940 non-null float64\n", + " 1 cut 53940 non-null object \n", + " 2 color 53940 non-null object \n", + " 3 clarity 53940 non-null object \n", + " 4 depth 53940 non-null float64\n", + " 5 table 53940 non-null float64\n", + " 6 price 53940 non-null int64 \n", + " 7 x 53940 non-null float64\n", + " 8 y 53940 non-null float64\n", + " 9 z 53940 non-null float64\n", + "dtypes: float64(6), int64(1), object(3)\n", + "memory usage: 4.1+ MB\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.preprocessing import OrdinalEncoder\n", + "\n", + "cut = ['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']\n", + "color = ['D', 'E', 'F', 'G', 'H', 'I', 'J']\n", + "clarity = ['I1', 'SI2', 'SI1', 'VS2', 'VS1', 'VVS2', 'VVS1', 'IF']\n", + "\n", + "oe = OrdinalEncoder(categories = [cut, color, clarity])\n", + "oe.fit_transform(df[['cut', 'color', 'clarity']])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "YzNS0HzEnv91", + "outputId": "dd7e29ae-3964-40ce-d3a4-a0a46f01fea3" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[4., 1., 1.],\n", + " [3., 1., 2.],\n", + " [1., 1., 4.],\n", + " ...,\n", + " [2., 0., 2.],\n", + " [3., 4., 1.],\n", + " [4., 0., 1.]])" + ] + }, + "metadata": {}, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.compose import ColumnTransformer\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "real_num = ['carat','depth','table', 'x','y','z']\n", + "cl = ColumnTransformer([\n", + " ('1', OrdinalEncoder(categories = [cut, color, clarity]), ['cut', 'color', 'clarity']),\n", + " ('2', StandardScaler(),real_num)\n", + "])" + ], + "metadata": { + "id": "gIR-vkMHnNWO" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "Y = df['price']\n", + "X = df.drop('price', axis=1)\n", + "\n", + "X = cl.fit_transform(X)" + ], + "metadata": { + "id": "KxNuja7LpyU7" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "xtrain, xtest, ytrain, ytest = train_test_split(X, Y)" + ], + "metadata": { + "id": "uLVGkYvWqLtR" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "lin = LinearRegression()\n", + "lin.fit(xtrain, ytrain)\n", + "\n", + "mean_squared_error(ytest, lin.predict(xtest))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "PfIerOxzqgEw", + "outputId": "cb92a48a-d819-45c3-e994-5fab3d0ce421" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1569472.6633326774" + ] + }, + "metadata": {}, + "execution_count": 27 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Keras" + ], + "metadata": { + "id": "-2Khue1sq47v" + } + }, + { + "cell_type": "code", + "source": [ + "(X.shape[1],)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "SviZAZELrLQT", + "outputId": "ea395645-6075-45b0-dde4-dfbac8c27b2a" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(9,)" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "source": [ + "import tensorflow as tf" + ], + "metadata": { + "id": "C55_zzG0q1LE" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "model = tf.keras.Sequential([\n", + " tf.keras.Input(shape=(X.shape[1],), name='input'),\n", + " tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1'),\n", + " tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2'),\n", + " tf.keras.layers.Dense(1, activation='linear', name='output'),\n", + "])\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "OPD93aYyq8hj", + "outputId": "62f8bfea-70d1-4b96-cfd3-07d72c9dd464" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential_5\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense_1 (Dense) (None, 20) 200 \n", + " \n", + " dense_2 (Dense) (None, 10) 210 \n", + " \n", + " output (Dense) (None, 1) 11 \n", + " \n", + "=================================================================\n", + "Total params: 421\n", + "Trainable params: 421\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Layers\n", + "\n", + "\n", + "\n", + "* `get_layer()`\n", + "* `get_weights`\n", + "* `set_weights`\n", + "\n" + ], + "metadata": { + "id": "NrZvXwPZu78I" + } + }, + { + "cell_type": "code", + "source": [ + "# model.layers[1].name\n", + "model.get_layer('dense_2').name" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "G81upI49sdur", + "outputId": "4350cc0f-77ef-469e-8148-042f6b0abce4" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'dense_2'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.get_layer('dense_2').trainable = False\n", + "\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ym6z-0r2uh_Q", + "outputId": "77e51a08-fa66-44d8-e8b6-c879332c1faf" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential_4\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense_1 (Dense) (None, 20) 200 \n", + " \n", + " dense_2 (Dense) (None, 10) 210 \n", + " \n", + " output (Dense) (None, 1) 11 \n", + " \n", + "=================================================================\n", + "Total params: 421\n", + "Trainable params: 211\n", + "Non-trainable params: 210\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.trainable = True\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "JTjwvss-umXM", + "outputId": "ee79a0bd-4fc7-4b6e-e567-65ad40f1832a" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential_4\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense_1 (Dense) (None, 20) 200 \n", + " \n", + " dense_2 (Dense) (None, 10) 210 \n", + " \n", + " output (Dense) (None, 1) 11 \n", + " \n", + "=================================================================\n", + "Total params: 421\n", + "Trainable params: 421\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "weights, biases = model.get_layer('dense_2').get_weights()\n", + "weights.shape, biases.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "911lkX7evCUf", + "outputId": "d53c50cb-f968-4b11-c372-ef951b47eac6" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "((20, 10), (10,))" + ] + }, + "metadata": {}, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.get_layer('dense_2').set_weights((weights, biases))" + ], + "metadata": { + "id": "Jj88lZqmve7e" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Training" + ], + "metadata": { + "id": "BdQxG6kpwMbX" + } + }, + { + "cell_type": "code", + "source": [ + "optimizer = tf.keras.optimizers.Adam(\n", + " learning_rate=0.01,\n", + " beta_1=0.9,\n", + " beta_2=0.999,\n", + " epsilon=1e-07,\n", + " amsgrad=False,\n", + " name=\"Adam\",\n", + ")\n", + "\n", + "model.compile(\n", + " optimizer = optimizer,\n", + " loss = 'mse',\n", + " metrics = ['mae']\n", + ")" + ], + "metadata": { + "id": "1vGyBjajwD_L" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(xtrain, ytrain, epochs=20, batch_size=32, validation_data=(xtest, ytest))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "loHCOYGCxSZi", + "outputId": "2cde7c37-59b0-4b76-8c8b-1e2f249ebe77" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 3541021.2500 - mae: 1052.9180 - val_loss: 1621820.2500 - val_mae: 651.6838\n", + "Epoch 2/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 908602.0625 - mae: 587.3908 - val_loss: 1450208.3750 - val_mae: 569.6687\n", + "Epoch 3/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 830691.3125 - mae: 540.2642 - val_loss: 1317816.1250 - val_mae: 539.1340\n", + "Epoch 4/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 792917.4375 - mae: 516.3724 - val_loss: 1218528.1250 - val_mae: 517.8723\n", + "Epoch 5/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 758870.8750 - mae: 499.4666 - val_loss: 1110867.3750 - val_mae: 498.8023\n", + "Epoch 6/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 732594.9375 - mae: 487.2462 - val_loss: 1045552.6250 - val_mae: 496.1373\n", + "Epoch 7/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 717453.3125 - mae: 479.0413 - val_loss: 931309.1250 - val_mae: 488.6411\n", + "Epoch 8/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 696750.1875 - mae: 469.7482 - val_loss: 876593.0625 - val_mae: 475.8308\n", + "Epoch 9/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 685237.4375 - mae: 463.5577 - val_loss: 846277.3125 - val_mae: 474.4117\n", + "Epoch 10/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 668493.7500 - mae: 456.3355 - val_loss: 746821.0625 - val_mae: 459.9638\n", + "Epoch 11/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 638636.8125 - mae: 449.4908 - val_loss: 688134.2500 - val_mae: 448.7004\n", + "Epoch 12/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 622973.9375 - mae: 443.7300 - val_loss: 671540.1875 - val_mae: 453.8398\n", + "Epoch 13/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 594510.0000 - mae: 437.6136 - val_loss: 699105.3125 - val_mae: 449.4216\n", + "Epoch 14/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 565427.6875 - mae: 427.8374 - val_loss: 700435.8750 - val_mae: 454.9417\n", + "Epoch 15/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 546010.5000 - mae: 422.3965 - val_loss: 662011.2500 - val_mae: 432.2979\n", + "Epoch 16/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 527876.0625 - mae: 414.9225 - val_loss: 688070.8750 - val_mae: 423.7885\n", + "Epoch 17/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 518986.5000 - mae: 411.9547 - val_loss: 706440.9375 - val_mae: 411.7516\n", + "Epoch 18/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 507427.8750 - mae: 406.8910 - val_loss: 705440.6250 - val_mae: 405.8596\n", + "Epoch 19/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 495755.7188 - mae: 402.7906 - val_loss: 793490.3750 - val_mae: 417.5538\n", + "Epoch 20/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 489539.0625 - mae: 398.4520 - val_loss: 781979.5000 - val_mae: 410.6672\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "pd.DataFrame(history.history).plot()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 293 + }, + "id": "Fq5no1R4yRW4", + "outputId": "3911d37b-f443-48e1-a013-b2de965c0b58" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 64 + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Further Topics are Advanced one\n" + ], + "metadata": { + "id": "cqumlE863ovu" + } + }, + { + "cell_type": "markdown", + "source": [ + "# CallBack\n", + "\n", + "https://keras.io/api/callbacks/" + ], + "metadata": { + "id": "2CCZIqvc0KyK" + } + }, + { + "cell_type": "code", + "source": [ + "def ee():\n", + " print('ee')\n", + "\n", + "lambda_callback = tf.keras.callbacks.LambdaCallback(\n", + " on_epoch_begin=None,\n", + " on_epoch_end=ee,\n", + " on_batch_begin=None,\n", + " on_batch_end=None,\n", + " on_train_begin=None,\n", + " on_train_end=None,\n", + ")\n", + "\n", + "class CustomCallback(tf.keras.callbacks.Callback):\n", + " # def on_epoch_begin():\n", + " # pass\n", + " def on_epoch_end(self, epoch, logs):\n", + " print(logs)\n", + " \n", + " # def on_batch_begin(**kwarg):\n", + " # pass\n", + " # def on_batch_end(**kwarg):\n", + " # pass\n", + " # def on_train_begin(**kwarg):\n", + " # pass\n", + " # def on_train_end(**kwarg):\n", + " # pass" + ], + "metadata": { + "id": "cIpxqhXLzCd7" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(xtrain, ytrain, epochs=20, batch_size=32, validation_data=(xtest, ytest), callbacks=[CustomCallback()])" + ], + "metadata": { + "id": "y7f9qNPt1N_u" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "model = tf.keras.Sequential([\n", + " tf.keras.Input(shape=(X.shape[1],), name='input'),\n", + " tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1'),\n", + " tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2'),\n", + " tf.keras.layers.Dense(1, activation='linear', name='output'),\n", + "])\n", + "model.compile(\n", + " optimizer = 'adam',\n", + " loss = 'mse',\n", + " metrics = ['mae']\n", + ")" + ], + "metadata": { + "id": "5SfJGU6l29cM" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "early_stoping = tf.keras.callbacks.EarlyStopping(\n", + " monitor=\"val_loss\",\n", + " min_delta=100000,\n", + " patience=5,\n", + " restore_best_weights=False,\n", + ")\n", + "model_checkpoint = tf.keras.callbacks.ModelCheckpoint(\n", + " './models/',\n", + " monitor=\"val_loss\",\n", + " save_best_only=True,\n", + " save_weights_only=True,# weights, optimizer\n", + ")\n", + "\n", + "history = model.fit(xtrain, ytrain, epochs=1000, batch_size=32, validation_data=(xtest, ytest), callbacks=[early_stoping, model_checkpoint])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "iq87YMVZ13xS", + "outputId": "3188eadd-68a3-443b-e2bb-9577e63f480e" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/1000\n", + "1265/1265 [==============================] - 5s 4ms/step - loss: 811799.1875 - mae: 535.6156 - val_loss: 1397307.2500 - val_mae: 547.8466\n", + "Epoch 2/1000\n", + "1265/1265 [==============================] - 5s 4ms/step - loss: 805493.4375 - mae: 530.7153 - val_loss: 1389875.6250 - val_mae: 544.8214\n", + "Epoch 3/1000\n", + "1265/1265 [==============================] - 4s 3ms/step - loss: 797423.6250 - mae: 526.8047 - val_loss: 1374737.2500 - val_mae: 539.5556\n", + "Epoch 4/1000\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 792061.5000 - mae: 523.0528 - val_loss: 1363270.1250 - val_mae: 536.1749\n", + "Epoch 5/1000\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 784844.8750 - mae: 519.5076 - val_loss: 1356152.2500 - val_mae: 533.6412\n", + "Epoch 6/1000\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 780153.4375 - mae: 516.4471 - val_loss: 1331084.6250 - val_mae: 529.4615\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Functional API\n", + "\n", + "https://www.tensorflow.org/api_docs/python/tf/keras/layers?version=nightly" + ], + "metadata": { + "id": "AwbeS4g_8vKn" + } + }, + { + "cell_type": "code", + "source": [ + "# model = tf.keras.Sequential([\n", + "# tf.keras.Input(shape=(X.shape[1],), name='input'),\n", + "# tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1'),\n", + "# tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2'),\n", + "# tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_3'),\n", + "# tf.keras.layers.Dense(1, activation='linear', name='output'),\n", + "# ])\n", + "\n", + "model_input = tf.keras.Input(shape=(X.shape[1],), name='input')\n", + "dense_1 = tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1')(model_input)\n", + "dense_2 = tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2')(dense_1)\n", + "dense_3 = tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_3')(tf.keras.layers.add([dense_1, dense_2]))\n", + "model_output = tf.keras.layers.Dense(1, activation='linear', name='output')(dense_3)\n", + "\n", + "model = tf.keras.Model(inputs=[model_input], outputs=[model_output])\n", + "\n", + "model.compile(\n", + " optimizer = 'adam',\n", + " loss = 'mse',\n", + " metrics = ['mae']\n", + ")\n", + "\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "58MZJ7UvAVwm", + "outputId": "aa14352f-78a6-441f-fddb-1910f23c764f" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"model_4\"\n", + "__________________________________________________________________________________________________\n", + " Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + " input (InputLayer) [(None, 9)] 0 [] \n", + " \n", + " dense_1 (Dense) (None, 20) 200 ['input[0][0]'] \n", + " \n", + " dense_2 (Dense) (None, 20) 420 ['dense_1[0][0]'] \n", + " \n", + " add_2 (Add) (None, 20) 0 ['dense_1[0][0]', \n", + " 'dense_2[0][0]'] \n", + " \n", + " dense_3 (Dense) (None, 10) 210 ['add_2[0][0]'] \n", + " \n", + " output (Dense) (None, 1) 11 ['dense_3[0][0]'] \n", + " \n", + "==================================================================================================\n", + "Total params: 841\n", + "Trainable params: 841\n", + "Non-trainable params: 0\n", + "__________________________________________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model_input = tf.keras.Input(shape=(X.shape[1],), name='input')\n", + "dense_1 = tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1')(model_input)\n", + "dense_2 = tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2')(dense_1)\n", + "concat = tf.keras.layers.Concatenate()([dense_1, dense_2])\n", + "dense_3 = tf.keras.layers.Dense(5, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_3')(concat)\n", + "model_output = tf.keras.layers.Dense(1, activation='linear', name='output')(dense_3)\n", + "\n", + "model = tf.keras.Model(inputs=[model_input], outputs=[model_output])\n", + "\n", + "model.compile(\n", + " optimizer = 'adam',\n", + " loss = 'mse',\n", + " metrics = ['mae']\n", + ")\n", + "\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "67EhDHxTAq2i", + "outputId": "09014fd7-d6c2-4396-9680-b6a648035863" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"model_5\"\n", + "__________________________________________________________________________________________________\n", + " Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + " input (InputLayer) [(None, 9)] 0 [] \n", + " \n", + " dense_1 (Dense) (None, 20) 200 ['input[0][0]'] \n", + " \n", + " dense_2 (Dense) (None, 10) 210 ['dense_1[0][0]'] \n", + " \n", + " concatenate_1 (Concatenate) (None, 30) 0 ['dense_1[0][0]', \n", + " 'dense_2[0][0]'] \n", + " \n", + " dense_3 (Dense) (None, 5) 155 ['concatenate_1[0][0]'] \n", + " \n", + " output (Dense) (None, 1) 6 ['dense_3[0][0]'] \n", + " \n", + "==================================================================================================\n", + "Total params: 571\n", + "Trainable params: 571\n", + "Non-trainable params: 0\n", + "__________________________________________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "tf.keras.utils.plot_model(model)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 564 + }, + "id": "HyzklfdVBV1T", + "outputId": "4b5d815c-52b0-4bf0-af89-4d1222049736" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQwAAAIjCAYAAAD2niXtAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3de1xUdf4/8NdcmBkGHPCCkgEGaJGIZpoZ6mbbuqVubQoqm2Zatl66uV5if2p+fdhFTQ1blW0tv1a20SCadtMuulq5amp4CQRvi2CIoCIoIJfh/fujdb4RFw+3OXN5PR+P+aMzZ87nNcfDq3PmzJyjEREBEZECWrUDEJHrYGEQkWIsDCJSjIVBRIrp1Q7QWvbs2YPXX39d7RhENzRjxgzcc889asdQxG33MHJycpCSkqJ2DFXs3bsXe/fuVTsGKZCSkoKcnBy1YyjmtnsY123YsEHtCA43atQoAJ753l2NRqNRO0KjuO0eBhG1PBYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiyMX/j888/h5+eHTz75RO0oDrV3717cfvvt0Gq10Gg06NSpE15++WW1Y9WwceNGhIWFQaPRQKPRIDAwEOPGjVM7lsdx++thNIan3nGhf//+OHbsGB588EF88cUXyMzMhL+/v9qxaoiJiUFMTAy6du2KCxcuIC8vT+1IHol7GL8wfPhwFBUV4aGHHlI7CsrKyhAdHa12DNV4+vt3ViwMJ7V27Vrk5+erHUM1nv7+nRUL47++++47hISEQKPRYNWqVQCAxMRE+Pj4wGw2Y8uWLRg6dCgsFguCgoKQlJRkf+3f/vY3mEwmdOzYEVOmTMFNN90Ek8mE6Oho7Nu3zz7fc889B4PBgMDAQPu0p59+Gj4+PtBoNLhw4QIAYPr06Zg5cyZOnToFjUaDrl27Omgt1OTq7//bb79F9+7d4efnB5PJhKioKHzxxRcAgEmTJtk/DwkPD0dqaioAYOLEiTCbzfDz88PHH38MALDZbJg/fz5CQkLg7e2Nnj17wmq1AgBee+01mM1mtGnTBvn5+Zg5cyZuvvlmZGZmNimz0xM3ZbVapbFvLycnRwDIypUr7dPmzp0rAGT79u1SVFQk+fn5MmjQIPHx8ZGKigr7fJMnTxYfHx9JT0+Xa9euSVpamtx1113Spk0byc7Ots83duxY6dSpU41xly5dKgCkoKDAPi0mJkbCw8Mb+7ZFRCQ2NlZiY2Mb/boHHnhAAEhhYaF9mrO9//DwcPHz81P0fjZs2CALFiyQS5cuycWLF6V///7Svn37GmPodDr56aefarzu0UcflY8//tj+37NmzRKj0SgpKSlSWFgoc+bMEa1WK/v376+xjp5//nlZuXKljBw5Uo4dO6YoIwCxWq2K5nUG3MNQKDo6GhaLBQEBAYiLi0NJSQmys7NrzKPX63H77bfDaDSie/fuSExMxJUrV7Bu3TqVUrccV3z/sbGx+J//+R+0bdsW7dq1w8MPP4yLFy+ioKAAADB16lTYbLYa+YqLi7F//34MGzYMAHDt2jUkJiZixIgRiImJgb+/P+bNmwcvL69a72vx4sV45plnsHHjRkRERDjujToQC6MJDAYDAKCysrLB+fr27Quz2YyMjAxHxHIYV33/Xl5eAH4+xACA3/72t7j11lvxv//7v/YzZB9++CHi4uKg0+kAAJmZmSgtLUWPHj3sy/H29kZgYKDTvC9HYmG0MqPRaP8/midS8/1/9tlnGDx4MAICAmA0GvHCCy/UeF6j0WDKlCk4ffo0tm/fDgB477338OSTT9rnKSkpAQDMmzfP/pmHRqPBmTNnUFpa6rg34yRYGK2osrISly9fRlBQkNpRVOHo9//NN98gISEBAJCdnY0RI0YgMDAQ+/btQ1FREZYsWVLrNRMmTIDJZMLbb7+NzMxMWCwWdOnSxf58QEAAACAhIQEiUuOxZ88eh7wvZ8IvbrWinTt3QkTQv39/+zS9Xn/DXXl34ej3f/DgQfj4+AAAjh49isrKSkybNg1hYWEA6r5pUNu2bTFmzBh8+OGHaNOmDZ566qkazwcHB8NkMuHQoUOtktnVcA+jBVVXV6OwsBBVVVU4cuQIpk+fjpCQEEyYMME+T9euXXHp0iVs3rwZlZWVKCgowJkzZ2otq127dsjNzUVWVhauXLniEiWj1vuvrKzE+fPnsXPnTnthhISEAAC+/vprXLt2DSdOnKhxiveXpk6divLycnz66ae1vrRnMpkwceJEJCUlITExEcXFxbDZbDh79izOnTvX2FXk+lQ8Q9OqGntadeXKlRIYGCgAxGw2y8MPPyyrV68Ws9ksAKRbt25y6tQpWbNmjVgsFgEgXbp0kePHj4vIz6cVvby85Oabbxa9Xi8Wi0UeeeQROXXqVI1xLl68KPfdd5+YTCYJDQ2VZ599VmbPni0ApGvXrvZTkD/88IN06dJFvL29ZeDAgZKXl6f4vTT2tOrevXslMjJStFqtAJDAwEB55ZVXnOr9//3vf5fw8HAB0OBj06ZN9rHi4+OlXbt24u/vL6NGjZJVq1YJAAkPD69xqldEpHfv3vL//t//q3P9lJeXS3x8vISEhIher5eAgACJiYmRtLQ0WbJkiXh7ewsACQ4OlvXr1yte7yKud1qVhdFCJk+eLO3atXPYeA1p6vcwmsOZ3n9TDBs2TE6fPu3wcV2tMHhI0oKun67zVK70/n95iHPkyBGYTCaEhoaqmMg18ENP8kjx8fGYOnUqRAQTJ07E+vXr1Y7kEriH0QLmzJmDdevWoaioCKGhoUhJSVE7kkO54vs3m82IiIjA7373OyxYsADdu3dXO5JL0Ii450UgkpOTMWbMGI+8xsWoUaMAABs2bFA5Cd2IRqOB1WrF6NGj1Y6iCPcwiEgxFgYRKcbCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFHP762Fc/+WmJ9m7dy8Az3zv1LrctjCCg4MRGxurdgxV/PIq3S3pwIEDAH6+QRG1jNjYWAQHB6sdQzG3vR4Gtbzr12xITk5WOQmphZ9hEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiwMIlKMhUFEirEwiEgxFgYRKcbCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYhoREbVDkPN55513sGLFCthsNvu0goICAEBAQIB9mk6nw/Tp0zFhwgRHRyQVsDCoTpmZmYiIiFA077FjxxTPS66NhyRUp9tuuw1RUVHQaDT1zqPRaBAVFcWy8CAsDKrX+PHjodPp6n1er9fj8ccfd2AiUhsPSaheubm5CAoKQn2biEajQXZ2NoKCghycjNTCPQyqV+fOnREdHQ2ttvZmotVqER0dzbLwMCwMatBjjz1W5+cYGo0G48ePVyERqYmHJNSgS5cuoVOnTqiqqqoxXafT4fz582jfvr1KyUgN3MOgBrVr1w5DhgyBXq+3T9PpdBgyZAjLwgOxMOiGxo0bh+rqavt/iwgee+wxFRORWnhIQjdUUlKCDh064Nq1awAAo9GICxcuwNfXV+Vk5Gjcw6Ab8vHxwcMPPwwvLy/o9Xo88sgjLAsPxcIgRcaOHYuqqirYbDY8+uijaschlehvPIt7Sk5OVjuCS7HZbDCZTBARXL16leuvkUaPHq12hBbhsZ9hNPQbCaKW5i5/Zh59SGK1WiEifCh87NixA//617/qfT42NhaxsbGq53Smh9VqVXszb1Eee0hCjXfvvfeqHYFUxsIgxer6TQl5Fm4BRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiwMIlKMhdFEkyZNQps2baDRaHDo0CG14zRLdXU1EhISEB0d7dBxN27ciLCwMGg0mhoPg8GAjh07YvDgwVi6dCkKCwsdmovqx8JoorfffhtvvfWW2jGa7cSJE/jNb36DGTNmoLS01KFjx8TE4PTp0wgPD4efnx9EBNXV1cjPz0dycjJCQ0MRHx+PyMhIHDhwwKHZqG4sDA92+PBh/PWvf8XUqVNxxx13qB0HwM9XQvP398fgwYOxbt06JCcn4/z58xg+fDiKiorUjufxWBjN4OqX+evVqxc2btyIsWPHwmg0qh2nTrGxsZgwYQLy8/Px5ptvqh3H47EwFBIRLF26FLfddhuMRiP8/Pwwe/bsWvPZbDbMnz8fISEh8Pb2Rs+ePe2XaUtMTISPjw/MZjO2bNmCoUOHwmKxICgoCElJSTWWs2vXLvTr1w9msxkWiwVRUVEoLi6+4RjuaMKECQCArVu32qdxPatEPBQAsVqtiuefO3euaDQaWb58uRQWFkppaamsXr1aAEhqaqp9vlmzZonRaJSUlBQpLCyUOXPmiFarlf3799uXA0C2b98uRUVFkp+fL4MGDRIfHx+pqKgQEZGrV6+KxWKRJUuWSFlZmeTl5cnIkSOloKBA0RhNcffdd0uvXr2a/HoRkdjYWImNjW3068LDw8XPz6/e54uLiwWABAcH26e5ynq2Wq3iTn9m7vNOGqkxhVFaWipms1mGDBlSY3pSUlKNwigrKxOz2SxxcXE1Xms0GmXatGki8n8bcllZmX2e68Vz8uRJERH58ccfBYB8+umntbIoGaMpnLkwREQ0Go34+/uLiGutZ3crDB6SKHDy5EmUlpbi/vvvb3C+zMxMlJaWokePHvZp3t7eCAwMREZGRr2vMxgMAIDKykoAQFhYGDp27Ihx48ZhwYIFyMrKavYYrqykpAQiAovFAoDrWU0sDAXOnj0LAAgICGhwvpKSEgDAvHnzanyv4MyZM406Zent7Y0dO3Zg4MCBeOWVVxAWFoa4uDiUlZW12Biu5Pjx4wCAiIgIAFzPamJhKGAymQAA5eXlDc53vVASEhJq3Z9iz549jRozMjISn3zyCXJzcxEfHw+r1Yply5a16BiuYtu2bQCAoUOHAuB6VhMLQ4EePXpAq9Vi165dDc4XHBwMk8nU7G9+5ubmIj09HcDPfxyLFi3CnXfeifT09BYbw1Xk5eUhISEBQUFBeOKJJwBwPauJhaFAQEAAYmJikJKSgrVr16K4uBhHjhzBmjVrasxnMpkwceJEJCUlITExEcXFxbDZbDh79izOnTuneLzc3FxMmTIFGRkZqKioQGpqKs6cOYP+/fu32BjORuTne7ZWV1dDRFBQUACr1YoBAwZAp9Nh8+bN9s8wuJ5V5OAPWZ0GGnla9cqVKzJp0iRp3769+Pr6ysCBA2X+/PkCQIKCguTw4cMiIlJeXi7x8fESEhIier1eAgICJCYmRtLS0mT16tViNpsFgHTr1k1OnTola9asEYvFIgCkS5cucvz4ccnKypLo6Ghp27at6HQ66dy5s8ydO1eqqqpuOEZj7NmzRwYMGCA33XSTABAAEhgYKNHR0bJr165GLUuk8WdJPv74Y+nZs6eYzWYxGAyi1WoFgP2MSL9+/WThwoVy8eLFWq91lfXsbmdJPPpmzFar1W3uqu0MRo0aBQDYsGGDykmcR3JyMsaMGQN3+TPjIQkRKcbCcCMZGRm1fipe1yMuLk7tqOSieDNmNxIREeE2u77knLiHQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiwMIlKMhUFEirEwiEgxFgYRKcbCICLFWBhEpBgLg4gU8+ift3vy1Z9bw/XbMSQnJ6ucxHm42zbm0ZfoI3IUd/kz89hDEvnVvSY85fHnP/8ZnTp1QlFRkcPGnDZtGkJCQlBeXq76+1fr4S48tjA8UWpqKtauXYtly5bZL9nvCH/961+Rl5eHDz74wGFjUuvw2EMSTyMiuPfee2Gz2fDdd985/JDsySefxDfffIOMjAzodDqHjk0th3sYHuL999/H7t27sWLFClU+v5kzZw6ysrJ4CwIXxz0MD3DlyhVERETg4Ycfxt///nfVcjz66KM4fPgwjh49Cq2W/69yRfxX8wALFy5EWVkZXnrpJVVzzJs3DxkZGfj4449VzUFNxz0MN3fixAlERUXh9ddfx7Rp09SOg5EjRyIrKwsHDx7kqW0XxMJwc8OGDUNOTg5SU1Oh16v/Pb3U1FT06dMHW7duxQMPPKB2HGokFoYb27x5M0aMGIGdO3fi3nvvVTuO3dChQ1FUVIR///vfakehRmJhuKny8nJERUXhrrvuwj//+U+149SwZ88eREdHO12R0Y2xMNzUSy+9hMWLF+PYsWMICQlRO04t9913H7y9vfH555+rHYUagWdJ3FBOTg6WLFmCF1980SnLAgBmzpyJbdu2IT09Xe0o1Ajcw3BDo0aNQmpqKtLS0mA0GtWOUycRQffu3fGb3/wG//jHP9SOQwpxD8PN7NixAykpKXjjjTectiyAn38t/Oyzz2L9+vW4cOGC2nFIIe5huJGqqir06dMHISEh+OSTT9SOc0OlpaUICQnB9OnTMW/ePLXjkALcw3Ajq1evRkZGBpYvX652FEXMZjOeeuoprFy5EteuXVM7DinAwnAT+fn5WLBgAWbOnIlbb71V7TiKPf3007h06RI2btyodhRSgIckbuLJJ5/EF198gYyMDPj6+qodp1FiY2ORl5eH7777Tu0odAPcw3ADBw8exDvvvINly5a5XFkAwNSpU7F7926kpqaqHYVugHsYLk5EEB0dDb1ej2+++cYlf9AlIrj99tvx29/+FomJiWrHoQZwD8PFvfPOO9i/fz9WrVrlkmUB/HyKdfLkyVi/fj2Ki4vVjkMNYGG4sOLiYsydOxdTpkxBr1691I7TLBMnTkR1dbXT/e6FauIhiQv7y1/+gvfeew/Hjx9H+/bt1Y7TbE888QRSU1P5WYYT4x6Gizp27BhWr16NRYsWuUVZAD/vZRw6dAiHDh1SOwrVg3sYLurBBx9Efn4+9u/f71ZX4Y6IiMDQoUORkJCgdhSqA/cwXNDGjRvx5Zdf4o033nCrsgCAsWPHYv369aioqFA7CtWBexgupqysDN27d8egQYPw3nvvqR2nxZ09exa33HILNm7ciD/+8Y9qx6Ff4R6Gi1m8eDEuXryIxYsXqx2lVQQFBWHw4MF499131Y5CdWBhuJDs7GwsW7YM8+fPR+fOndWO02omTJiATz/9lD97d0IsDBcyffp03HzzzXj22WfVjtKqRo4cCYPBgE2bNqkdhX6FheEitm/fjo8++sjpL4zTEsxmM4YOHcrbKjohfujpAqqqqtC7d2907doVH330kdpxHCI5ORmPPvoocnNz0bFjR7Xj0H9xD8MFvPHGGzhx4gRee+01taM4zB/+8AeYTCYeljgZFoYTycrKqjXt/PnzeOmll/DCCy+gW7dujg+lErPZjOHDh/OwxMmwMJxEWVkZIiIi8Nxzz+Hy5cv26fHx8bBYLIiPj1cxnTpGjRqFXbt24fz582pHof9iYTiJI0eOoLy8HImJiQgNDcXbb7+N77//HuvXr8frr78OHx8ftSM63LBhw2AwGFzigsaegh96OonVq1dj+vTpqKqqAgBotVr4+vqiW7duOHDggMrp1DN8+HCYTCZe89NJcA/DSRw8eLDGBXCqq6tRWlqKgwcPYty4ccjLy1MxnXqGDRuGL7/8EuXl5WpHIbAwnMbevXtRWVlZY9r1vQ2r1YquXbsiISGh1jzubtiwYbh69Sp2796tdhQCC8MpXLt2DcePH6/3+aqqKpSUlGDGjBl44403HJhMfaGhobj99tt502YnwcJwAkeOHIHNZqv3eY1GA61Wi8WLF2PWrFkOTOYchg0bxsJwEiwMJ3Dw4EHo9fo6n9PpdDAajfjoo4888tQq8HNhHDt2rM7vqZBjsTCcwA8//FDnFb+9vLzQoUMH7N69Gw8//LAKyZzDgAEDYDKZ8O2336odxeOxMJzAnj17an2Y6eXlhaioKBw6dAh33nmnSsmcg9FoRN++fVkYToCFobKKigpkZmbWmKbVavGHP/wB3377LQIDA1VK5lwGDRqEb775Ru0YHo+FobIjR47YT59eN3v2bKSkpMBsNquUyvkMGjQIx48fR35+vtpRPBoLQ2U//PADtFottFotvLy88P7772Px4sXQavlP80sDBgyAVqvlYYnKuFWq7ODBg6iurkabNm3w9ddfY+zYsWpHckoWiwW9evViYais1rm85ORkjBkzRo0sHq2oqAj33nuv2jEcLjY2VvFP2O+55x7s27evlRNRQ+o++Y+fv45MLWfMmDGYPn067rnnHvu0qqoqLF++HM8884xH/hq1sTcr6tOnD9auXYvKykp4eXm1UipqSL2FMXr0aEfmcHtjxozBPffcU2O9VlRUYPTo0fV+acvdNfbiOH369MG1a9eQkZGBqKioVkpFDeFnGCoyGAweWxZNERkZCbPZ7NE/91cbC4Nchk6nQ1RUFA4ePKh2FI/FwiCX0rdvXxaGilgY5FL69OmDQ4cOedx1QZwFC4NcSu/evW94/RBqPSwMcim333479Ho90tLS1I7ikVgY5FKMRiPCwsKQnp6udhSPxMIglxMZGck9DJWwMMjldO/enXsYKmFhkMuJjIzEiRMnUFFRoXYUj8PCIJcTGRmJyspKnDhxQu0oHoeFQS4nLCwMAHDmzBmVk3geFga5HF9fX/j7+yMnJ0ftKB6HhUEuKSgoCGfPnlU7hsdplcKYNGkS2rRpA41Gg0OHDrXGEK1u4cKF6N69OywWC4xGI7p27YoXXngBV69ebfWxN27ciLCwMGg0mhoPg8GAjh07YvDgwVi6dCkKCwtbPYuzCg4O5h6GClqlMN5++2289dZbrbFoh9mxYweeeeYZZGVl4cKFC3j11VexYsUKjBo1qtXHjomJwenTpxEeHg4/Pz+ICKqrq5Gfn4/k5GSEhoYiPj4ekZGRHvtTbxaGOnhIUg9fX19MnjwZ7dq1Q5s2bTB69GiMGDEC27ZtU2VD1Wg08Pf3x+DBg7Fu3TokJyfj/PnzGD58OIqKihyeR22dO3f22Dvaq6nVCqOuO3m5kk8//RQ6na7GtA4dOgAASktL1YhUQ2xsLCZMmID8/Hy8+eabasdxOB8fH5SUlKgdw+O0SGGICJYuXYrbbrsNRqMRfn5+mD17dq35bDYb5s+fj5CQEHh7e6Nnz572a4cmJibCx8cHZrMZW7ZswdChQ2GxWBAUFISkpKQay9m1axf69esHs9kMi8WCqKgoFBcX33CM5vrpp5/g7e2N0NDQFllec02YMAEAsHXrVvs0V1/HSrEwVCK/YrVapY7JDZo7d65oNBpZvny5FBYWSmlpqaxevVoASGpqqn2+WbNmidFolJSUFCksLJQ5c+aIVquV/fv325cDQLZv3y5FRUWSn58vgwYNEh8fH6moqBARkatXr4rFYpElS5ZIWVmZ5OXlyciRI6WgoEDRGE1VUlIibdq0keeee65JrwcgVqu1Ua8JDw8XPz+/ep8vLi4WABIcHGyf5krrODY2VmJjYxv1muveeecd8fb2btJrqemaXRilpaViNptlyJAhNaYnJSXVKIyysjIxm80SFxdX47VGo1GmTZsmIv+3MZeVldnnuV48J0+eFBGRH3/8UQDIp59+WiuLkjGaau7cuXLrrbdKcXFxk17fGoUhIqLRaMTf319EXG8dN6cwNmzYIBqNRmw2W5NeT03T7EOSkydPorS0FPfff3+D82VmZqK0tBQ9evSwT/P29kZgYCAyMjLqfZ3BYAAA+xWWwsLC0LFjR4wbNw4LFixAVlZWs8e4kU2bNiE5ORlffPEF2rRp0+TltLSSkhKICCwWCwDXXseN5e3tDRFBWVmZw8akFvgM4/qXZwICAhqc7/rx5rx582p8t+DMmTON+hDR29sbO3bswMCBA/HKK68gLCwMcXFxKCsra7ExfunDDz/E4sWLsXPnTtxyyy1NWkZruX7VqYiICACuu46b4voPz66XHTlGswvDZDIBAMrLyxuc73qhJCQkQH4+FLI/9uzZ06gxIyMj8cknnyA3Nxfx8fGwWq1YtmxZi44BACtXrsT777+PHTt2oHPnzo1+fWvbtm0bAGDo0KEAXHMdN1VJSQkMBgNvaORgzS6MHj16QKvVYteuXQ3OFxwcDJPJ1Oxvfubm5tqvhRAQEIBFixbhzjvvRHp6eouNISKIj4/H0aNHsXnzZvj6+jZrea0hLy8PCQkJCAoKwhNPPAHAtdZxc5WWlvLu9ipodmEEBAQgJiYGKSkpWLt2LYqLi3HkyBGsWbOmxnwmkwkTJ05EUlISEhMTUVxcDJvNhrNnz+LcuXOKx8vNzcWUKVOQkZGBiooKpKam4syZM+jfv3+LjZGeno7XXnsNb731Fry8vGp9RXvZsmWKl9VcIoKrV6+iuroaIoKCggJYrVYMGDAAOp0Omzdvtn+G4UrruLlKSko88vaSqvv1p6BNOa165coVmTRpkrRv3158fX1l4MCBMn/+fAEgQUFBcvjwYRERKS8vl/j4eAkJCRG9Xi8BAQESExMjaWlpsnr1ajGbzQJAunXrJqdOnZI1a9aIxWIRANKlSxc5fvy4ZGVlSXR0tLRt21Z0Op107txZ5s6dK1VVVTccQ6mjR48KgHofS5cubdT6EWncWZKPP/5YevbsKWazWQwGg2i1WgFgPyPSr18/WbhwoVy8eLHWa11lHYs07yzJK6+8IrfeemuTXktNpxER+WWBXL97+68mUzNpNBpYrVbes/YXrv8up7H3WAWA559/HgcOHMDu3btbOhY1gL8lIZd09uxZBAcHqx3D43hMYWRkZNT6LKKuR1xcnNpRSYGcnBwEBQWpHcPjeMytwyMiIniY5UZycnK4h6ECj9nDIPdRUVGB/Px87mGogIVBLufs2bOorq7mHoYKWBjkco4dOwYAuPXWW1VO4nlYGORy0tLSEBQUBH9/f7WjeBwWBrmctLQ0REZGqh3DI7EwyOWkp6eje/fuasfwSMFNpHAAACAASURBVCwMcinV1dU4duwY9zBUwsIgl3LmzBmUlJRwD0MlLAxyKYcOHYJWq61xxS9yHBYGuZQDBw7gtttuc6pLJXoSFga5lIMHD6JPnz5qx/BYLAxyKT/88AMLQ0UsDHIZ2dnZKCgoYGGoiIVBLuPgwYPQarW444471I7iser9ebur3xvVGY0ZMwZjxoxRO4ZTiY2NVTzvwYMHceutt/IDTxXVKozo6GiH3yfTk23evBmbNm1CQkIC2rdvr3Ych2vML07379+Pvn37tmIaupFa1/Qkx6qoqEBUVBR69+6NDz/8UO04Tstms6F9+/ZYvHgxpkyZonYcj8XPMFRmMBiwbNkyWK1W7Ny5U+04Tuvw4cMoKirCgAED1I7i0VgYTuChhx7CsGHD8Mwzz6CqqkrtOE5p9+7d8PPz429IVMbCcBJvvPEGTp48iTfffFPtKE5p9+7diI6OhlbLTVZNXPtOomvXrnj++ecxf/58FBQUqB3HqYgIdu7ciXvvvVftKB6PheFEXnzxRZjNZsybN0/tKE7lyJEjOH/+PIYMGaJ2FI/HwnAivr6+WLJkCd5++218//33asdxGl999RU6dOjAL2w5AZ5WdTIigsGDB6OyshK7d+/mF+gAPPDAA2jXrh2SkpLUjuLxuIfhZDQaDVasWIHvv/8e69evVzuO6kpLS/Htt9/ycMRJsDCcUO/evfHUU0/hhRdeQFFRkdpxVLVt2zaUl5dj2LBhakchsDCc1iuvvAKbzYaXX35Z7Siq2rRpEwYOHIjAwEC1oxBYGE6rXbt2WLhwIVasWIEff/xR7TiqqKysxOeff46RI0eqHYX+ix96OrHq6mrcfffd8Pf3x1dffaV2HIfbunUrhg8fjqysLISEhKgdh8A9DKem1WqxYsUKbN++HZs3b1Y7jsN99NFH6Nu3L8vCibAwnNyAAQPwpz/9Cc8//zxKS0vVjuMwNpsNW7ZswYgRI9SOQr/AwnABy5cvx+XLl7F8+XK1ozjMt99+i/z8fBaGk2FhuIDAwEDMmTMHixYtQlZWltpxHOKjjz5CZGQkIiIi1I5Cv8DCcBF/+ctfEBISgtmzZ6sdpdWJCD766CPuXTghFoaLMBgM+Nvf/oaUlBR88cUXasdpVTt37kROTg6vf+qEeFrVxTz00EM4ffo0Dh06BC8vL7XjtIrx48cjIyODP8BzQtzDcDErVqzA6dOnkZiYqHaUVlFcXIyNGzdi4sSJakehOrAwXEx4eDhmzJiB+fPn49y5c2rHaXFWqxXV1dWIi4tTOwrVgYckLqi0tBTdu3fH/fffj7Vr16odp0VFR0fjlltuwQcffKB2FKoD9zBckNlsxuLFi/HOO+9g3759asdpMcePH8fevXt5OOLEuIfhwu677z5cuXIF33//vVtcHDc+Ph4ffPABsrKyoNPp1I5DdXD9rcyDrVq1CocPH8a7776rdpRmq6qqwvvvv4+JEyeyLJwY9zBc3LPPPovk5GRkZmbC399f7ThN9tlnn+Ghhx7CyZMnERYWpnYcqgcLw8UVFhbitttuw9ixY5GQkKB2nCb7wx/+gGvXruHrr79WOwo1gIckLq5t27Z4+eWXsWrVKhw9elTtOE1y8uRJbN26Fc8++6zaUegGuIfhBqqrq3HPPffA19cX27dvVztOoz3//PPYsmULTp06xc8vnBz3MNzA9Qvt/Otf/8LGjRvVjtMoV65cwbvvvotnnnmGZeECWBhu4p577sG4cePwl7/8BSUlJWrHUeydd95BZWUlnnjiCbWjkAIsDDeydOlSFBcXY+nSpWpHqaW6urrWNBFBYmIixo8fj3bt2qmQihqLheFGOnXqhHnz5uG1117Df/7zH/v0qqoqrFmzBi+88IJq2VatWoUxY8bg8OHD9mnbtm1DRkYGpk2bplouaiQht1JRUSEREREyYsQIERHZsWOHRERECACJiIhQLdeMGTMEgACQoUOHyt69e2Xo0KFy//33q5aJGk+vcl9RC/Py8sLKlSsxZMgQDBo0CN999x30+p//mU+cOIGysjJ4e3s7PFd2djY0Gg1EBF999RW2bt0Ko9GImTNnOjwLNR0PSdxMRUUF0tLS4OXlZf9hWlVVFYCfr8R95MgRVXKdPn0a8t8z+L/M8+qrr6Jnz57YsGGD/XlyXiwMN/LJJ5+ga9eumDlzJiorK1FZWVnjeb1ej4MHD6qS7ezZs7WmXS+O9PR0jB49Gj179nTJ75F4Eh6SuIGqqirExsZiy5Yt0Gq1dZ6RuO6HH35wYLKfVVVV4eLFi/U+b7PZoNPpcPHiRf6OxMlxD8MN6PV6zJ49G23btm3wy09VVVXYs2ePA5P97Ny5c7DZbPU+r9frERAQgG+//RahoaEOTEaNxcJwEwMGDMDBgwcRGhra4MWBMzMzce3aNQcmA3Jycup9zsvLCx06dMB3332H8PBwB6aipmBhuJHQ0FAcOHAAv/3tb+u9oI7NZnP4j9RycnKg0WhqTffy8kL79u1ZFi6EheFm2rRpg88++6zeL0Pp9XqHf46Rk5NTa6+HZeGaWBhuSKfTYeXKlfjHP/4BrVZbY29Do9E4/EzJr8+QsCxcFwvDjf35z3/G1q1b4e3tbf/yVmVlpcM/+MzOzraf4mVZuDYWhpv7/e9/j71796JTp072w4KMjAyUl5c7LMN//vMfiAjLwg2wMDxAjx49cPDgQfTq1QsajQZVVVX48ccfHTb+9UOS9u3bY/fu3SwLF9bsK27t2bMHr7/+ekvloVZks9lw4MAB5OTkoE+fPg75zkN1dTU2bdoEk8mEwYMHw9fXt9XHpJYxY8YM3HPPPTWmNXsPIycnBykpKc1dDDmATqfD3XffjaioKFy+fLnFl793717s3bu3xrRr167BbDazLFxMSkpKnd+fabGvhm/YsKGlFkUOcPjwYfTq1atFlzlq1CgANbeFkydPQqPR8DDExdT1vRmAvyXxWC1dFvXp2rWrQ8Yhx+CHnkSkGAuDiBRjYRCRYiwMIlKMhUFEirEwiEgxFgYRKcbCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMAjV1dVISEhAdHS0ahkyMzPx7LPPIjIyEm3atIFer4efnx9uvfVWDB8+XJUbMFFtLAwPd+LECfzmN7/BjBkzUFpaqkqGtWvXIioqCkeOHMHrr7+OnJwclJSUIDU1FS+99BIuX77s8HupUN1YGAqUlZWp9n/f1hz78OHD+Otf/4qpU6fijjvuaJUxbmTv3r2YPHkyBg0ahO3bt+OBBx6Av78/jEYjwsLCMGbMGMyfPx8VFRWq5FPCXbePuvACOgqsXbsW+fn5bjd2r169sHHjRgDAypUrHX4LRQB4+eWXYbPZsGjRIvutEH7tgQcewAMPPODgZMq56/ZRJ2kmq9UqTVnMe++9J3369BGj0Shms1m6dOkiCxcuFBGR6upqWb58uURERIjBYBB/f3/54x//KMeOHbO/fvXq1WI2m8Xb21s2b94sDz74oLRp00Zuvvlm+eCDDxo13jfffCO33367WCwWMRqN0qNHD9m2bZuIiDz//PNiMBgEgACQ8PBwERGpqqqSF198UYKDg8VkMklUVJR8+OGHjc7W0mM31d133y29evVq1jJiY2MlNjZW8fzl5eViMpmkffv2jRqH20frbx8AxGq11p7eqKXUoSmFkZCQIABk0aJFcvHiRbl06ZL84x//kLFjx4qIyPz588VgMMj69evl8uXLcuTIEbnzzjulQ4cOkpeXZ1/O3LlzBYBs375dioqKJD8/XwYNGiQ+Pj5SUVGheLwNGzbIggUL5NKlS3Lx4kXp379/jY04JibG/o9x3axZs8RoNEpKSooUFhbKnDlzRKvVyv79+xuVrTXGbgo1CuP48eMCQPr379+ocbh9tP724TSFUVFRIf7+/nLffffVmF5VVSUrVqyQ0tJS8fX1lbi4uBrPf//99wLA3voi/7fSy8rK7NNWr14tAOTkyZOKxqvLq6++KgAkPz9fRGr/o5SVlYnZbK6RsbS0VIxGo0ybNk1xttYauynUKIwDBw4IAPnd736n+DXcPhyzfdRXGA7/0PPIkSO4fPlyrWNSnU6H559/Hmlpabh69Sr69u1b4/m77roLBoMB+/bta3D5BoMBAOy35rvReHW5focwm81W5/OZmZkoLS1Fjx497NO8vb0RGBiIjIwMxdkcObYzun7bgcacneH2oe724fDCKC4uBgD4+/vX+fz1+2XUdQ8Lf39/XLlypUXHA4DPPvsMgwcPRkBAAIxGI1544YUGl1lSUgIAmDdvHjQajf1x5syZRp+aVHNstd1yyy0wmUw4fvy44tdw+1B3+3B4YXTu3BkAcOHChTqfv/4PV9c//OXLlxEUFNSi42VnZ2PEiBEIDAzEvn37UFRUhCVLljS4zICAAABAQkIC5OfDOvujMV8wUnNsZ2A0GvHAAw/gwoUL2L17d73zXbp0CZMmTQLA7UPt7cPhhXHLLbegXbt2+PLLL+t8vkePHvD19cWBAwdqTN+3bx8qKirQp0+fFh3v6NGjqKysxLRp0xAWFgaTyVTvTVyuCw4OhslkwqFDhxqVxZnGdhYLFiyA0WjEjBkzUFZWVuc8P/74o/2UK7cPdbcPhxeG0WjEnDlz8M033+C5557DTz/9hOrqaly5cgXp6ekwmUyYOXMmNm3ahPfffx/FxcU4evQopk6diptuugmTJ09u0fFCQkIAAF9//TWuXbuGEydO1DoObteuHXJzc5GVlYUrV65Ap9Nh4sSJSEpKQmJiIoqLi2Gz2XD27FmcO3dOcTY1x3YWd9xxB/75z3/ixx9/xKBBg/D555+jqKgIlZWV+M9//oO33noLTz75pP3YnduHytuH4o9N69HU72GsWrVKoqKixGQyiclkkt69e8vq1atF5Ofz7EuXLpVu3bqJl5eXtG3bVkaMGCGZmZn2118/lw1AunXrJqdOnZI1a9aIxWIRANKlSxc5fvy4ovHi4+OlXbt24u/vL6NGjZJVq1bZz2tnZ2fLDz/8IF26dBFvb28ZOHCg5OXlSXl5ucTHx0tISIjo9XoJCAiQmJgYSUtLa1S2lh67Mfbs2SMDBgyQm266yX4uPzAwUKKjo2XXrl2N/jdt7FmSX8rOzpZZs2ZJVFSU+Pr6ik6nE39/f+ndu7c8+eSTsnv3bvu83D5af/tAPWdJmn339uTkZIwZMwbNXAy5gbrurUquSaPRwGq1YvTo0TWm87ckRKQYC8ONZGRk1DiVVt8jLi5O7ajkovjjMzcSERHBQ0NqVdzDICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKtdjP269fbYk81969ewFwW3BnzS6M4OBgxMbGtkQWcnLXr9T965sIXde/f39HxqFWFBsbi+Dg4FrTm31NT/Ic16/vmJycrHISUgs/wyAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiwMIlKMhUFEirEwiEgxFgYRKcbCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsU0IiJqhyDn884772DFihWw2Wz2aQUFBQCAgIAA+zSdTofp06djwoQJjo5IKmBhUJ0yMzMRERGhaN5jx44pnpdcGw9JqE633XYboqKioNFo6p1Ho9EgKiqKZeFBWBhUr/Hjx0On09X7vF6vx+OPP+7ARKQ2HpJQvXJzcxEUFIT6NhGNRoPs7GwEBQU5OBmphXsYVK/OnTsjOjoaWm3tzUSr1SI6Oppl4WFYGNSgxx57rM7PMTQaDcaPH69CIlITD0moQZcuXUKnTp1QVVVVY7pOp8P58+fRvn17lZKRGriHQQ1q164dhgwZAr1eb5+m0+kwZMgQloUHYmHQDY0bNw7V1dX2/xYRPPbYYyomIrXwkIRuqKSkBB06dMC1a9cAAEajERcuXICvr6/KycjRuIdBN+Tj44OHH34YXl5e0Ov1eOSRR1gWHoqFQYqMHTsWVVVVsNlsePTRR9WOQyrR33gW95ScnKx2BJdis9lgMpkgIrh69SrXXyONHj1a7QgtwmM/w2joNxJELc1d/sw8+pDEarVCRPhQ+NixYwf+9a9/1ft8bGwsYmNjVc/pTA+r1ar2Zt6iPPaQhBrv3nvvVTsCqYyFQYrV9ZsS8izcAohIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAujiSZNmoQ2bdpAo9Hg0KFDasdpkiVLliAiIgLe3t7w8fFBREQEXnzxRRQXFztk/I0bNyIsLAwajabGw2AwoGPHjhg8eDCWLl2KwsJCh+ShG2NhNNHbb7+Nt956S+0YzfLtt9/iqaeeQnZ2Ns6fP4+XXnoJS5YsQWxsrEPGj4mJwenTpxEeHg4/Pz+ICKqrq5Gfn4/k5GSEhoYiPj4ekZGROHDggEMyUcNYGB7MYDDg6aefRkBAAHx9fTFq1Cg88sgj+Oqrr3Du3DlVMmk0Gvj7+2Pw4MFYt24dkpOTcf78eQwfPhxFRUWqZKL/w8JoBle/zN+mTZtgMplqTLv55psBAFevXlUjUi2xsbGYMGEC8vPz8eabb6odx+OxMBQSESxduhS33XYbjEYj/Pz8MHv27Frz2Ww2zJ8/HyEhIfD29kbPnj3tl2lLTEyEj48PzGYztmzZgqFDh8JisSAoKAhJSUk1lrNr1y7069cPZrMZFosFUVFR9s8WGhqjuU6cOAF/f3906dKlRZbXEiZMmAAA2Lp1q32aq69nlyUeCoBYrVbF88+dO1c0Go0sX75cCgsLpbS0VFavXi0AJDU11T7frFmzxGg0SkpKihQWFsqcOXNEq9XK/v377csBINu3b5eioiLJz8+XQYMGiY+Pj1RUVIiIyNWrV8VisciSJUukrKxM8vLyZOTIkVJQUKBojMaqqKiQs2fPysqVK8VoNMr69eubtJzY2FiJjY1t9OvCw8PFz8+v3ueLi4sFgAQHB9unucp6tlqt4k5/Zu7zThqpMYVRWloqZrNZhgwZUmN6UlJSjcIoKysTs9kscXFxNV5rNBpl2rRpIvJ/G3JZWZl9nuvFc/LkSRER+fHHHwWAfPrpp7WyKBmjsTp16iQApH379vLGG2/Y/6Aaq7UKQ0REo9GIv7+/iLjWena3wuAhiQInT55EaWkp7r///gbny8zMRGlpKXr06GGf5u3tjcDAQGRkZNT7OoPBAACorKwEAISFhaFjx44YN24cFixYgKysrGaP0ZCcnBzk5+fjgw8+wLvvvovevXsjPz+/SctqDSUlJRARWCwWAK67nt0BC0OBs2fPAgACAgIanK+kpAQAMG/evBrfKzhz5gxKS0sVj+ft7Y0dO3Zg4MCBeOWVVxAWFoa4uDiUlZW12Bi/5OXlhYCAAPz+97/Hhx9+iLS0NLz66qtNWlZrOH78OAAgIiICgOuuZ3fAwlDg+pmE8vLyBue7XigJCQm17k+xZ8+eRo0ZGRmJTz75BLm5uYiPj4fVasWyZctadIy6dO3aFTqdDmlpac1eVkvZtm0bAGDo0KEA3GM9uyoWhgI9evSAVqvFrl27GpwvODgYJpOp2d/8zM3NRXp6OoCf/zgWLVqEO++8E+np6S02xsWLF+u8R+qJEydgs9kQHBzcrOW3lLy8PCQkJCAoKAhPPPEEANdaz+6GhaFAQEAAYmJikJKSgrVr16K4uBhHjhzBmjVrasxnMpkwceJEJCUlITExEcXFxbDZbDh79myjvgiVm5uLKVOmICMjAxUVFUhNTcWZM2fQv3//FhvDx8cHX375JXbs2IHi4mJUVlYiNTUVjz/+OHx8fDBjxgzFy2oJIj/fs7W6uhoigoKCAlitVgwYMAA6nQ6bN2+2f4bhSuvZ7Tj4Q1angUaeVr1y5YpMmjRJ2rdvL76+vjJw4ECZP3++AJCgoCA5fPiwiIiUl5dLfHy8hISEiF6vl4CAAImJiZG0tDRZvXq1mM1mASDdunWTU6dOyZo1a8RisQgA6dKlixw/flyysrIkOjpa2rZtKzqdTjp37ixz586VqqqqG47RGA8//LCEhoaKr6+vGI1GCQ8Pl7i4ODl69GijlnNdY8+SfPzxx9KzZ08xm81iMBhEq9UKAPsZkX79+snChQvl4sWLtV7rKuvZ3c6SePTNmK1Wq9vcVdsZjBo1CgCwYcMGlZM4j+TkZIwZMwbu8mfGQxIiUoyF4UYyMjJq/VS8rkdcXJzaUclF8WbMbiQiIsJtdn3JOXEPg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEp5tE/b/fkqz+3huu3Y0hOTlY5ifNwt23Moy/RR+Qo7vJn5rF7GO7yD+hI169/yj0Iz8XPMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYRCRYiwMIlKMhUFEirEwiEgxFgYRKcbCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDG92gHIOe3atQt79+6tMS0jIwMAsGTJkhrT+/fvj3vvvddh2Ug9GhERtUOQ8/nqq6/w+9//Hl5eXtBq694Rra6uRmVlJb788ksMGTLEwQlJDSwMqpPNZkOnTp1w8eLFBudr27Yt8vPzoddzZ9UT8DMMqpNOp8PYsWNhMBjqncdgMOCxxx5jWXgQFgbV609/+hMqKirqfb6iogJ/+tOfHJiI1MZDEmpQly5dkJ2dXedzQUFByM7OhkajcXAqUgv3MKhB48aNg5eXV63pBoMBjz/+OMvCw3APgxp07NgxdO/evc7njh49ih49ejg4EamJhUE31L17dxw7dqzGtIiIiFrTyP3xkIRuaPz48TUOS7y8vPD444+rmIjUwj0MuqHs7GzccsstuL6paDQanD59Grfccou6wcjhuIdBNxQSEoK+fftCq9VCo9HgrrvuYll4KBYGKTJ+/HhotVrodDo89thjaschlfCQhBQpKCjATTfdBAD46aef0KlTJ5UTkRpYGL+SnJyMMWPGqB2DXJDVasXo0aPVjtGq+COAelitVrUjOJ1du3bh1KlT+OKLL7h+fsVT/ifDwqiHu/+foikefPBBfPTRR/jiiy+4fn7FUwqDH3qSYhaLBd7e3mrHIBWxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFiLAwiUoyFQUSKsTCISDEWBhEpxsIgIsVYGESkGAuDiBRjYVCr2rhxI8LCwqDRaGo8DAYDOnbsiMGDB2Pp0qUoLCxUOyopwMKgVhUTE4PTp08jPDwcfn5+EBFUV1cjPz8fycnJCA0NRXx8PCIjI3HgwAG149INsDCcUFlZGaKjo11+jPpoNBr4+/tj8ODBWLduHZKTk3H+/HkMHz4cRUVFqmQiZVgYTmjt2rXIz893+TGUio2NxYQJE5Cfn48333xT7TjUABZGCxARvP7667j99tthNBrRtm1bPPLII8jIyLDP89xzz8FgMCAwMNA+7emnn4aPjw80Gg0uXLgAAJg+fTpmzpyJU6dOQaPRoGvXrvjb3/4Gk8mEjh07YsqUKbjppptgMpkQHR2Nffv2tcgYapswYQIAYOvWrfZpNpsN8+fPR0hICLy9vdGzZ0/7tUQTExPh4+MDs9mMLVu2YOjQobBYLAgKCkJSUlKNZe/atQv9+vWD2WyGxWJBVFQUiouLbzgG1UGoBqvVKo1dLfPnzxeDwSDr16+Xy5cvy5EjR+TOO++UDh06SF5enn2+sWPHSqdOnWq8dunSpQJACgoK7NNiYmIkPDy8xnyTJ08WHx8fSU9Pl2vXrklaWprcdddd0qZNG8nOzm6RMZRoyvoREQkPDxc/P796ny8uLhYAEhwcbJ82a9YsMRqNkpKSIoWFhTJnzhzRarWyf/9+ERGZO3euAJDt27dLUVGR5Ofny6BBg8THx0cqKipEROTq1atisVhkyZIlUlZWJnl5eTJy5Ej7urjRGEoBEKvV2tjV4nK4h9FMZWVleP311zFy5EiMGzcOfn5+iIqKwptvvokLFy5gzZo1LTaWXq+378V0794diYmJuHLlCtatW9diY6ilTZs20Gg0uHLlCgDg2rVrSExMxIgRIxATEwN/f3/MmzcPXl5etd5vdHQ0LBYLAgICEBcXh5KSEmRnZwMAsrKyUFxcjMjISJhMJnTq1AkbN25Ehw4dGjUG/YyF0UxpaWm4evUq+vbtW2P6XXfdBYPBUOOQoaX17dsXZrO5xqGPqyopKYGIwGKxAAAyMzNRWlqKHj162Ofx9vZGYGBgg+/XYDAAACorKwEAYWFh6NixI8aNG4cFCxYgKyvLPm9Tx/BkLIxmunz5MgDA19e31nP+/v72/2O2FqPRiIKCglYdwxGOHz8OAIiIiADwc4EAwLx582p8f+PMmTMoLS1VvFxvb2/s2LEDAwcOxCuvvIKwsDDExcWhrKysxcbwJCyMZvL39weAOovh8uXLCAoKarWxKysrW30MR9m2bRsAYOjQoQCAgIAAAEBCQgJEpMZjz549jVp2ZGQkPvnkE+Tm5iI+Ph5WqxXLli1r0TE8BQujmXr06AFfX99aXzrat28fKioq0KdPH/s0vV5v31VuCTt37oSIoH///q02hiPk5eUhISEBQUFBeOKJJwAAwcHBMJlMOHToULOWnZubi/T0dAA/l9CiRYtw5513Ij0959tj5wAAAptJREFUvcXG8CQsjGYymUyYOXMmNm3ahPfffx/FxcU4evQopk6diptuugmTJ0+2z9u1a1dcunQJmzdvRmVlJQoKCnDmzJlay2zXrh1yc3ORlZWFK1eu2AuguroahYWFqKqqwpEjRzB9+nSEhITYT0m2xBitSURw9epVVFdXQ0RQUFAAq9WKAQMGQKfTYfPmzfbPMEwmEyZOnIikpCQkJiaiuLgYNpsNZ8+exblz5xSPmZubiylTpiAjIwMVFRVITU3FmTNn0L9//xYbw6Ooc3LGeTXltGF1dbUsXbpUunXrJl5eXtK2bVsZMWKEZGZm1pjv4sWLct9994nJZJLQ0FB59tlnZfbs2QJAunbtaj89+sMPP0iXLl3E29tbBg4cKHl5eTJ58mTx8vKSm2++WfR6vVgsFnnkkUfk1KlTLTZGa6yfjz/+WHr27Clms1kMBoNotVoBIBqNRvz9/aVfv36ycOFCuXjxYq3XlpeXS3x8vISEhIher5eAgACJiYmRtLQ0Wb16tZjNZgEg3bp1k1OnTsmaNWvEYrEIAOnSpYscP35csrKyJDo6Wtq2bSs6nU46d+4sc+fOlaqqqhuO0RjwkNOqLIxfaer3DFrb5MmTpV27dmrHcNr1ozZPKQwekrgQm82mdgTycCwMIlKMheEC5syZg3Xr1qGoqAihoaFISUlROxJ5KL3aAejGXn31Vbz66qtqxyDiHgYRKcfCICLFWBhEpBgLg4gUY2EQkWIsDCJSjIVBRIqxMIhIMRYGESnGwiAixVgYRKQYC4OIFGNhEJFi/LVqPTQajdoRnBrXj2fSiIioHcKZnD17Fv/+97/VjkEuKDo62i1u+dAQFgYRKcbPMIhIMRYGESnGwiAixfQANqgdgohcw/8Hlw85Jn0hIZcAAAAASUVORK5CYII=\n" + }, + "metadata": {}, + "execution_count": 88 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model_input = tf.keras.Input(shape=(X.shape[1],), name='input')\n", + "\n", + "dense_1 = tf.keras.layers.Dense(20, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_1')(model_input)\n", + "dense_2 = tf.keras.layers.Dense(10, activation='leaky_relu', kernel_initializer='he_uniform', name='dense_2')(dense_1)\n", + "concat = tf.keras.layers.Concatenate()([dense_1, dense_2])\n", + "model_output = tf.keras.layers.Dense(1, activation='linear', name='output')(concat)\n", + "\n", + "model = tf.keras.Model(inputs=[model_input], outputs=[model_output, concat])\n", + "\n", + "model.compile(\n", + " optimizer = 'adam',\n", + " loss = ['mse'],\n", + " metrics = ['mae']\n", + ")\n", + "\n", + "tf.keras.utils.plot_model(model)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 466 + }, + "id": "canejM8SB2JN", + "outputId": "e5fcdafb-aa65-4d5b-cb5b-3360a0df2a76" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ], + "image/png": "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\n" + }, + "metadata": {}, + "execution_count": 96 + } + ] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(xtrain, ytrain, epochs=5, batch_size=32, validation_data=(xtest, ytest))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "urRTNJBmB7Lm", + "outputId": "2d217457-dac0-4d38-c774-5936aeaaa98d" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/5\n", + "1265/1265 [==============================] - 4s 2ms/step - loss: 19443602.0000 - output_loss: 19443602.0000 - output_mae: 2841.3425 - concatenate_7_mae: 3896.1292 - val_loss: 6633373.5000 - val_output_loss: 6633373.5000 - val_output_mae: 1785.1199 - val_concatenate_7_mae: 3919.7078\n", + "Epoch 2/5\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 4023764.2500 - output_loss: 4023764.2500 - output_mae: 1377.2480 - concatenate_7_mae: 3876.2539 - val_loss: 3077297.0000 - val_output_loss: 3077297.0000 - val_output_mae: 1138.7142 - val_concatenate_7_mae: 3927.1462\n", + "Epoch 3/5\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 2166064.7500 - output_loss: 2166064.7500 - output_mae: 1005.4685 - concatenate_7_mae: 3881.5818 - val_loss: 2239321.5000 - val_output_loss: 2239321.5000 - val_output_mae: 929.3035 - val_concatenate_7_mae: 3929.8960\n", + "Epoch 4/5\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 1497824.6250 - output_loss: 1497824.6250 - output_mae: 830.7947 - concatenate_7_mae: 3884.1799 - val_loss: 1851428.2500 - val_output_loss: 1851428.2500 - val_output_mae: 786.3316 - val_concatenate_7_mae: 3932.3213\n", + "Epoch 5/5\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 1209720.5000 - output_loss: 1209720.5000 - output_mae: 739.7021 - concatenate_7_mae: 3886.1221 - val_loss: 1731644.6250 - val_output_loss: 1731644.6250 - val_output_mae: 726.5963 - val_concatenate_7_mae: 3934.2502\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# BatchNorm" + ], + "metadata": { + "id": "3a6NMzcmDvio" + } + }, + { + "cell_type": "code", + "source": [ + "model = tf.keras.Sequential([\n", + " tf.keras.Input(shape=(X.shape[1],), name='input'),\n", + " \n", + " tf.keras.layers.Dense(20, kernel_initializer='he_uniform', name='dense_1', kernel_regularizer=tf.keras.regularizers.L1(l1=0.02)),\n", + " tf.keras.layers.BatchNormalization(name='batchnorm1'),\n", + " tf.keras.layers.ReLU(),\n", + "\n", + " tf.keras.layers.Dropout(rate=0.2), # previous layer is affected\n", + " \n", + " tf.keras.layers.Dense(10, kernel_initializer='he_uniform', name='dense_2', kernel_regularizer='l2'),\n", + " tf.keras.layers.BatchNormalization(name='batchnorm2'),\n", + " tf.keras.layers.ReLU(),\n", + "\n", + " tf.keras.layers.Dropout(rate=0.2), # previous layer is affected\n", + "\n", + " tf.keras.layers.Dense(1, activation='linear', name='output'),\n", + "])\n", + "\n", + "model.compile(\n", + " optimizer = 'adam',\n", + " loss = 'mse',\n", + " metrics = ['mae']\n", + ")\n", + "\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Ov0x16CSDokK", + "outputId": "86d35b91-544c-48ab-e2f7-fb7a2b2d73c2" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential_20\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense_1 (Dense) (None, 20) 200 \n", + " \n", + " batchnorm1 (BatchNormalizat (None, 20) 80 \n", + " ion) \n", + " \n", + " re_lu_6 (ReLU) (None, 20) 0 \n", + " \n", + " dropout_2 (Dropout) (None, 20) 0 \n", + " \n", + " dense_2 (Dense) (None, 10) 210 \n", + " \n", + " batchnorm2 (BatchNormalizat (None, 10) 40 \n", + " ion) \n", + " \n", + " re_lu_7 (ReLU) (None, 10) 0 \n", + " \n", + " dropout_3 (Dropout) (None, 10) 0 \n", + " \n", + " output (Dense) (None, 1) 11 \n", + " \n", + "=================================================================\n", + "Total params: 541\n", + "Trainable params: 481\n", + "Non-trainable params: 60\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(xtrain, ytrain, epochs=20, batch_size=32, validation_data=(xtest, ytest))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "IJh_4n3MEm6V", + "outputId": "83b89eae-cc11-4ae8-f456-0739d7c444a9" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/20\n", + "1265/1265 [==============================] - 6s 3ms/step - loss: 31092216.0000 - mae: 3911.5173 - val_loss: 31323378.0000 - val_mae: 3943.1685\n", + "Epoch 2/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 30429744.0000 - mae: 3870.1997 - val_loss: 30414290.0000 - val_mae: 3887.7966\n", + "Epoch 3/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 29355664.0000 - mae: 3799.7788 - val_loss: 29083384.0000 - val_mae: 3803.1350\n", + "Epoch 4/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 27960278.0000 - mae: 3705.4343 - val_loss: 27489924.0000 - val_mae: 3698.7102\n", + "Epoch 5/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 26221450.0000 - mae: 3584.6946 - val_loss: 25511474.0000 - val_mae: 3564.4148\n", + "Epoch 6/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 24265120.0000 - mae: 3440.2009 - val_loss: 23339488.0000 - val_mae: 3406.4849\n", + "Epoch 7/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 22079126.0000 - mae: 3272.7253 - val_loss: 20944722.0000 - val_mae: 3231.8457\n", + "Epoch 8/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 19836192.0000 - mae: 3089.2517 - val_loss: 18642378.0000 - val_mae: 3050.1194\n", + "Epoch 9/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 17530376.0000 - mae: 2884.8950 - val_loss: 15899387.0000 - val_mae: 2798.4241\n", + "Epoch 10/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 15187069.0000 - mae: 2662.8132 - val_loss: 13397392.0000 - val_mae: 2567.2976\n", + "Epoch 11/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 12946217.0000 - mae: 2431.8345 - val_loss: 11183434.0000 - val_mae: 2295.0916\n", + "Epoch 12/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 10797393.0000 - mae: 2188.1177 - val_loss: 8532675.0000 - val_mae: 2020.5256\n", + "Epoch 13/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 8796306.0000 - mae: 1940.0984 - val_loss: 6984680.0000 - val_mae: 1741.3541\n", + "Epoch 14/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 7076949.0000 - mae: 1702.2233 - val_loss: 5245982.5000 - val_mae: 1509.8745\n", + "Epoch 15/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 5664502.0000 - mae: 1486.8158 - val_loss: 3993390.0000 - val_mae: 1247.0170\n", + "Epoch 16/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 4626841.0000 - mae: 1321.6732 - val_loss: 2923536.5000 - val_mae: 1047.4983\n", + "Epoch 17/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 3853236.5000 - mae: 1205.2939 - val_loss: 2587632.2500 - val_mae: 946.7275\n", + "Epoch 18/20\n", + "1265/1265 [==============================] - 3s 2ms/step - loss: 3323822.0000 - mae: 1123.4414 - val_loss: 2155173.2500 - val_mae: 723.6109\n", + "Epoch 19/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 3130168.2500 - mae: 1102.2725 - val_loss: 1725843.2500 - val_mae: 526.8715\n", + "Epoch 20/20\n", + "1265/1265 [==============================] - 3s 3ms/step - loss: 2921132.5000 - mae: 1066.2325 - val_loss: 2020326.3750 - val_mae: 563.4874\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "" + ], + "metadata": { + "id": "25IAMgOPGrey" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file