diff --git a/dianna/__init__.py b/dianna/__init__.py index 52dde758..0dbb22d9 100644 --- a/dianna/__init__.py +++ b/dianna/__init__.py @@ -32,6 +32,29 @@ __version__ = "0.7.0" +def explain_timeseries(model_or_function, timeseries_data, method, labels, **kwargs): + """Explain timeseries data given a model and a chosen method. + + Args: + model_or_function (callable or str): The function that runs the model to be explained _or_ + the path to a ONNX model on disk. + timeseries_data (np.ndarray): Timeseries data to be explained + method (string): One of the supported methods: RISE, LIME or KernelSHAP + labels (Iterable(int)): Labels to be explained + kwargs: key word arguments + + Returns: + One heatmap per class. + + """ + explainer = _get_explainer(method, kwargs, modality="Timeseries") + explain_image_kwargs = utils.get_kwargs_applicable_to_function(explainer.explain, kwargs) + return explainer.explain(model_or_function, + timeseries_data, + labels, + **explain_image_kwargs) + + def explain_image(model_or_function, input_data, method, labels, **kwargs): """Explain an image (input_data) given a model and a chosen method. diff --git a/dianna/methods/rise.py b/dianna/methods/rise.py index 28cab728..1097609b 100644 --- a/dianna/methods/rise.py +++ b/dianna/methods/rise.py @@ -3,6 +3,9 @@ from tqdm import tqdm from dianna import utils +# To Do: remove this import when the method for different input type is splitted +from dianna.methods.rise_timeseries import RISETimeseries # noqa: F401 ignore unused import + def normalize(saliency, n_masks, p_keep): """Normalizes salience by number of masks and keep probability.""" diff --git a/dianna/methods/rise_timeseries.py b/dianna/methods/rise_timeseries.py new file mode 100644 index 00000000..e50d64cf --- /dev/null +++ b/dianna/methods/rise_timeseries.py @@ -0,0 +1,70 @@ +import numpy as np +from tqdm import tqdm +from dianna import utils +from dianna.utils.maskers import generate_masks +from dianna.utils.maskers import mask_data + + +def _make_predictions(input_data, runner, batch_size): + """Process the input_data with the model runner in batches and return the predictions.""" + number_of_masks = input_data.shape[0] + batch_predictions = [] + for i in tqdm(range(0, number_of_masks, batch_size), desc='Explaining'): + batch_predictions.append(runner(input_data[i:i + batch_size])) + return np.concatenate(batch_predictions) + + +# Duplicate code from rise.py: +def normalize(saliency, n_masks, p_keep): + """Normalizes salience by number of masks and keep probability.""" + return saliency / n_masks / p_keep + + +class RISETimeseries: + """RISE implementation for timeseries adapted from the image version of RISE.""" + + def __init__(self, n_masks=1000, feature_res=8, p_keep=0.5, + preprocess_function=None): + """RISE initializer. + + Args: + n_masks (int): Number of masks to generate. + feature_res (int): Resolution of features in masks. + p_keep (float): Fraction of input data to keep in each mask (Default: auto-tune this value). + preprocess_function (callable, optional): Function to preprocess input data with + """ + self.n_masks = n_masks + self.feature_res = feature_res + self.p_keep = p_keep + self.preprocess_function = preprocess_function + self.masks = None + self.predictions = None + + def explain(self, model_or_function, input_timeseries, labels, batch_size=100, mask_type='mean'): + """Runs the RISE explainer on images. + + The model will be called with masked timeseries, + with a shape defined by `batch_size` and the shape of `input_data`. + + Args: + model_or_function (callable or str): The function that runs the model to be explained _or_ + the path to a ONNX model on disk. + input_timeseries (np.ndarray): Input timeseries data to be explained + batch_size (int): Batch size to use for running the model. + labels (Iterable(int)): Labels to be explained + mask_type: Masking strategy for masked values. Choose from 'mean' or a callable(input_timeseries) + + Returns: + Explanation heatmap for each class (np.ndarray). + """ + runner = utils.get_function(model_or_function, preprocess_function=self.preprocess_function) + self.masks = generate_masks(input_timeseries, number_of_masks=self.n_masks, p_keep=self.p_keep) + masked = mask_data(input_timeseries, self.masks, mask_type=mask_type) + + self.predictions = _make_predictions(masked, runner, batch_size) + n_labels = self.predictions.shape[1] + + saliency = self.predictions.T.dot(self.masks.reshape(self.n_masks, -1)).reshape(n_labels, + *input_timeseries.shape) + selected_saliency = saliency[labels] + return normalize(selected_saliency, self.n_masks, self.p_keep) diff --git a/dianna/utils/maskers.py b/dianna/utils/maskers.py index bed4c9d7..56076736 100644 --- a/dianna/utils/maskers.py +++ b/dianna/utils/maskers.py @@ -1,4 +1,5 @@ import warnings +from typing import Union import numpy as np @@ -17,21 +18,20 @@ def generate_masks(input_data: np.array, number_of_masks: int, p_keep: float = 0 number_of_steps_masked = _determine_number_of_steps_masked(p_keep, series_length) masked_data_shape = [number_of_masks] + list(input_data.shape) - masks = np.zeros(masked_data_shape, dtype=np.bool) + masks = np.ones(masked_data_shape, dtype=np.bool) for i in range(number_of_masks): steps_to_mask = np.random.choice(series_length, number_of_steps_masked, False) - masked_value = 1 - masks[i, steps_to_mask] = masked_value + masks[i, steps_to_mask] = False return masks -def mask_data(data, masks, mask_type='mean'): +def mask_data(data: np.array, masks: np.array, mask_type: Union[object, str]): """Mask data given using a set of masks. Args: - data: ? + data: Input data. masks: an array with shape [number_of_masks] + data.shape - mask_type: ? + mask_type: Masking strategy. Returns: Single array containing all masked input where the first dimension represents the batch. @@ -39,13 +39,15 @@ def mask_data(data, masks, mask_type='mean'): number_of_masks = masks.shape[0] input_data_batch = np.repeat(np.expand_dims(data, 0), number_of_masks, axis=0) result = np.empty(input_data_batch.shape) - result[~masks] = input_data_batch[~masks] - result[masks] = _get_mask_value(data, mask_type) + result[masks] = input_data_batch[masks] + result[~masks] = _get_mask_value(data, mask_type) return result def _get_mask_value(data: np.array, mask_type: str) -> int: """Calculates a masking value of the given type for the data.""" + if callable(mask_type): + return mask_type(data) if mask_type == 'mean': return np.mean(data) raise ValueError(f'Unknown mask_type selected: {mask_type}') diff --git a/tests/methods/test_rise_timeseries.py b/tests/methods/test_rise_timeseries.py new file mode 100644 index 00000000..d34800bc --- /dev/null +++ b/tests/methods/test_rise_timeseries.py @@ -0,0 +1,37 @@ +import numpy as np +import dianna +from tests.methods.time_series_test_case import average_temperature_timeseries_with_1_cold_and_1_hot_day +from tests.methods.time_series_test_case import input_train_mean +from tests.methods.time_series_test_case import run_expert_model +from tests.utils import run_model + + +def test_rise_timeseries_correct_output_shape(): + """Test if rise runs and outputs the correct shape given some data and a model function.""" + input_data = np.random.random((10, 1)) + axis_labels = ['t', 'channels'] + labels = [1] + + heatmaps = dianna.explain_timeseries(run_model, input_data, "RISE", labels, axis_labels=axis_labels, + n_masks=200, p_keep=.5) + + assert heatmaps.shape == (len(labels), *input_data.shape) + + +def test_rise_timeseries_with_expert_model_for_correct_max_and_min(): + """Test if RISE highlights the correct areas for this artificial example.""" + hot_day_index = 6 + cold_day_index = 12 + temperature_timeseries = average_temperature_timeseries_with_1_cold_and_1_hot_day(cold_day_index, hot_day_index) + + summer_explanation, winter_explanation = dianna.explain_timeseries(run_expert_model, + timeseries_data=temperature_timeseries, + method='rise', + labels=[0, 1], + p_keep=0.1, n_masks=10000, + mask_type=input_train_mean) + + assert np.argmax(summer_explanation) == hot_day_index + assert np.argmin(summer_explanation) == cold_day_index + assert np.argmax(winter_explanation) == cold_day_index + assert np.argmin(winter_explanation) == hot_day_index diff --git a/tests/methods/time_series_test_case.py b/tests/methods/time_series_test_case.py new file mode 100644 index 00000000..40e42e73 --- /dev/null +++ b/tests/methods/time_series_test_case.py @@ -0,0 +1,38 @@ +import numpy as np + + +"""Test case for timeseries xai methods. +This test case is designed to show if the xai methods could provide reasonable results. +In this test case, every test instance is a 28 days by 1 channel array indicating the max temp on a day. +""" + + +def input_train_mean(_data): + """Return overall mean temperature of 14.""" + return 14 + + +def average_temperature_timeseries_with_1_cold_and_1_hot_day(cold_day_index, hot_day_index): + """Creates a temperature time series of all 14s and a single cold (-2) and hot (30) day.""" + temperature_timeseries = np.expand_dims(np.zeros(28), axis=1) + 14 + temperature_timeseries[hot_day_index] = 30 + temperature_timeseries[cold_day_index] = -2 + return temperature_timeseries + + +def run_expert_model(data): + """A simple model that classifies a batch of timeseries. + + All instances with an average above 14 are classified as summer (0) and the rest as winter (1). + """ + # Make actual decision + is_summer = np.mean(np.mean(data, axis=1), axis=1) > 14 + + # Create the correct output format + number_of_classes = 2 + number_of_instances = data.shape[0] + result = np.zeros((number_of_instances, number_of_classes)) + result[is_summer] = [1.0, 0.0] + result[~is_summer] = [0.0, 1.0] + + return result diff --git a/tests/test_common_usage.py b/tests/test_common_usage.py index a143b6f7..5b5cc6e4 100644 --- a/tests/test_common_usage.py +++ b/tests/test_common_usage.py @@ -4,13 +4,29 @@ from tests.utils import run_model -input_data = np.random.random((224, 224, 3)) -axis_labels = {-1: 'channels'} -labels = [0, 1] +def test_common_RISE_image_pipeline(): # noqa: N802 ignore case + """No errors thrown while creating a relevance map and visualizing it.""" + input_image = np.random.random((224, 224, 3)) + axis_labels = {-1: 'channels'} + labels = [0, 1] + + heatmap = dianna.explain_image(run_model, input_image, "RISE", labels, axis_labels=axis_labels)[0] + dianna.visualization.plot_image(heatmap, show_plot=False) + dianna.visualization.plot_image(heatmap, original_data=input_image[0], show_plot=False) -def test_common_RISE_pipeline(): # noqa: N802 ignore case +def test_common_RISE_timeseries_pipeline(): # noqa: N802 ignore case """No errors thrown while creating a relevance map and visualizing it.""" - heatmap = dianna.explain_image(run_model, input_data, "RISE", labels, axis_labels=axis_labels)[0] - dianna.visualization.plot_image(heatmap, show_plot=False) - dianna.visualization.plot_image(heatmap, original_data=input_data[0], show_plot=False) + input_timeseries = np.random.random((31, 1)) + labels = [0] + + heatmap = dianna.explain_timeseries(run_model, input_timeseries, "RISE", labels)[0] + heatmap_channel = heatmap[:, 0] + segments = [] + for i in range(len(heatmap_channel) - 1): + segments.append({ + 'index': i, + 'start': i, + 'stop': i + 1, + 'weight': heatmap_channel[i]}) + dianna.visualization.plot_timeseries(range(len(heatmap_channel)), input_timeseries[:, 0], segments, show_plot=False) diff --git a/tutorials/models/season_prediction_model_temp_max_binary.onnx b/tutorials/models/season_prediction_model_temp_max_binary.onnx new file mode 100644 index 00000000..f82b8f2c Binary files /dev/null and b/tutorials/models/season_prediction_model_temp_max_binary.onnx differ diff --git a/tutorials/rise_timeseries_weather.ipynb b/tutorials/rise_timeseries_weather.ipynb new file mode 100644 index 00000000..be21dc1d --- /dev/null +++ b/tutorials/rise_timeseries_weather.ipynb @@ -0,0 +1,1822 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Exploration of RISE for timeseries with weather dataset" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "This notebook shows how to use the RISE for timeseries explainer to explain trained onnx model with weather dataset." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Load weather dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import os\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "import onnx\n", + "import onnxruntime as ort\n", + "import dianna\n", + "np.random.seed(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "outputs": [ + { + "data": { + "text/plain": " DATE MONTH BASEL_cloud_cover BASEL_humidity \\\ncount 3.654000e+03 3654.000000 3654.000000 3654.000000 \nmean 2.004568e+07 6.520799 5.418446 0.745107 \nstd 2.874287e+04 3.450083 2.325497 0.107788 \nmin 2.000010e+07 1.000000 0.000000 0.380000 \n25% 2.002070e+07 4.000000 4.000000 0.670000 \n50% 2.004567e+07 7.000000 6.000000 0.760000 \n75% 2.007070e+07 10.000000 7.000000 0.830000 \nmax 2.010010e+07 12.000000 8.000000 0.980000 \n\n BASEL_pressure BASEL_global_radiation BASEL_precipitation \\\ncount 3654.000000 3654.000000 3654.000000 \nmean 1.017876 1.330380 0.234849 \nstd 0.007962 0.935348 0.536267 \nmin 0.985600 0.050000 0.000000 \n25% 1.013300 0.530000 0.000000 \n50% 1.017700 1.110000 0.000000 \n75% 1.022700 2.060000 0.210000 \nmax 1.040800 3.550000 7.570000 \n\n BASEL_sunshine BASEL_temp_mean BASEL_temp_min ... \\\ncount 3654.000000 3654.000000 3654.000000 ... \nmean 4.661193 11.022797 6.989135 ... \nstd 4.330112 7.414754 6.653356 ... \nmin 0.000000 -9.300000 -16.000000 ... \n25% 0.500000 5.300000 2.000000 ... \n50% 3.600000 11.400000 7.300000 ... \n75% 8.000000 16.900000 12.400000 ... \nmax 15.300000 29.000000 20.800000 ... \n\n STOCKHOLM_temp_min STOCKHOLM_temp_max TOURS_wind_speed \\\ncount 3654.000000 3654.000000 3654.000000 \nmean 5.104215 11.470635 3.677258 \nstd 7.250744 8.950217 1.519866 \nmin -19.700000 -14.500000 0.700000 \n25% 0.000000 4.100000 2.600000 \n50% 5.000000 11.000000 3.400000 \n75% 11.200000 19.000000 4.600000 \nmax 21.200000 32.900000 10.800000 \n\n TOURS_humidity TOURS_pressure TOURS_global_radiation \\\ncount 3654.000000 3654.000000 3654.000000 \nmean 0.781872 1.016639 1.369787 \nstd 0.115572 0.018885 0.926472 \nmin 0.330000 0.000300 0.050000 \n25% 0.700000 1.012100 0.550000 \n50% 0.800000 1.017300 1.235000 \n75% 0.870000 1.022200 2.090000 \nmax 1.000000 1.041400 3.560000 \n\n TOURS_precipitation TOURS_temp_mean TOURS_temp_min TOURS_temp_max \ncount 3654.000000 3654.000000 3654.000000 3654.000000 \nmean 0.186100 12.205802 7.860536 16.551779 \nstd 0.422151 6.467155 5.692256 7.714924 \nmin 0.000000 -6.200000 -13.000000 -3.100000 \n25% 0.000000 7.600000 3.700000 10.800000 \n50% 0.000000 12.300000 8.300000 16.600000 \n75% 0.160000 17.200000 12.300000 22.400000 \nmax 6.200000 31.200000 22.600000 39.800000 \n\n[8 rows x 165 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
DATEMONTHBASEL_cloud_coverBASEL_humidityBASEL_pressureBASEL_global_radiationBASEL_precipitationBASEL_sunshineBASEL_temp_meanBASEL_temp_min...STOCKHOLM_temp_minSTOCKHOLM_temp_maxTOURS_wind_speedTOURS_humidityTOURS_pressureTOURS_global_radiationTOURS_precipitationTOURS_temp_meanTOURS_temp_minTOURS_temp_max
count3.654000e+033654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.000000...3654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.0000003654.000000
mean2.004568e+076.5207995.4184460.7451071.0178761.3303800.2348494.66119311.0227976.989135...5.10421511.4706353.6772580.7818721.0166391.3697870.18610012.2058027.86053616.551779
std2.874287e+043.4500832.3254970.1077880.0079620.9353480.5362674.3301127.4147546.653356...7.2507448.9502171.5198660.1155720.0188850.9264720.4221516.4671555.6922567.714924
min2.000010e+071.0000000.0000000.3800000.9856000.0500000.0000000.000000-9.300000-16.000000...-19.700000-14.5000000.7000000.3300000.0003000.0500000.000000-6.200000-13.000000-3.100000
25%2.002070e+074.0000004.0000000.6700001.0133000.5300000.0000000.5000005.3000002.000000...0.0000004.1000002.6000000.7000001.0121000.5500000.0000007.6000003.70000010.800000
50%2.004567e+077.0000006.0000000.7600001.0177001.1100000.0000003.60000011.4000007.300000...5.00000011.0000003.4000000.8000001.0173001.2350000.00000012.3000008.30000016.600000
75%2.007070e+0710.0000007.0000000.8300001.0227002.0600000.2100008.00000016.90000012.400000...11.20000019.0000004.6000000.8700001.0222002.0900000.16000017.20000012.30000022.400000
max2.010010e+0712.0000008.0000000.9800001.0408003.5500007.57000015.30000029.00000020.800000...21.20000032.90000010.8000001.0000001.0414003.5600006.20000031.20000022.60000039.800000
\n

