# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 48054, "status": "ok", "timestamp": 1573636583219, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="2mU_ZLUH5jz4" outputId="c4cbc445-56dd-49df-de87-c34e18da5f6c"
import tensorflow as tf
import glob
import nibabel as nib
import os
import time

import pandas as pd
import numpy as np

from mricode.utils import log_textfile
from mricode.utils import copy_colab

tf.__version__
# -

tf.test.is_gpu_available()

# + colab={} colab_type="code" id="nH4XzW8C5yhH"
path_output = './'
path_tfrecords = '/data2/res64/down/'
path_csv = '/data2/csv/'
#path_csv = '/content/drive/My Drive/Capstone/05_Data/01_Label/'
filename_res = {'train': 'intell_residual_train.csv', 'val': 'intell_residual_valid.csv', 'test': 'intell_residual_test.csv'}
filename_norm = {'train': 'intell_train.csv', 'val': 'intell_valid.csv', 'test': 'intell_test.csv'}
filename_fluid = {'train': 'training_fluid_intelligence_sri.csv', 'val': 'validation_fluid_intelligence_sri.csv', 'test': 'test_fluid_intelligence_sri.csv'}
filename_final = filename_res
sample_size = 'site16_allimages'
batch_size = 8
onlyt1 = False
t1_mean = 0.35196779465675354 
t2_mean = 0.5694633522033692
t1_std = 0.8948413240464094
t2_std = 1.2991791534423829

# + colab={} colab_type="code" id="ZzpJsO5Rx_LM"


# + colab={} colab_type="code" id="96CI6bJ26JIo"
def return_iter(path, sample_size, batch_size=8, onlyt1=False):
  # Some definitions
  if onlyt1:
    read_features = {
      't1': tf.io.FixedLenFeature([], dtype=tf.string),
      'subjectid': tf.io.FixedLenFeature([], dtype=tf.string)
    }
  else:
    read_features = {
      't1': tf.io.FixedLenFeature([], dtype=tf.string),
      't2': tf.io.FixedLenFeature([], dtype=tf.string),
      'subjectid': tf.io.FixedLenFeature([], dtype=tf.string)
    }
  def _parse_(serialized_example, decoder = np.vectorize(lambda x: x.decode('UTF-8')), onlyt1=False):
    example = tf.io.parse_single_example(serialized_example, read_features)
    subjectid = example['subjectid']
    if not(onlyt1):
      t1 = tf.expand_dims(tf.reshape(tf.io.decode_raw(example['t1'], tf.int8), (64,64,64)), axis=-1)
      t2 = tf.expand_dims(tf.reshape(tf.io.decode_raw(example['t2'], tf.float32), (64,64,64)), axis=-1)
      return ({'t1': t1, 't2': t2, 'subjectid': subjectid})
    else:
      t1 = tf.expand_dims(tf.reshape(tf.io.decode_raw(example['t1'], tf.int8), (256,256,256)), axis=-1)
      return ({'t1': t1, 'subjectid': subjectid})
  
  train_ds = tf.data.TFRecordDataset(path +'t1t2_train_' + str(sample_size) + '_v4.tfrecords')
  val_ds = tf.data.TFRecordDataset(path + 't1t2_val_' + str(sample_size) + '_v4.tfrecords')
  test_ds = tf.data.TFRecordDataset(path + 't1t2_test_' + str(sample_size) + '_v4.tfrecords')
  train_iter = train_ds.map(lambda x:_parse_(x, onlyt1=onlyt1)).shuffle(True).batch(batch_size)
  val_iter = val_ds.map(lambda x:_parse_(x, onlyt1=onlyt1)).batch(batch_size)
  test_iter = test_ds.map(lambda x:_parse_(x, onlyt1=onlyt1)).batch(batch_size)
  return train_iter, val_iter, test_iter

def return_csv(path, filenames={'train': 'intell_train.csv', 'val': 'intell_valid.csv', 'test': 'intell_test.csv'}, fluid = False):
  train_df = pd.read_csv(path + filenames['train'])
  val_df = pd.read_csv(path + filenames['val'])
  test_df = pd.read_csv(path + filenames['test'])
  norm = None
  if fluid:
    train_df.columns = ['subjectkey', 'fluid_res', 'fluid']
    val_df.columns = ['subjectkey', 'fluid_res', 'fluid']
    test_df.columns = ['subjectkey', 'fluid_res', 'fluid']
  train_df['subjectkey'] = train_df['subjectkey'].str.replace('_', '')
  val_df['subjectkey'] = val_df['subjectkey'].str.replace('_', '')
  test_df['subjectkey'] = test_df['subjectkey'].str.replace('_', '')
  if not(fluid):
    for df in [train_df, val_df, test_df]:
      df['race.ethnicity'] = df['race.ethnicity'] - 1
      df['married'] = df['married'] - 1
      df['high.educ_group'] = 0
      df.loc[(train_df['high.educ']>=11) & (df['high.educ']<=12),'high.educ_group'] = 1
      df.loc[(train_df['high.educ']>=13) & (df['high.educ']<=13),'high.educ_group'] = 2
      counter = 3
      for i in range(14,22):
        df.loc[(df['high.educ']>=i) & (df['high.educ']<=i),'high.educ_group'] = counter
      df['income_group'] = 0
      counter = 1
      for i in range(4,11):
        df.loc[(df['income']>=i) & (df['income']<=i),'income_group'] = counter
        counter += 1
    norm = {}
    for col in ['BMI', 'age', 'vol', 'weight', 'height', 'nihtbx_fluidcomp_uncorrected', 'nihtbx_cryst_uncorrected', 
                'nihtbx_pattern_uncorrected', 'nihtbx_picture_uncorrected', 
                'nihtbx_list_uncorrected', 'nihtbx_flanker_uncorrected',
                'nihtbx_picvocab_uncorrected', 'nihtbx_cardsort_uncorrected',
                'nihtbx_totalcomp_uncorrected', 'nihtbx_reading_uncorrected']:
      mean = train_df[col].mean()
      std = train_df[col].std()
      train_df[col + '_norm'] = (train_df[col]-mean)/std
      val_df[col + '_norm'] = (val_df[col]-mean)/std
      test_df[col + '_norm'] = (test_df[col]-mean)/std
      norm[col] = {'mean': mean, 'std': std}
  return train_df, val_df, test_df, norm


# + colab={"base_uri": "https://localhost:8080/", "height": 71} colab_type="code" executionInfo={"elapsed": 4520, "status": "ok", "timestamp": 1573636640714, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="B-rSS9vT6TuF" outputId="f5b43cbc-7d59-4c7c-b6d6-78882b1ef3e1"
train_iter, val_iter, test_iter = return_iter(path_tfrecords, sample_size, batch_size, onlyt1=onlyt1)

# + colab={} colab_type="code" id="_WxRhswDxB6a"
a = next(iter(train_iter))

# + colab={} colab_type="code" id="lJ0VnyEzBAes"
if False:
  t1_mean = 0.
  t1_std = 0.
  t2_mean = 0.
  t2_std = 0.
  n = 0.
  for b in train_iter:
      t1_mean += np.mean(b['t1'])
      t1_std += np.std(b['t1'])
      t2_mean += np.mean(b['t2'])
      t2_std += np.std(b['t2'])
      n += np.asarray(b['t1']).shape[0]

  t1_mean /= n
  t1_std /= n
  t2_mean /= n
  t2_std /= n

# + colab={"base_uri": "https://localhost:8080/", "height": 85} colab_type="code" executionInfo={"elapsed": 2924, "status": "ok", "timestamp": 1573636640716, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="mSwhEqDPM_r8" outputId="14a4ac0b-9587-4776-fc64-1e008f0c5c31"
t1_mean, t1_std, t2_mean, t2_std

# + colab={} colab_type="code" id="PAyV5ktlA6K1"
train_df, val_df, test_df, norm_dict = return_csv(path_csv, filename_final, False)

# + colab={"base_uri": "https://localhost:8080/", "height": 442} colab_type="code" executionInfo={"elapsed": 3147, "status": "ok", "timestamp": 1573636641787, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="0xYy4XUyVBeC" outputId="a6a19d59-31ff-4064-f1dc-952befcce4b3"
norm_dict

# + colab={"base_uri": "https://localhost:8080/", "height": 697} colab_type="code" executionInfo={"elapsed": 2660, "status": "ok", "timestamp": 1573636641788, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="_SVRoaUTgv1O" outputId="7b86ff58-14d7-488a-9b56-4962b095211e"
train_df.max()

# + colab={} colab_type="code" id="FmJMaxLJLIgE"
import tensorflow as tf
from tensorflow.keras.layers import Conv3D
from tensorflow import nn
from tensorflow.python.ops import nn_ops
from tensorflow.python.framework import tensor_shape
from tensorflow.python.keras.engine.base_layer import InputSpec
from tensorflow.python.keras.utils import conv_utils

# + colab={} colab_type="code" id="eTk95ptFV5oN"
cat_cols = {'female': 2, 'race.ethnicity': 5, 'high.educ_group': 4, 'income_group': 8, 'married': 6}
#cat_cols = {}
num_cols = [x for x in list(val_df.columns) if '_norm' in x]
#num_cols = num_cols[0:3]

# + colab={"base_uri": "https://localhost:8080/", "height": 272} colab_type="code" executionInfo={"elapsed": 1134, "status": "ok", "timestamp": 1573636642235, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="gSh5zfycjI7A" outputId="b7a137d4-fb48-413e-9307-fcab56fc28d8"
num_cols

# + colab={} colab_type="code" id="1j3q7l7DDWSq"
from tensorflow.keras import Model

class MyDNN(Model):
  def __init__(self, cat_cols, num_cols):
    super(MyDNN, self).__init__()
    self.cat_cols = cat_cols
    self.num_cols = num_cols
    self.ac = tf.keras.layers.ReLU()
    self.maxpool = tf.keras.layers.MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last')
    self.conv1 = tf.keras.layers.Conv3D(
        filters = 1,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn1 = tf.keras.layers.BatchNormalization()
    self.conv2 = tf.keras.layers.Conv3D(
        filters = 16,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn2 = tf.keras.layers.BatchNormalization()
    self.conv3 = tf.keras.layers.Conv3D(
        filters = 32,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn3 = tf.keras.layers.BatchNormalization()
    self.conv4 = tf.keras.layers.Conv3D(
        filters = 256,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn4 = tf.keras.layers.BatchNormalization()
    self.fc = {}
    for k in list(self.cat_cols.keys()):
      self.fc[k] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(self.cat_cols[k], activation='softmax')
                                        ])
    for i in range(len(self.num_cols)):
      self.fc[self.num_cols[i]] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(1)
                                        ])
    #self.fc1 = tf.keras.Sequential([
    #                                    tf.keras.layers.Dense(256, activation='relu'),
    #                                    tf.keras.layers.BatchNormalization(),
    #                                    tf.keras.layers.Dense(1)
    #                                    ])
    #self.fc2 = tf.keras.Sequential([
    #                                tf.keras.layers.Dense(256, activation='relu'),
    #                                tf.keras.layers.BatchNormalization(),
    #                                tf.keras.layers.Dense(1)
    #                                ])
    #self.fc3 = tf.keras.Sequential([
    #                                tf.keras.layers.Dense(256, activation='relu'),
    #                                tf.keras.layers.BatchNormalization(),
    #                                tf.keras.layers.Dense(1)
    #                                ])

  def call(self, x):
    x = self.conv1(x)
    x = self.bn1(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv2(x)
    x = self.bn2(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv3(x)
    x = self.bn3(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv4(x)
    x = self.bn4(x)
    x = self.ac(x)
    x = tf.keras.layers.GlobalAveragePooling3D()(x)
    out = {}
    for k in list(self.fc.keys()):
      out[k] = self.fc[k](x)
    #['age_norm', 'vol_norm', 'weight_norm']
    #out['age_norm'] = self.fc1(x)
    #out['vol_norm'] = self.fc2(x)
    #out['weight_norm'] = self.fc3(x)
    return out


# + colab={} colab_type="code" id="pwzdY28gkCdN"
from tensorflow.keras import Model

class MyDNN(Model):
  def __init__(self, cat_cols, num_cols):
    super(MyDNN, self).__init__()
    self.cat_cols = cat_cols
    self.num_cols = num_cols
    self.ac = tf.keras.layers.ReLU()
    self.maxpool = tf.keras.layers.MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last')
    self.conv1 = tf.keras.layers.Conv3D(
        filters = 32,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last',
        input_shape = (64,64,64,2)
    )
    self.bn1 = tf.keras.layers.BatchNormalization()
    self.conv2 = tf.keras.layers.Conv3D(
        filters = 64,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn2 = tf.keras.layers.BatchNormalization()
    self.conv3 = tf.keras.layers.Conv3D(
        filters = 128,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn3 = tf.keras.layers.BatchNormalization()
    self.conv4 = tf.keras.layers.Conv3D(
        filters = 256,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn4 = tf.keras.layers.BatchNormalization()
    self.fc = {}
    for k in list(self.cat_cols.keys()):
      self.fc[k] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(self.cat_cols[k], activation='softmax')
                                        ])
    for i in range(len(self.num_cols)):
      self.fc[self.num_cols[i]] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(1)
                                        ])

  def call(self, x):
    x = self.conv1(x)
    x = self.bn1(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv2(x)
    x = self.bn2(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv3(x)
    x = self.bn3(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv4(x)
    x = self.bn4(x)
    x = self.ac(x)
    x = tf.keras.layers.GlobalAveragePooling3D()(x)
    out = {}
    for k in list(self.fc.keys()):
      out[k] = self.fc[k](x)
    return out


# + colab={} colab_type="code" id="q9PZkxi_k5b-"
from tensorflow.keras import Model

class MyDNN(Model):
  def __init__(self, cat_cols, num_cols):
    super(MyDNN, self).__init__()
    self.cat_cols = cat_cols
    self.num_cols = num_cols
    self.ac = tf.keras.layers.ReLU()
    self.maxpool = tf.keras.layers.MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last')
    self.conv1 = tf.keras.layers.Conv3D(
        filters = 32,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last',
        input_shape = (64,64,64,2)
    )
    self.bn1 = tf.keras.layers.BatchNormalization()
    self.conv2 = tf.keras.layers.Conv3D(
        filters = 64,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn2 = tf.keras.layers.BatchNormalization()
    self.conv3 = tf.keras.layers.Conv3D(
        filters = 128,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn3 = tf.keras.layers.BatchNormalization()
    self.conv4 = tf.keras.layers.Conv3D(
        filters = 256,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last',
        name='lastconv_1'
    )
    self.bn4 = tf.keras.layers.BatchNormalization()
    self.fc = {}
    for k in list(self.cat_cols.keys()):
      self.fc[k] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(self.cat_cols[k], activation='softmax', name='output_' + k)
                                        ])
    for i in range(len(self.num_cols)):
      self.fc[self.num_cols[i]] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(1)
                                        ])

  def call(self, x):
    x = self.conv1(x)
    x = self.bn1(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv2(x)
    x = self.bn2(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv3(x)
    x = self.bn3(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv4(x)
    x = self.bn4(x)
    x = self.ac(x)
    x = tf.keras.layers.GlobalAveragePooling3D()(x)
    out = {}
    for k in list(self.fc.keys()):
      out[k] = self.fc[k](x)
    return out


# + colab={} colab_type="code" id="tpab_A9TDYeK"
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adam(lr = 0.001)


# + colab={} colab_type="code" id="hROMApYiDagm"
def calc_loss_acc(out_loss, out_acc, y_true, y_pred, cat_cols, num_cols, norm_dict):
  for col in num_cols:
    tmp_col = col
    tmp_std = norm_dict[tmp_col.replace('_norm','')]['std']
    tmp_y_true = tf.cast(y_true[col], tf.float32).numpy()
    tmp_y_pred = np.squeeze(y_pred[col].numpy())
    if not(tmp_col in out_loss):
      out_loss[tmp_col] = np.sum(np.square(tmp_y_true-tmp_y_pred))
    else:
      out_loss[tmp_col] += np.sum(np.square(tmp_y_true-tmp_y_pred))
    if not(tmp_col in out_acc):
      out_acc[tmp_col] = np.sum(np.square((tmp_y_true-tmp_y_pred)*tmp_std))
    else:
      out_acc[tmp_col] += np.sum(np.square((tmp_y_true-tmp_y_pred)*tmp_std))
  for col in list(cat_cols.keys()):
    tmp_col = col
    if not(tmp_col in out_loss):
      out_loss[tmp_col] = tf.keras.losses.SparseCategoricalCrossentropy()(tf.squeeze(y_true[col]), tf.squeeze(y_pred[col])).numpy()
    else:
      out_loss[tmp_col] += tf.keras.losses.SparseCategoricalCrossentropy()(tf.squeeze(y_true[col]), tf.squeeze(y_pred[col])).numpy()
    if not(tmp_col in out_acc):
      out_acc[tmp_col] = tf.reduce_sum(tf.dtypes.cast((y_true[col] == tf.argmax(y_pred[col], axis=-1)), tf.float32)).numpy()
    else:
      out_acc[tmp_col] += tf.reduce_sum(tf.dtypes.cast((y_true[col] == tf.argmax(y_pred[col], axis=-1)), tf.float32)).numpy()    
  return(out_loss, out_acc)

def format_output(out_loss, out_acc, n, cols, print_bl=False):
  loss = 0
  acc = 0
  output = []
  for col in cols:
    output.append([col, out_loss[col]/n, out_acc[col]/n])
    loss += out_loss[col]/n
    acc += out_acc[col]/n
  df = pd.DataFrame(output)
  df.columns = ['name', 'loss', 'acc']
  if print_bl:
    print(df)
  return(loss, acc, df)

@tf.function
def train_step(X, y, model, optimizer, cat_cols, num_cols):
  with tf.GradientTape() as tape:
    predictions = model(X)
    i = 0
    loss = tf.keras.losses.MSE(tf.cast(y[num_cols[i]], tf.float32), tf.squeeze(predictions[num_cols[i]]))
    for i in range(1,len(num_cols)):
      loss += tf.keras.losses.MSE(tf.cast(y[num_cols[i]], tf.float32), tf.squeeze(predictions[num_cols[i]]))
    for col in list(cat_cols.keys()):
      loss += tf.keras.losses.SparseCategoricalCrossentropy()(tf.squeeze(y[col]), tf.squeeze(predictions[col]))
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return(y, predictions, loss)

@tf.function
def test_step(X, y, model):
  predictions = model(X)
  return(y, predictions)

def epoch(data_iter, df, model, optimizer, cat_cols, num_cols, norm_dict):
  out_loss = {}
  out_acc = {}
  n = 0.
  n_batch = 0.
  total_time_dataload = 0.
  total_time_model = 0.
  start_time = time.time()
  for batch in data_iter:
    total_time_dataload += time.time() - start_time
    start_time = time.time()
    t1 = (tf.cast(batch['t1'], tf.float32)-t1_mean)/t1_std
    t2 = (batch['t2']-t2_mean)/t2_std
    subjectid = decoder(batch['subjectid'])
    y = get_labels(df, subjectid, list(cat_cols.keys())+num_cols)
    X = tf.concat([t1, t2], axis=4)
    if optimizer != None:
      y_true, y_pred, loss = train_step(X, y, model, optimizer, cat_cols, num_cols)
    else:
      y_true, y_pred = test_step(X, y, model)
    out_loss, out_acc = calc_loss_acc(out_loss, out_acc, y_true, y_pred, cat_cols, num_cols, norm_dict)
    n += X.shape[0]
    n_batch += 1
    if (n_batch % 10) == 0:
      print(n_batch)
    total_time_model += time.time() - start_time
    start_time = time.time()
  return (out_loss, out_acc, n, total_time_model, total_time_dataload)

def get_labels(df, subjectid, cols = ['nihtbx_fluidcomp_uncorrected_norm']):
  subjects_df = pd.DataFrame(subjectid)
  result_df = pd.merge(subjects_df, df, left_on=0, right_on='subjectkey', how='left')
  output = {}
  for col in cols:
    output[col] = np.asarray(result_df[col].values)
  return output

def best_val(df_best, df_val, df_test):
  df_best = pd.merge(df_best, df_val, how='left', left_on='name', right_on='name')
  df_best = pd.merge(df_best, df_test, how='left', left_on='name', right_on='name')
  df_best.loc[df_best['best_loss_val']>=df_best['cur_loss_val'], 'best_loss_test'] = df_best.loc[df_best['best_loss_val']>=df_best['cur_loss_val'], 'cur_loss_test']
  df_best.loc[df_best['best_loss_val']>=df_best['cur_loss_val'], 'best_loss_val'] = df_best.loc[df_best['best_loss_val']>=df_best['cur_loss_val'], 'cur_loss_val']
  df_best.loc[(df_best['best_acc_val']<=df_best['cur_acc_val'])&(df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'best_acc_test'] = df_best.loc[(df_best['best_acc_val']<=df_best['cur_acc_val'])&(df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'cur_acc_test']
  df_best.loc[(df_best['best_acc_val']<=df_best['cur_acc_val'])&(df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'best_acc_val'] = df_best.loc[(df_best['best_acc_val']<=df_best['cur_acc_val'])&(df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'cur_acc_val']
  df_best.loc[(df_best['best_acc_val']>=df_best['cur_acc_val'])&(~df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'best_acc_test'] = df_best.loc[(df_best['best_acc_val']>=df_best['cur_acc_val'])&(~df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'cur_acc_test']
  df_best.loc[(df_best['best_acc_val']>=df_best['cur_acc_val'])&(~df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'best_acc_val'] = df_best.loc[(df_best['best_acc_val']>=df_best['cur_acc_val'])&(~df_best['name'].isin(['female', 'race.ethnicity', 'high.educ_group', 'income_group', 'married'])), 'cur_acc_val']
  df_best = df_best.drop(['cur_loss_val', 'cur_acc_val', 'cur_loss_test', 'cur_acc_test'], axis=1)
  return(df_best)


# + colab={"base_uri": "https://localhost:8080/", "height": 357} colab_type="code" executionInfo={"elapsed": 415, "status": "ok", "timestamp": 1573636653401, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="8iQKsZftjsPR" outputId="22d8df05-3f92-4c31-d831-e9308b0db4c9"
cat_cols, num_cols

# + colab={} colab_type="code" id="XK13wNFtoIC4"
modelname = 'site16_downsample_t1t2_test_'

# + colab={"base_uri": "https://localhost:8080/", "height": 1000} colab_type="code" executionInfo={"elapsed": 46355, "status": "ok", "timestamp": 1573636701683, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="RV24LE3k-00n" outputId="067125be-6ce2-40c9-998e-62f800ccb2f1"
decoder = np.vectorize(lambda x: x.decode('UTF-8'))
template = 'Epoch {0}, Loss: {1:.3f}, Accuracy: {2:.3f}, Val Loss: {3:.3f}, Val Accuracy: {4:.3f}, Time Model: {5:.3f}, Time Data: {6:.3f}'
for col in [0]:
  log_textfile(path_output + modelname + 'multitask_test' + '.log', cat_cols),
  log_textfile(path_output + modelname + 'multitask_test' + '.log', num_cols)
  loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
  optimizer = tf.keras.optimizers.Adam(lr = 0.001)
  model = MyDNN(cat_cols, num_cols)
  df_best = None
  for e in range(10):
    log_textfile(path_output + modelname + 'multitask_test' + '.log', 'Epochs: ' + str(e))
    loss = tf.Variable(0.)
    acc = tf.Variable(0.) 
    val_loss = tf.Variable(0.)
    val_acc = tf.Variable(0.)
    test_loss = tf.Variable(0.)
    test_acc = tf.Variable(0.)  
    train_out_loss, train_out_acc, n, time_model, time_data = epoch(train_iter, train_df, model, optimizer, cat_cols, num_cols, norm_dict)
    val_out_loss, val_out_acc, n, _, _ = epoch(val_iter, val_df, model, None, cat_cols, num_cols, norm_dict)
    test_out_loss, test_out_acc, n, _, _ = epoch(test_iter, test_df, model, None, cat_cols, num_cols, norm_dict)
    loss, acc, _ = format_output(train_out_loss, train_out_acc, n, list(cat_cols.keys())+num_cols)
    val_loss, val_acc, df_val = format_output(val_out_loss, val_out_acc, n, list(cat_cols.keys())+num_cols, print_bl=False)
    test_loss, test_acc, df_test = format_output(test_out_loss, test_out_acc, n, list(cat_cols.keys())+num_cols, print_bl=False)
    df_val.columns = ['name', 'cur_loss_val', 'cur_acc_val']
    df_test.columns = ['name', 'cur_loss_test', 'cur_acc_test']
    if e == 0:
      df_best = pd.merge(df_test, df_val, how='left', left_on='name', right_on='name')
      df_best.columns = ['name', 'best_loss_test', 'best_acc_test', 'best_loss_val', 'best_acc_val']
    df_best = best_val(df_best, df_val, df_test)
    print(df_best[['name', 'best_loss_test', 'best_acc_test']])
    print(df_best[['name', 'best_loss_val', 'best_acc_val']])
    log_textfile(path_output +  modelname + 'multitask_test' + '.log', template.format(e, loss, acc, val_loss, val_acc, time_model, time_data))
    df_best.to_csv(path_output +  modelname + 'multitask_test' + '.csv')

# + colab={"base_uri": "https://localhost:8080/", "height": 241} colab_type="code" executionInfo={"elapsed": 52176, "status": "ok", "timestamp": 1573636708782, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="ENiEqcTM2o5b" outputId="7661277a-f2b1-485e-fbfb-85fc5e7d9c94"
# !pip install tf-explain

# + colab={"base_uri": "https://localhost:8080/", "height": 190} colab_type="code" executionInfo={"elapsed": 57697, "status": "ok", "timestamp": 1573636714920, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="je8ZbBq3tZys" outputId="3c420738-3d47-44ed-9f75-25a268651cf3"
# !pip install nilearn

# + colab={"base_uri": "https://localhost:8080/", "height": 71} colab_type="code" executionInfo={"elapsed": 56450, "status": "ok", "timestamp": 1573636715232, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="cv99Rx9vtUBF" outputId="ad64ddb7-7353-4df0-fe1e-f3b4ac938005"
import glob
from nilearn import plotting
import matplotlib.pyplot as plt
import nilearn
import numpy as np
import nibabel as nib
from nilearn.image import crop_img
import os
import tqdm

# %matplotlib inline

# + colab={} colab_type="code" id="tyWmz3FstC8G"
a = next(iter(test_iter))
t1 = (tf.cast(a['t1'], tf.float32)-t1_mean)/t1_std
t2 = (a['t2']-t2_mean)/t2_std
X = tf.concat([t1, t2], axis=4)

# + colab={} colab_type="code" id="k1J0Fsn1Ijr2"
inputs = tf.keras.Input(shape=(64,64,64,2), name='inputlayer123')
a = model(inputs)['female']
mm = Model(inputs=inputs, outputs=a)

# + colab={"base_uri": "https://localhost:8080/", "height": 221} colab_type="code" executionInfo={"elapsed": 54985, "status": "ok", "timestamp": 1573636716755, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="1yvswMaT2lKD" outputId="bcc1195f-8702-4a2b-c41d-f264fb24143c"
mm.summary()

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1327, "status": "ok", "timestamp": 1573636746552, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="4rORUysK2cM3" outputId="03452a7a-6db7-4f87-b1be-f05fbdb00b2a"
mm.get_layer('my_dnn').get_layer('lastconv_1').output

# + colab={} colab_type="code" id="wf3u-dJ1PIT_"
from tf_explain.core.smoothgrad import SmoothGrad
explainer = SmoothGrad()
grid = explainer.explain((X[0:1], _), mm, 0, 20, 1.)

# + colab={"base_uri": "https://localhost:8080/", "height": 218} colab_type="code" executionInfo={"elapsed": 4327, "status": "ok", "timestamp": 1573636753055, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="SsBZysWOs34f" outputId="fe3a9a63-539e-4e88-a10b-57738791cd7f"
ppp = '/content/drive/My Drive/Capstone/05_Data/02_Sample_MRI/downsampled_resize/T2/sub-NDARINVFJJPAA2A_T2.nii.gz'
org = nib.load(ppp)
plotting.plot_anat(nilearn.image.new_img_like(ppp, grid, affine=None, copy_header=False))
plotting.show()

# + colab={} colab_type="code" id="-G7cjveLADUG"
from tf_explain.core.occlusion_sensitivity import OcclusionSensitivity

# + colab={} colab_type="code" id="nhXfjGsxADeD"
explainer = OcclusionSensitivity()

# + colab={} colab_type="code" id="_gGRXRJSADkG"
?? OcclusionSensitivity

# + colab={"base_uri": "https://localhost:8080/", "height": 351} colab_type="code" executionInfo={"elapsed": 4225, "status": "error", "timestamp": 1573636765486, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="Q1GJABrBBDOx" outputId="8b8bc278-991b-4a4a-dbb0-dea4c55ffeee"
sensitivity_maps = np.array(
            [
                explainer.get_sensitivity_map(mm, X[0], 0, 4)
            ]
        )

# + colab={} colab_type="code" id="o3SM73D7BVZS"
image = X[0]
patch_size = 4
class_index=0

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1766, "status": "ok", "timestamp": 1573637561679, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="mOYf3Oh0G42B" outputId="1c2d487b-7d54-4afa-efef-9b2242d897c3"
image.shape


# + colab={} colab_type="code" id="yCP9mb_bC6SR"
def apply_grey_patch(image, top_left_x, top_left_y, top_left_z, patch_size):
    """
    Replace a part of the image with a grey patch.
    Args:
        image (numpy.ndarray): Input image
        top_left_x (int): Top Left X position of the applied box
        top_left_y (int): Top Left Y position of the applied box
        patch_size (int): Size of patch to apply
    Returns:
        numpy.ndarray: Patched image
    """
    patched_image = np.array(image, copy=True)
    patched_image[
        top_left_x : top_left_x + patch_size, top_left_y : top_left_y + patch_size, top_left_z : top_left_z + patch_size, 0
    ] = 0

    return patched_image

import math

sensitivity_map = np.zeros((
    math.ceil(image.shape[0] / patch_size),
    math.ceil(image.shape[1] / patch_size),
    math.ceil(image.shape[2] / patch_size),
))

# + colab={"base_uri": "https://localhost:8080/", "height": 289} colab_type="code" executionInfo={"elapsed": 41009, "status": "ok", "timestamp": 1573637656803, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="urOT4dZqFzvY" outputId="2476c3b8-e514-40a0-b2a7-0e70bad97ad0"
for index_z, top_left_z in enumerate(range(0, image.shape[2], patch_size)):
  print(index_z, top_left_z)
  patches = [
             apply_grey_patch(image, top_left_x, top_left_y, top_left_z, patch_size)
             for index_x, top_left_x in enumerate(range(0, image.shape[0], patch_size))
             for index_y, top_left_y in enumerate(range(0, image.shape[1], patch_size))
            ]
  coordinates = [
               (index_y, index_x)
               for index_x, _ in enumerate(range(0, image.shape[0], patch_size))
               for index_y, _ in enumerate(range(0, image.shape[1], patch_size))
               ]
  predictions = mm.predict(np.array(patches), batch_size=1)
  target_class_predictions = [prediction[class_index] for prediction in predictions]
  for (index_y, index_x), confidence in zip(coordinates, target_class_predictions):
    sensitivity_map[index_y, index_x, index_z] = 1 - confidence

# + colab={} colab_type="code" id="TJNEmMOrG0Hi"
from skimage.transform import resize

# + colab={} colab_type="code" id="YnQgVHssHqWX"
sm = resize(sensitivity_map, (64,64,64))

# + colab={} colab_type="code" id="8dT5GWoNHvKu"
heatmap = (sm - np.min(sm)) / (sm.max() - sm.min())

# + colab={"base_uri": "https://localhost:8080/", "height": 103} colab_type="code" executionInfo={"elapsed": 2692, "status": "ok", "timestamp": 1573638001081, "user": {"displayName": "<NAME>", "photoUrl": "<KEY>", "userId": "06737229821528734971"}, "user_tz": -60} id="J53m22tPIIe-" outputId="53c0ebad-1730-47ff-9766-17bd8a5d0034"
import cv2

step = 4
n_slices = int(64/4)
i = 0
n = 0
data = (heatmap * 255).astype("uint8")
slice = 0
fig, ax = plt.subplots(1, n_slices, figsize=[18, 1.2*1])
for _ in range(n_slices):
  #tmp_data = cv2.applyColorMap(cv2.cvtColor(data[:,:,slice], cv2.COLOR_GRAY2BGR), colormap)
  ax[n].imshow(data[:,:,slice])
  ax[n].set_xticks([])
  ax[n].set_yticks([])
  if i == 0:
    ax[n].set_title(str(slice), color='r')
  else:
    ax[n].set_title('', color='r')
  n += 1
  slice += step


# + colab={} colab_type="code" id="AvHj5mgfBTsU"
''def apply_grey_patch(image, top_left_x, top_left_y, top_left_z, patch_size):
    """
    Replace a part of the image with a grey patch.
    Args:
        image (numpy.ndarray): Input image
        top_left_x (int): Top Left X position of the applied box
        top_left_y (int): Top Left Y position of the applied box
        patch_size (int): Size of patch to apply
    Returns:
        numpy.ndarray: Patched image
    """
    patched_image = np.array(image, copy=True)
    patched_image[
        top_left_y : top_left_y + patch_size, top_left_x : top_left_x + patch_size, top_left_z : top_left_z + patch_size, :
    ] = 127.5

    return patched_image

import math

sensitivity_map = np.zeros((
    math.ceil(image.shape[0] / patch_size),
    math.ceil(image.shape[1] / patch_size),
    math.ceil(image.shape[2] / patch_size),
))

patches = [
           apply_grey_patch(image, top_left_x, top_left_y, top_left_z, patch_size)
           for index_x, top_left_x in enumerate(range(0, image.shape[0], patch_size))
           for index_y, top_left_y in enumerate(range(0, image.shape[1], patch_size))
           for index_z, top_left_z in enumerate(range(0, image.shape[2], patch_size))
]

coordinates = [
               (index_y, index_x, index_z)
               for index_x, _ in enumerate(range(0, image.shape[0], patch_size))
               for index_y, _ in enumerate(range(0, image.shape[1], patch_size))
]

# + colab={} colab_type="code" id="5tykySZbBhd6"
predictions = mm.predict(np.array(patches), batch_size=1)
target_class_predictions = [
                            prediction[class_index] for prediction in predictions
]

for (index_y, index_x), confidence in zip(coordinates, target_class_predictions):
  sensitivity_map[index_y, index_x] = 1 - confidence

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 24896, "status": "ok", "timestamp": 1573636310007, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="T7CP5XZmB5zk" outputId="51b20ba5-c4a1-437f-c380-1a091287d046"
sensitivity_map.shape

# + colab={"base_uri": "https://localhost:8080/", "height": 307} colab_type="code" executionInfo={"elapsed": 2668, "status": "error", "timestamp": 1573635968909, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="YSWQ9aLgADhm" outputId="2064a784-4ba7-48a1-fe7b-14423fb33eff"
grid = explainer.explain((X[0:1], _), mm, 0, 20, 1.)

# + colab={} colab_type="code" id="GsN40IBZADbd"


# + colab={} colab_type="code" id="<KEY>"
from tf_explain.core.grad_cam import GradCAM
explainer = GradCAM()

# + colab={} colab_type="code" id="JleqbVNFt61o"
??GradCAM

# + colab={"base_uri": "https://localhost:8080/", "height": 1000} colab_type="code" executionInfo={"elapsed": 928, "status": "ok", "timestamp": 1573635431699, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="y9rvvybc68Zz" outputId="d733eeb0-9623-4abe-d37c-808b55b6abf5"
model.summary()

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1155, "status": "ok", "timestamp": 1573635511676, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="Klr1s868--Pd" outputId="91ae4930-a29b-40e7-e6ba-b54f339f9de5"
mm.get_layer('my_dnn_2').get_layer('sequential_40').output

# + colab={} colab_type="code" id="A98V_pwSQRHe"
grad_model = tf.keras.models.Model(
            [mm.inputs], [mm.get_layer('my_dnn_2').get_layer('lastconv_1').output, mm.get_layer('my_dnn_2').get_layer('sequential_40').output]
        )

# + colab={} colab_type="code" id="ZtMPV1LRu-M9"
import cv2

def image_to_uint_255(image):
    """
    Convert float images to int 0-255 images.
    Args:
        image (numpy.ndarray): Input image. Can be either [0, 255], [0, 1], [-1, 1]
    Returns:
        numpy.ndarray:
    """
    if image.dtype == np.uint8:
        return image

    if image.min() < 0:
        image = (image + 1.0) / 2.0

    return (image * 255).astype("uint8")

def heatmap_display(heatmap, original_image, colormap=cv2.COLORMAP_VIRIDIS):
    """
    Apply a heatmap (as an np.ndarray) on top of an original image.
    Args:
        heatmap (numpy.ndarray): Array corresponding to the heatmap
        original_image (numpy.ndarray): Image on which we apply the heatmap
        colormap (int): OpenCV Colormap to use for heatmap visualization
    Returns:
        np.ndarray: Original image with heatmap applied
    """
    heatmap = cv2.resize(heatmap, original_image.shape[0])

    image = image_to_uint_255(original_image)

    heatmap = (heatmap - np.min(heatmap)) / (heatmap.max() - heatmap.min())

    heatmap = cv2.applyColorMap(
        cv2.cvtColor((heatmap * 255).astype("uint8"), cv2.COLOR_GRAY2BGR), colormap
    )

    output = cv2.addWeighted(cv2.cvtColor(image, cv2.COLOR_RGB2BGR), 0.7, heatmap, 1, 0)

    return cv2.cvtColor(output, cv2.COLOR_BGR2RGB)


# + colab={} colab_type="code" id="0x7n6xNlVuCE"
colormap=cv2.COLORMAP_VIRIDIS

with tf.GradientTape() as tape:
  X_in = tf.cast(X[0:1], tf.float32)
  conv_outputs, predictions = grad_model(X_in)
  loss = predictions[:, 0]
  tape.watch(loss)
  tape.watch(conv_outputs)
  grads = tape.gradient(loss, conv_outputs)

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1109, "status": "ok", "timestamp": 1573635531488, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="zkzfoc8651jB" outputId="57b5fff2-116a-4c75-cbf0-e4526ee4cf32"
grads.shape

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1231, "status": "ok", "timestamp": 1573635624114, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="yEUMgSwp_fvl" outputId="507004b5-d2bb-4890-fcc8-1b64f6bbf34d"
conv_outputs.shape

# + colab={} colab_type="code" id="NbK4gsGD5z8G"
guided_grads = (
    tf.cast(conv_outputs > 0, "float32") * tf.cast(grads > 0, "float32") * grads
)

cams = GradCAM.generate_ponderated_output(conv_outputs, guided_grads)

#heatmaps = np.array([
#                     heatmap_display(cam.numpy(), image, colormap) 
#                     for cam, image in zip(cams, X[0:1])
#                     ]
#)

# + colab={} colab_type="code" id="GQRFygoO_lhl"
?? GradCAM

# + colab={} colab_type="code" id="KJQ3A6D1vOga"
cam = cams[0].numpy()
original_image = X[0].numpy()

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 553, "status": "ok", "timestamp": 1573635677057, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="jq6WwRHM_suQ" outputId="1260086f-78c7-4e90-83f5-29fbd499bd52"
cam.shape

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 994, "status": "ok", "timestamp": 1573635684025, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="8-vBiYBL_uHv" outputId="38340d19-c523-4e35-c8a0-c02b2ed97298"
original_image.shape

# + colab={} colab_type="code" id="Lf1EpM0huWkN"
image = image_to_uint_255(original_image)

# + colab={} colab_type="code" id="RfWTQbouwPr6"
cam = (cam - np.min(cam)) / (cam.max() - cam.min())

# + colab={"base_uri": "https://localhost:8080/", "height": 218} colab_type="code" executionInfo={"elapsed": 3100, "status": "ok", "timestamp": 1573635695548, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="Vc3-eSm_Wdtp" outputId="628281a8-8722-4854-fb6f-907dea010039"
ppp = '/content/drive/My Drive/Capstone/05_Data/02_Sample_MRI/downsampled_resize/T2/sub-NDARINVFJJPAA2A_T2.nii.gz'
org = nib.load(ppp)
plotting.plot_anat(nilearn.image.new_img_like(ppp, cam, affine=None, copy_header=False))
plotting.show()

# + colab={"base_uri": "https://localhost:8080/", "height": 103} colab_type="code" executionInfo={"elapsed": 2499, "status": "ok", "timestamp": 1573632489896, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="Zon4lQxqxy_g" outputId="e27ca556-4b0e-419d-f080-948504cda843"
step = 4
n_slices = int(64/4)
i = 0
n = 0
data = (cam * 255).astype("uint8")
slice = 0
fig, ax = plt.subplots(1, n_slices, figsize=[18, 1.2*1])
for _ in range(n_slices):
  tmp_data = cv2.applyColorMap(cv2.cvtColor(data[:,:,slice], cv2.COLOR_GRAY2BGR), colormap)
  ax[n].imshow(tmp_data)
  ax[n].set_xticks([])
  ax[n].set_yticks([])
  if i == 0:
    ax[n].set_title(str(slice), color='r')
  else:
    ax[n].set_title('', color='r')
  n += 1
  slice += step




# + colab={"base_uri": "https://localhost:8080/", "height": 850} colab_type="code" executionInfo={"elapsed": 988, "status": "ok", "timestamp": 1573632429787, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="CswyaFSSzUT1" outputId="e23d5f93-8b96-493c-943a-220806dd2676"
image[:,:,slice]

# + colab={"base_uri": "https://localhost:8080/", "height": 850} colab_type="code" executionInfo={"elapsed": 1103, "status": "ok", "timestamp": 1573632359963, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="sHi5Wa4OxzHv" outputId="f75dcc53-bb56-4004-c563-0732b9b00f95"
cv2.applyColorMap(cv2.cvtColor(data[:,:,slice], cv2.COLOR_GRAY2BGR), colormap)

# + colab={} colab_type="code" id="6j0saosJV0nl"
grads

# + colab={"base_uri": "https://localhost:8080/", "height": 71} colab_type="code" executionInfo={"elapsed": 1724, "status": "ok", "timestamp": 1573573601574, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="9ll5ZhBYS0CC" outputId="da8f25d9-8618-4d94-a49c-6d12f26e452c"


# + colab={"base_uri": "https://localhost:8080/", "height": 190} colab_type="code" executionInfo={"elapsed": 5602, "status": "ok", "timestamp": 1573573592894, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="2l2aRBO0S0lH" outputId="8eb4d09c-aa88-4223-dc2d-872ff68cab0b"


# + colab={} colab_type="code" id="fmCx2QDeTgV5"
ppp = '/content/drive/My Drive/Capstone/05_Data/02_Sample_MRI/downsampled_resize/T2/sub-NDARINVFJJPAA2A_T2.nii.gz'
org = nib.load(ppp)

# + colab={} colab_type="code" id="3aOZOBl7UAYf"


# + colab={"base_uri": "https://localhost:8080/", "height": 218} colab_type="code" executionInfo={"elapsed": 2719, "status": "ok", "timestamp": 1573573909666, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="x9nuB0SiS3lG" outputId="da89a83a-9b5d-4286-c265-f9b6d614177e"


# + colab={} colab_type="code" id="dSeow2ZMTSM4"
nilearn.image.

# + colab={"base_uri": "https://localhost:8080/", "height": 307} colab_type="code" executionInfo={"elapsed": 1068, "status": "error", "timestamp": 1573570989091, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="aUUkRh73Ikou" outputId="9280f05b-2745-4b4f-eb3c-22a9bb5c2ee3"
import tensorflow as tf

mm = tf.keras.Model(inputs=inputs, output=inputs)

# + colab={} colab_type="code" id="5iG2jty7ItI6"
aaa = model.fc['female']

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1101, "status": "ok", "timestamp": 1573572176029, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="rBkxNGXJMm3f" outputId="8f9443a0-ce63-4b6b-cfd6-5bdcb191d7f8"
aaa.layers[-1]

# + colab={"base_uri": "https://localhost:8080/", "height": 164} colab_type="code" executionInfo={"elapsed": 1594, "status": "error", "timestamp": 1573571926766, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="R7pvBAzEMgIb" outputId="b674a27f-9b52-49c7-d0d6-bda6bebe1508"
list(model.fc['female'].children())

# + colab={} colab_type="code" id="aQ6iuJbGEym7"
from tensorflow.keras import Model

class WrapperMyDNN(Model):
  def __init__(self, model):
    super(WrapperMyDNN, self).__init__()
    self.model = model
    #self.output = self.model.fc['female'].layers[-1]
  
  def call(self, x):
    x_tmp = self.model(x)
    return(x_tmp['female'])


# + colab={} colab_type="code" id="S4Qim0gN0Lua"
?? Model

# + colab={} colab_type="code" id="IbySX5WM0F4G"
from tensorflow.keras import Model

class MyDNN2(Model):
  def __init__(self, cat_cols, num_cols, **kwargs):
    super(MyDNN2, self).__init__(**kwargs)
    self.cat_cols = cat_cols
    self.num_cols = num_cols
    self.ac = tf.keras.layers.ReLU()
    self.maxpool = tf.keras.layers.MaxPool3D(pool_size=(2, 2, 2), data_format='channels_last')
    self.conv1 = tf.keras.layers.Conv3D(
        filters = 32,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last',
        input_shape = (64,64,64,2)
    )
    self.bn1 = tf.keras.layers.BatchNormalization()
    self.conv2 = tf.keras.layers.Conv3D(
        filters = 64,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn2 = tf.keras.layers.BatchNormalization()
    self.conv3 = tf.keras.layers.Conv3D(
        filters = 128,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn3 = tf.keras.layers.BatchNormalization()
    self.conv4 = tf.keras.layers.Conv3D(
        filters = 256,
        kernel_size = 3,
        padding='valid',
        data_format='channels_last'
    )
    self.bn4 = tf.keras.layers.BatchNormalization()
    self.fc = {}
    for k in list(self.cat_cols.keys()):
      self.fc[k] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(self.cat_cols[k], activation='softmax')
                                        ])
    for i in range(len(self.num_cols)):
      self.fc[self.num_cols[i]] = tf.keras.Sequential([
                                        tf.keras.layers.Dense(256, activation='relu'),
                                        tf.keras.layers.BatchNormalization(),
                                        tf.keras.layers.Dense(1)
                                        ])

  def call(self, x):
    x = self.conv1(x)
    x = self.bn1(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv2(x)
    x = self.bn2(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv3(x)
    x = self.bn3(x)
    x = self.ac(x)
    x = self.maxpool(x)
    x = self.conv4(x)
    x = self.bn4(x)
    x = self.ac(x)
    x = tf.keras.layers.GlobalAveragePooling3D()(x)
    out = {}
    for k in list(self.fc.keys()):
      out[k] = self.fc[k](x)
    return out


# + colab={} colab_type="code" id="DytC-LQsPZSd"
model2 = WrapperMyDNN(model)
a = next(iter(test_iter))
t1 = (tf.cast(a['t1'], tf.float32)-t1_mean)/t1_std
t2 = (a['t2']-t2_mean)/t2_std
X = tf.concat([t1, t2], axis=4)

# + colab={"base_uri": "https://localhost:8080/", "height": 283} colab_type="code" executionInfo={"elapsed": 1130, "status": "error", "timestamp": 1573572569092, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="-FnN0VNHOuHC" outputId="e39d17e4-1629-4f90-d4e3-e8341a78c956"
model2.output

# + colab={"base_uri": "https://localhost:8080/", "height": 477} colab_type="code" executionInfo={"elapsed": 4623, "status": "error", "timestamp": 1573572511655, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="1HQqLXqWWxXJ" outputId="1422a528-c7a4-4e68-db58-1485075ac412"
from tf_explain.core.smoothgrad import SmoothGrad
explainer = SmoothGrad()
grid = explainer.explain((X, None), model2, 1, 20, 1.)

# + colab={} colab_type="code" id="cP7thtjAqunC"
output = []
output.append(['colname', 'mse'])
for col in num_cols:
  mean = test_df[col].mean()
  mse_norm = np.mean(np.square(test_df[col]-mean))
  output.append([col, mse_norm])

for col in list(cat_cols.keys()):
  mean = test_df[col].value_counts().idxmax()
  mse_norm = np.mean(test_df[col]==mean)
  output.append([col, mse_norm])

# + colab={} colab_type="code" id="Rw_KzTw6Q4wr"
a = next(iter(test_iter))

# + colab={} colab_type="code" id="ben3zkRr32sD"
t1 = (tf.cast(a['t1'], tf.float32)-t1_mean)/t1_std
t2 = (a['t2']-t2_mean)/t2_std
X = tf.concat([t1, t2], axis=4)

# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1117, "status": "ok", "timestamp": 1573490357380, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="622IROlaVWVu" outputId="9b50cdce-6128-4fc7-9757-80d1fdce306f"
X.shape

# + colab={"base_uri": "https://localhost:8080/", "height": 1000} colab_type="code" executionInfo={"elapsed": 1122, "status": "ok", "timestamp": 1573490251609, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="ynswVv2MUwZi" outputId="276f09a5-4318-4fa2-a029-34a2a8c4dd3d"
model2.model.summary()

# + colab={"base_uri": "https://localhost:8080/", "height": 477} colab_type="code" executionInfo={"elapsed": 5540, "status": "error", "timestamp": 1573490614301, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="2RwCwYigS0UO" outputId="7f1ede39-9d2b-40f1-eed3-f1b72b4573f9"
from tf_explain.core.smoothgrad import SmoothGrad
explainer = SmoothGrad()
grid = explainer.explain((X, None), model2, 1, 20, 1.)

# + colab={"base_uri": "https://localhost:8080/", "height": 85} colab_type="code" executionInfo={"elapsed": 3698, "status": "ok", "timestamp": 1573490096976, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="b033WUfMTy_S" outputId="e71254e5-e55f-488b-a2ce-5ce5f7117b5d"
# !ls /content/drive/My\ Drive/Capstone/

# + colab={"base_uri": "https://localhost:8080/", "height": 935} colab_type="code" executionInfo={"elapsed": 8973, "status": "ok", "timestamp": 1573490110703, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="-RohbTtqS4qd" outputId="497f7261-9a93-4151-a55e-d449ecfaa40b"
IMAGE_PATH = '/content/drive/My Drive/Capstone/cat.jpg'

model_res = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=True)

img = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(224, 224))
img = tf.keras.preprocessing.image.img_to_array(img)

model_res.summary()
data = ([img], None)

tabby_cat_class_index = 281
explainer = SmoothGrad()
# Compute SmoothGrad on VGG16
grid = explainer.explain(data, model_res, tabby_cat_class_index, 20, 1.)
explainer.save(grid, '.', 'smoothgrad.png')

# + colab={} colab_type="code" id="8kJ4t1IgT_FF"
from google.colab import files

files.download('./smoothgrad.png')

# + colab={} colab_type="code" id="zDC5mlR9UpWo"


# + colab={"base_uri": "https://localhost:8080/", "height": 34} colab_type="code" executionInfo={"elapsed": 1594, "status": "ok", "timestamp": 1573489069509, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="-dvYng1iQBUQ" outputId="b4ddf708-f070-43a7-938b-12bc92419372"
model2(X)

# + colab={"base_uri": "https://localhost:8080/", "height": 170} colab_type="code" executionInfo={"elapsed": 1585, "status": "ok", "timestamp": 1573488955519, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": -60} id="7JMy-Zmg3_8t" outputId="a0d77624-e846-451d-c8f8-84f587118f0b"
'model.call(X)['female']

# + colab={} colab_type="code" id="mIYd0IsfiKER"
pd.DataFrame(output).to_csv(path_output + 'baseline.csv')

# + colab={"base_uri": "https://localhost:8080/", "height": 286} colab_type="code" executionInfo={"elapsed": 811, "status": "ok", "timestamp": 1572985942408, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": 300} id="j3kFZEWAQ5XU" outputId="c9769171-4ee2-4e40-d803-fcde7a266188"
val_df.groupby(['married']).count() / val_df.shape[0]

# + colab={"base_uri": "https://localhost:8080/", "height": 514} colab_type="code" executionInfo={"elapsed": 1403, "status": "ok", "timestamp": 1572884554781, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": 300} id="6ivDV4iphO9A" outputId="43969338-33ff-44f8-e207-2b03cf78d9a2"
pd.merge(pd.DataFrame(output), df, left_on=0, right_on=0)

# + colab={} colab_type="code" id="3TEP3PWnc4-g"
cols = ['nihtbx_fluidcomp_uncorrected', 'nihtbx_cryst_uncorrected', 
              'nihtbx_pattern_uncorrected', 'nihtbx_picture_uncorrected', 
              'nihtbx_list_uncorrected', 'nihtbx_flanker_uncorrected',
              'nihtbx_picvocab_uncorrected', 'nihtbx_cardsort_uncorrected',
              'nihtbx_totalcomp_uncorrected', 'nihtbx_reading_uncorrected']

# + colab={} colab_type="code" id="GG6ZMe11hqLf"
output = []
output.append(['colname', 'mse'])
for col in cols:
  mean = val_df[col].mean()
  mse_norm = np.mean(np.square(val_df[col]-mean))
  output.append([col, mse_norm])

# + colab={"base_uri": "https://localhost:8080/", "height": 390} colab_type="code" executionInfo={"elapsed": 793, "status": "ok", "timestamp": 1572621420115, "user": {"displayName": "<NAME>", "photoUrl": "https://lh3.googleusercontent.com/a-/AAuE7mDViwxKXBjVKZfXMWGuXrQ48D62bye6HNutAOX0=s64", "userId": "06737229821528734971"}, "user_tz": 240} id="6YJAmfWtil8q" outputId="1cf07203-3ec7-4448-e8dd-1e7be5ab8636"
pd.DataFrame(output)

# + colab={} colab_type="code" id="OViFTzBKioI2"


# + colab={} colab_type="code" id="AExg0jq563dS"
model.get_layer('lastconv')

StarcoderdataJupyterScriptsDedupFiltered