# Path: mimic3models/keras_utils.py
# class DecompensationMetrics(keras.callbacks.Callback):
# class InHospitalMortalityMetrics(keras.callbacks.Callback):
# class PhenotypingMetrics(keras.callbacks.Callback):
# class LengthOfStayMetrics(keras.callbacks.Callback):
# class MultitaskMetrics(keras.callbacks.Callback):
# class CollectAttetion(Layer):
# class Slice(Layer):
# class GetTimestep(Layer):
# class ExtendMask(Layer):
#     def __init__(self, train_data_gen, val_data_gen, deep_supervision,
#                  batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data, val_data, target_repl, batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, batch_size=32,
#                  early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, partition, batch_size=32,
#                  early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, partition,
#                  batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
# def softmax(x, axis, mask=None):
# def _collect_attention(x, a, mask):
#     def __init__(self, **kwargs):
#     def call(self, inputs, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def __init__(self, indices, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#     def __init__(self, pos=-1, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#     def __init__(self, add_epsilon=False, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#         B = self.batch_size


from keras.models import Model
from keras.layers import Input, Dense, LSTM, Masking, Dropout
from keras.layers.wrappers import TimeDistributed
from mimic3models.keras_utils import Slice, GetTimestep, LastTimestep, ExtendMask
from keras.layers.merge import Concatenate, Multiply
            if ch.find("mask->") != -1:
                continue
            pos = ch.find("->")
            if pos != -1:
                channel_names.add(ch[:pos])
            else:
                channel_names.add(ch)
        channel_names = sorted(list(channel_names))
        print("==> found {} channels: {}".format(len(channel_names), channel_names))

        channels = []  # each channel is a list of columns
        for ch in channel_names:
            indices = range(len(header))
            indices = list(filter(lambda i: header[i].find(ch) != -1, indices))
            channels.append(indices)

        # Input layers and masking
        X = Input(shape=(None, input_dim), name='X')
        mX = Masking()(X)

        # Masks
        ihm_M = Input(shape=(1,), name='ihm_M')
        decomp_M = Input(shape=(None,), name='decomp_M')
        los_M = Input(shape=(None,), name='los_M')

        inputs = [X, ihm_M, decomp_M, los_M]

        # Preprocess each channel
        cX = []
        for ch in channels:

# Path: mimic3models/keras_utils.py
# class DecompensationMetrics(keras.callbacks.Callback):
# class InHospitalMortalityMetrics(keras.callbacks.Callback):
# class PhenotypingMetrics(keras.callbacks.Callback):
# class LengthOfStayMetrics(keras.callbacks.Callback):
# class MultitaskMetrics(keras.callbacks.Callback):
# class CollectAttetion(Layer):
# class Slice(Layer):
# class GetTimestep(Layer):
# class ExtendMask(Layer):
#     def __init__(self, train_data_gen, val_data_gen, deep_supervision,
#                  batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data, val_data, target_repl, batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, batch_size=32,
#                  early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, partition, batch_size=32,
#                  early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
#     def __init__(self, train_data_gen, val_data_gen, partition,
#                  batch_size=32, early_stopping=True, verbose=2):
#     def calc_metrics(self, data_gen, history, dataset, logs):
#     def on_epoch_end(self, epoch, logs={}):
# def softmax(x, axis, mask=None):
# def _collect_attention(x, a, mask):
#     def __init__(self, **kwargs):
#     def call(self, inputs, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def __init__(self, indices, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#     def __init__(self, pos=-1, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#     def __init__(self, add_epsilon=False, **kwargs):
#     def call(self, x, mask=None):
#     def compute_output_shape(self, input_shape):
#     def compute_mask(self, input, input_mask=None):
#     def get_config(self):
#         B = self.batch_size


# Path: mimic3models/keras_models/multitask_channel_wise_lstms.py
from keras.models import Model
from keras.layers import Input, Dense, LSTM, Masking, Dropout
from keras.layers.wrappers import TimeDistributed
from mimic3models.keras_utils import Slice, GetTimestep, LastTimestep, ExtendMask
from keras.layers.merge import Concatenate, Multiply

            if ch.find("mask->") != -1:
                continue
            pos = ch.find("->")
            if pos != -1:
                channel_names.add(ch[:pos])
            else:
                channel_names.add(ch)
        channel_names = sorted(list(channel_names))
        print("==> found {} channels: {}".format(len(channel_names), channel_names))

        channels = []  # each channel is a list of columns
        for ch in channel_names:
            indices = range(len(header))
            indices = list(filter(lambda i: header[i].find(ch) != -1, indices))
            channels.append(indices)

        # Input layers and masking
        X = Input(shape=(None, input_dim), name='X')
        mX = Masking()(X)

        # Masks
        ihm_M = Input(shape=(1,), name='ihm_M')
        decomp_M = Input(shape=(None,), name='decomp_M')
        los_M = Input(shape=(None,), name='los_M')

        inputs = [X, ihm_M, decomp_M, los_M]

        # Preprocess each channel
        cX = []
        for ch in channels:

            cX.append(Slice(ch)(mX))