8 rows × 165 columns

\n
" + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fname = \"weather_prediction_dataset.csv\"\n", + "if os.path.isfile(fname):\n", + " data = pd.read_csv(fname)\n", + "else:\n", + " data = pd.read_csv(f\"https://zenodo.org/record/5071376/files/{fname}?download=1\")\n", + "data.describe()" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "markdown", + "source": [ + "### Prepare dataset\n", + "Given how the classification model is trained, we prepare the testing data for prediction." + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 3, + "outputs": [ + { + "data": { + "text/plain": " DE_BILT_temp_max\ncount 3654.000000\nmean 14.798604\nstd 7.210740\nmin -4.700000\n25% 9.200000\n50% 14.900000\n75% 20.200000\nmax 35.700000", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
DE_BILT_temp_max
count3654.000000
mean14.798604
std7.210740
min-4.700000
25%9.200000
50%14.900000
75%20.200000
max35.700000
\n
" + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# select only data from De Bilt\n", + "columns = [col for col in data.columns if col.startswith('DE_BILT') and col.endswith('temp_max')]#[:9]\n", + "data_debilt = data[columns]\n", + "data_debilt.describe()" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 4, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(120, 28, 1)\n" + ] + } + ], + "source": [ + "# find where the month changes\n", + "idx = np.where(np.diff(data['MONTH']) != 0)[0]\n", + "# idx contains the index of the last day of each month, except for the last month.\n", + "# of the last month only a single day is recorded, so we discard it.\n", + "\n", + "nmonth = len(idx)\n", + "# add start of first month\n", + "idx = np.insert(idx, 0, 0)\n", + "ncol = len(columns)\n", + "# create single object containing each timeseries\n", + "# for simplicity we truncate each timeseries to the same length, i.e. 28 days\n", + "nday = 28\n", + "data_ts = np.zeros((nmonth, nday, ncol))\n", + "for m in range(nmonth):\n", + " data_ts[m] = data_debilt[idx[m]:idx[m+1]][:28]\n", + " \n", + "print(data_ts.shape)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 5, + "outputs": [ + { + "data": { + "text/plain": " 0 1 2 3\ncount 120.000000 120.000000 120.000000 120.000000\nmean 0.250000 0.250000 0.250000 0.250000\nstd 0.434828 0.434828 0.434828 0.434828\nmin 0.000000 0.000000 0.000000 0.000000\n25% 0.000000 0.000000 0.000000 0.000000\n50% 0.000000 0.000000 0.000000 0.000000\n75% 0.250000 0.250000 0.250000 0.250000\nmax 1.000000 1.000000 1.000000 1.000000", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
0123
count120.000000120.000000120.000000120.000000
mean0.2500000.2500000.2500000.250000
std0.4348280.4348280.4348280.434828
min0.0000000.0000000.0000000.000000
25%0.0000000.0000000.0000000.000000
50%0.0000000.0000000.0000000.000000
75%0.2500000.2500000.2500000.250000
max1.0000001.0000001.0000001.000000
\n
" + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# the labels are based on the month of each timeseries, in range 1 to 12\n", + "months = (np.arange(nmonth) + data['MONTH'][0] - 1) % 12 + 1\n", + "\n", + "# one class per meteorological season\n", + "labels = np.zeros_like(months, dtype=int)\n", + "spring = (3 <= months) & (months <= 5) # mar - may\n", + "summer = (6 <= months) & (months <= 8) # jun - aug\n", + "autumn = (9 <= months) & (months <= 11) # sep - nov\n", + "winter = (months <= 2) | (months == 12) # dec - feb\n", + "\n", + "labels[spring] = 0\n", + "labels[summer] = 1\n", + "labels[autumn] = 2\n", + "labels[winter] = 3\n", + "\n", + "target = pd.get_dummies(labels)\n", + "\n", + "classes = ['spring', 'summer', 'autumn', 'winter']\n", + "nclass = len(classes)\n", + "\n", + "target.describe()" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 6, + "outputs": [], + "source": [ + "classes = ['summer', 'winter']\n", + "nclass = 2\n", + "labels[summer] = 0\n", + "labels[winter] = 1\n", + "target = pd.get_dummies(labels[summer + winter])\n", + "data_ts = data_ts[summer + winter]" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "markdown", + "source": [ + "### Train/test split" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 7, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(45, 28, 1) (7, 28, 1) (8, 28, 1)\n" + ] + } + ], + "source": [ + "data_trainval, data_test, target_trainval, target_test = train_test_split(data_ts, target, stratify=target, random_state=0, test_size=.12)\n", + "data_train, data_val, target_train, target_val = train_test_split(data_trainval, target_trainval, stratify=target_trainval, random_state=0, test_size=.12)\n", + "print(data_train.shape, data_val.shape, data_test.shape)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "markdown", + "source": [ + "### Check predictions with ONNX model" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 8, + "outputs": [], + "source": [ + "# onnx model available on surf drive\n", + "# path to ONNX model\n", + "onnx_file = 'models/season_prediction_model_temp_max_binary.onnx'\n", + "\n", + "# verify the ONNX model is valid\n", + "onnx_model = onnx.load(onnx_file)\n", + "onnx.checker.check_model(onnx_model)\n", + "\n", + "def run_model(data):\n", + " # model must receive input in the order of [batch, timeseries, channels]\n", + " # data = data.transpose([0,2,1])\n", + " # get ONNX predictions\n", + " sess = ort.InferenceSession(onnx_file)\n", + " input_name = sess.get_inputs()[0].name\n", + " output_name = sess.get_outputs()[0].name\n", + "\n", + " onnx_input = {input_name: data.astype(np.float32)}\n", + " pred_onnx = sess.run([output_name], onnx_input)[0]\n", + " print(f'mean:{np.mean(data)}, prediction:{pred_onnx}')\n", + " \n", + " return pred_onnx" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 9, + "outputs": [], + "source": [ + "# We can use this 'expert' model instead of a trained model. This expert model decides it's summer if the mean temp is\n", + "# above some threshold, and winter in other cases.\n", + "\n", + "def run_expert_model(data):\n", + " is_summer = np.mean(np.mean(data, axis=1), axis=1) > 14\n", + " print(f'{is_summer=}')\n", + " number_of_classes = 2\n", + " number_of_instances = data.shape[0]\n", + " result = np.zeros((number_of_instances ,number_of_classes))\n", + " result[is_summer] = [1.0, 0.0]\n", + " result[~is_summer] = [0.0, 1.0]\n", + " return result" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 10, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "is_summer=array([False])\n", + "The predicted class is: winter\n", + "The actual class is: winter\n", + "(1, 28) [[8.1 8.7 9.6 9.4 7.4 9.1 7.4 8.1 7. 4.3 4.4 2.6 3.6 4. 5.4 6.9 7.5 8.6\n", + " 5.6 6.1 7.8 6.1 4.4 0.9 2.8 5.5 3.8 5.9]]\n" + ] + } + ], + "source": [ + "idx = 6 # explained instance\n", + "data_instance = data_test[idx][np.newaxis, ...]\n", + "# precheck ONNX predictions\n", + "pred_onnx = run_expert_model(data_instance)\n", + "pred_class = classes[np.argmax(pred_onnx)]\n", + "print(\"The predicted class is:\", pred_class)\n", + "print(\"The actual class is:\", classes[np.argmax(target_test.iloc[idx])])\n", + "input_image = data_instance[0]\n", + "print(input_image.T.shape, input_image.T)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 11, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 28) [[30.]\n", + " [29.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]\n", + " [ 0.]]\n" + ] + } + ], + "source": [ + "very_cold_to_super_hot = np.expand_dims(np.arange(-6, 35, 1.5), axis=1)\n", + "very_cold = np.expand_dims(np.arange(-6, -4, 1/14), axis=1)\n", + "very_hot = np.expand_dims(np.arange(30, 28, -1/14), axis=1)\n", + "cold_with_2_hot_days = np.expand_dims(np.array([30, 29] + list(np.zeros(26))) , axis=1)\n", + "input_image = cold_with_2_hot_days\n", + "print(input_image.T.shape, input_image)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 12, + "outputs": [ + { + "data": { + "text/plain": "['DE_BILT_temp_max']" + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "columns" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 13, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "using mean 14.649444444444446\n" + ] + } + ], + "source": [ + "train_mean = np.mean(data_train)\n", + "print('using mean ', train_mean)\n", + "def input_train_mean(_data):\n", + " return train_mean" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 14, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Explaining: 100%|██████████| 100/100 [00:00<00:00, 4349.95it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "is_summer=array([False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, True, True, False, True, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " True, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, True, False, False, False, True, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, True, True, False, False, True,\n", + " False, False, False, False, True, False, False, True, True,\n", + " False, False, True, True, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, True, False, False, True, False, False, True,\n", + " True, False, False, True, True, True, False, True, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, False, True, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " True, True, False, False, True, False, False, True, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, True, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, True, False, False, False, False,\n", + " False, True, True, False, False, False, False, True, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, True, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, True, False, False, False, True, False, True,\n", + " False, True, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, True, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, True, False, False, True, True, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, True, True, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, True, True, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " True, True, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, True, False, False, True, False, True, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, True, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, True, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, True, True, True, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, True, False, True, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, True, False, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, True, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, False, True, True, False,\n", + " False, False, False, True, False, True, False, True, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, True, True, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, True, True, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, False, True, False, False, False, False, True, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, True, True, True, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, False, True, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, True,\n", + " True, False, False, False, True, False, True, False, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, True, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, True, False, True, False, True, False, False, False,\n", + " True, True, False, False, True, False, False, False, False,\n", + " False, True, False, False, True, False, False, False, False,\n", + " True, True, True, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, True, False, False, True, True,\n", + " True, False, False, False, True, True, True, False, False,\n", + " False, True, False, False, True, False, False, True, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, True, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, True, True, False, True, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, True, False, False, True, False, False, True,\n", + " True])\n", + "is_summer=array([False, False, True, True, False, False, True, True, False,\n", + " True, False, False, True, False, False, True, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, True, False, False, False, False, False, True,\n", + " False, True, True, True, False, False, False, True, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, True, True, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, True, False, True, False, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, True, False, True, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " True, True, True, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " True, False, True, False, False, True, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " True, False, True, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " True, False, False, True, False, True, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, True, True, True, True, False, False, False, True,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, True, False, True, False,\n", + " True, False, True, True, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, True, False, False, False, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, True, False, False, True, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, True, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, True, False, True, False, False, True, False, False,\n", + " False, False, True, False, True, False, False, True, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, False, True, False, False, True, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, False, False, False, True, True,\n", + " False, True, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, True, False, True, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, True, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, True, True, True, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, True, False, False, True, True, False, True,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, True, False, True, False, False, False, False,\n", + " True, False, True, False, False, True, True, False, True,\n", + " False, False, False, False, False, True, False, False, False,\n", + " True, False, True, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, True, False, True,\n", + " False])\n", + "is_summer=array([False, True, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, True, False, True, True, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " True, True, False, True, False, True, False, False, False,\n", + " False, False, False, False, True, False, True, True, False,\n", + " False, False, False, True, False, False, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, True, True, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, True, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, True, False, True,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " True, True, False, False, False, False, False, False, True,\n", + " False, False, True, False, True, False, True, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, True, False, True, True, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, True, True, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, True, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False, False, False, False, False, False, True, True, True,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, True, False, True,\n", + " False, False, False, True, False, False, False, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, True, False, False, True, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, True, False, False, True, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, True, False, True, False, False, True, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " True, True, True, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, True, False, False, False, True, False,\n", + " False, False, True, False, True, True, False, False, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, False, True, False, False, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, True, True, True,\n", + " False, False, True, False, True, True, True, True, False,\n", + " False, False, False, False, True, True, False, False, True,\n", + " False, False, False, False, True, True, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, True, False, False, False, False, False, False,\n", + " False, True, True, True, False, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, False, True, True, True,\n", + " False, False, False, True, False, False, False, False, True,\n", + " True, True, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, True, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, True, True, False, True, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, True, True, False, False, True, False, False, True,\n", + " False, False, False, False, True, False, True, False, False,\n", + " True, False, False, False, True, False, True, True, False,\n", + " True, True, False, True, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, True, False, True, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, True, False, False, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, True, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, True, False, True, False, False, False, True, True,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([ True, False, False, True, False, False, False, False, False,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, True, True, False, False, False, True, False,\n", + " True, False, True, False, False, True, False, True, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False, True, True, True, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False])\n", + "is_summer=array([ True, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, True, False, True, False,\n", + " False, True, True, False, False, False, False, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, True, False, True, True, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, True, True, True, False,\n", + " False])\n", + "is_summer=array([False, True, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " False, True, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, True, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, True, False, True, True,\n", + " False, True, False, False, False, True, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, True, False, False, True,\n", + " False, False, False, True, False, False, True, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, True, False, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, False, False, True, False, True, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, True, False, False, True, False,\n", + " False, True, False, False, False, False, False, True, True,\n", + " False, False, False, False, True, False, False, True, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " True, True, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, True, False, False, False, False, True, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, True, True, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, True, True, False, True,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, True, True, False, True,\n", + " False, False, False, True, True, False, True, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, True, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, False, False, False, True, False, False, False,\n", + " False, True, False, False, False, False, True, True, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, True, False, False,\n", + " False, False, False, True, False, False, True, False, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, True, True, False, False, True,\n", + " False, False, True, False, False, True, False, False, False,\n", + " True, False, True, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True])\n", + "is_summer=array([False, False, True, False, True, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, False, False, False, True, True, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, False, True, False, True, False,\n", + " False, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, False, False, True, False, True, False, False, True,\n", + " False, True, True, False, False, False, False, True, False,\n", + " True, False, False, False, True, True, True, True, True,\n", + " False, False, False, False, False, False, False, True, True,\n", + " True, True, False, True, True, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, False, True, False, False, False, False,\n", + " True, True, True, True, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, True, False, True, False, False, False, False, True,\n", + " False, False, False, True, False, True, True, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, True, False, True, True, False, False, False, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, True, False, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, True, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, True, True,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, True, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, True, False, False, True, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, True, True, True, False, False, False, False, False,\n", + " True, False, False, False, True, False, True, True, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, True, True, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, True, False, False, False, True, True,\n", + " True, False, False, True, False, True, False, False, False,\n", + " True, True, False, True, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " True, True, False, False, False, False, False, False, True,\n", + " False, False, False, True, True, True, False, True, True,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, True, False, False, False, False,\n", + " False, True, False, True, False, True, False, False, False,\n", + " True, True, False, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, True, False, False, False, False, True,\n", + " True, True, True, False, True, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, False, False, True, False, True,\n", + " False, False, False, False, True, False, True, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, True, True, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, True, False, True, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, True, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, True, False, True, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, True, False, False, True, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([ True, True, True, True, False, False, True, False, False,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, True, True, False, True, False,\n", + " False, True, False, False, True, False, True, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, True, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, True, True, False, True, True, False, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " True, False, True, False, True, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, True, True, False, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, True, False, False, True, False, False, True,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, True, False, True, True, True, True, False, False,\n", + " False, False, False, True, True, True, True, False, False,\n", + " False, False, False, False, True, True, False, True, False,\n", + " True, True, False, False, False, False, True, False, True,\n", + " True])\n", + "is_summer=array([False, False, False, False, True, False, False, False, False,\n", + " False, False, True, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, True, False, True, False, False,\n", + " True, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, True, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, True, False, False, False, False, True, False,\n", + " False, False, True, False, True, False, False, False, True,\n", + " False, True, False, True, False, False, False, False, False,\n", + " True, True, True, False, False, True, False, False, False,\n", + " True, True, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([ True, True, False, False, False, True, False, False, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, True, False, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, True, False, False, True, True, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, True, True, True, False, False, False,\n", + " True, False, False, True, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, True, True, False, False, False, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, True, True,\n", + " False, False, False, True, False, True, True, False, True,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, True, True, False, False, True, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " True, True, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, True, False, False, False,\n", + " False, True, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, True, False, True, True, False, False,\n", + " False, True, False, False, True, False, True, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, True, True, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, True, False,\n", + " True, True, False, False, False, True, False, True, False,\n", + " False, True, True, False, False, False, False, False, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " False, True, False, True, False, False, True, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, True, True,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, True, False, False, False, False,\n", + " False, False, False, True, False, True, False, True, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False])\n", + "is_summer=array([ True, True, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, True, True, False, False, False, False, True,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, True, False, True, False, True, True, True, True,\n", + " False, False, False, True, False, False, False, True, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([ True, True, False, False, False, False, True, False, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, True, False, False, False,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, True, False, True, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, True, False, False, True, False, False, True,\n", + " False, False, True, True, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, True, False, False, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, True, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, True, False, False, True, True, False,\n", + " False, True, True, False, False, False, False, False, True,\n", + " False, True, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, True, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, True, False, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, True, False, True, False, False, False,\n", + " False, True, False, True, False, False, False, False, True,\n", + " False, False, False, True, True, True, False, True, False,\n", + " False])\n", + "is_summer=array([ True, True, False, True, False, False, False, False, False,\n", + " False, False, True, False, True, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, True, False, False, False, False,\n", + " False, False, False, True, True, False, False, True, True,\n", + " False, False, False, False, True, True, True, True, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, True, True, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, True, True, False, False, False, True, False, False,\n", + " True, True, False, False, True, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, True, False, True, False, True,\n", + " True, False, True, False, False, False, False, True, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, True, False, False, False,\n", + " False, True, False, False, False, True, False, False, True,\n", + " True, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, True, True, False,\n", + " False, False, False, True, True, False, False, False, True,\n", + " False, False, True, False, False, True, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, True,\n", + " False, True, True, True, True, False, True, False, False,\n", + " True, True, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, True, True, False, True, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, True, True, False, True,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, True, True, True, False,\n", + " False, False, True, False, True, True, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, True,\n", + " True, False, True, False, True, False, False, True, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, True, False, False, False, True, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, True, False,\n", + " False, True, False, False, True, False, False, True, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, True, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, True, True, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, True, False,\n", + " True, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, True, True, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, True,\n", + " False, False, False, False, True, False, True, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, True, True, False,\n", + " False, False, False, True, False, False, False, True, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, False, False, False, True, False, True,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, False, True, True, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, True, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, True, False, False, False, True, False, False, True,\n", + " True, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, True, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, True, False, True, True, False, False,\n", + " False, True, False, False, False, False, False, True, False,\n", + " True, False, True, False, True, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, True, True, True, False, True, False, False,\n", + " False, True, False, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, True, False, False, True, False, True,\n", + " False, False, False, True, True, False, False, False, False,\n", + " True])\n", + "is_summer=array([ True, False, True, False, False, True, False, True, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, False, False, False, True,\n", + " True, False, False, True, True, False, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, True, True, False, False, True, True, True,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " True, False, True, True, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False])\n", + "is_summer=array([ True, False, True, False, False, False, False, True, True,\n", + " True, False, False, False, False, False, True, False, True,\n", + " False, True, True, False, False, False, False, True, False,\n", + " True, False, False, True, False, False, True, True, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, True, True, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([ True, False, False, False, False, True, True, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, True, False, False, False,\n", + " False])\n", + "is_summer=array([ True, False, True, True, False, False, True, False, True,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, True, False, False, True, False, False, True,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, True, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, True, True,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, True, True, False, True,\n", + " False, False, False, False, False, True, True, False, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, False, False, True, False, True, True, True, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, False, True, False, True, True, True, False, False,\n", + " False, False, True, False, False, False, True, False, True,\n", + " False, False, False, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, True, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False])\n", + "is_summer=array([False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, True,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, True, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, True, False, False, False, True, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, False, False, True, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, True, False, False, False,\n", + " False, False, False, True, False, False, True, False, True,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, True, False, False, False, False, True, False, False,\n", + " True, True, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, True, True, True, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " True, False, False, False, False, True, False, False, False,\n", + " True, False, False, True, False, False, False, True, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, True, False, False, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, True, True, True, False, False, False, False, True,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, True, False, True, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([False, False, False, False, False, False, True, True, False,\n", + " True, False, False, False, False, False, False, False, True,\n", + " False, False, True, False, True, False, True, False, True,\n", + " False, True, False, False, False, False, False, False, False,\n", + " True, True, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, True, True, False,\n", + " False, False, False, True, True, False, False, False, False,\n", + " False, True, False, True, False, False, False, False, True,\n", + " False, False, False, True, False, False, False, True, False,\n", + " True, True, False, False, False, False, True, False, False,\n", + " False])\n", + "is_summer=array([False, False, True, True, False, False, False, False, False,\n", + " True, True, True, False, True, False, False, False, True,\n", + " True, False, False, False, False, True, True, False, False,\n", + " False, False, True, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False, False, True, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, False,\n", + " False, False, True, False, True, False, True, False, False,\n", + " False, False, False, True, True, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, False, False, True, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, False,\n", + " True, False, True, True, False, False, True, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, True, False, False, False, True,\n", + " False])\n", + "is_summer=array([False, True, True, True, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, True, False, False, False,\n", + " False, True, False, False, False, False, False, False, True,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " False, False, False, False, False, False, False, True, False,\n", + " False, False, True, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, False, False, False, False, False,\n", + " True])\n", + "is_summer=array([ True, False, True, False, True, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, True, False, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, True, False, False, True,\n", + " True, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, True, False, True, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])\n", + "is_summer=array([False, False, False, False, False, False, False, False, False,\n", + " True, True, False, False, False, False, False, False, False,\n", + " False, False, True, False, True, True, False, False, False,\n", + " False, False, True, False, False, False, True, False, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, True, False, False, False, False, False,\n", + " False, False, True, False, True, False, False, False, False,\n", + " True, False, True, False, False, True, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True])\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "explanation = dianna.explain_timeseries(run_expert_model, timeseries_data=input_image, method='rise', labels=[0,1], p_keep=0.1, n_masks=10000, mask_type=input_train_mean)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 15, + "outputs": [ + { + "data": { + "text/plain": "array([[1.044, 1.048, 0.142, 0.181, 0.129, 0.145, 0.157, 0.173, 0.163,\n 0.146, 0.15 , 0.143, 0.141, 0.14 , 0.174, 0.146, 0.143, 0.153,\n 0.152, 0.144, 0.167, 0.165, 0.149, 0.157, 0.14 , 0.146, 0.142,\n 0.171]])" + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "explanation[0].T" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 16, + "outputs": [ + { + "data": { + "text/plain": "array([[ 0.99129489, 1. , -0.97170838, -0.88683351, -1. ,\n -0.96517954, -0.9390642 , -0.90424374, -0.92600653, -0.96300326,\n -0.95429815, -0.9695321 , -0.97388466, -0.97606094, -0.90206746,\n -0.96300326, -0.9695321 , -0.94776931, -0.94994559, -0.96735582,\n -0.91730141, -0.92165397, -0.95647443, -0.9390642 , -0.97606094,\n -0.96300326, -0.97170838, -0.9085963 ]])" + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def normalize(data):\n", + " \"\"\"Squash all values into [-1,1] range.\"\"\"\n", + " zero_to_one = (data - np.min(data)) / (np.max(data) - np.min(data))\n", + " return 2*zero_to_one -1\n", + "saliency_map = normalize(explanation[0])\n", + "saliency_map.T" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "code", + "execution_count": 17, + "outputs": [ + { + "data": { + "text/plain": "
", + "image/png": "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WrdujVmzZuHdd99Fhw4dEBgYiLfffhv+/v4YM2aMeJVuALVdB09PTyxcuBBjx46FSqXC5cuXMWfOHAQFBSEyMlLEWtevGTNmYPPmzfj+++/h6upq6Pfj5uYGZ2dnuLm5YcqUKYiJiYGnpyeUSiVmzpyJsLAw9OvXT+Ta15/7XYfLly9j8+bNGDlyJFq0aIGTJ09i9uzZeOihh9CjRw+Ra082T+xha03dp59+KrRu3VpwdHQU+vbtKxw6dEjsKjWqp59+WvDz8xMcHR2Fli1bCk8//bRw6dIlsavVoH755RcBQJVl4sSJgiBUDKF/++23BV9fX8HJyUkIDw8XUlNTxa10A6jtOhQVFQnDhw8XvL29BQcHB6FNmzbC1KlTBbVaLXa161V15w9AWLdunWGbO3fuCC+//LLg4eEhuLi4CI899piQkZEhXqUbwP2uQ3p6uvDQQw8Jnp6egpOTkxAUFCS88cYbQl5enrgVJxIEQSYIgtCYgRcRERGRVLCPEBEREdksBkJERERksxgIERERkc1iIEREREQ2i4EQERER2SwGQkRERGSzGAgRERGRzWIgRERERDaLgRARERHZLAZCREREZLMYCBHZkJs3b0KlUuH99983rDt48CAcHR2NnpBORGQr+KwxIhvz008/YcyYMTh48CA6duyI4OBgjB49GkuXLhW7akREjY6BEJENmjFjBvbu3YvevXvj1KlTOHr0KJycnMSuFhFRo2MgRGSD7ty5g27duuHq1atITk5G9+7dxa4SEZEo2EeIyAZdvnwZN27cgE6nw5UrV8SuDhGRaJgRIrIxWq0Wffv2RXBwMDp27Ijly5fj1KlT8PHxEbtqRESNjoEQkY154403sH37dpw4cQLNmzfH4MGD4ebmhl27doldNSKiRsemMSIbkpiYiOXLl+O///0vlEol5HI5/vvf/+LXX3/FqlWrxK4eEVGjY0aIiIiIbBYzQkRERGSzGAgRERGRzWIgRERERDaLgRARERHZLAZCREREZLMYCBEREZHNYiBERERENouBEBEREdksBkJERERksxgIERERkc1iIEREREQ2i4EQERER2az/Dx8dm0ay7vAcAAAAAElFTkSuQmCC\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": "" + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from dianna import visualization\n", + "heatmap_channel = normalize(explanation[0])\n", + "segments = []\n", + "for i in range(len(heatmap_channel) - 1):\n", + " segments.append({\n", + " 'index': i,\n", + " 'start': i - 0.5,\n", + " 'stop': i + 0.5,\n", + " 'weight': heatmap_channel[i]})\n", + "visualization.plot_timeseries(range(len(heatmap_channel)), input_image, segments, show_plot=True)\n" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + } + ], + "metadata": { + "kernelspec": { + "name": "python3", + "language": "python", + "display_name": "Python 3 (ipykernel)" + }, + "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.10.6" + }, + "vscode": { + "interpreter": { + "hash": "951e587de391aa2bb289e8fbd39b65d4ffaa4789dc01c18d4fc05216cb0e7d1f" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file