{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Encoder-Decoder model for ENSO-forecasting\n", "\n", "The Encoder-Decoder model is enspired by the architecture of autoencoders. Here, the size of the input layer of the neural network is the same size as the output layer. Furthermore, there is a so-called bottleneck layer present in the network which has less neurons than the input/output layers. For an Autoencoder the label and feature are the same. Because of the bottleneck layer, the network is forced to learn a lower dimesional expression of the input\n", "\n", "For the Encoder-Decoder model (DEM), a time lag between the feature and the label is introduced. Such that the DEM is a forecast model. Hence, the DEM is forced to learn a lower dimensional expression that explains best the future state of the considered variable field.\n", "\n", "\"Drawing\"\n", "\n", "In this tutorial, the considered variable field is again the SST anomaly data from the ERSSTv5 data set." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Read data \n", "\n", "In the following cell, we read the SST anoamly data that was computed in an earlier tutorial." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/xarray/core/nanops.py:160: RuntimeWarning: Mean of empty slice\n", " return np.nanmean(a, axis=axis, dtype=dtype)\n" ] } ], "source": [ "from ninolearn.IO.read_processed import data_reader\n", "\n", "#read data\n", "reader = data_reader(startdate='1959-11', enddate='2018-12')\n", "\n", "# read SST data and directly make seasonal averages\n", "SSTA = reader.read_netcdf('sst', dataset='ERSSTv5', processed='anom').rolling(time=3).mean()[2:]\n", "\n", "# read the ONI for later comparison\n", "oni = reader.read_csv('oni')[2:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generate the feature and label arrays\n", "\n", "The following cell generates the feature and label arrays. Because `feature` and `label` need to refer to an other object in the backend so that they can be changed without influencing each other.\n", "\n", "Moreover, the data is scalled because this helps the DEM to be more precise." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", " return f(*args, **kwds)\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", " return f(*args, **kwds)\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/sklearn/utils/extmath.py:747: RuntimeWarning: invalid value encountered in true_divide\n", " updated_mean = (last_sum + new_sum) / updated_sample_count\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/sklearn/utils/extmath.py:688: RuntimeWarning: Degrees of freedom <= 0 for slice.\n", " result = op(x, *args, **kwargs)\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/sklearn/utils/extmath.py:747: RuntimeWarning: invalid value encountered in true_divide\n", " updated_mean = (last_sum + new_sum) / updated_sample_count\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/sklearn/utils/extmath.py:688: RuntimeWarning: Degrees of freedom <= 0 for slice.\n", " result = op(x, *args, **kwargs)\n" ] } ], "source": [ "from sklearn.preprocessing import StandardScaler\n", "import numpy as np\n", "\n", "# make deep copies of the sst data\n", "feature = SSTA.copy(deep=True)\n", "label = SSTA.copy(deep=True)\n", "\n", "# reshape the data such that one time step is a 1-D vector\n", "# i.e. the feature_unscaled array is hence 2-D (timestep, number of grid points)\n", "feature_unscaled = feature.values.reshape(feature.shape[0],-1)\n", "label_unscaled = label.values.reshape(label.shape[0],-1)\n", "\n", "# scale the data\n", "scaler_f = StandardScaler()\n", "Xorg = scaler_f.fit_transform(feature_unscaled)\n", "\n", "scaler_l = StandardScaler()\n", "yorg = scaler_l.fit_transform(label_unscaled)\n", "\n", "# replace nans with 0\n", "Xall = np.nan_to_num(Xorg)\n", "yall = np.nan_to_num(yorg)\n", "\n", "# shift = 3 is needed to align with the usual way how lead time is defined\n", "shift = 3\n", "\n", "# the lead time\n", "lead = 3\n", "\n", "y = yall[lead+shift:]\n", "X = Xall[:-lead-shift]\n", "timey = oni.index[lead+shift:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Split the data set \n", "\n", "For the training and testing of machine learning models it is crucial to split the data set into:\n", "\n", "1. __Train data set__ which is used to train the weights of the neural network\n", "\n", "2. __Validation data set__ which is used to check for overfitting (e.g. when using early stopping) and to optimize the hyperparameters \n", "\n", "3. __Test data set__ which is used to to evaluate the trained model. \n", "\n", "__NOTE:__ It is important to understand that hyperparamters must be tuned so that the result is best for the Validation data set and __not__ for the test data set. Otherwise you can not rule out the case that the specific hyperparameter setting just works good for the specific test data set but is not generally a good hyperparameter setting.\n", "\n", "In the following cell the train and the validation data set are still one data set, because this array will be later splitted into two arrays when th model is fitted." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "test_indeces = test_indeces = (timey>='2001-01-01') & (timey<='2018-12-01')\n", "train_val_indeces = np.invert(test_indeces)\n", "\n", "train_val_X, train_val_y, train_val_timey = X[train_val_indeces,:], y[train_val_indeces,:], timey[train_val_indeces]\n", "testX, testy, testtimey = X[test_indeces,:], y[test_indeces,:], timey[test_indeces]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fit the model\n", "\n", "Let's train the model using a random search. This takes quite some time (for `n_iter=100` it took an hour on my local machine without GPU support). In this training process the train/validation data set will be splitted In this example below this train/validation data is first divided into 5 segments (`n_segments=5`). One segment alwawys serves as the validation data set and the rest as training. Each segment is one time (`n_members_segment=1`) the validation data set. Hence, the ensemble consists in the end out of 5 models." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 88 from C header, got 96 from PyObject\n", " return f(*args, **kwds)\n", "Using TensorFlow backend.\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 216, got 192\n", " return f(*args, **kwds)\n", "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", " return f(*args, **kwds)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "##################################################################\n", "Search iteration Nr 1/100\n", "##################################################################\n", "\n", "Train member Nr 1/5\n", "--------------------------------------\n", "WARNING:tensorflow:From /home/paul/miniconda2/envs/ninolearn/lib/python3.6/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", "WARNING:tensorflow:From /home/paul/miniconda2/envs/ninolearn/lib/python3.6/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", "WARNING:tensorflow:From /home/paul/miniconda2/envs/ninolearn/lib/python3.6/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", "Restoring model weights from the end of the best epoch\n", "Epoch 00144: early stopping\n", "97/97 [==============================] - 0s 385us/step\n", "Loss: 0.594995876562964\n", "Train member Nr 2/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00066: early stopping\n", "97/97 [==============================] - 0s 356us/step\n", "Loss: 0.8159599267330366\n", "Train member Nr 3/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00105: early stopping\n", "97/97 [==============================] - 0s 405us/step\n", "Loss: 0.5462328782401134\n", "Train member Nr 4/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00063: early stopping\n", "97/97 [==============================] - 0s 299us/step\n", "Loss: 0.5024169173437295\n", "Train member Nr 5/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00183: early stopping\n", "97/97 [==============================] - 0s 331us/step\n", "Loss: 0.8275724508098721\n", "Mean loss: 0.6574356099379431\n", "New best hyperparameters\n", "--------------------------------------\n", "Mean loss: 0.6574356099379431\n", "{'neurons': (377, 64), 'dropout': 0.17748694048962252, 'noise': 0.03505773761882175, 'noise_out': 0.3952481502079784, 'l1_hidden': 0.0009036151723019773, 'l2_hidden': 0.0005879437425613628, 'l1_out': 0.0007628003918528734, 'l2_out': 0.0007007246175814432, 'lr': 0.009096045351913332, 'batch_size': 100}\n", "\n", "##################################################################\n", "Search iteration Nr 2/100\n", "##################################################################\n", "\n", "Train member Nr 1/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00102: early stopping\n", "97/97 [==============================] - 0s 362us/step\n", "Loss: 0.5652457008656767\n", "Train member Nr 2/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00089: early stopping\n", "97/97 [==============================] - 0s 280us/step\n", "Loss: 0.7114116641664013\n", "Train member Nr 3/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00082: early stopping\n", "97/97 [==============================] - 0s 315us/step\n", "Loss: 0.5489584788219216\n", "Train member Nr 4/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00088: early stopping\n", "97/97 [==============================] - 0s 240us/step\n", "Loss: 0.49401161228258583\n", "Train member Nr 5/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00087: early stopping\n", "97/97 [==============================] - 0s 223us/step\n", "Loss: 0.6976618815943137\n", "Mean loss: 0.6034578675461798\n", "New best hyperparameters\n", "--------------------------------------\n", "Mean loss: 0.6034578675461798\n", "{'neurons': (376, 42), 'dropout': 0.18913376771171697, 'noise': 0.28026741526557086, 'noise_out': 0.1229727047756281, 'l1_hidden': 0.000651087924120019, 'l2_hidden': 3.58935132779703e-06, 'l1_out': 0.0002169064123443609, 'l2_out': 0.000934985065019076, 'lr': 0.005925022913261249, 'batch_size': 100}\n", "\n", "##################################################################\n", "Search iteration Nr 3/100\n", "##################################################################\n", "\n", "Train member Nr 1/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00075: early stopping\n", "97/97 [==============================] - 0s 262us/step\n", "Loss: 0.5696860170855964\n", "Train member Nr 2/5\n", "--------------------------------------\n", "Restoring model weights from the end of the best epoch\n", "Epoch 00071: early stopping\n", "97/97 [==============================] - 0s 282us/step\n", "Loss: 0.7966842565339866\n", "Train member Nr 3/5\n", "--------------------------------------\n" ] } ], "source": [ "import keras.backend as K\n", "from ninolearn.learn.models.encoderDecoder import EncoderDecoder\n", "\n", "K.clear_session()\n", "\n", "model = EncoderDecoder()\n", "\n", "model.set_parameters(neurons=[(32, 8), (512, 64)], dropout=[0., 0.2], noise=[0., 0.5] , noise_out=[0., 0.5],\n", " l1_hidden=[0.0, 0.001], l2_hidden=[0.0, 0.001], l1_out=[0.0, 0.001], l2_out=[0.0, 0.001], batch_size=100,\n", " lr=[0.0001, 0.01], n_segments=5, n_members_segment=1, patience = 40, epochs=1000, verbose=0)\n", "\n", "model.fit_RandomizedSearch(train_val_X, train_val_y, n_iter=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Make predictions on the test data set" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import xarray as xr\n", "\n", "# make prediction\n", "pred, pred_all_members = model.predict(testX)\n", "test_label = scaler_l.inverse_transform(testy)\n", "\n", "# reshape data into an xarray data array that is 3-D\n", "pred_map = xr.zeros_like(label[lead+shift:,:,:][test_indeces])\n", "pred_map.values = scaler_l.inverse_transform(pred).reshape((testX.shape[0], label.shape[1], label.shape[2]))\n", "\n", "test_label_map = xr.zeros_like(label[lead+shift:,:,:][test_indeces])\n", "test_label_map.values = test_label.reshape((testX.shape[0], label.shape[1], label.shape[2]))\n", "\n", "# calculate the ONI\n", "pred_oni = pred_map.loc[dict(lat=slice(-5, 5), lon=slice(190, 240))].mean(dim=\"lat\").mean(dim='lon')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot prediction for the ONI" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/paul/miniconda2/envs/ninolearn/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py:102: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.\n", "\n", "To register the converters:\n", "\t>>> from pandas.plotting import register_matplotlib_converters\n", "\t>>> register_matplotlib_converters()\n", " warnings.warn(msg, FutureWarning)\n" ] } ], "source": [ "import matplotlib.pyplot as plt\n", "# Plot ONI Forecasts\n", "plt.subplots(figsize=(8,1.8))\n", "\n", "plt.plot(testtimey, pred_oni, c='navy')\n", "plt.plot(testtimey, oni.loc[testtimey[0]: testtimey[-1]], \"k\")\n", "\n", "plt.xlabel('Time [Year]')\n", "plt.ylabel('ONI [K]')\n", "\n", "plt.axhspan(-0.5, -6, facecolor='blue', alpha=0.1,zorder=0)\n", "plt.axhspan(0.5, 6, facecolor='red', alpha=0.1,zorder=0)\n", "\n", "plt.xlim(testtimey[0], testtimey[-1])\n", "plt.ylim(-3,3)\n", "\n", "plt.title(f\"Lead time: {lead} month\")\n", "plt.grid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluate the seasonal skill for predicting the ONI" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from ninolearn.plot.evaluation import plot_correlation\n", "import pandas as pd\n", "\n", "# make a plot of the seasonal correaltion\n", "# note: - pd.tseries.offsets.MonthBegin(1) appears to ensure that the correlations are plotted\n", "# agains the correct season\n", "\n", "plot_correlation(oni.loc[testtimey[0]: testtimey[-1]], pred_oni, testtimey - pd.tseries.offsets.MonthBegin(1), title=\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Check the correlations on a map\n", "\n", "In the following the pearson correlation coefficent between the predicted and the observed value for each grid point are computed and afterwards plotted." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# rehshape predictions to a map\n", "corr_map = np.zeros(pred.shape[1])\n", "\n", "for j in range(len(corr_map)):\n", " corr_map[j] = np.corrcoef(pred[:,j], test_label[:,j])[0,1]\n", "corr_map = corr_map.reshape((label.shape[1:]))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW8AAACcCAYAAACwTSoXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO2dd9RkR3Xgf7fDFycH5TAEIUCAgklefHZFtJA5xuwxNogFxMEIvCIY5BUC1sIGfCwwYNICKxAIMMFkBAeDZS0Y74LAM0JpJJRHAY00yjPzhY53/+g3mq5b9fV7X+zu0f2d8873Vb2qeveFrn59b917RVVxHMdxhotSvwVwHMdx5o9P3o7jOEOIT96O4zhDiE/ejuM4Q4hP3o7jOEOIT96O4zhDiE/ezpyIyBYRURGpFGx/lIjsFZHycss2zIjIDhF5Xr/lcIYbn7yHlEGYAKwMqnqbqq5S1VYfZPmAiNwuIrtF5FYReddKy5BCRC4Ukff1Ww7nwMMnb+dA4QLg8aq6BvhPwGki8l/7LJPjLBs+eR+AiMiLRORyEXlQRH4uIk/p2neOiNwkIntE5BoReUnXvrKIfFBE7hWRm4E/6HGMLwFHAd/PVCVnWzWLiPxURN6XybBXRL4vIhtF5MvZG/J/iMiWrjEfLyIXi8j9InKdiPxJ0XNW1etUdaqrqg08dg7ZTxaROzKZd4nIThH5IxE5VUSuz47/zq72oyLyERG5M9s+IiKjZqyzusZ6TbbvDOAVwNn7zr9LjBNE5EoReUhE/klExoqeq+MAoKq+DeEG7ACel6g/CdgFPAMoA6/O2o5m+18KHEbni/tPgSng0GzfG4DfAEcCG4CfAApUisgAbOluD/wUuBF4DLAWuAa4HngeUAG+CHw+azsJ3A68Jtt3EnAvcFy2/zTgypxrcg6wN5PhZuCIOdqdDDSBc4Eq8DrgHuArwGrgOGAWeHTW/j3ApcBBwGbg58B7zVjvycY6FZgG1mf7LwTel7huv8ruwwbgWuAN/X6mfBuuzd+8DzxeB/xvVf2lqrZU9QtADXgmgKp+Q1XvVNW2qv4TcAPw9KzvnwAfUdXbVfV+4O+WQJ7Pq+pNqvoQ8M/ATar6r6raBL4BnJi1exGwQ1U/r6pNVb0M+Bbwx5ncX1HVp6QOsA9VPY/O5HsS8CXgoR7NG8DfqmoD+BqwCfioqu5R1e3AdmDf8V4BvEdVd6nqPcDfAK80Y71HVRuq+kM6XyDH5lyXj2X34X7g+8AJOe0dJ8An7wOPo4GzMpXJgyLyIJ036cMARORVXSqVB4En0Zm4yNrc3jXWrUsgz91d/88kyqu65H6GkfsVwCHzOZh2+HU29t/0aHqf7jeszswh6z7ZDiO8Frdmdd1jNbvK01195+KuebZ3nIBCS8CcoeJ2Om+Uf2t3iMjRwGeA5wK/UNWWiFwOSNZkJ52Jfh9H5RxrKUNS3g78m6o+f4nGq9BR1ywFd9L5ctmelY/K6orgYTudZcHfvIebqoiMdW0VOpPzG0TkGdJhUkT+QERW09ErKx39Lplh7Uld430deLOIHCEi6+nokHtxN/DoJTqXHwCPE5FXikg1254mIk/I6ygiJRF5vYisz8756cCZwCVLJNtXgf8pIptFZBMdXfk/Fuy7lNfIcR7GJ+/h5od0ft7v2/5aVbfS0Xt/AniAjsHwdABVvQb4EPALOpPKk4H/1zXeZ4AfA1cAlwHfzjn+39GZ1B4Ukb9czImo6h7gBcDL6LzV3gW8H9i3quMVIrJ97hF4CXATsIfOxPrxbFsK3gdsBa4ErqJzbYqu3b4AeGJ2jb67RPI4DqLqv+ocx3GGDX/zdhzHGUJ88nYcx1lmRORzmRPX1XPsFxH5mIjcmDlvnZQ3pk/ejuM4y8+FwCk99r8QOCbbzgA+lTegT96O4zjLjKr+DLi/R5MXA1/M/BQuBdaJyKG9xvTJ23Ecp/8cTuggd0dWNycr6qSzadMm3bJly8Pl7b+9O2qjYipMWdrxuHl9UthxJBHEtNQwbRawMkeliDC2kzlOYgw1X7vRNShwnKhP4qt8Idc2HiRfFttGUn1sG3sPE89GqRF2Ks02g7I2zE1OHEgq8cdER6tBuTEZXrx2uLszzkgoYKmU/zy1WuZCteyNj/s8+aCDc8ftF9dvuzkoP+534iXwN1xxW1DWZnjPUn0s27Ztu1dVNy9AxJ78/rMn9b77w8li25W17XRi4ezjfFU9f55Dpz5ZPR+QFZ28t2zZwtatWx8uP+Fd/xC1aY+EZTtJlWeJsB8UrZhzTsxsdpzRB+LrNLkr/LCVZ+1sEctiL3drLP/HjRWv1AoHaVfiAzUmwnFb5rqlbruau90cD8dtJeLatU2f9kg8cN4EX2okLpStMpe2XIu72C/T6lQoS2U67jOxK+w0cd2uoNz67V1EqLnvmzZGTerHHhaU73r6eFCePjT+JqkcHgo4MVaPj23YOxXelNb9o0FZmvG13frms3LH7RfPr7wsKF+89WtRm1MOPTMot+4O79nFW7+RexwRWYrQDhH33t/k5z8KX4jHDrtlVlWfusih7yD0bj6CHC9eV5s4juMURIEmrWBbIi4CXpWtOnkm8JCq7uzVwWObOI7jFERRGprQz+UgIl+lEz54k4jcAbybTghhVPXTdLylT6XjET1NJzRyT/o6eaf0mpGaxPx8rk4RYdUmrdHwp6QdE6BsfrGWmnGbtsnEWDHqjHI9vonSCOsq0+HBpZVQOxi1iDSN2mQkPoFSMxSuadQzKR14a8QqvY0+OPETvFwL2zQm4jYl8/Jhr7fVO3fGDcvV6bDNyJ74jab6UKgCqd69O2xw/4NRn9b9DwTl9ioTvO+EOHLrg8dOBuWpw+Lrb9UipYNDlcjkRKz3WT2W0AV1y9pOHKccHqc5aXT29bjPli+FkXwrI+G1bN4T68d2vHFR0Q3m5IWPDlU4lS1HBuVTjn173GkmoRvt4vmlly5aroXSBmYXkOVPVV+es1/pxOMpjL95O47jFERRGgMSKNInb8dxnIKoQuKHZF/wydtxHKcgijCb0sP2AZ+8HcdxCqJAwyfvYmt5o3I9/s0ibWPwM3ZEa3gEKM+YckoWY8RsV8ObVq4lDJbWkaRmjBupJc+2SdOMq/EJ2KXf1iiYWhsu9qEzzj/WOAlQmQ3rxu+Lz9nek/Jsq2cZoPpAeANkd2iJbj8Yp5/Uemhllg3rg3Lj2NAYBrDn6McF5b2Hh9dgJrEeu7XBGEbHY0eeDatCo9qasbDcLuA1NVUPF+e32nGfSsUYGyvhs9C2TjyAmnGa9bBPam34crH3yWEWO2mHz8rMhngKao2GTkabt4bPQuk+Y6gGdr7I3PtPfnM+YhamjTBrHSb6xGBI4TiOMwQoQj3xMtUPfPJ2HMcpiAINfPJ2HMcZKtoqzGoicE0fWNHJ+5pb7+bEN3x4f8VkQi9r9MypgFFRH+P4UjL6xlJCxWd1udWZhC7X6JHtcVqjseHC1pWavcfoVIZFHQtvS8o+0hoPv/3tL7lUQKyy1U0bHXclcQ2qu0M9c3k61v9KI7xJWjUORGvDeBwA00etCcrt0bVhuRIHVJveFF6I2gaj2x2Pr21jnTmn1aFxY2xVbOxYM9HbSQRgrBI+qLVmeM9KCQ+0eiu8LrONsE+tFk8KLROIqt0o8NZXM21MbJmR3fEDdeKffzgo//pTb8s/TgFqa4yNYXNYbk7EfZqT4bXb/djw2WiuWh31sY5ty4UiNFzn7TiOM1y4zttxHGcIaSPMpuL99oHcBYsicqSI/ERErhWR7SLylqx+g4hcLCI3ZH/X543lOI4zzHQ8LCvB1i+KHLkJnKWql4nIamCbiFwMnA5coqrnicg5wDlAIspMFyVoje3Xv131obdGTY47O47x3U25SNKEtl3znBjIxt2uxjridjlnPWxid+76/QLBuOy4STly1nnbYFEA1b1tUw71tqV63MmuOa9vGI/aTB8SvonMbghPaDYOhx3pp9ujYTl1HXUilFdGQ3kloWeuVEL5V68K15evyQkWBTDTiN+0HpoxcbaNnaXZjH9aN+rhg9hqmmBizdRJ9y5LNbZT2HXe0jD+CcbHAaCSqFsKfvWl3rHFH/uBD0d1N54d6tuPvvD9QVkSSSzaiTXyy0FH5z0YapPcN29V3amql2X/7wGupZOe58XAF7JmXwD+aLmEdBzHGQQ67vHVYCuCiJwiItdl2eHPSexfKyLfF5ErMg1HbkjYefl5isgW4ETgl8DB+4KFZ38Pms9YjuM4w8a+N+/uLQ8RKQP/i06G+CcCLxeRJ5pmZwLXqOrxdOJ+f0hEbH6sgMKTt4isAr4F/IWqxv6pc/c7Q0S2isjW5kwiGLfjOM6Q0IltMr/JG3g6cKOq3qyqdeBrdDQXdujVIiLAKjqZ5hNZBvZTaPIWkSqdifvLqvrtrPrufanps7+7Un1V9XxVfaqqPrUyPplq4jiOMxS0Vai1q8FWgCKZ4T8BPIFO3sqrgLeo9k7Zk2uwzL4JLgCuVdVu68JFwKuB87K/38sbq12B2obebewXmZiMNzYDDsQGSztGKkhTfY2pSDi12ABXUcb2xJdu5FRUJHm8DUxlyqksP3GALuOYlHBaEJM5pzUWnkB9bfw4zGwM2+w9Ij6h2sHGSWfcOPaMxoZQI0qUSb1cifuMjpgsMmZ/pZSfnmqs2vNlBogNlPWE8XF6NvxF26iZa5cyTE+HbaKAaomAUbnP4KrE+ViD95gxOq9PBMCaDuuednpoSEwFd9t2weIdeaxxMsWtp/deBwGxUXO5UIRGfDE2icjWrrLNHl8kM/zvA5cDzwEeA1wsIv/eS8tRZLXJs4BXAleJyOVZ3TvpTNpfF5HXArcB/ctN5DiOswLMsdrk3pzs8UUyw78GOC9Lh3ajiNwCPB741VyD5k7eqvp/mfv98bl5/R3HcQ4UVKGWXHvck/8AjhGRRwG/BV4GnGba3EZnPv13ETkYOBa4udeg7mHpOI5TkIWs81bVpoi8EfgxUAY+p6rbReQN2f5PA+8FLhSRq+i8LL9dVe/tNe7KTt4CrbH9qp7Hnxs75IwYZ4HKlM3Ynligb5xYGqvCcj2OY0NzldH/JhblWJ8PTTgHRH1McPwoOUPCeSbScdfCMaphYvJOG6P7t7rQVJb3mtFpN1aHbWY3JgI7rQ+FK62KA1NNTIbCjFbjNpbp2TBY1YRxlkk5zzRMYCfrGDNVi2/i5Ggom83QvrsRfwTUjGuPC7EjjNqkCDNxn/JMzvqAVMwye5yyeW4biTGt85KxqTWq8YH2mmBi03VzPonf3ls++cFQtvH44S4ZWW457Z3xQEvBCiWYUIT6/N+8UdUfAj80dZ/u+v9O4AXzGdPfvB3HcQqiSspg2Rd88nYcxymIIjQ9h6XjOM5woSrUW4MxbQ6GFI7jOEOAwiP0zVtBumxZSYcbY5C00fFS0f+axjjXHLf7YwONNVC2RxMOHjY7jYlQJ/XETTTDWCeLUiOWPzcQYcIWU18XVlo1XOqcrZG2PRk6eJQTxsj1JgpfOWG0tZnTK/akE1RX7wnKM835x0iuGWPjaMKxxxofbeTB8QJOO812PO6IyaSzR8IogymTrUmKQ2naVCTus3WwiYyaiftRquRf/0i2dcYQasaVcv5xSgknqUnjsHX89/8qKM8ksgdd/8fn9hY2gYwVSLm1BCjQbD8SJ2/HcZwhRlWou8HScRxnuPA3b8dxnCFEkchXoF+s6OQtbRjZs1+xV0k4n1z+yd6Bak56fZx5wwb2svaE8mxCmViyuvX4hlhdsxpnoJTdwjrpWJ19eSaRsadi9I1GX91IOBm1JkL9ok6EBypPxLrcqtEJj482eu4HmDAON6PleNy2UdaOV/KddOxPz3YBxxibfX0kIa9lciTUuVrZRhJRv2Zb4QOVWtdr377aplxL6J3royaTzkj+x89mjamMhfJrYiKxQb3a5tluJDL2lI3OuGqCgI2PxgYqa/9IZTIaMamvUo5UlrwgU9Xx+PkqJ4LPLQe+zttxHGcoeYS+eTuO4wwzqtBaoXyZeRTJHv85EdklIld31f21iPxWRC7PtlOXV0zHcZz+sy+ed/fWL4q8eV9IJ8vDF039P6jqB+Pmc3Pc4Qez9bz9GeNPel2sv86jOR5/61nds11mnFp2HOmeU1+mdomtWWOeWn8dBc8362NtGaAVLhGO1/aujXV8q9aE669tkoFyYs3tqNE/Wj3zaCXW/5YLrNm2FyJPnw1QM15qJaMvrZZjfXaqrtcYc9XlYfuUEhGjUjr5bkYT68ejDOdjUZNcbM4QKcf3xya2aLfN+ST08TY5hiW1wqJlhkk9c7NmLf7MdBiQrDkVr/MWE8CrVAvLrUo8baUCvi0XK5WpPo8i2eN/RiefmuM4ziMaVWi2SsFWhLzs8VmbkzNNxnYR+be8MRejeX+jiFyZqVXW9xD64QTE99xzzyIO5ziO018Uod0uBVseRbLHi8g64JPAH6rqcRTITLbQyftTdPKsnQDsBD40V8PuBMSbN29e4OEcx3EGAO2oAbu3AhTJHn8a8G1VvQ1AVZMJ3btZ0OStqneraivLbvyZTDjHcZwDnnZLgq0ARbLHPw5YLyI/FZFtIvKqvEEXtFRQRA5V1Z1Z8SXA1b3az0Uqm9Dxbw6z6zQnTB9ThrThMO84kR0uYbCxDjZqy4nj2mNpyQSQGk0YLFf3zlazbu1U1McaKO0bQDVhPLIGpVFzEVIGJ5uRPfWmUbGWXUORtxPbJrWW1mbOKRvDYspmZcfdWw+dROwYqeOkssdHWX1avZ12UtirknJysamYbAaf1LVtNkLZ1Djl6GziA2Fu4WwpNCSGoceKIybDTXlvKMvYdCy/NT7az2o7EZyulO8XtiSoJh2jliJ7fAX4HTp5LMeBX4jIpap6/Vyy5E7eIvJV4ORMwDuAdwMni8gJmQA7gNfnjeM4jnMgoPG7ylJkj78jG2cKmBKRnwHHAwufvFX15YnqC/L6OY7jHHCoROEGClAke/z3gE+ISAUYAZ4BxEl+u3APS8dxnPlQzEi5v3mB7PGqeq2I/Ai4ko4S67Oq2lMd3dfJ2yZRAGhMhmU1a/htECdIBIMqoP+KHHsKLPK34xZJIi2mTXMi/s0l4yYI0EQiS4UhT4+c2l+1SnzDSGJ/ySgcmzZDBfkhMluJCF5Wl251yI3EmDaxQn0BMSasa7MdE1JBpxKOYaafbZN8O8txGErdMzXjRFnqU31skhAjWymRxd4+/yWjq059Pko1o89OJlcJyyO7w2swujvhMGTEa46a+74mPmfr6LaszD/XRW72+Kz898DfFx3T37wdx3GKookv0D7hk7fjOM48kAFxj/fJ23EcpygqkRqqX/R18p45JNYB2sQJUaKCMK4NAGqC8xTRgVdMYCpNXIkoWI/RdVX3xn2sfG0Te15H4nMemwgFtOutq4ngQ1bnanXIqSBTNuCS1XFXcnTiAGOJi1k3j5FNzpDS5dpobHaNcyqglF1/bfsk9dc5KwPsmKlxbDCo1LFj4ntm9eIpeSNZzLNs13mTSKyA6SONAvpr06ZUt+W4T9k8CqVa3KY6ZQKOTZvyVMLOUjN2lkkT6KwS211aYys4oa5gEKxe+Ju34zhOUdTVJo7jOMPJ/KMMLws+eTuO4xRFY7Vsv/DJ23EcZx4UyU+yEqzo5H3Vrrt51Ef3R4+VcuIbzBj0rF0oZSeymYja46FF4ebX/495yTkXNmiWtGNhYiOmCbg0FhtbauOhJ9LYOpPhPJFBZqLa25En1WfMWJgq5ilMZYafMZnUU1llKpVQFptJp4h8UVafcmyIs0ZOa9RMGUbzAl6lDJZFAmlZY6MdN2UotQGuWibjTbORyBBT6h2YKvUT3upk88pzjRP0SR0ncuxJdDT9rANOazRhcLWfeXOc6kwszGXvf1vY5wNvi9osBaIrm7WnF/7m7TiOMx8GxGC50ATEG0TkYhG5Ifs7ZyYdx3GcAwlph1u/KBIc4kLgFFN3DnCJqh4DXJKVHcdxDmwytUn31i+KhIT9mYhsMdUvphPjG+ALwE+Bt+ceTePg7BHm66Q0Yx0MEhnCjYNBahH/UnDFx94alI9/Uxyx0er0KkY/N7EzkUl9Noyq8+DhRjd6UCLIlNEZr66GHhJjldiZxuq4Jythn3YigNTaapilvkjyAstUM/asigJeGX12Eb15Eaxe3AadSjkDWZ13M5XNwzDTDG0Dqezys02TSb0e9qkksro3jRNOs2wcVsqx/IlPSNgnlXhErTOQsSeMJJImtHuXs9qeRU14QFXtY2jkLTX6u1Yv1z8r1UfkFOCjdKIKflZVz5uj3dOAS4E/VdVv9hpzoTksD96XSSf7e9ACx3EcxxkedP5qkyIJiLvavZ9O6NhcFpM9vhDd2eNbU3E6L8dxnGFBWJDapEgCYoA3Ad8CcpMPw8In77tF5FDo5LPsdbDu7PHlycm5mjmO4ww+C3jzpkACYhE5nE4+4CDGdy8WulTwIuDVwHnZ3+8V6iWg3YGmErqj5kRY2VhjAhbNxt835ZrVi4f7H/uBD0d9bjx78etAr/j4W6O6484O9eBRwJ/EN/XYvWF59IFQF1pbFy/mufnwVUF51UHhr5pNq+JfOZNmbXjT6LjHbaQhYNwInFznnRPQanQkXgBs9es1k9liPBXMyvSxevIUNkjWhLEFjCYWJ9vjpGwBFruGftasjweolo2O2wQTqzXjj2Ot1Pscm4nr1KrYteHmniU+9bEe3I6b+LCaYFCp21GOkqkY3XopHjdel272J0R55mkfiiuXi3jCXooExB8B3q6qLUlFQkuw0ATE5wFfF5HXArcBLy10NMdxnGEm7aSzFAmInwp8LZu4NwGnikhTVb8716ALTUAMnRT1juM4jygWsLY7NwGxqj7q4fFFLgR+0GviBvewdBzHmRfznbyLJCBeiBw+eTuO4xREdGFelUUSEHfVn15kzJWdvMtKe+1+A5EknBLGJ0PHEau7r9dikRtToVWk/FDYJuVjcfT5YZLmW8+Ig1dt+XhoBNnxprPigQyt8bDcNgablLHFJqeJMmw/EPfZuD00os2uXxuUdx65LupTX2+UdWvDA69bHxs5j1j7UFDePBqnD7KGzlFzQq3EoqaUoa2blPOMNfEUydgz3QxTGa0yzkzVhC2paj6d7YQstVbvj07KsFs1ht2ahGOkglk1TTCrRt1kLZpJyGGN5DXjmNSIz9lmwbFtkoGprK03cUvbVjx7DxPhVVvm81A2TjlRhqsV5hEZVdBxHGeoWeCb93Lgk7fjOM488JCwjuM4w8Yj+s27S3lmA80D1Guhkviml71rWcTY8sVkXJgAq+N+jHH2SfmmiNVxpxJOGKyqtmmcH1KBeKwOcvUdoQJy3Y2xcJWpUJnYWB3qg/cctSHqc8NRG4PyVUfEjjwTG6dDWcZDBeq6sTC4FcS6Z4sNtAWxs4zVK0+3wvOBOBiX1YHXEwGkrPNMChvgygavSo1rk0nYQFU2WQNAs2ECUU2FfUpTCflNMLfyrNFfJ5ImWLuLLSdNEDbIVGI2sf5NduKLdOJAc8LYMqxsCflXakLd5x4/CPibt+M4TlE0nUGrH/jk7TiOMw8euWoTx3GcYUXT6tJ+sLKTd1ModQVd0pH458dN//0vV0SUHa+af/Ifu1489QUcxZQxysLUt7bVC6rRk7fGY7357MZQGLHJeetxYKTybJgUIYpDlfg1uP56I/B1Cb3s2JqgPLM+lPeBTYkEDiY/Q2tjKMz4mtmoz+RYGFhrvBr2Sa3ztuvFbeKIVHKJstF5jyQ+rXaN+XTD+BokxrV6cJuModFIXFvr12DWRZfq8TlbHXfZXMpSInd1uWYCwFmdd/JhD4spfwr7bLetDahAXFObCEITCShWSg8t+Ju34zjOUOI6b8dxnGFD06t1+sGiJm8R2QHsAVpAMycsouM4znBzgK02ebaq3pvfzHEcZ/h5ROq8pQ0ju/dbKK47N85EM8jcfFaYfccGtwIQY1CSunWQSBjVcoxDiQQrsYOENeKkAgnZOjtIMi22MX7NxPJbea2Rqron7hMF27ordJ7RcuxwM2PGfWityQy/Ov5U6YipM9epNBJbusomYFo1kQnIGqbbNvtLKpiVcUBrN8IT0kbCemeyx9tMUjaLFMQ/68vG36kykzDS1mzZtCmQCyb1RmqN72oNyKP5TmzW9yo1eaacfZYDUaXUmv+bd172eBF5BfD2rLgX+HNVvaLXmItNQKzAv4jINhE5Y5FjOY7jDDzLlD3+FuC/qOpTgPcC55PDYr+vnqWqd4rIQcDFIvIbVf2ZEfwM4AyAyto4F6PjOM7QoMD837wfzh4PICL7ssdf8/Cwqj/van8pnVRpPVnUm7eq3pn93QV8JxPStvHs8Y7jHDCUWhpsBcjNHm94LfDPeYMu+M1bRCaBkqruyf5/AfCeXn2edOjBbB0yPXcvUgkcjvnGe4NyfXfojSKz8felGCVxyygTkw4I1tfB6NJbown9o9WTJ3XcvY/THM/vE/m0JH5a2nOyGcNTwYfsONXdYZ+xe2IvkZIJ9mSPm3IssTrWdqx+pzEZXgerc9VK4jqZqnIiEYHFXofydH6finHKsfrr6t5EooiZ8OKWTTkdHM1cg0QQNvuItatGz59K4GCcctpVqzeP+6wUkl5tshTZ4zsNRZ5NZ/L+vTxZFqM2ORj4TpbtuAJ8RVV/tIjxHMdxBhsFaUbz7lJkj0dEngJ8Fnihqt6XJ8qCJ+9Mf3P8Qvs7juMMH7qQdd652eNF5Cjg28ArVfX6IoO6h6XjOE5RFGSeBsuC2ePPBTYCn8y0GblOjz55O47jzANpzd9LJy97vKr+GfBn8xnTJ+8l5oaX/lVQPu577w7K9Xp8yesPjAXlkvFGqSSMVDaanI0UV0o4b9hMJ9bI1ipgjGyPp8IimjbWYSVhcLUGVsxP0baJOpg6TsrYaLEOK9YAaJ2qII7CN7I7HnfiLtPHOrUksA4rDbP4qrEqkUk9fDTibDUJU1hz3MhmEhlZJ6pOG+OYtCf0HCtPxaEIZcbURSE1gZIxNo6YE0j0qW8cj+oGhoUtFVwWfPJ2HMcpiKBIezD847Ul8gkAAAcVSURBVH3ydhzHKYqCNH3ydhzHGTIU/M37kcEha/YEZZt1HOD+0VC/uGd3qPNrlGIvkWo4bKwDTzm5WH2vVT+2EzpXowcvzSbaTIYPcxTvIeFV0TZOLFGfhCy2j1YL6B5zmqR03jZ4WGNN1ITKVNjGZmyvTOcHf6pOmTETAaPaJiGSDeRkMxKl6mYOCfvU1sfnXFsbPmNrdxgHqHpsuJC7woewfd/9URttzj/49egxjw7HXRV+Hlqr4s+Ddf5ZNlzn7TiOM4QoSHMwklj65O04jlMYV5s4juMMHwosYJ33cuCT9zIzWg51fpOV/BtvNWqJOEI0MMkLjMrP6mQhDhhlgwalsorbtdRaSuiI6+bgZuBktm+zQNnKLwlZoqQPdtjEMuNU8otuUtnX7XFS69SjIF82S3olcVwjsL3+qYBLdtwoQFTCNmDlN0nqaaxO6NatLn087DR6SDxVrNoYLkKfuD5en9289Q5zoHyVQ+uGm4NyeU1odJAth8V9Vo9FdcuCKixAj78c+OTtOI4zH1xt4jiOM2SoQmswDJaLWl8jIqeIyHUicqOInLNUQjmO4wwmCs1WuPWJBU/eBfOyOY7jHDgoaKsVbP1iMWqT3LxsDvz2obVBeWykEbUZLYcPQNlYssrVWMfWHA3rtBZaFtupTDrGeBcZ5hKqPGvQS2XfiZ17bCaUVFZxUy6ZrOJjqUw0Rn5rjEwFXDLyl42TkcS3g7IN8pWwT5VnzT0ywaxS17Jc7+3cEWUgIjZiWqeddioTkJHXOvakMgM1x+z1D/fX1sV9auvCgaYPig2Jq7dsDMqjO8IcA81bbo0HNrR2h5HB5Lpa1Kay5ciobllYoMGyQPZ4yfafCkwDp6vqZb3GXIzaZL552RzHcYYcnfebd0EtxQuBY7LtDOBTeeMuZvIulJdNRM4Qka0isvWee+5ZxOEcx3H6jNIxWHZv+TyspVDVOrBPS9HNi4EvaodLgXUicmivQRczeRfKy9adPX7z5s2LOJzjOE5/UVXajWawFaCIlmLemozF6Lxz87JZtm3bdq+I3ApsAu5dxLFXmmGSd5hkheGSd5hkheGSt7iss4m630Q1Ry9OnDR7eODH/9r++iZTPbYE2eMLZ5jfx2ISECfzsuX02QwgIlvz8rMNEsMk7zDJCsMl7zDJCsMl77DIqqqnLKBbES1FIU1GN4ty0knlZXMcx3ECimgpLgLemK3aewbwkKru7DWoe1g6juMsIwWzx/+QzjLBG+ksFXxN3rj9mrzPz28yUAyTvMMkKwyXvMMkKwyXvMMk67wpkD1egTPnM6ZoFJrNcRzHGXRWKHeQ4ziOs5Ss+OQ9yMGsRORzIrJLRK7uqtsgIheLyA3Z3/X9lHEfInKkiPxERK4Vke0i8pasflDlHRORX4nIFZm8f5PVD6S80PGME5Ffi8gPsvIgy7pDRK4Skcv3LVsbVHlFZJ2IfFNEfpM9v787qLIOMis6eQ9BMKsLAbsU6BzgElU9BrgkKw8CTeAsVX0C8EzgzOxaDqq8NeA5qno8cAJwiog8k8GVF+AtwLVd5UGWFeDZqnpC15K7QZX3o8CPVPXxwPF0rvGgyjq4qOqKbcDvAj/uKr8DeMdKylBAxi3A1V3l64BDs/8PBa7rt4xzyP094PnDIC8wAVxGZ0nUQMpLZ53tJcBzgB8M+rMA7AA2mbqBkxdYA9xCZm8bZFkHfVtptckwBrM6WLP1ltnfg/osT4SIbAFOBH7JAMubqSEuB3YBF6vqIMv7EeBsoDs+4KDKCh1vvH8RkW0ickZWN4jyPhq4B/h8ppL6rIhMMpiyDjQrPXnP2wXU6Y2IrAK+BfyFqu7Oa99PVLWlqifQeat9uog8qd8ypRCRFwG7VHVbv2WZB89S1ZPoqCTPFJH/3G+B5qACnAR8SlVPBKZwFcmCWOnJe94uoAPA3fuie2V/d/VZnocRkSqdifvLqvrtrHpg5d2Hqj4I/JSOfWEQ5X0W8IcisoNOBLjniMg/MpiyAqCqd2Z/dwHfoRPJbhDlvQO4I/vVBfBNOpP5IMo60Kz05P2wm6iIjNBxE71ohWWYLxcBr87+fzUd3XLfyYK3XwBcq6of7to1qPJuFpF12f/jwPPohBMaOHlV9R2qeoSqbqHzjP4fVf1vDKCsACIyKSKr9/0PvAC4mgGUV1XvAm4XkWOzqufSSeAycLIOPCutZKfjAno9cBPwrn4r/Y1sXwV2Ag06bwivBTbSMVzdkP3d0G85M1l/j47K6Urg8mw7dYDlfQrw60zeq4Fzs/qBlLdL7pPZb7AcSFnp6JGvyLbt+z5XAyzvCcDW7Fn4LrB+UGUd5M09LB3HcYYQ97B0HMcZQnzydhzHGUJ88nYcxxlCfPJ2HMcZQnzydhzHGUJ88nYcxxlCfPJ2HMcZQnzydhzHGUL+P32bzDJnAzUvAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "# Plot correlation map\n", "fig, ax = plt.subplots(figsize=(8,2))\n", "plt.title(f\"Lead time: {lead} month\")\n", "C=ax.imshow(corr_map, origin='lower', vmin=0, vmax=1)\n", "cb=plt.colorbar(C)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Animate the full test prediction" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import matplotlib.animation as animation\n", "\n", "def animation_ed(true, pred, nino, nino_pred, time):\n", " fig, ax = plt.subplots(3, 1, figsize=(6,7), squeeze=False)\n", "\n", " vmin = -3\n", " vmax = 3\n", "\n", " true_im = ax[0,0].imshow(true[0], origin='lower', vmin=vmin, vmax=vmax, cmap=plt.cm.bwr)\n", " pred_im = ax[1,0].imshow(pred[0], origin='lower', vmin=vmin, vmax=vmax, cmap=plt.cm.bwr)\n", " title = ax[0,0].set_title('')\n", "\n", " ax[2,0].plot(time, nino)\n", " ax[2,0].plot(time, nino_pred)\n", " ax[2,0].set_ylim(-3,3)\n", " ax[2,0].set_xlim(time[0], time[-1])\n", "\n", " vline = ax[2,0].plot([time[0], time[0]], [-10,10], color='k')\n", "\n", "\n", " def update(data):\n", " true_im.set_data(data[0])\n", " pred_im.set_data(data[1])\n", " title_str = np.datetime_as_string(data[0].time.values)[:10]\n", " title.set_text(title_str)\n", "\n", " vline[0].set_data([data[2], data[2]],[-10,10])\n", "\n", " def data_gen():\n", " k = 0\n", " kmax = len(true)\n", " while k\n", " \n", " Your browser does not support the video tag.\n", "" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "ani = animation_ed(test_label_map, pred_map, \n", " oni.loc[testtimey[0]:testtimey[-1]], pred_oni, \n", " testtimey)\n", "\n", "HTML(ani.to_html5_video())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So it looks like that the Encoder-Decoder ensemble has some skill. However, more research is needed to release the full potential of this model. \n", "\n", "Maybe you are interested working on this? :D" ] } ], "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.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }