--- a +++ b/PDLforTalos0.3.6.ipynb @@ -0,0 +1,1761 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Practical Deep Learning for Genomic Prediction\n", + "## A Keras based guide to implement deep learning\n", + "\n", + "### M Perez-Enciso & ML Zingaretti\n", + "### miguel.perez@uab.es, laura.zingaretti@cragenomica.es\n", + "\n", + "### If you find this resource useful, please cite: \n", + "### Perez-Enciso M, Zingaretti ML, 2019. \n", + "### A Guide on Deep Learning for Genomic Prediction. \n", + "### Submitted\n", + "\n", + "### install dependencies if needed (only once)\n", + "### Warning!!! This is the version for talos 0.6.3\n", + "### \n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "# main modules needed\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "from sklearn import linear_model\n", + "from sklearn.model_selection import train_test_split\n", + "from matplotlib import pyplot as plt\n", + "from scipy import stats\n", + "from sklearn.decomposition import PCA\n", + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.preprocessing import scale\n", + "\n", + "# keras items \n", + "from keras import regularizers\n", + "from keras.models import Sequential, load_model\n", + "from keras.layers import Dense, Activation, Dropout\n", + "from keras.layers import Flatten, Conv1D, MaxPooling1D, LSTM #CNNs\n", + "from keras.activations import relu, elu, linear, softmax\n", + "from keras.callbacks import EarlyStopping, Callback\n", + "from keras.wrappers.scikit_learn import KerasRegressor\n", + "from keras.optimizers import adam, Nadam, sgd\n", + "from keras.losses import mean_squared_error, categorical_crossentropy, logcosh\n", + "from keras.utils.np_utils import to_categorical\n", + "\n", + "# talos items (for hyperparameter search)\n", + "import talos as ta\n", + "import wrangle as wr\n", + "from talos.model import lr_normalizer, early_stopper\n", + "from talos.utils import hidden_layers" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(479, 1279) (479,)\n", + "(120, 1279) (120,)\n", + " min max mean sd\n", + "Train: -2.41866172921982 2.59396290204909 0.0035229899045819135 1.0008351216016704\n", + "Test: -2.22424623595239 3.27892080508434 -0.01406260136912258 1.0007208094563\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# DATA LOADING AND BASIC INSPECTION\n", + "# We use wheat data from BGLR (https://cran.r-project.org/web/packages/BGLR/BGLR.pdf)\n", + "'''\n", + "Matrix Y contains the average grain yield, column 1: Grain yield for environment 1 and so on.\n", + "Matrix X contains marker genotypes.\n", + "'''\n", + "\n", + "# load the dataset as a pandas data frame\n", + "X = pd.read_csv('DATA/wheat.X', header=None, sep='\\s+')\n", + "Y = pd.read_csv('DATA/wheat.Y', header=None, sep='\\s+')\n", + "\n", + "# data partitioning into train and validation\n", + "itrait=0 # first trait analyzed\n", + "X_train, X_test, y_train, y_test = train_test_split(X, Y[itrait], test_size=0.2)\n", + "print(X_train.shape, y_train.shape)\n", + "print(X_test.shape, y_test.shape)\n", + "\n", + "# print basic statistics: max, min, mean, sd\n", + "print(' min max mean sd')\n", + "print('Train:', y_train.min(), y_train.max(), y_train.mean(), np.sqrt(y_train.var()))\n", + "print('Test:', y_test.min(), y_test.max(), y_test.mean(), np.sqrt(y_test.var()))\n", + "\n", + "# do basic histograms\n", + "plt.title('Train / test data')\n", + "plt.hist(y_train, label='Train')\n", + "plt.hist(y_test, label='Test')\n", + "plt.legend(loc='best')\n", + "plt.show()\n", + "\n", + "# marker PCA, use whole X with diff color for train and test\n", + "X = np.concatenate((X_train, X_test))\n", + "pca = PCA(n_components=2)\n", + "p = pca.fit(X).fit_transform(X)\n", + "Ntrain=X_train.shape[0]\n", + "plt.title('PCA decomposition')\n", + "plt.scatter(p[0:Ntrain,0], p[0:Ntrain,1], label='Train')\n", + "plt.scatter(p[Ntrain:,0], p[Ntrain:,1], label='Test', color='orange')\n", + "plt.legend(loc='best')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# OPTIONAL: SNP preselection according to a simple GWAS\n", + "pvals = []\n", + "for i in range(X_train.shape[1]):\n", + " b, intercept, r_value, p_value, std_err = stats.linregress(X_train[i], y_train)\n", + " pvals.append(-np.log10(p_value))\n", + "pvals = np.array(pvals)\n", + "\n", + "# plot GWAS\n", + "plt.ylabel('-log10 P-value')\n", + "plt.xlabel('SNP')\n", + "plt.plot(pvals, marker='o')\n", + "plt.show()\n", + "\n", + "# select N_best most associated SNPs\n", + "#N_best = X_train.shape[1] #all SNPs\n", + "N_best = 100\n", + "snp_list = pvals.argsort()[-N_best:]\n", + "\n", + "# or select by min_P_value\n", + "min_P_value = 2 # P = 0.01\n", + "snp_list = np.nonzero(pvals>min_P_value)\n", + "\n", + "# finally slice X\n", + "X_train = X_train[X_train.columns[snp_list]] \n", + "X_test = X_test[X_test.columns[snp_list]] \n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "MSE in prediction = Tensor(\"Mean:0\", shape=(), dtype=float64)\n", + "\n", + "Corr obs vs pred = 0.36859378337152526\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Standard penalized methods (lasso using scikit-learn)\n", + "\n", + "# alpha is the regularization parameter\n", + "lasso = linear_model.Lasso(alpha=0.01)\n", + "lasso.fit(X_train, y_train)\n", + "y_hat = lasso.predict(X_test)\n", + "\n", + "# mean squared error\n", + "mse = mean_squared_error(y_test, y_hat)\n", + "print('\\nMSE in prediction =',mse)\n", + "\n", + "# correlation btw predicted and observed\n", + "corr = np.corrcoef(y_test,y_hat)[0,1]\n", + "print('\\nCorr obs vs pred =',corr)\n", + "\n", + "# plot observed vs. predicted targets\n", + "plt.title('Lasso: Observed vs Predicted Y')\n", + "plt.ylabel('Predicted')\n", + "plt.xlabel('Observed')\n", + "plt.scatter(y_test, y_hat, marker='o')\n", + "plt.show()\n", + "\n", + "# Exercises\n", + "# - Implement an internal crossvalidation to optimize alpha\n", + "# - try different sizes of most associated SNPs\n", + "# - implement ridge regression instead of lasso" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From /usr/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Colocations handled automatically by placer.\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "dense_1 (Dense) (None, 64) 11136 \n", + "_________________________________________________________________\n", + "activation_1 (Activation) (None, 64) 0 \n", + "_________________________________________________________________\n", + "dense_2 (Dense) (None, 32) 2080 \n", + "_________________________________________________________________\n", + "activation_2 (Activation) (None, 32) 0 \n", + "_________________________________________________________________\n", + "dense_3 (Dense) (None, 1) 33 \n", + "=================================================================\n", + "Total params: 13,249\n", + "Trainable params: 13,249\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n", + "WARNING:tensorflow:From /usr/anaconda3/lib/python3.7/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.cast instead.\n", + "Epoch 1/100\n", + "479/479 [==============================] - 1s 3ms/step - loss: 1.5226\n", + "Epoch 2/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.9355\n", + "Epoch 3/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.8895\n", + "Epoch 4/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.8424\n", + "Epoch 5/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.8349\n", + "Epoch 6/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.7950\n", + "Epoch 7/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.7963\n", + "Epoch 8/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.7649\n", + "Epoch 9/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.7543\n", + "Epoch 10/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.7544\n", + "Epoch 11/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.7288\n", + "Epoch 12/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.7178\n", + "Epoch 13/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.7113\n", + "Epoch 14/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.6739\n", + "Epoch 15/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.7002\n", + "Epoch 16/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.6625\n", + "Epoch 17/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.6491\n", + "Epoch 18/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.6554\n", + "Epoch 19/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.6377\n", + "Epoch 20/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.6437\n", + "Epoch 21/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.6190\n", + "Epoch 22/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.6274\n", + "Epoch 23/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.6063\n", + "Epoch 24/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.5920\n", + "Epoch 25/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.6275\n", + "Epoch 26/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.5611\n", + "Epoch 27/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.5742\n", + "Epoch 28/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.5517\n", + "Epoch 29/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.5853\n", + "Epoch 30/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.5496\n", + "Epoch 31/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.5800\n", + "Epoch 32/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.5194\n", + "Epoch 33/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.5332\n", + "Epoch 34/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.5585\n", + "Epoch 35/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.5044\n", + "Epoch 36/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.5066\n", + "Epoch 37/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.6161\n", + "Epoch 38/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.5065\n", + "Epoch 39/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4912\n", + "Epoch 40/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.4725\n", + "Epoch 41/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4767\n", + "Epoch 42/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4884\n", + "Epoch 43/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4801\n", + "Epoch 44/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4930\n", + "Epoch 45/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.4589\n", + "Epoch 46/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.5313\n", + "Epoch 47/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4658\n", + "Epoch 48/100\n", + "479/479 [==============================] - 0s 121us/step - loss: 0.4544\n", + "Epoch 49/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4975\n", + "Epoch 50/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4681\n", + "Epoch 51/100\n", + "479/479 [==============================] - 0s 121us/step - loss: 0.4314\n", + "Epoch 52/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4129\n", + "Epoch 53/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4180\n", + "Epoch 54/100\n", + "479/479 [==============================] - 0s 120us/step - loss: 0.4289\n", + "Epoch 55/100\n", + "479/479 [==============================] - 0s 119us/step - loss: 0.5101\n", + "Epoch 56/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4041\n", + "Epoch 57/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4795\n", + "Epoch 58/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.4464\n", + "Epoch 59/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.4535\n", + "Epoch 60/100\n", + "479/479 [==============================] - 0s 119us/step - loss: 0.4113\n", + "Epoch 61/100\n", + "479/479 [==============================] - 0s 120us/step - loss: 0.3982\n", + "Epoch 62/100\n", + "479/479 [==============================] - 0s 120us/step - loss: 0.3913\n", + "Epoch 63/100\n", + "479/479 [==============================] - 0s 121us/step - loss: 0.5051\n", + "Epoch 64/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.3801\n", + "Epoch 65/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.3729\n", + "Epoch 66/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.4132\n", + "Epoch 67/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.3622\n", + "Epoch 68/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.3480\n", + "Epoch 69/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4368\n", + "Epoch 70/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.3768\n", + "Epoch 71/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.3304\n", + "Epoch 72/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.4086\n", + "Epoch 73/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.3432\n", + "Epoch 74/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.3948\n", + "Epoch 75/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.3599\n", + "Epoch 76/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4225\n", + "Epoch 77/100\n", + "479/479 [==============================] - 0s 118us/step - loss: 0.3417\n", + "Epoch 78/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.3166\n", + "Epoch 79/100\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "479/479 [==============================] - 0s 115us/step - loss: 0.3803\n", + "Epoch 80/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.3800\n", + "Epoch 81/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.4361\n", + "Epoch 82/100\n", + "479/479 [==============================] - 0s 116us/step - loss: 0.3142\n", + "Epoch 83/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.4091\n", + "Epoch 84/100\n", + "479/479 [==============================] - 0s 117us/step - loss: 0.3262\n", + "Epoch 85/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.2947\n", + "Epoch 86/100\n", + "479/479 [==============================] - 0s 114us/step - loss: 0.3562\n", + "Epoch 87/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.3503\n", + "Epoch 88/100\n", + "479/479 [==============================] - 0s 112us/step - loss: 0.2902\n", + "Epoch 89/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.3552\n", + "Epoch 90/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.2845\n", + "Epoch 91/100\n", + "479/479 [==============================] - 0s 113us/step - loss: 0.2720\n", + "Epoch 92/100\n", + "479/479 [==============================] - 0s 115us/step - loss: 0.4351\n", + "Epoch 93/100\n", + "479/479 [==============================] - 0s 112us/step - loss: 0.3092\n", + "Epoch 94/100\n", + "479/479 [==============================] - 0s 112us/step - loss: 0.2614\n", + "Epoch 95/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.3199\n", + "Epoch 96/100\n", + "479/479 [==============================] - 0s 112us/step - loss: 0.3166\n", + "Epoch 97/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.3222\n", + "Epoch 98/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.3258\n", + "Epoch 99/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.3207\n", + "Epoch 100/100\n", + "479/479 [==============================] - 0s 111us/step - loss: 0.2643\n", + "120/120 [==============================] - 0s 182us/step\n", + "\n", + "MSE in prediction = 0.9618856310844421\n", + "\n", + "Corr obs vs pred = 0.39642125509842363\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Implements a standard fully connected network (MLP) for a quantitative target\n", + "\n", + "# no. of SNPs in data\n", + "nSNP=X_train.shape[1] \n", + "\n", + "# Instantiate\n", + "model = Sequential()\n", + "\n", + "# Add first layer\n", + "model.add(Dense(64, input_dim=nSNP))\n", + "model.add(Activation('relu'))\n", + "# Add second layer\n", + "model.add(Dense(32))\n", + "model.add(Activation('softplus'))\n", + "# Last, output layer\n", + "model.add(Dense(1))\n", + "\n", + "# Model Compiling (https://keras.io/models/sequential/) \n", + "# compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)\n", + "# Stochastic Gradient Descent (‘sgd’) as optimization algorithm\n", + "# Mean Squared Error as loss, ie, quantitative variable, regression\n", + "model.compile(loss='mean_squared_error', optimizer='sgd')\n", + "\n", + "# list some properties\n", + "model.summary()\n", + "\n", + "# training\n", + "# fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, validation_freq=1)\n", + "model.fit(X_train, y_train, epochs=100)\n", + "\n", + "# cross-validation: get predicted target values\n", + "y_hat = model.predict(X_test, batch_size=128)\n", + "\n", + "mse_prediction = model.evaluate(X_test, y_test, batch_size=128)\n", + "print('\\nMSE in prediction =',mse_prediction)\n", + "\n", + "# correlation btw predicted and observed\n", + "corr = np.corrcoef(y_test,y_hat[:,0])[0,1]\n", + "print('\\nCorr obs vs pred =',corr)\n", + "\n", + "# plot observed vs. predicted targets\n", + "plt.title('MLP: Observed vs Predicted Y')\n", + "plt.ylabel('Predicted')\n", + "plt.xlabel('Observed')\n", + "plt.scatter(y_test, y_hat, marker='o')\n", + "plt.show()\n", + "\n", + "# Exercises\n", + "# - Check predictions across environments (Y[0] is first environment, etc)\n", + "# - Try to improve model with other activation functions and|or no. of neurons∫ " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From /usr/anaconda3/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n", + "Train on 431 samples, validate on 48 samples\n", + "Epoch 1/100\n", + "431/431 [==============================] - 0s 641us/step - loss: 11.0735 - val_loss: 8.1335\n", + "Epoch 2/100\n", + "431/431 [==============================] - 0s 136us/step - loss: 8.8888 - val_loss: 7.6685\n", + "Epoch 3/100\n", + "431/431 [==============================] - 0s 153us/step - loss: 8.3311 - val_loss: 7.3006\n", + "Epoch 4/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 7.7928 - val_loss: 6.9755\n", + "Epoch 5/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 7.4445 - val_loss: 6.6852\n", + "Epoch 6/100\n", + "431/431 [==============================] - 0s 162us/step - loss: 7.1215 - val_loss: 6.4828\n", + "Epoch 7/100\n", + "431/431 [==============================] - 0s 154us/step - loss: 6.8060 - val_loss: 6.2487\n", + "Epoch 8/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 6.5735 - val_loss: 6.0574\n", + "Epoch 9/100\n", + "431/431 [==============================] - 0s 154us/step - loss: 6.3664 - val_loss: 5.8993\n", + "Epoch 10/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 6.2304 - val_loss: 5.7265\n", + "Epoch 11/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 6.0646 - val_loss: 5.6079\n", + "Epoch 12/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 5.8711 - val_loss: 5.6681\n", + "Epoch 13/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 5.5650 - val_loss: 5.3465\n", + "Epoch 14/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 5.4968 - val_loss: 5.2489\n", + "Epoch 15/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 5.3823 - val_loss: 5.1211\n", + "Epoch 16/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 5.2013 - val_loss: 4.9954\n", + "Epoch 17/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 5.1538 - val_loss: 4.9169\n", + "Epoch 18/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 4.9599 - val_loss: 4.8474\n", + "Epoch 19/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 4.9343 - val_loss: 4.7526\n", + "Epoch 20/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 4.7676 - val_loss: 4.6432\n", + "Epoch 21/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 4.6988 - val_loss: 4.5475\n", + "Epoch 22/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 4.6121 - val_loss: 4.5407\n", + "Epoch 23/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 4.5287 - val_loss: 4.4045\n", + "Epoch 24/100\n", + "431/431 [==============================] - 0s 163us/step - loss: 4.4035 - val_loss: 4.3266\n", + "Epoch 25/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 4.4245 - val_loss: 4.2318\n", + "Epoch 26/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 4.2384 - val_loss: 4.2747\n", + "Epoch 27/100\n", + "431/431 [==============================] - 0s 165us/step - loss: 4.2108 - val_loss: 4.1056\n", + "Epoch 28/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 4.1560 - val_loss: 4.0833\n", + "Epoch 29/100\n", + "431/431 [==============================] - 0s 165us/step - loss: 4.0483 - val_loss: 4.0844\n", + "Epoch 30/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 4.0163 - val_loss: 3.9222\n", + "Epoch 31/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 3.8882 - val_loss: 3.9660\n", + "Epoch 32/100\n", + "431/431 [==============================] - 0s 166us/step - loss: 3.8464 - val_loss: 3.8105\n", + "Epoch 33/100\n", + "431/431 [==============================] - 0s 163us/step - loss: 3.7855 - val_loss: 3.7818\n", + "Epoch 34/100\n", + "431/431 [==============================] - 0s 160us/step - loss: 3.8090 - val_loss: 3.7049\n", + "Epoch 35/100\n", + "431/431 [==============================] - 0s 162us/step - loss: 3.7698 - val_loss: 3.7090\n", + "Epoch 36/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.6522 - val_loss: 3.6429\n", + "Epoch 37/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 3.6161 - val_loss: 3.6558\n", + "Epoch 38/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 3.5550 - val_loss: 3.5107\n", + "Epoch 39/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 3.5052 - val_loss: 3.5068\n", + "Epoch 40/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 3.5670 - val_loss: 3.4957\n", + "Epoch 41/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.5073 - val_loss: 3.4255\n", + "Epoch 42/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.4641 - val_loss: 3.3612\n", + "Epoch 43/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.3987 - val_loss: 3.3401\n", + "Epoch 44/100\n", + "431/431 [==============================] - 0s 154us/step - loss: 3.4624 - val_loss: 3.2606\n", + "Epoch 45/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.4092 - val_loss: 3.2107\n", + "Epoch 46/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.3889 - val_loss: 3.2065\n", + "Epoch 47/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.3314 - val_loss: 3.1806\n", + "Epoch 48/100\n", + "431/431 [==============================] - 0s 151us/step - loss: 3.3730 - val_loss: 3.2217\n", + "Epoch 49/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.3974 - val_loss: 3.1296\n", + "Epoch 50/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.3167 - val_loss: 3.1619\n", + "Epoch 51/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.2421 - val_loss: 3.0737\n", + "Epoch 52/100\n", + "431/431 [==============================] - 0s 153us/step - loss: 3.3131 - val_loss: 3.0209\n", + "Epoch 53/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.2336 - val_loss: 3.0977\n", + "Epoch 54/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.2781 - val_loss: 2.9665\n", + "Epoch 55/100\n", + "431/431 [==============================] - 0s 153us/step - loss: 3.2543 - val_loss: 2.9649\n", + "Epoch 56/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.2479 - val_loss: 2.9266\n", + "Epoch 57/100\n", + "431/431 [==============================] - 0s 160us/step - loss: 3.2035 - val_loss: 2.9429\n", + "Epoch 58/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.2518 - val_loss: 2.8969\n", + "Epoch 59/100\n", + "431/431 [==============================] - 0s 159us/step - loss: 3.1878 - val_loss: 3.0264\n", + "Epoch 60/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.3237 - val_loss: 2.9506\n", + "Epoch 61/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.2695 - val_loss: 2.7967\n", + "Epoch 62/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.1953 - val_loss: 2.7630\n", + "Epoch 63/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.1557 - val_loss: 2.7652\n", + "Epoch 64/100\n", + "431/431 [==============================] - 0s 154us/step - loss: 3.1746 - val_loss: 2.7809\n", + "Epoch 65/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.2733 - val_loss: 2.6974\n", + "Epoch 66/100\n", + "431/431 [==============================] - 0s 154us/step - loss: 3.1445 - val_loss: 2.8848\n", + "Epoch 67/100\n", + "431/431 [==============================] - 0s 153us/step - loss: 3.3162 - val_loss: 2.8662\n", + "Epoch 68/100\n", + "431/431 [==============================] - 0s 152us/step - loss: 3.2128 - val_loss: 2.6977\n", + "Epoch 69/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.2070 - val_loss: 2.6727\n", + "Epoch 70/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.1986 - val_loss: 2.6277\n", + "Epoch 71/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.1298 - val_loss: 2.6532\n", + "Epoch 72/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.1255 - val_loss: 2.5992\n", + "Epoch 73/100\n", + "431/431 [==============================] - 0s 161us/step - loss: 3.2244 - val_loss: 2.6069\n", + "Epoch 74/100\n", + "431/431 [==============================] - 0s 160us/step - loss: 3.2525 - val_loss: 2.6649\n", + "Epoch 75/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.1734 - val_loss: 2.5440\n", + "Epoch 76/100\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "431/431 [==============================] - 0s 160us/step - loss: 3.1797 - val_loss: 2.5231\n", + "Epoch 77/100\n", + "431/431 [==============================] - 0s 160us/step - loss: 3.2379 - val_loss: 2.5636\n", + "Epoch 78/100\n", + "431/431 [==============================] - 0s 162us/step - loss: 3.0843 - val_loss: 2.8673\n", + "Epoch 79/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.2910 - val_loss: 2.7848\n", + "Epoch 80/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.0765 - val_loss: 2.4974\n", + "Epoch 81/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.1720 - val_loss: 2.4704\n", + "Epoch 82/100\n", + "431/431 [==============================] - 0s 165us/step - loss: 3.0708 - val_loss: 2.4581\n", + "Epoch 83/100\n", + "431/431 [==============================] - 0s 163us/step - loss: 3.2271 - val_loss: 2.4939\n", + "Epoch 84/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.2576 - val_loss: 2.4177\n", + "Epoch 85/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.1177 - val_loss: 2.4178\n", + "Epoch 86/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.1127 - val_loss: 2.4349\n", + "Epoch 87/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.2711 - val_loss: 2.4189\n", + "Epoch 88/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.2293 - val_loss: 2.4339\n", + "Epoch 89/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 3.1431 - val_loss: 2.3829\n", + "Epoch 90/100\n", + "431/431 [==============================] - 0s 165us/step - loss: 3.3225 - val_loss: 2.4098\n", + "Epoch 91/100\n", + "431/431 [==============================] - 0s 165us/step - loss: 3.2028 - val_loss: 2.7059\n", + "Epoch 92/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 3.3306 - val_loss: 2.4703\n", + "Epoch 93/100\n", + "431/431 [==============================] - 0s 164us/step - loss: 3.2750 - val_loss: 2.3801\n", + "Epoch 94/100\n", + "431/431 [==============================] - 0s 156us/step - loss: 3.1962 - val_loss: 2.3339\n", + "Epoch 95/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.1348 - val_loss: 2.2986\n", + "Epoch 96/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.1598 - val_loss: 2.3099\n", + "Epoch 97/100\n", + "431/431 [==============================] - 0s 157us/step - loss: 3.2389 - val_loss: 2.3352\n", + "Epoch 98/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.1554 - val_loss: 2.4245\n", + "Epoch 99/100\n", + "431/431 [==============================] - 0s 158us/step - loss: 3.3565 - val_loss: 2.9161\n", + "Epoch 100/100\n", + "431/431 [==============================] - 0s 155us/step - loss: 3.3069 - val_loss: 2.2687\n", + "120/120 [==============================] - 0s 23us/step\n", + "\n", + "MSE in prediction = 6.54182243347168\n" + ] + } + ], + "source": [ + "# Controlling overfit: regularization, dropout and early stopping\n", + "\n", + "# deletes current model\n", + "del model\n", + "\n", + "model = Sequential()\n", + "\n", + "# Add l1 & l2 regularization in first layer\n", + "model.add(Dense(64, input_dim=nSNP,\n", + " kernel_regularizer=regularizers.l2(0.01),\n", + " activity_regularizer=regularizers.l1(0.01)))\n", + "model.add(Activation('relu'))\n", + "# Add second layer\n", + "model.add(Dense(32))\n", + "model.add(Activation('softplus'))\n", + "## Adding dropout to second layer\n", + "model.add(Dropout(0.2))\n", + "# Last, output layer\n", + "model.add(Dense(1))\n", + "\n", + "# Model Compiling (https://keras.io/models/sequential/) \n", + "model.compile(loss='mean_squared_error', optimizer='sgd')\n", + "\n", + "# Split the train set into proper train & validation\n", + "X_train0, X_val, y_train0, y_val = train_test_split(X_train, y_train, test_size=0.1)\n", + "nEpochs=100\n", + "\n", + "# Early stopping\n", + "early_stopper = EarlyStopping(monitor='val_loss', patience=10, min_delta=0.01)\n", + "model.fit(X_train0, y_train0, epochs=nEpochs, verbose=1, validation_data=(X_val, y_val), callbacks=[early_stopper])\n", + "\n", + "# cross-validation\n", + "mse_prediction = model.evaluate(X_test, y_test, batch_size=128)\n", + "print('\\nMSE in prediction =',mse_prediction)\n", + "\n", + "## In this case neither l1 nor l2 regularization helps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Talos is a powerful tool to keras hyperparameter optimization and model evaluation. For regression models, it includes root_mean_squared_error as an evaluation metric, but you can also use a custom function as the train/test correlation. \n", + "**Warning**: you should include the string 'acc' in the name in order to pick epochs will be well recorded." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Defining pearson correlation as custom metric to model optimization in talos! \n", + "# warning! you have to use acc in the metric name!\n", + "\n", + "from keras import backend as K\n", + "\n", + "def acc_pearson_r(y_true, y_pred):\n", + " x = y_true\n", + " y = y_pred\n", + " mx = K.mean(x, axis=0)\n", + " my = K.mean(y, axis=0)\n", + " xm, ym = x - mx, y - my\n", + " r_num = K.sum(xm * ym)\n", + " x_square_sum = K.sum(xm * xm)\n", + " y_square_sum = K.sum(ym * ym)\n", + " r_den = K.sqrt(x_square_sum * y_square_sum)\n", + " r = r_num / r_den\n", + " return K.mean(r) \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# HYPERPARAMETER OPTIMIZATION USING TALOS: Simple example\n", + "# https://autonomio.github.io/docs_talos/\n", + "# 1. Hyperparameter ranges and Model definition\n", + "\n", + "# model definition\n", + "def baby_model(x, y, x_val, y_val, params): \n", + " # replace the hyperparameter inputs with references to params dictionary \n", + " model = Sequential()\n", + " model.add(Dense(params['first_neuron'], input_dim=x.shape[1],\n", + " activation=params['activation']))\n", + " #last neuron\n", + " model.add(Dense(1, activation=None))\n", + " model.compile(loss=mean_squared_error, optimizer='sgd', metrics=[acc_pearson_r])\n", + " \n", + " # make sure history object is returned by model.fit()\n", + " out = model.fit(x, y,\n", + " epochs=50,\n", + " validation_data=[x_val, y_val],\n", + " batch_size=params['batch_size'],\n", + " verbose=0)\n", + " \n", + " # modify the output model\n", + " return out, model\n", + "\n", + "# dictionary with hyperparameters and range values allowed\n", + "p = {\n", + " 'first_neuron': [12, 48],\n", + " 'activation': [relu, elu],\n", + " 'batch_size': [10, 30]\n", + "}\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 0%| | 0/8 [00:00<?, ?it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function relu at 0x7fb79005fa60>, 'batch_size': 10, 'first_neuron': 12}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 12%|█▎ | 1/8 [00:08<00:58, 8.36s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function relu at 0x7fb79005fa60>, 'batch_size': 10, 'first_neuron': 48}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 25%|██▌ | 2/8 [00:16<00:50, 8.35s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function relu at 0x7fb79005fa60>, 'batch_size': 30, 'first_neuron': 12}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 38%|███▊ | 3/8 [00:19<00:34, 6.80s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function relu at 0x7fb79005fa60>, 'batch_size': 30, 'first_neuron': 48}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 50%|█████ | 4/8 [00:23<00:22, 5.71s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function elu at 0x7fb79005f730>, 'batch_size': 10, 'first_neuron': 12}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 62%|██████▎ | 5/8 [00:31<00:19, 6.54s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function elu at 0x7fb79005f730>, 'batch_size': 10, 'first_neuron': 48}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 75%|███████▌ | 6/8 [00:39<00:13, 6.98s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function elu at 0x7fb79005f730>, 'batch_size': 30, 'first_neuron': 12}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 88%|████████▊ | 7/8 [00:42<00:05, 5.84s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'activation': <function elu at 0x7fb79005f730>, 'batch_size': 30, 'first_neuron': 48}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 8/8 [00:45<00:00, 5.03s/it]\n" + ] + } + ], + "source": [ + "# HYPERPARAMETER OPTIMIZATION USING TALOS: Simple example\n", + "# 2. Search, run this grid should take between 1-2 minutes\n", + "\n", + "# Split the train set into proper train & validation\n", + "X_train0, X_val, y_train0, y_val = train_test_split(X_train, y_train, test_size=0.1)\n", + "X_train0=np.asarray(X_train0)\n", + "X_val=np.asarray(X_val)\n", + "y_train0=np.asarray(y_train0)\n", + "y_val=np.asarray(y_val)\n", + "\n", + "# COOL! this shows real time plots\n", + "t_Init = ta.Scan(x=X_train0,\n", + " y=y_train0,\n", + " x_val=X_val,\n", + " y_val=y_val,\n", + " model=baby_model, \n", + " params=p, \n", + " experiment_name=\"Baby\",\n", + " print_params=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " round_epochs val_loss val_acc_pearson_r loss acc_pearson_r \\\n", + "0 50 0.809556 0.479088 0.316570 NaN \n", + "1 50 0.974029 0.290083 0.206135 NaN \n", + "2 50 0.818821 0.516016 0.425335 0.762408 \n", + "3 50 0.755092 0.566010 0.306461 0.856790 \n", + "4 50 0.898624 0.402562 0.381604 NaN \n", + "5 50 1.003472 0.481772 0.400567 NaN \n", + "6 50 0.883474 0.430548 0.526288 0.699488 \n", + "7 50 0.956687 0.459817 0.501658 0.721474 \n", + "\n", + " activation batch_size first_neuron \n", + "0 <function relu at 0x7fb79005fa60> 10 12 \n", + "1 <function relu at 0x7fb79005fa60> 10 48 \n", + "2 <function relu at 0x7fb79005fa60> 30 12 \n", + "3 <function relu at 0x7fb79005fa60> 30 48 \n", + "4 <function elu at 0x7fb79005f730> 10 12 \n", + "5 <function elu at 0x7fb79005f730> 10 48 \n", + "6 <function elu at 0x7fb79005f730> 30 12 \n", + "7 <function elu at 0x7fb79005f730> 30 48 \n", + "\n", + "Best prediction combination:\n", + " round_epochs val_loss val_acc_pearson_r loss acc_pearson_r \\\n", + "3 50 0.755092 0.56601 0.306461 0.85679 \n", + "\n", + " activation batch_size first_neuron \n", + "3 <function relu at 0x7fb79005fa60> 30 48 \n", + "\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEXCAYAAAC+mHPKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XucznX+//HHyxByzikNIpScGgzZNlJW0YFWFq12s52+KmVb2Wo7rtr96vDdkmr9pFa1ZeisTXYpYne1DI0KHYQwyZnCxMx4/f64PnPtNWMOH8zlmmae99vNretzeL8/r+uK63V93u/P5/Uxd0dERKQklRIdgIiI/DAoYYiISChKGCIiEooShoiIhKKEISIioShhiIhIKEoYEldm1tzM9phZUqJjETCzSWZ2d5z6XmFmvePRt5QNpvswpDSY2TqgMZAbs/pUd//6KPocAVzj7mcfXXQVUzw/PzObCmx097tKu28pu3SGIaXpEnevGfOn2GRhET+Iv4NmVjnRMYgk2g/iH6v8cJlZCzPzvC9cM5tvZn8ws38B+4BTzGyEma0xs+/MbK2ZDTez04FJwI+CIa1dRfQ/38zuN7N/Be3/YWYNYrb3MLN/m9kuM1seO2RiZuvM7Ccxy/eZ2V8LxH21ma0H3gvWDwiGXnYFxz69QH+3mtlHZrbbzKabWbUi4v6zmb0as/ygmb1rZlbIvq3M7D0z225m28zsRTOrG7O9mZm9ZmZbg32eKOrzM7OpZvZA8HqVmV0c00/loI8uwfLLZvZN8F4WmFn7YP11wHDgt0HfbxX8PM2sqpk9ZmZfB38eM7OqwbbeZrbRzMaY2RYz22Rmvyrsc5KyRQlDEuEXwHVALWAr8DjQ391rAWcBGe6+ChgJLArOVuoW2Rv8HPgV0Ag4DrgVwMySgbeBB4ATgvWvmlnDw4j1HOB04AIzOxWYBvwaaAjMAt4ys+Ni9h8C9ANaAp2AEUX0OwboGCTLnsDVwJVe+BixAf8LnBTE0gy4L3iPScDfgK+AFkAykBby85sGXB6zfAGwzd2XBcvvAG2IfK7LgBcB3H1y8PqhoO9LCun7TqAHkAKcAXQHYoevTgTqBPFeDTxpZvUK6UfKECUMKU1vBL+8d5nZG8XsN9XdV7h7DpADHAQ6mFl1d9/k7isO87h/cffP3T0LmEHkSwrgCmCWu89y94PuPgdIBy48jL7vc/e9Qd9DgbfdfY67ZwOPANWJJLk8j7v71+6+A3grJpZ83H0fkcT5J+CvwE3uvrGIfVcHx9zv7luDNucEm7sTSSRjgzi/d/d/hnxvLwEDzOz4YPnnRJJI3nGfdffv3H0/kQR1hpnVCdn3cGCcu28JYv598H7zZAfbs919FrAHOC1k35IgShhSmi5197rBn0uL2W9D3gt330vki3gksMnM3jaztod53G9iXu8DagavTwZ+FpPEdgFnA00Oo+8NMa9PIvJLPi/2g8H25BCxHMLd/wOsIXIGMaOo/cyssZmlmVmmmX1LJMHkDbs1A74Kku9hcffVwCrgkiBpDCCSRDCzJDMbb2ZfBsdcFzRrUGhnh8r3WQWvT4pZ3l4g5mI/KykblDAkEfINu7j73929L5Ev8k+Bpwvb7whsAF6ISWJ13b2Gu48Ptu8Fjo/Z/8QSYv2aSBICIpP2RL6wM48kODO7Eaga9PvbYnb9YxBHR3evTeTMKW+uYwPQvIhJ+TCfX96w1EBgZZBEIHK2MRD4CZGhoxZ5YYfsO99nBTQP1skPmBKGJFTw63mgmdUA9hMZmjgYbN4MNC0wR3A4/krk1/MFwS/masGEa9NgewYwzMyqmFkqMLiE/mYAF5lZHzOrQmQeYj/w78MNLJgPeYDIl/8viEwgFzp8RWSuZw+wO5iXGRuzbTGwCRhvZjWC9/jjYFuYzy8NOB+4nuDsIuaY+4HtRJLqHwu02wycUky/04C7zKxhcBHCPUT+f8gPmBKGJFol4DdEfn3uIDI2f32w7T1gBfCNmW073I7dfQORX8m/IzK5voHIl23e3/u7gVbATiJj7C8V0k1sf58R+YKfCGwDLiFyKfGBw4krOBv4K/Cguy939y+CGF/Iu5KogN8DXYDdRCbxX4uJKTeIozWwHthIZIgPQnx+7r4JWERkHmZ6zKbniQwjZQIrgQ8KNH0GaFfMfNUDROaLPgI+JjJp/kBhMcgPh27cExGRUHSGISIioShhiIhIKEoYIiISihKGiIiEUq4KqjVo0MBbtGiR6DBERH5Qli5dus3dSyyZU64SRosWLUhPT090GCIiPyhm9lXJe2lISkREQlLCEBGRUJQwREQkFCUMEREJRQlDRERCUcIQEZFQlDBERCSUcnUfhogUb+LEiaxevbrkHYuQmRl5VlRycnIJexatdevW3HTTTUfcXhJHCUNEQsvKykp0CJJAShgiFcjR/rIfPXo0ABMmTCiNcOQHRnMYIiISihKGiIiEooQhIiKhKGGIiEgoShgiIhKKEoaIiISihCEiIqHEPWGYWT8z+8zMVpvZ7YVsH2FmW80sI/hzTcy23Jj1M+Mdq4iIFC2uN+6ZWRLwJNAX2AgsMbOZ7r6ywK7T3X1UIV1kuXtKPGMUEZFw4n2G0R1Y7e5r3P0AkAYMjPMxRUQkDuKdMJKBDTHLG4N1BV1mZh+Z2Stm1ixmfTUzSzezD8zs0sIOYGbXBfukb926tRRDFxGRWGVh0vstoIW7dwLmAM/FbDvZ3VOBnwOPmVmrgo3dfbK7p7p7asOGDY9NxCIiFVC8E0YmEHvG0DRYF+Xu2919f7A4Begasy0z+O8aYD7QOZ7BiohI0eKdMJYAbcyspZkdBwwD8l3tZGZNYhYHAKuC9fXMrGrwugHwY6DgZLmIiBwjcb1Kyt1zzGwU8HcgCXjW3VeY2Tgg3d1nAjeb2QAgB9gBjAianw78PzM7SCSxjS/k6ioRETlG4v48DHefBcwqsO6emNd3AHcU0u7fQMd4xyciIuGUhUlvERH5AVDCEBGRUJQwREQkFCUMEREJRQlDRERCUcIQEZFQlDBERCQUJQwREQlFCUNEREJRwhARkVCUMEREJBQlDBERCUUJQ0REQlHCEBGRUJQwREQkFCUMEREJRQlDRERCifsT9yqaiRMnsnr16qPqIzMzE4Dk5OQj7qN169bcdNNNRxWHiEgsJYwyKCsrK9EhiIgcQgmjlJXGr/rRo0cDMGHChKPuS0SktGgOQ0REQlHCEBGRUJQwREQkFCUMEREJRZPeBZTGZbFHK+/4eZPfiaDLckWkICWMAlavXk3GJ6vIPf6EhMVQ6YADsHTN5oQcP2nfjoQcV0TKtrgnDDPrB0wAkoAp7j6+wPYRwMNAZrDqCXefEmy7ErgrWP+Auz8X73gBco8/gay2Fx6LQ5VJ1T+dlegQRKQMimvCMLMk4EmgL7ARWGJmM919ZYFdp7v7qAJtTwDuBVIBB5YGbXfGM2YRESlcvCe9uwOr3X2Nux8A0oCBIdteAMxx9x1BkpgD9ItTnCIiUoJ4J4xkYEPM8sZgXUGXmdlHZvaKmTU7zLYiInIMlIVJ77eAae6+38z+B3gOOC9sYzO7DrgOoHnz5kcdTGZmJkn7dlfocfykfdvJzMxJdBgiUsbEO2FkAs1ilpvy38ltANx9e8ziFOChmLa9C7SdX/AA7j4ZmAyQmprqRxuwSFmlS77/S5d9J0a8E8YSoI2ZtSSSAIYBP4/dwcyauPumYHEAsCp4/Xfgj2ZWL1g+H7gjzvGSnJzMN/srV/irpJKTGyc6DClAl3xH6LLvxIlrwnD3HDMbReTLPwl41t1XmNk4IN3dZwI3m9kAIAfYAYwI2u4ws/uJJB2Ace6uvylSoVX0S75Bl30nUtznMNx9FjCrwLp7Yl7fQRFnDu7+LPBsXAMUEZFQVEtKRERCUcIQEZFQysJltWVO0r4dCR0nrfT9twAcrFY7IcePTCpq0ltE8isxYZhZJWCwu884BvEkXOvWrRMdAqtXfwdA61MS9aXduEx8DiJStpSYMNz9oJn9FqgQCaMsXNutZ3qLSFkUdg5jrpndambNzOyEvD9xjUxERMqUsHMYQ4P/3hizzoFTSjccEREpq0IlDHdvWdx2M+vr7nNKJyQRkfg72lIrmZmRKkfJyUdeE/WHVuKktC6rfbCU+hER+UHIysoiKysr0WEcU6V1Wa2VUj8/eKVRIK40Crz90H65iBxrR/vvoyJenFJaCUNVYktR9erVEx2CiMghdONeKdOvepH4y8zMTHiJ9YpY6r20Esa6UupHRKREWVlZfLHiQ5rXzE1YDMdlR6aA93+VnrAY1u9JOqbHC50wzOwsoEVsG3d/PvjvoFKPTESkGM1r5vK7Lt8mOoyE+uOyY1s+KFTCMLMXgFZABpCX0h14Pk5xiYhIGRP2DCMVaOfumtwWkYTbv38/X32fdMx/YZc1X32XRI3MzJJ3LCVh78P4BDgxnoGIiEjZFvYMowGw0swWA/vzVrr7gLhEJSJSjKpVq9KsSpbmMJbVpupR3Gl+uMImjPviGYSIyOFavyexQ1Kb90UGaBoffzBhMazfk0SbY3i8sLWk3jezxkC3YNVid98Sv7BERIpWvXp1khP8zJYDwX0YVU9OXBxtOLbP8Al7ldQQ4GFgPpEyIBPNbKy7vxLH2ERECpWcnJzwkhwqDVK0O4FueWcVZtYQmAsoYYiIVBBhE0alAkNQ2ym9SrciIsfc0RYKrYhFQsMmjNlm9ndgWrA8FJgVn5BERMq+ilgkNOyk91gzGwScHaya7O6vxy8sEZH4+iH9si8rwk561wDedPfXzOw04DQzq+Lu2fENT0REyoqw8xALgKpmlgzMBn4BTI1XUCIiUvaETRjm7vuAQcCf3f1nQPtQDc36mdlnZrbazG4vZr/LzMzNLDVYbmFmWWaWEfyZFDJWERGJg7CT3mZmPwKGA1cH60osxG5mScCTQF9gI7DEzGa6+8oC+9UCRgP/KdDFl+6eEjJGERGJo7BnGKOBO4DX3X2FmZ0CzAvRrjuw2t3XuPsBIA0YWMh+9wMPAt+HjEdERI6xEhNGcJYwwN0HuPuDAEECuDlE/8nAhpjljcG62P67AM3c/e1C2rc0sw/N7H0z61lEfNeZWbqZpW/dujVESCIiciRKTBjunst/L6ctVWZWCfgTMKaQzZuA5u7eGfgN8JKZHVJpzN0nu3uqu6c2bNgwHmGKiAjh5zA+NLOZwMvA3ryV7v5aCe0ygWYxy02DdXlqAR2A+WYGkWduzDSzAe6eTlBK3d2XmtmXwKlA4h6gKyJSgYVNGNWIlAM5L2adAyUljCVAGzNrSSRRDAN+Hu3AfTeRZ20AYGbzgVvdPT2oV7XD3XODOZM2wJqQ8YqISCkLe6f3r46kc3fPMbNRwN+JXFX1bDBpPg5Id/eZxTTvBYwzs2zgIDDS3XccSRwiInL0wt7pXY3I5bTtiZxtAODuV5XU1t1nUaDulLvfU8S+vWNevwq8GiY+ERGJv7CX1b5AZH7hAuB9InMR38UrKBERKXvCJozW7n43sNfdnwMuAs6MX1giIlLWhE0YeUUGd5lZB6AO0Cg+IYmISFkU9iqpyWZWD7gbmAnUBAqdhxARkfIp7FVSU4KX7wOnxC8cEREpq0INSZlZYzN7xszeCZbbmdnVJbUTEZHyI+wcxlQi91KcFCx/Dvw6HgGJiEjZFHYOo4G7zzCzOyB6Q15uHOOScmDixImsXr36qPrIzIxUkklOTi5hz6K1bt1aj+MUKQVhE8ZeM6tPpBwIZtYD2B23qEQCWVlZiQ5BRAJhE8ZviFwd1crM/gU0BAbHLSopF0rjV/3o0aMBmDBhwlH39UOXmZlJ0r7dVP90Vsk7l2NJ+7aTmZmT6DAqpLBXSS0zs3OA0wADPnP37BKaiYhIOXI4taRuIPJcDAcWmtkkd9cT8kSOkeTkZL7ZX5msthcmOpSEqv7pLJKTGyc6jAop7JDU80RqR00Mln9OpL7Uz+IRlJQNpTFpfbTyjp83NJUImjQXiQibMDq4e7uY5XlmtjIeAUnZsXr1ar5Y8SHNaybugrjjsiNXfu//KjHPzVq/JykhxxUpi8ImjGVm1sPdPwAwszPRk+8qhOY1c/ldl28THUbC/HHZIU8FFqmwwiaMrsC/zWx9sNwc+MzMPgbc3TvFJToRESkzwiaMfsVtNLN67r6zFOIREZEyKuxltV8Vt93MlgFdSiUiKTMyMzPZ+11ShR6W+eq7JGoEd5uLVHRha0mVxEqpHxERKaPCDkmVxEupHylDkpOT2Z+zqcJPelc9ijpWIuVJaZ1hiIhIOachKRERCSVsaZAewAp3/y5Yrg2c7u7/CXbpE6f4JMHW70nspPfmfZHfNI2PP5iQ46/fk0SbhBxZpOwJO4fxZ/JfBbUndp277yjluKQMaN26daJD4EBQGqTqyYmJpQ1l43MQKQvCJgxz9+jEtrsfNLPSmjCXMqos1E9SeXORsiPsHMYaM7vZzKoEf0YDa+IZmIiIlC1hE8ZI4CwgE9gInAlcF6+gRESk7Al7p/cWYNiRHMDM+gETgCRgiruPL2K/y4BXgG7unh6suwO4GsgFbnb3vx9JDJIYpVEevTTKm6s8uUjpCHWGYWbPmVndmOV6ZvZsiHZJwJNAf6AdcLmZtStkv1rAaOA/MevaEUlS7YnUsnoq6E8qkOrVq1O9evVEhyEihJ/07uTuu/IW3H2nmXUO0a47sNrd1wCYWRowECj4LI37gQeBsTHrBgJp7r4fWGtmq4P+FoWMWRJMv+pFypewcxiVzKxe3oKZnUC4ZJMMbIhZ3hisizKzLkAzd3/7cNsG7a8zs3QzS9+6dWuIkERE5EiEPcP4P2CRmb1M5K7uwcAfjvbgZlYJ+BMw4kj7cPfJwGSA1NRU1bQSEYmTsJPez5vZUuDcYNUgdw/ziNZMoFnMctNgXZ5aQAdgvpkBnAjMNLMBIdqKiMgxFPrmO3dfYWZbgWoAZtbc3deX0GwJ0MbMWhL5sh8G/Dymz91Ag7xlM5sP3Oru6WaWBbxkZn8CTiJy0+3isPGKiEjpCnuV1AAz+wJYC7wPrAPeKamdu+cAo4C/A6uAGUHiGRecRRTXdgUwg8gE+WzgRnfPDROviIiUvrBnGPcDPYC57t7ZzM4FrgjT0N1nAbMKrLuniH17F1j+A6UwVyIiIkcv7FVS2e6+ncjVUpXcfR6QGse4RESkjAl7hrHLzGoCC4AXzWwLsDd+YYmISFkT9gxjILAPuIXIfMKXwCXxCkpERMqesJfV5p1NHASeK7jdzBa5+49KMzARESlbSusRrdVKqR8RESmjSith6A5rEZFyrrQShoiIlHOllTCslPoREZEyqrQSxi9KqR8RESmjir1Kysy+o/D5CQPc3WsTefFJHGITEZEypNiE4e61jlUgIiJStoWuVgtgZo2IuYQ2RLVaEREpJ+JarVZERMqPsJPeedVqP3f3lkAf4IO4RSUiImWOqtWKiEgoh1utdiGqVisiUiGFPcOYB9QBRqNqtSIiFVLYhFEZ+AcwH6gFTA+GqEREpIIIlTDc/ffu3h64EWgCvG9mc+MamYiIlCmHWxpkC/ANsB1oVPrhiIhIWRX2PowbzGw+8C5QH7jW3TvFMzARESlbwl4l1Qz4tbtnxDMYEREpu8I+ovWOeAciIiJl22HVkhKRxErat4Pqn85K2PErff8tAAer1U5YDEn7dgCNE3b8ikwJQ+QHonXr1okOgdWrvwOg9SmJ/MJuXCY+i4pICUPkB+Kmm25KdAiMHj0agAkTJiQ4EkkEPdNbRERCiXvCMLN+ZvaZma02s9sL2T7SzD42swwz+6eZtQvWtzCzrGB9hplNinesIiJStLgOSZlZEvAk0BfYCCwxs5nuvjJmt5fcfVKw/wDgT0C/YNuX7p4SzxhFRCSceJ9hdAdWu/sadz8ApAEDY3dw929jFmtQ+DPERUQkweI96Z0MbIhZ3gicWXAnM7sR+A1wHHBezKaWZvYh8C1wl7svLKTtdcB1AM2bNz8kgOzsbDZu3Mj3339/FG9DRACGDBmCu7N27VqaNm1KlSpVEh2SHENl4iopd38SeNLMfg7cBVwJbAKau/t2M+sKvGFm7QuckeDuk4HJAKmpqYecnWzcuJFatWrRokULzCzu70WkPFu/fj3uTo0aNdi4cSMtW7ZMdEhyDMV7SCqTSFmRPE2DdUVJAy4FcPf9eSXU3X0pkWdwnHq4AXz//ffUr19fyUKklJgZ9evX11l7BRTvhLEEaGNmLc3sOGAYMDN2BzNrE7N4EfBFsL5hMGmOmZ0CtAHWHEkQShYipUv/piqmuA5JuXuOmY0C/g4kAc+6+wozGweku/tMYJSZ/QTIBnYSGY4C6AWMM7Ns4CAw0t13xDNeEREpWtzvw3D3We5+qru3cvc/BOvuCZIF7j7a3du7e4q7n+vuK4L1r8as7+Lub8U7Vild8+fP59///nd0edKkSTz//PNH1NfUqVP5+uuvo8vXXHMNK1euLKaFiJS2MjHpLeXT/PnzqVmzJmeddRYAI0eOPOK+pk6dSocOHTjppJMAmDJlSqnEKCLhqTSIHLZLL72Url270r59eyZPngzA7Nmz6dKlC2eccQZ9+vRh3bp1TJo0iUcffZSUlBQWLlzIfffdxyOPPMKnn35K9+7do/2tW7eOjh07AjBu3Di6detGhw4duO6663B3XnnlFdLT0xk+fDgpKSlkZWXRu3dv0tPTAZg2bRodO3akQ4cO3HbbbdF+a9asyZ133skZZ5xBjx492Lx58zH8lETKHyUMOWzPPvssS5cuJT09nccff5zNmzdz7bXX8uqrr7J8+XJefvllWrRowciRI7nlllvIyMigZ8+e0fZt27blwIEDrF27FoDp06czdOhQAEaNGsWSJUv45JNPyMrK4m9/+xuDBw8mNTWVF198kYyMDKpXrx7t6+uvv+a2227jvffeIyMjgyVLlvDGG28AsHfvXnr06MHy5cvp1asXTz/99DH8lETKHyUMOWyPP/549Ff7hg0bmDx5Mr169Ypek3/CCSeU2MeQIUOYPn06kD9hzJs3jzPPPJOOHTvy3nvvsWLFimL7WbJkCb1796Zhw4ZUrlyZ4cOHs2DBAgCOO+44Lr74YgC6du3KunXrjvQtiwhKGHKY5s+fz9y5c1m0aBHLly+nc+fOpKQcfrmvoUOHMmPGDD7//HPMjDZt2vD9999zww038Morr/Dxxx9z7bXXHtW1/lWqVIle/pmUlEROTs4R9yUiShhymHbv3k29evU4/vjj+fTTT/nggw/4/vvvWbBgQXSIaceOyNXPtWrV4rvvviu0n1atWpGUlMT9998fPbvISw4NGjRgz549vPLKK9H9i+qre/fuvP/++2zbto3c3FymTZvGOeecU6rvWUQidJWUHJZ+/foxadIkTj/9dE477TR69OhBw4YNmTx5MoMGDeLgwYM0atSIOXPmcMkllzB48GDefPNNJk6ceEhfQ4cOZezYsdFEU7duXa699lo6dOjAiSeeSLdu3aL7jhgxgpEjR1K9enUWLVoUXd+kSRPGjx/Pueeei7tz0UUXMXDgwEOOJSJHz9zLT3HY1NRUz7tyJs+qVas4/fTTExSRSPmyfv16IFLoU/+2yg8zW+ruqSXtpyEpEREJRQlDRERCUcIQEZFQlDBERCQUJQwREQlFCUNEREKpcPdhjPrNWLZsK73HajRqcAJP/Onho+pj4cKFjBw5kipVqrBo0aJ8tZKOxh//+Ed+97vfRZfPOuusfOXG423q1Kmkp6fzxBNPHHVfBd9LrKVLlzJixAiysrK48MILmTBhQrEP+OnZs2f0JsAtW7bQvXt33njjDfbv389FF13Etm3buOOOO7jttttIT0+nQYMG+drfcsstzJs3D4B9+/axZcsWdu3aBcBtt93G22+/DcDdd98dvSlx7dq1DBs2jO3bt9O1a1deeOEFjjvuOPbv388vf/lLli5dSv369Zk+fTotWrRg3bp10XtdAHr06MGkSZMAePnll7nnnns48cQTo3EUZv369VxzzTVs2LABM2PWrFm0aNGiyFhESlLhEsaWbTv4snEp3gm8+f0janbgwAGys7OpUaMGL774InfccQdXXHFF6cXFoV+y8UgWOTk5VK4c/79GxSWM66+/nqeffpozzzyTCy+8kNmzZ9O/f/8i+1q4cGH09WWXXRa90e/DDz8EICMjAyBf5dtYjz76aPT1xIkTo+3efvttli1bRkZGBvv376d3797079+f2rVrc9ttt3HLLbcwbNgwRo4cyTPPPMP111/PM888Q7169Vi9ejVpaWncdttt0RpbrVq1isYS65lnnuHpp5/m7LPPLvI9Avzyl7/kzjvvpG/fvuzZs4dKlSpF31dhsezcuZN69eoV26dUbBqSOsZWrVrFmDFjOO200/j888+ZMmUKM2bM4O6772b48OHMnz8/WjAPItVbp06dCkCLFi2499576dKlCx07duTTTz8FYM+ePfzqV7+iY8eOdOrUiVdffZXbb7+drKwsUlJSGD58OBAp9w3g7owdO5YOHTrQsWPH6BfU/Pnz6d27N4MHD6Zt27YMHz6cwm7s7N27N7/+9a9JTU1lwoQJbN26lcsuu4xu3brRrVs3/vWvfx3SZsSIEflKfeTFUlBhpdMLey95Nm3axLfffkuPHj0wM375y1/yxhtvkJOTQ7du3Zg/fz4Ad9xxB3feeWe+tt9++y3vvfcel156KVu2bOGKK65gyZIlpKSk8OWXXwLw0EMP0bFjR7p3787q1asPiXfatGlcfvnlAKxcuZJevXpRuXJlatSoQadOnZg9ezbuznvvvcfgwYMBuPLKK6MVdd98802uvDLykMnBgwfz7rvvFvqZ5xk3bhz//Oc/ufrqqxk7dizr1q2jZ8+edOnShS5dukR/FKxcuZKcnBz69u0b/byPP/74YmOZPn06HTp04P/+7//YunVrkTFIxaWEcQzs3buXv/zlL5x99tlce+21tGvXjo8++ojOnTtzzTXXMGDAAB5++GFefPHFEvtq0KABy5Yt4/rrr+eRRx4B4P7776dOnTp8/PHHfPTRR5x33nmMHz+e6tUXG00MAAAT9UlEQVSrk5GRcUi/r732GhkZGSxfvpy5c+cyduxYNm3aBER+ZT/22GOsXLmSNWvWFPrlD5EzpPT0dMaMGcPo0aO55ZZbWLJkCa+++irXXHPNEX9WBUunb9++vdj3kpmZSdOmTaPLTZs2JTMzk8qVKzN16lSuv/565s6dy+zZs7n33nvztX3jjTfo06cPtWvXplGjRkyZMoWePXuSkZFBq1atAKKf66hRo/j1r3+dr/1XX33F2rVrOe+88wA444wzmD17Nvv27WPbtm3MmzePDRs2sH37durWrRs9E8uLMS/+Zs2aAVC5cmXq1KnD9u3bgcgwVufOnTnnnHOiZ0X33HNPtNT7ww8/HC3DsmzZMqZPn87NN98MwOeff07dunUZNGgQnTt3ZuzYseTm5hYby8iRI3nnnXfYt28fvXr1YvDgwcyePZuDBw8e8f9PKV8q3JBUIjRp0oROnToxZcoU2rZte1R9DRo0CIiU637ttdcAmDt3LmlpadF9ShpW+Oc//8nll19OUlISjRs35pxzzmHJkiXUrl2b7t27R7+AU1JSWLduXaFDH3lj83nHj31c6rfffsuePXuO6P09/vjjvP766wBs2LCBL774gvr16x9RX+3bt+cXv/gFF198MYsWLTpknH7atGklJre8s4fLL7+cW265Jd+2tLQ0Bg8eTFJSEgDnn38+S5Ys4ayzzqJhw4b86Ec/im47XE2aNGH9+vXUr1+fpUuXcumll7JixQpq166db7/s7GxGjRpFRkYGSUlJfP7550BkqHDhwoV8+OGHNG/enKFDhzJ16tQS62w1a9aMu+++m7vuuot33nmHq666itTUVGbOnHlE70PKF51hHAOvvPIKycnJDBo0iHHjxvHVV18VuW/lypXz/aIrWN67atWqQPzKdef1X9IxatSoEX198OBBPvjgAzIyMsjIyCAzM/OQIafY93Xw4EEOHDhwSJ+FlU4vqbx5cnIyGzdujC5v3LiR5OTk6PLHH39M3bp12bJlS75227ZtY/HixVx00UXF9h87eV5wIj0tLS2aUPLceeedZGRkMGfOHNydU089lfr167Nr167oZxkbY3JyMhs2bAAiX/K7d++mfv36VK1aNZoou3btSqtWraLJINajjz5K48aNWb58Oenp6dHPtWnTpqSkpHDKKadQuXJlLr30UpYtW1ZsLHkWL17MDTfcwM0338yQIUP43//932I/I6k4lDCOgfPPP5/p06ezcOFC6tSpw8CBA/nJT35S6AN9Tj75ZFauXMn+/fvZtWsX7777bon99+3blyeffDK6vHPnTiDyPIjs7OxD9u/ZsyfTp08nNzeXrVu3smDBgnyPTD2S9xdbjbawidoWLVqwdOlSAGbOnFloXIWVTs9T1Htp0qQJtWvX5oMPPsDdef7556O/ol977TV27NjBggULuOmmm6JXMkEkiV988cVUq1at2PcW+5CnH/3oR9H1n376KTt37sy3Lm/IB+Cjjz7io48+4vzzz8fMOPfcc6NzOM8991w0xgEDBvDcc89FYzrvvPMwM7Zu3Upubi4Aa9as4YsvvuCUU04p9DNr0qQJlSpV4oUXXoi26datG7t27YrORbz33nu0a9eu2Fj+8Y9/0KlTJ+666y7OPfdcVq5cyWOPPUb79u2L/Yyk4qhwQ1KNGpxwxFc2FdlfSPXr12f06NGMHj2axYsXFzpc0axZM4YMGUKHDh1o2bIlnTt3LrHfu+66ixtvvJEOHTqQlJTEvffey6BBg7juuuvo1KkTXbp0yTf2/9Of/pRFixZxxhlnYGY89NBDnHjiidFJ9MP1+OOPc+ONN9KpUydycnLo1atX9BLQPNdeey0DBw7kjDPOoF+/fvnOUPIUVjo9T1HvBeCpp56KXlbbv39/+vfvz7Zt27j99tt59913adasGaNGjWL06NHRL+e0tDRuv/32Et/bzp076dSpE1WrVmXatGnR9WlpaQwbNizfWUd2dnb0UbS1a9fmr3/9a3Su4MEHH2TYsGHcdddddO7cmauvvhqAq6++ml/84he0bt2aE044ITq0uGDBAu655x6qVKlC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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# HYPERPARAMETER OPTIMIZATION USING TALOS: Simple example\n", + "# 3. Inspect results\n", + "Data=pd.DataFrame(t_Init.data)\n", + "Data[\"loss\"] = pd.to_numeric(Data[\"loss\"])\n", + "Data[\"val_acc_pearson_r\"] = pd.to_numeric(Data[\"val_acc_pearson_r\"])\n", + "print(Data)\n", + "\n", + "# Minimum loss set\n", + "i=Data['val_acc_pearson_r'].argmax()\n", + "print('\\nBest prediction combination:')\n", + "print(Data[i:(i+1)],'\\n')\n", + "\n", + "# Visualize some parameters combinations \n", + "x = sns.boxplot(y=\"val_acc_pearson_r\",x=\"first_neuron\",hue=\"activation\",data=Data).set_title('First neuron x activation')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hyperparameter tunning: 'the real world model'. Talos uses a dictionary for keras hyperparameter optimization. You ha ve to declare the hyperparameters and their boundaries in a python dictionary. \n", + "Warning! Keras optimizer, losses, activation, initializer need to be loaded! \n", + "Note that talos Scan includes an argument called grid_downsampling, which allows a random search. Just to illustrate how to use talos, we've chosen 0.01 " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + " 0%| | 0/23 [00:00<?, ?it/s]\u001b[A\n", + " 4%|▍ | 1/23 [00:09<03:35, 9.80s/it]\u001b[A\n", + " 9%|▊ | 2/23 [00:22<03:44, 10.69s/it]\u001b[A\n", + " 13%|█▎ | 3/23 [00:34<03:41, 11.08s/it]\u001b[A\n", + " 17%|█▋ | 4/23 [00:45<03:32, 11.18s/it]\u001b[A\n", + " 22%|██▏ | 5/23 [00:54<03:05, 10.32s/it]\u001b[A\n", + " 26%|██▌ | 6/23 [01:09<03:18, 11.68s/it]\u001b[A\n", + " 30%|███ | 7/23 [01:17<02:49, 10.61s/it]\u001b[A\n", + " 35%|███▍ | 8/23 [01:30<02:49, 11.28s/it]\u001b[A\n", + " 39%|███▉ | 9/23 [01:37<02:20, 10.07s/it]\u001b[A\n", + " 43%|████▎ | 10/23 [01:44<01:58, 9.11s/it]\u001b[A\n", + " 48%|████▊ | 11/23 [01:56<02:02, 10.20s/it]\u001b[A\n", + " 52%|█████▏ | 12/23 [02:03<01:39, 9.02s/it]\u001b[A\n", + " 57%|█████▋ | 13/23 [02:08<01:19, 7.95s/it]\u001b[A\n", + " 61%|██████ | 14/23 [02:15<01:08, 7.63s/it]\u001b[A\n", + " 65%|██████▌ | 15/23 [02:30<01:18, 9.79s/it]\u001b[A\n", + " 70%|██████▉ | 16/23 [02:37<01:02, 8.94s/it]\u001b[A\n", + " 74%|███████▍ | 17/23 [02:46<00:54, 9.12s/it]\u001b[A\n", + " 78%|███████▊ | 18/23 [02:54<00:43, 8.80s/it]\u001b[A\n", + " 83%|████████▎ | 19/23 [03:03<00:35, 8.78s/it]\u001b[A\n", + " 87%|████████▋ | 20/23 [03:16<00:30, 10.02s/it]\u001b[A\n", + " 91%|█████████▏| 21/23 [03:22<00:17, 8.89s/it]\u001b[A\n", + " 96%|█████████▌| 22/23 [03:37<00:10, 10.59s/it]\u001b[A\n", + "100%|██████████| 23/23 [03:45<00:00, 9.79s/it]\u001b[A" + ] + } + ], + "source": [ + "# HYPERPARAMETER OPTIMIZATION USING TALOS: more complex example\n", + "# We do a random search here (by downsampling among all possible grid values)\n", + "\n", + "# model definition\n", + "def grown_model(x, y, x_val, y_val, params):\n", + " # next we can build the model exactly like we would normally do it\n", + " model = Sequential()\n", + " model.add(Dense(params['first_neuron'], input_dim=x.shape[1],\n", + " activation=params['activation'],\n", + " kernel_initializer=params['kernel_initializer']))\n", + " \n", + " model.add(Dropout(params['dropout']))\n", + " \n", + " # if we want to also test for number of layers and shapes, that's possible\n", + " hidden_layers(model, params, 1)\n", + "\n", + " # then we finish again with completely standard Keras way\n", + " model.add(Dense(1, activation=params['last_activation'],\n", + " kernel_initializer='normal'))\n", + " \n", + " model.compile(loss=params['losses'],\n", + " optimizer=params['optimizer'](lr=lr_normalizer(params['lr'],params['optimizer'])),\n", + " metrics=[acc_pearson_r])\n", + " \n", + " \n", + " out = model.fit(x, y, validation_data=[x_val, y_val], verbose=0,batch_size=params['batch_size'],\n", + " epochs=params['epochs'])\n", + "\n", + " # finally we have to make sure that history object and model are returned\n", + " return out, model\n", + "\n", + "# hyperparameters\n", + "p = {'first_neuron':[32,64],\n", + " 'lr':[0.2,0.5],\n", + " 'batch_size': [30,50],\n", + " 'hidden_layers':[1,2,3,4],\n", + " 'epochs': [100],\n", + " 'dropout': [0, 0.01, 0.1, 0.5],\n", + " 'optimizer': [adam,sgd,Nadam],\n", + " 'losses': [mean_squared_error],\n", + " 'activation':[relu, elu,linear],\n", + " 'last_activation': [None],\n", + " 'shapes': ['brick'], \n", + " 'kernel_initializer':[\"uniform\",\"normal\"]}\n", + "\n", + "# Split the train set into proper train & validation\n", + "X_train0, X_val, y_train0, y_val = train_test_split(X_train, y_train, test_size=0.1)\n", + "X_train0=np.asarray(X_train0)\n", + "X_val=np.asarray(X_val)\n", + "y_train0=np.asarray(y_train0)\n", + "y_val=np.asarray(y_val)\n", + "\n", + "# Example with multiclass target\n", + "# grid_downsample number of combinations to be checked 10% in this example\n", + "tcomp = ta.Scan(x=X_train0,\n", + " y=y_train0,\n", + " x_val=X_val,\n", + " y_val=y_val,\n", + " model=grown_model, \n", + " params=p, \n", + " \n", + " experiment_name='exte_model',\n", + " fraction_limit=0.01)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# HYPERPARAMETER OPTIMIZATION USING TALOS: more complex example\n", + "# Some plotting\n", + "Data=pd.DataFrame(tcomp.data)\n", + "Data[\"val_loss\"] = pd.to_numeric(Data[\"val_loss\"])\n", + "Data[\"acc_pearson_r\"] = pd.to_numeric(Data[\"acc_pearson_r\"])\n", + "Data[\"val_acc_pearson_r\"] = pd.to_numeric(Data[\"val_acc_pearson_r\"])\n", + "#print Data\n", + "#print(Data)\n", + "#write Data\n", + "Data.to_csv(\"mlp_real_world.csv\",index=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Best loss combination:\n", + " round_epochs val_loss val_acc_pearson_r loss acc_pearson_r \\\n", + "4 100 0.577515 0.547202 0.626803 0.616183 \n", + "\n", + " activation batch_size dropout epochs \\\n", + "4 <function elu at 0x7fb79005f730> 50 0.5 100 \n", + "\n", + " first_neuron hidden_layers kernel_initializer last_activation \\\n", + "4 32 3 normal None \n", + "\n", + " losses lr \\\n", + "4 <function mean_squared_error at 0x7fb790032620> 0.2 \n", + "\n", + " optimizer shapes \n", + "4 <class 'keras.optimizers.Adam'> brick \n", + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 720x475.2 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Maximum correlation\n", + "i=Data['val_acc_pearson_r'].argmax()\n", + "print('\\nBest loss combination:')\n", + "print(Data[i:(i+1)],'\\n')\n", + "# talos have a function called reporting, which has implemented some plots \n", + "# reporting to see the best model, draw an histogram\n", + "r = ta.Reporting('mlp_real_world.csv')\n", + "r.plot_hist('val_acc_pearson_r')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.5472017526626587\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsQAAAHPCAYAAABUeszdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3XmYXGd95v279upaet9bvbd2S/Iqr3jBGBuPPTaBjDFDWJIQnIEhCUnmDYTrDW8mCyRhYAIxa4AhJgYCg8HGNnhByJusfd96k9QttdT73l1dXXXeP2QLy7bUW516TlV9P9fFZatVXXXnl3bVraPnPI/LsixLAAAAQI5ymw4AAAAAmEQhBgAAQE6jEAMAACCnUYgBAACQ0yjEAAAAyGkUYgAAAOQ0CjEAAAByGoUYAAAAOY1CDAAAgJxGIQYAAEBOoxADAAAgp1GIAQAAkNOyrhCPjY2ZjpD1mLG9mK/9mLG9mK+9mK/9mLG9nDjfrCvEAAAAwEJQiAEAAJDTKMQAAADIaRRiAAAA5DQKMQAAAHIahRgAAAA5jUIMAACAnEYhBgAAQE6jEAMAACCnUYgBAACQ0yjEAAAAyGkUYgAAAOQ0CjEAAAByGoUYAAAAOY1CDAAAgJxGIQYAAEBOoxADAAAgp1GIAQAAkNO8pgMAAGC3Y73j+s6v2uRxu/SW1RW6qqVU4SAfgQDO4t0AAJCVLMvS1rYBffOpo4rFk7plXYW8bree2nNKDz55RG6XS1evKNUDt69Qnp+PQyCX8Q4AAMg6+44P6a9/uEdVxSHddeUyVRbmnfu9FdX5kqRYPKGtbQP68IMv6asPXKNI0GcqLgDDKMQAgKxyvHdcf/nvu/TRO1aqMOy/4OMCPo/esrpc+Xk+/f6DL+nrD1yj/NCFHw8ge827EG/fvl0///nPNTQ0pPz8fL3//e9XS0uLndkAAFiQgbGY/uhbW/V7b225aBl+rQ0NRfJ63fr9B1/S1x64RkWRgM0pATjNvArxoUOH9Mgjj+j3fu/3VF9fr9HRUbtzAQCwIFMzs/ro11/Wu69tUGVR3tzf8BprlxXI63adK8Wl+UGbUgJwonltu/bYY4/pHe94hxobG+V2u1VYWKjCwkK7swEAMC+JpKU/+dY2vWVNuZZXRRf1HCur8/Wua+r0wFe3KBZPpDghACeb8wpxMpnUiRMntH79ev3VX/2V4vG4NmzYoHe+853y+xe/1mpsbGzR33sx4+PjtjwvfoMZ24v52o8Z2yvd87UsS3//yGFVRL26pCqo6cmJRT9XTb5bG+oievDn+/X7tzalMGXq8PNrP2ZsL1PzjUYv/IflOQvx6OioEomEdu3apU984hPyeDz66le/qieeeEL33HOPLaGWys7nxlnM2F7M137M2F7pnO/Te05pZCqpD9zSnJLne9ulIf3DTw/ovhuXq7o4lJLnTDV+fu3HjO3ltPnOuWTi1avAN998swoKChSJRHTrrbfqwIEDtocDAOBi4omkvvzEYb3r2rqUPafb7dJvX1uvv/mPvSl7TgDONmchDoVCrBcGADjSw8916vKmkpTvIdxcGZUlafOB0yl9XgDONK+b6q699lpt2rRJY2Njmpyc1LPPPqt169bZnQ0AgAsam4rrRy8d11svqbTl+d91TZ3+16MHucEOyAHz2nbtzjvv1Pj4uD7zmc/I5/Pp8ssv1x133GF3NgAALugrvziiW9dVyeed17WdBYvm+XTtyjJ9/amj+u93rrblNQA4w7wKscfj0f3336/777/f7jwAAMypZ2hSLx/t05/fs9bW17lxTYX+6acH9M6r67SsJGzrawEwx54/VgMAYKN/fOSA7rmqVi6Xy9bXcbtceve19frcT/bb+joAzKIQAwAyyoGuYfWPxbSypiAtr9dUEVX/aEw9Q5NpeT0A6UchBgBklH/4yX791tWp22ZtPm66pFLf3dSR1tcEkD4UYgBAxjjYNayAz6Oqory0vu6G+kK9cLhX0zPsOAFkIwoxACBj/NuvO3TTmvK0v67b5dJVzSX62fautL82APtRiAEAGWFsKq7DJ0fUXGnmyNcbVpfrhy8ck2VZRl4fgH0oxACAjPCTl0/o6uWltu8scSGhgFfVxSFtbx8w8voA7EMhBgA4nmVZemTrCV27osxojlsuqdC3nmkzmgFA6lGIAQCOt6N9QDXFIQX9HqM5qotCGpmc0alBtmADsgmFGADgeN/d1K6b11aYjiFJumltpb67qd10DAApRCEGADjawFhMPcPTjjk6eX19oV480scWbEAWoRADABzthy8c0/Urza4dfi23y6WNLSX62Ta2YAOyBYUYAOBYyaSlJ3ef1JXNJaajnOeaFWV6lD2JgaxBIQYAONbmg2e0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\n", + "text/plain": [ + "<Figure size 720x475.2 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(r.high('val_acc_pearson_r'))\n", + "# we can see the distribution of the val_acc parameter chosen \n", + "r.plot_kde('val_acc_pearson_r')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABH4AAAIuCAYAAADJ68/UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3XlcVXX+x/H3vRfhCogLoAkqZKCNaeWWNSmijjpZrpPa4p62aKlJ7qamD7cMM0t/mpVa06JpWqLpWNFiUJbW5FK4JCguMGpGcgWXe35/ON7xBuhhl8vr+Xjw6N7z/Z7P+VwdPoMfvud7LIZhGAIAAAAAAIDHsZZ2AgAAAAAAACgeNH4AAAAAAAA8FI0fAAAAAAAAD0XjBwAAAAAAwEPR+AEAAAAAAPBQNH4AAAAAAAA8FI2fcmLAgAFq1qzZNedZLBa98sorV50TFxcni8Wi5OTkq867//77FR0dnY8si0ZycrIsFovi4uJK/NrXq+nTp+tvf/ubAgICTP3dARJ1ozxLSkrSsGHD9Je//EW+vr6qW7euRowYodOnT5d2arjOUTfKr+PHj6tr166qU6eO7Ha7atasqZ49e2rfvn2lnRquc9QNXNa9e3dTf8/IP6/STgDXl8TERN14442lnQaK2JIlSxQREaE2bdroo48+Ku104GGoG55ny5Yt+vrrr/XEE0/o1ltv1a+//qpJkyYpMTFR33zzjaxWfm+EwqFueB6Hw6GqVatq+vTpCgsL0/HjxzVz5ky1bdtWO3fuVJUqVUo7RZRx1A3P9q9//UuJiYmlnYbHovEDN3feeWdpp+BxDMNQdna27HZ7qeVw6NAhWa1WxcXF0fhBkaNuFL3SrhsPPvighg0bJovFIkmKjo5WrVq11LFjR3311Vdq3bp1qeQFz0HdKHqlXTfq1q2r5cuXux1r2rSp6tWrp88++0w9evQolbzgOagbRa+068Zl58+f14gRIzRjxgwNHjy4VHPxVPzKrpzZsmWLbr31Vvn5+ally5bavXu32/ifl9YZhqGpU6eqevXqqlSpkvr166eMjIwccQ8fPqxOnTqpYsWKCg8P12uvvZbr9Xft2qV7771XlSpVUqVKldSzZ08dP37cNf7555/LYrHo888/V8+ePeXv76+6detq0aJFhfrcb775plq2bKlq1aqpatWqatOmjb7//nvX+MaNG2W1WnXw4EG38w4ePCir1aoPP/zQdezDDz9Us2bNZLfbdcMNN2jMmDE6f/68a3zq1KkKCgrS1q1b1bx5c9ntdr3//vs6f/68nnnmGdWpU0c+Pj4KCQlR9+7dde7cuUJ9NjP47TwKg7pR/upGYGCgq+lzWePGjSVJR48eLdZrwzNQN8pf3chNYGCgJJXKtVH2UDfKb9146aWXVLFiRQ0cOLBErlce8a/BcuTQoUMaPXq0Jk6cqHfffVfp6enq3bu3DMPI85wFCxZo2rRpevTRR7V69WpVrFhRY8aMcZtjGIa6du2qXbt26fXXX9e8efP00ksv5Viqt3//ft19993KysrSP//5Ty1fvly7d+9W586dc+QwZMgQ3XbbbVq7dq2io6M1bNgwbdu2rcCfPTk5Wf369dP777+vd955R7Vr11arVq3066+/SpI6duyokJAQrVixwu285cuXq3r16rr33nslSatWrVKPHj10xx136KOPPtKUKVP06quvavz48W7nORwO9e/fX4MHD9amTZt0xx13aNasWXr77bc1ffp0bdmyRfPnz1flypV18eLFPPM2DEMXLly45hdQXKgb1I3LLv/d1KtXL9/nonyhbpTvuuF0OnX+/HmlpKRoxIgRCgsLc30uIC/UjfJbN44fP67p06dr/vz5/LK6OBkoF/r372/YbDZj7969rmNr1641JBk///yz65gk4+WXXzYMwzAuXLhg1KxZ03j88cfdYv3tb38zJBkHDx40DMMwNmzYYEgyvvnmG9ec5ORkw2azGa1bt3Yd69Onj1GvXj0jOzvbdWzv3r2G1Wo14uLiDMMwjPj4eEOS8eyzz7rmnDt3zggKCjLGjh1r6rMePHjQkGSsX78+1/GLFy8a58+fN+rXr28899xzruMTJ040wsPDDafTaRiGYTidTiMsLMyIiYlxva9Tp44xYMAAt3ivv/66YbfbjRMnThiGYRhTpkwxJBnr1q1zm3fvvfcao0aNMvUZLlu2bJkh6ZpfZq1fv97t7w64GurG/5TnumEYhpGZmWncfPPNbn83QG6oG/9TXuvGY4895ppft25dt/8tALmhbvxPeawbffv2NXr27Ol6f+XfM4oOLbVyJDw8XJGRka73DRo0kCSlpqbmOv/w4cM6duyYunbt6nb8z/dob9u2TTVq1FCLFi1cx8LC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c+fmGcf0rV4Wi0UXL17MdczpdMpiseT/UwAAAAAAACCHJ598UpmZmerfv7/sdrvbWGpqql577TU99dRTkqQWLVrkGcd046dNmzZ69tln1bx5c4WFhbmOp6SkaPLkyWrXrl1+PwMAAAAAAABysXPnTsXFxbke4X6lbdu26bXXXtPkyZOvGcd042f+/Plq27atIiMj1aRJE9WoUUPp6enavn27ateurXnz5uXvEwAAAAAAACBXDodD/v7+eY6bvfPKdOMnPDxcv/zyi9544w199913OnbsmBo0aKCBAwdqwIAB8vb2NhuqXHI6nTp16pSys7NLOxXguuDj46Nq1arJajW91RgAAAAAeKTjx49ryZIlmjx5squhEx8fr/r16+c6v0GDBqb3WrYYhmEUWaZlnMViUXH9cWRkZGj27NnFEhsoq8aNG6eAgIDSTqNQirNuAPBMxV03Lv/MMeD+7vL39S226wDXuzMOh5avXusRP29I/MwBeLodO3aoWbNmOn/+vGw2W5HGNr3iJz09XZmZma7HhRmGoaVLl2rPnj1q166dOnfuXKSJeRp/f3+NGjWKFT/Af/n4+Fx12SIAAAAAoPBMN34GDBigiIgILViwQJI0efJkzZo1SxEREXrllVf02muvacCAAcWVZ5lntVoVFBRU2mkAAAAAAIByxPTmGjt27FDbtm0lXdqvZvHixZo5c6Z++eUXTZw4UfPnzy+2JAEAAAAAAJB/phs/v//+uwIDAyVJ27dv16lTp/Twww9Lktq2bav9+/cXT4YAAAAAAAAoENONn1q1amnPnj2SpA0bNujmm29WaGiopEtNIbvdXjwZAgAAAAAAoEBM7/EzaNAgjR49Wp988ok2bNigWbNmuca++eYb/eUvfymWBAEAAAAAADzd5ce4FzXTjZ/x48erVq1a2rZtm15++WUNGjTINXbq1CkNHjzY9EW3bt2qxMREeXl5qW/fvjk2PT579qwmT56sBx98UE2aNJHT6dTKlSt19OhRVa5cWf369ZO3t7fp6wEAAAAAAFyv6tevr/j4+CJ/lLtksvGTnZ2tF154Qffdd5/69u2bY3zx4sWmL5iZmamEhATFxMTo8OHDWrduXY6m0SeffKLw8HDX+927d8tisSgmJkZbtmxRYmKiWrdubfqaAAAAAAAA1ys/Pz9FRUW5HXvuueeueo5hGJo6deo1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\n", + "text/plain": [ + "<Figure size 1152x576 with 8 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import seaborn as sns\n", + "# You also can use seaborn to check other combination of parameters\n", + "sns.set_context(\"paper\", rc={\"font.size\":15,\"axes.titlesize\":15,\"axes.labelsize\":15}) \n", + "g = sns.FacetGrid(tcomp.data, col=\"hidden_layers\",row=\"first_neuron\", margin_titles=True,height=4)\n", + "g.map(sns.boxplot,\"lr\",\"val_acc_pearson_r\", palette=sns.cubehelix_palette(8),saturation=.5);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, use Deploy() to save and transfer the results of your \"star\" model " + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deploy package the_real_word_experiment have been saved.\n" + ] + }, + { + "data": { + "text/plain": [ + "<talos.commands.deploy.Deploy at 0x7fb6f80a7a90>" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from talos import Deploy\n", + "\n", + "Deploy(tcomp, 'the_real_word_experiment',metric='val_acc_pearson_r',asc=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "N / class\n", + "Test [91, 321, 67]\n", + "Train [30, 83, 6]\n", + "All [121, 404, 73]\n", + "120/120 [==============================] - 0s 523us/step\n", + "\n", + "MSE in prediction = 1.8882378339767456\n", + "\n", + "Probabilities matrix\n", + " [[2.69096762e-01 6.29787683e-01 1.01074547e-01 4.10420907e-05]\n", + " [8.95286202e-02 8.15132022e-01 9.53183770e-02 2.10014132e-05]\n", + " [2.16145217e-01 6.68324649e-01 1.15473352e-01 5.67840725e-05]\n", + " [4.67411563e-04 2.20375791e-01 7.79125273e-01 3.15680081e-05]]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 2 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# MLP example with multiclass target\n", + "\n", + "# Let us round class vector and make a few classes, all positive numbers\n", + "# just a trick to convert to classes\n", + "yi_train=[int(round(x-np.min(y_train))/2) for x in y_train]\n", + "yi_test=[int(round(x-np.min(y_test))/2) for x in y_test]\n", + "\n", + "# N obs / clas; this may result in some very rare classes so consider merging\n", + "print('N / class')\n", + "print('Test ',[yi_train.count(i) for i in range(max(yi_train+yi_test))])\n", + "print('Train ',[yi_test.count(i) for i in range(max(yi_train+yi_test))])\n", + "print('All ',[(yi_test+yi_train).count(i) for i in range(max(yi_train+yi_test))])\n", + "# WARNING: make sure all clases in test are in train!!\n", + "\n", + "# convert to classes, i need to make all classes equivalent\n", + "n_train=len(yi_train)\n", + "itemp = to_categorical(yi_train+yi_test)\n", + "i_train = itemp[:n_train,:]\n", + "i_test = itemp[n_train:,:]\n", + "\n", + "# no. of SNPs in data\n", + "nSNP=X_train.shape[1]\n", + "nClasses=i_train.shape[1]\n", + "\n", + "# Instantiate\n", + "model = Sequential()\n", + "\n", + "# Add first layer\n", + "model.add(Dense(64, input_dim=nSNP))\n", + "model.add(Activation('relu'))\n", + "# Add second layer\n", + "model.add(Dense(32))\n", + "model.add(Activation('softplus'))\n", + "# Last, output layer\n", + "model.add(Dense(nClasses, activation='softmax'))\n", + "\n", + "# Model Compiling \n", + "model.compile(loss='categorical_crossentropy', optimizer='adam')\n", + "\n", + "# training\n", + "model.fit(X_train, i_train, epochs=100, verbose=0)\n", + "\n", + "# cross-validation: get predicted target values\n", + "i_hat = model.predict(X_test, batch_size=128)\n", + "\n", + "mse_prediction = model.evaluate(X_test, i_test, batch_size=128)\n", + "print('\\nMSE in prediction =',mse_prediction)\n", + "\n", + "# do a heatplot, obs vs expected class distribution\n", + "# collect all results by class\n", + "# compute average prediction by class\n", + "heat = np.zeros([nClasses,nClasses])\n", + "for i in range(nClasses):\n", + " iclass = np.nonzero(i_test[:,i]>0) # samples of i-th class\n", + " for j in range(nClasses):\n", + " heat[i,j] = np.mean(i_hat[iclass,j])\n", + "\n", + "# plot observed vs. predicted targets\n", + "print('\\nProbabilities matrix\\n',heat)\n", + "plot = sns.heatmap(heat, cmap=\"Blues\")\n", + "plot.set(xlabel='Observed class', ylabel='Predicted class')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "conv1d_1 (Conv1D) (None, 57, 32) 128 \n", + "_________________________________________________________________\n", + "max_pooling1d_1 (MaxPooling1 (None, 28, 32) 0 \n", + "_________________________________________________________________\n", + "flatten_1 (Flatten) (None, 896) 0 \n", + "_________________________________________________________________\n", + "dense_4 (Dense) (None, 64) 57408 \n", + "_________________________________________________________________\n", + "activation_3 (Activation) (None, 64) 0 \n", + "_________________________________________________________________\n", + "dense_5 (Dense) (None, 32) 2080 \n", + "_________________________________________________________________\n", + "activation_4 (Activation) (None, 32) 0 \n", + "_________________________________________________________________\n", + "dense_6 (Dense) (None, 1) 33 \n", + "=================================================================\n", + "Total params: 59,649\n", + "Trainable params: 59,649\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n", + "120/120 [==============================] - 0s 750us/step\n", + "\n", + "MSE in prediction = 0.9081454873085022\n", + "\n", + "Corr obs vs pred = 0.45705769571247923\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#--> CNN example\n", + "\n", + "nSNP=X_train.shape[1] \n", + "nStride=3 # stride between convolutions\n", + "nFilter=32 # no. of convolutions\n", + "\n", + "# Instantiate\n", + "model_cnn = Sequential()\n", + "\n", + "#WARNING!!! I need this to match dimensions \n", + "#https://stackoverflow.com/questions/43396572/dimension-of-shape-in-conv1d\n", + "X2_train = np.expand_dims(X_train, axis=2) \n", + "X2_test = np.expand_dims(X_test, axis=2) \n", + "\n", + "# add convolutional layer\n", + "model_cnn.add(Conv1D(nFilter, kernel_size=3, strides=nStride, input_shape=(nSNP,1)))\n", + "# add pooling layer: takes maximum of two consecutive values\n", + "model_cnn.add(MaxPooling1D(pool_size=2))\n", + "# Solutions above are linearized to accommodate a standard layer\n", + "model_cnn.add(Flatten())\n", + "model_cnn.add(Dense(64))\n", + "model_cnn.add(Activation('relu'))\n", + "model_cnn.add(Dense(32))\n", + "model_cnn.add(Activation('softplus'))\n", + "model_cnn.add(Dense(1))\n", + "\n", + "# Model Compiling (https://keras.io/models/sequential/) \n", + "model_cnn.compile(loss='mean_squared_error', optimizer='sgd')\n", + "\n", + "# list some properties\n", + "model_cnn.summary()\n", + "\n", + "# training\n", + "model_cnn.fit(X2_train, y_train, epochs=200, verbose=0)\n", + "\n", + "# cross-validation\n", + "mse_prediction = model_cnn.evaluate(X2_test, y_test, batch_size=128)\n", + "print('\\nMSE in prediction =',mse_prediction)\n", + "\n", + "# get predicted target values\n", + "y_hat = model_cnn.predict(X2_test, batch_size=128)\n", + "\n", + "# correlation btw predicted and observed\n", + "corr = np.corrcoef(y_test,y_hat[:,0])[0,1]\n", + "print('\\nCorr obs vs pred =',corr)\n", + "\n", + "# plot observed vs. predicted targets\n", + "plt.title('MLP: Observed vs Predicted Y')\n", + "plt.ylabel('Predicted')\n", + "plt.xlabel('Observed')\n", + "plt.scatter(y_test, y_hat, marker='o')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(479, 173)\n" + ] + } + ], + "source": [ + "print(X_train.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "lstm_1 (LSTM) (None, None, 32) 4352 \n", + "_________________________________________________________________\n", + "dropout_1 (Dropout) (None, None, 32) 0 \n", + "_________________________________________________________________\n", + "lstm_2 (LSTM) (None, None, 64) 24832 \n", + "_________________________________________________________________\n", + "dropout_2 (Dropout) (None, None, 64) 0 \n", + "_________________________________________________________________\n", + "lstm_3 (LSTM) (None, 64) 33024 \n", + "_________________________________________________________________\n", + "dropout_3 (Dropout) (None, 64) 0 \n", + "_________________________________________________________________\n", + "dense_7 (Dense) (None, 1) 65 \n", + "_________________________________________________________________\n", + "activation_5 (Activation) (None, 1) 0 \n", + "=================================================================\n", + "Total params: 62,273\n", + "Trainable params: 62,273\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "#--> RNN example\n", + "\n", + "nSNP=X_train.shape[1] \n", + "\n", + "#-->data shape\n", + "X2_train = np.expand_dims(X_train, axis=2) \n", + "X2_test = np.expand_dims(X_test, axis=2) \n", + "\n", + "# Instantiate\n", + "model_cnn = Sequential()\n", + "\n", + "# Instantiate\n", + "model = Sequential()\n", + "model.add(LSTM(32,return_sequences=True,input_shape=(None,1), activation=\"tanh\"))\n", + "model.add(Dropout(0.1))\n", + "model.add(LSTM(64, return_sequences=True, activation=\"tanh\"))\n", + "model.add(Dropout(0.1))\n", + "model.add(LSTM(64, activation=\"tanh\"))\n", + "model.add(Dropout(0.1))\n", + "model.add(Dense(units=1))\n", + "model.add(Activation(\"tanh\"))\n", + "model.compile(optimizer=\"adam\",loss=mean_squared_error, metrics=['mae'])\n", + "model.summary()\n", + "\n", + "model.fit(X2_train, y_train, epochs=200, verbose=0)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# cross-validation\n", + "mse_prediction = model.evaluate(X2_test, y_test, batch_size=128)\n", + "print('\\nMSE in prediction =',mse_prediction)\n", + "\n", + "# get predicted target values\n", + "y_hat = model.predict(X2_test, batch_size=128)\n", + "\n", + "# correlation btw predicted and observed\n", + "corr = np.corrcoef(y_test,y_hat[:,0])[0,1]\n", + "print('\\nCorr obs vs pred =',corr)\n", + "\n", + "# plot observed vs. predicted targets\n", + "plt.title('MLP: Observed vs Predicted Y')\n", + "plt.ylabel('Predicted')\n", + "plt.xlabel('Observed')\n", + "plt.scatter(y_test, y_hat, marker='o')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# save and reuse model\n", + "from keras.models import load_model\n", + "\n", + "# creates a HDF5 file 'my_model.h5'\n", + "model.save('my_model.h5') \n", + "\n", + "# deletes the existing model\n", + "del model\n", + "\n", + "# loads a compiled model, identical to the previous one\n", + "model = load_model('my_model.h5')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}