Kaggle competition: RSNA Intracranial Hemorrhage Detection
def model(train_set, train_labels, validation_set, validation_labels, layers_dims, learning_rate=0.01, num_epochs=1001,
print_cost=True, plot_cost=True, l2_beta=0., keep_prob=1.0, hidden_activation='relu', return_best=False,
minibatch_size=0, lr_decay=0, print_accuracy=True, plot_accuracy=True):

 ops.reset_default_graph()
input_size = layers_dims[0]
output_size = layers_dims[-1]
num_examples = train_set.shape[0]
n_layers = len(layers_dims)
 train_costs = []
validation_costs = []
train_accuracies = []
validation_accuracies = []
prediction = []
best_iteration = [float('inf'), 0, float('-inf'), 0]
best_params = None
if minibatch_size == 0 or minibatch_size > num_examples:
minibatch_size = num_examples
num_minibatches = num_examples // minibatch_size
if num_minibatches == 0:
num_minibatches = 1
submission_name = build_submission_name(layers_dims, num_epochs, lr_decay, learning_rate, l2_beta, keep_prob,
minibatch_size, num_examples)
 x, y = create_placeholders(input_size, output_size)
 tf_valid_dataset = tf.cast(tf.constant(validation_set), tf.float32)
 parameters = initialize_parameters(layers_dims)
 fw_output = forward_propagation(x, parameters, keep_prob, hidden_activation)
 train_cost = compute_cost(fw_output, y)
 train_prediction = tf.nn.softmax(fw_output)
 fw_output_valid = forward_propagation(tf_valid_dataset, parameters, 1, hidden_activation)
 validation_cost = compute_cost(fw_output_valid, validation_labels)
 valid_prediction = tf.nn.softmax(fw_output_valid)
 if l2_beta > 0:
train_cost = l2_regularizer(train_cost, l2_beta, parameters, n_layers)
 validation_cost = l2_regularizer(validation_cost, l2_beta, parameters, n_layers)
 if lr_decay != 0:
global_step = tf.Variable(0, trainable=False)
 learning_rate = tf.train.inverse_time_decay(learning_rate, global_step=global_step, decay_rate=lr_decay,
decay_steps=1)
 optimizer = tf.train.AdamOptimizer(learning_rate ).minimize(train_cost, global_step=global_step)
 else:
optimizer = tf.train.AdamOptimizer(learning_rate ).minimize(train_cost)
 init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
 for epoch in range(num_epochs):
train_epoch_cost = 0.
 validation_epoch_cost = 0.
 minibatches = mini_batches(train_set, train_labels, minibatch_size)
 for minibatch in minibatches: 
(minibatch_X, minibatch_Y)= minibatch
feed_dict = {x: minibatch_X, y: minibatch_Y}
_, minibatch_train_cost, prediction, minibatch_validation_cost = sess.run(
 [optimizer, train_cost, train_prediction, validation_cost], feed_dict=feed_dict)
 train_epoch_cost += minibatch_train_cost / num_minibatches
validation_epoch_cost += minibatch_validation_cost / num_minibatches
validation_accuracy = accuracy(valid_prediction.eval() , validation_labels)
 train_accuracy = accuracy(prediction, minibatch_Y)
 if print_cost is True and epoch % 500 == 0:
print("Train cost after epoch %i: %f" %(epoch, train_epoch_cost))
print("Validation cost after epoch %i: %f" %(epoch, validation_epoch_cost))
if print_accuracy is True and epoch % 500 == 0:
print('Train accuracy after epoch {}: {:.2f}'.format(epoch, train_accuracy))
print('Validation accuracy after epoch {}: {:.2f}'.format(epoch, validation_accuracy))
if plot_cost is True and epoch % 10 == 0:
train_costs.append(train_epoch_cost)
 validation_costs.append(validation_epoch_cost)
 if plot_accuracy is True and epoch % 10 == 0:
train_accuracies.append(train_accuracy)
 validation_accuracies.append(validation_accuracy)
 if return_best is True:
if validation_epoch_cost < best_iteration[0]:
best_iteration[0] = validation_epoch_cost
best_iteration[1] = epoch
best_params = sess.run(parameters)
 if validation_accuracy > best_iteration[2]:
best_iteration[2] = validation_accuracy
best_iteration[3] = epoch
best_params = sess.run(parameters)
 if return_best is True:
parameters = best_params
else:
parameters = sess.run(parameters)
 print("Parameters have been trained, getting metrics...")
 train_accuracy = accuracy(predict(train_set, parameters), train_labels)
 validation_accuracy = accuracy(predict(validation_set, parameters), validation_labels)
 print('Train accuracy: {:.2f}'.format(train_accuracy))
print('Validation accuracy: {:.2f}'.format(validation_accuracy))
print('Lowest validation cost: {:.2f} at epoch {}'.format(best_iteration[0], best_iteration[1]))
print('Highest validation accuracy: {:.2f} at epoch {}'.format(best_iteration[2], best_iteration[3]))
submission_name = 'tr_acc-{:.2f}-vd_acc{:.2f}-'.format(train_accuracy, validation_accuracy)+ submission_name
if return_best is True:
print('Lowest cost: {:.2f} at epoch {}'.format(best_iteration[0], best_iteration[1]))
if plot_cost is True:
plot_model_cost(train_costs, validation_costs, submission_name)
 if plot_accuracy is True:
plot_model_accuracy(train_accuracies, validation_accuracies, submission_name)
 return parameters, submission_name<load_from_csv>
import numpy as np
import pandas as pd
import pydicom
import os
import sys
import matplotlib.pyplot as plt
import collections
from tqdm import tqdm_notebook as tqdm
from datetime import datetime
from math import ceil, floor
import cv2
import tensorflow as tf
import keras
import seaborn as sns
from glob import glob
from keras import initializers, regularizers, constraints, optimizers, layers
from keras.optimizers import Optimizer
from keras.callbacks import *
TRAIN_PATH = '.. /input/train.csv'
TEST_PATH = '.. /input/test.csv'
train, test = load_data(TRAIN_PATH, TEST_PATH)
 CLASSES = 2
train_dataset_size = train.shape[0]
train_raw_labels = pd.get_dummies(train.Survived ).as_matrix()<data_type_conversions>
BASE_PATH = '/kaggle/input/rsna_noben_png_224_224_v1/'
TRAIN_PATH = 'stage_1_train_images/'
TEST_PATH = 'stage_1_test_images/'
TMP_DIR_PATH = '/kaggle/tmp/'
TRAIN_TMP_DIR_PATH = TMP_DIR_PATH + 'train_png_img/'
TEST_TMP_DIR_PATH = TMP_DIR_PATH + 'test_png_img/'
IMG_SIZE = 224
train = pre_process_data(train)
 test = pre_process_data(test)
 train_pre = train.drop(['Survived'], axis=1 ).as_matrix().astype(np.float)
 test_pre = test.as_matrix().astype(np.float )<train_model>
train_df_csv = pd.read_csv(BASE_PATH + 'stage_1_train.csv')
 print(train_df_csv.shape)
standard_scaler = preprocessing.StandardScaler()
train_pre = standard_scaler.fit_transform(train_pre)
 test_pre = standard_scaler.fit_transform(test_pre)
 X_train, X_valid, Y_train, Y_valid = train_test_split(train_pre, train_raw_labels, test_size=0.3, random_state=1 )<init_hyperparams>
train_df_csv['filename'] = train_df_csv['ID'].apply(lambda st: "ID_" + st.split('_')[1] + ".dcm")
 train_df_csv['type'] = train_df_csv['ID'].apply(lambda st: st.split('_')[2])
 print(train_df_csv.shape)
input_layer = train_pre.shape[1]
output_layer = 2
num_epochs = 10001
learning_rate = 0.0001
train_size = 0.8
layers_dims = [input_layer, 256, 128, 64, output_layer]<train_model>
train_df_csv.filename.nunique()
parameters, submission_name = model(X_train, Y_train, X_valid, Y_valid, layers_dims, num_epochs=num_epochs,
learning_rate=learning_rate, print_cost=False, plot_cost=True, l2_beta=0.1,
keep_prob=0.5, minibatch_size=0, return_best=True, print_accuracy=False,
plot_accuracy=True )<predict_on_test>
label_dist = train_df_csv.groupby("type" ).Label.value_counts().unstack().reset_index()
label_dist
final_prediction = predict(test_pre, parameters )<save_to_csv>
pivot_train_df_csv=pd.concat([pivot_train_df_csv_any,pivot_train_df_csv_nany] )
submission = pd.DataFrame({"PassengerId":test.index.values})
 submission["Survived"] = np.argmax(final_prediction, 1)
 submission.to_csv("submission.csv", index=False )<import_modules>
pivot_train_df_csv=pivot_train_df_csv.reset_index(drop=True )
import numpy as np
import pandas as pd
import tensorflow
import featuretools as ft<set_options>
test_df_csv = pd.read_csv(BASE_PATH + 'stage_1_sample_submission.csv')
 test_df_csv['filename'] = test_df_csv['ID'].apply(lambda st: "ID_" + st.split('_')[1] + ".dcm")
 test_df_csv['type'] = test_df_csv['ID'].apply(lambda st: st.split('_')[2])
 print(test_df_csv.shape)
 test_df_csv.head()
np.random.seed(7 )<load_from_csv>
test_df_csv = pd.DataFrame(test_df_csv.filename.unique() , columns=['filename'])
 print(test_df_csv.shape)
train_data=pd.read_csv('.. /input/train.csv')
 test_data=pd.read_csv('.. /input/test.csv' )<drop_column>
pivot_train_df_csv['filename'] = pivot_train_df_csv['filename'].apply(lambda st: st.split('.')[0] + ".png")
 pivot_train_df_csv.head(2 )
train_data['Age']=train_data['Age'].fillna(train_data['Age'].mean())
 train_data=train_data.drop(['Cabin'],axis=1 )<data_type_conversions>
test_df_csv['filename'] = test_df_csv['filename'].apply(lambda st: st.split('.')[0] + ".png")
 test_df_csv.head(2 )
train_data['Embarked']=train_data['Embarked'].fillna(method='ffill' )<feature_engineering>
print(BASE_PATH + TEST_PATH)
 train_dcm_img = sorted(glob(BASE_PATH + TRAIN_PATH + "*.png"))
test_dcm_img = sorted(glob(BASE_PATH + TEST_PATH + "*.png"))
print("train files: ", len(train_dcm_img))
print("test files: ", len(test_dcm_img))
pd.reset_option('max_colwidth' )
train_data['Sex']=train_data['Sex'].apply(lambda x:1 if x=='male' else 0)
 train_data['Embarked']=train_data['Embarked'].apply(lambda x:1 if x=='S'else 2 if x=='C' else 3)
 train_data['Fare']=train_data['Fare'].apply(lambda x: x/513)
<prepare_x_and_y>
num_ill_patients = pivot_train_df_csv[pivot_train_df_csv["any"]==1].shape[0]
num_ill_patients
X=train_data[['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']]
Y=train_data[['Survived']]<choose_model_class>
undersample_seed = 42
healthy_patients = pivot_train_df_csv[pivot_train_df_csv["any"]==0].index.values
healthy_patients_selection = np.random.RandomState(undersample_seed ).choice(
 healthy_patients, size=num_ill_patients, replace=False 
)
 len(healthy_patients_selection )
model = Sequential()
model.add(Dense(12, input_dim=7, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))<choose_model_class>
def create_datagen() :
train_aug = ImageDataGenerator(rescale=1./255,
horizontal_flip = True,
rotation_range = 10,
validation_split=0.20,
preprocessing_function=preprocess_image 
)
 return train_aug
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'] )<train_model>
BATCH_SIZE = 32
def create_test_gen() :
return ImageDataGenerator(rescale=1./255,
preprocessing_function=preprocess_image ).flow_from_dataframe(
 test_df_csv,
directory= BASE_PATH+TEST_PATH,
x_col='filename',
class_mode=None,
target_size=(IMG_SIZE, IMG_SIZE),
batch_size=BATCH_SIZE,
shuffle=False
)
model.fit(X, Y, epochs=75, batch_size=100 )<compute_test_metric>
def create_flow(datagen, subset):
return datagen.flow_from_dataframe(
 pivot_train_df_csv,
directory =BASE_PATH+TRAIN_PATH,
x_col = 'filename',
y_col = ['any', 'epidural', 'intraparenchymal','intraventricular', 'subarachnoid', 'subdural'],
class_mode='raw',
target_size=(IMG_SIZE, IMG_SIZE),
batch_size=BATCH_SIZE,
subset=subset
)
scores = model.evaluate(X, Y)
 print("
%s: %.2f%%" %(model.metrics_names[1], scores[1]*100))<feature_engineering>
%%time
train_data_generator = create_datagen()
train_gen = create_flow(train_data_generator, 'training')
 val_gen = create_flow(train_data_generator, 'validation')
 test_gen = create_test_gen()
test_data['Age']=test_data['Age'].fillna(test_data['Age'].mean())
 test_data['Fare']=test_data['Fare'].fillna(test_data['Fare'].mean())
 test_data['Fare']=test_data['Fare'].apply(lambda x: x/513)
 test_data=test_data.drop(['Cabin'],axis=1)
 test_data['Embarked']=test_data['Embarked'].fillna(method='ffill')
 test_data['Sex']=test_data['Sex'].apply(lambda x:1 if x=='male' else 0)
 test_data['Embarked']=test_data['Embarked'].apply(lambda x:1 if x=='S'else 2 if x=='C' else 3 )<count_missing_values>
from keras.applications.xception import Xception
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D, Dropout, Input
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
from sklearn.model_selection import train_test_split
import keras
from keras.engine import Layer,InputSpec
from keras.applications.resnet50 import ResNet50
test_data.isnull().sum()<prepare_x_and_y>
class RAdam(keras.optimizers.Optimizer):

 def __init__(self, learning_rate=0.001, beta_1=0.9, beta_2=0.999,
epsilon=None, decay=0., weight_decay=0., amsgrad=False,
total_steps=0, warmup_proportion=0.1, min_lr=0., **kwargs):
learning_rate = kwargs.pop('lr', learning_rate)
 super(RAdam, self ).__init__(**kwargs)
 with K.name_scope(self.__class__.__name__):
self.iterations = K.variable(0, dtype='int64', name='iterations')
 self.learning_rate = K.variable(learning_rate, name='learning_rate')
 self.beta_1 = K.variable(beta_1, name='beta_1')
 self.beta_2 = K.variable(beta_2, name='beta_2')
 self.decay = K.variable(decay, name='decay')
 self.weight_decay = K.variable(weight_decay, name='weight_decay')
 self.total_steps = K.variable(total_steps, name='total_steps')
 self.warmup_proportion = K.variable(warmup_proportion, name='warmup_proportion')
 self.min_lr = K.variable(min_lr, name='min_lr')
 if epsilon is None:
epsilon = K.epsilon()
self.epsilon = epsilon
self.initial_decay = decay
self.initial_weight_decay = weight_decay
self.initial_total_steps = total_steps
self.amsgrad = amsgrad
def get_updates(self, loss, params):
grads = self.get_gradients(loss, params)
 self.updates = [K.update_add(self.iterations, 1)]
lr = self.lr
if self.initial_decay > 0:
lr = lr *(1./(1.+ self.decay * K.cast(self.iterations, K.dtype(self.decay))))
t = K.cast(self.iterations, K.floatx())+ 1
if self.initial_total_steps > 0:
warmup_steps = self.total_steps * self.warmup_proportion
decay_steps = K.maximum(self.total_steps - warmup_steps, 1)
 decay_rate =(self.min_lr - lr)/ decay_steps
lr = K.switch(
 t <= warmup_steps,
lr *(t / warmup_steps),
lr + decay_rate * K.minimum(t - warmup_steps, decay_steps), 
)
 ms = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='m_' + str(i)) for(i, p)in enumerate(params)]
vs = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='v_' + str(i)) for(i, p)in enumerate(params)]
if self.amsgrad:
vhats = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='vhat_' + str(i)) for(i, p)in enumerate(params)]
else:
vhats = [K.zeros(1, name='vhat_' + str(i)) for i in range(len(params)) ]
self.weights = [self.iterations] + ms + vs + vhats
beta_1_t = K.pow(self.beta_1, t)
 beta_2_t = K.pow(self.beta_2, t)
 sma_inf = 2.0 /(1.0 - self.beta_2)- 1.0
sma_t = sma_inf - 2.0 * t * beta_2_t /(1.0 - beta_2_t)
 for p, g, m, v, vhat in zip(params, grads, ms, vs, vhats):
m_t =(self.beta_1 * m)+(1.- self.beta_1)* g
v_t =(self.beta_2 * v)+(1.- self.beta_2)* K.square(g)
 m_corr_t = m_t /(1.0 - beta_1_t)
 if self.amsgrad:
vhat_t = K.maximum(vhat, v_t)
 v_corr_t = K.sqrt(vhat_t /(1.0 - beta_2_t))
self.updates.append(K.update(vhat, vhat_t))
else:
v_corr_t = K.sqrt(v_t /(1.0 - beta_2_t))
r_t = K.sqrt(( sma_t - 4.0)/(sma_inf - 4.0)* 
(sma_t - 2.0)/(sma_inf - 2.0)*
sma_inf / sma_t)
 p_t = K.switch(sma_t >= 5, r_t * m_corr_t /(v_corr_t + self.epsilon), m_corr_t)
 if self.initial_weight_decay > 0:
p_t += self.weight_decay * p
p_t = p - lr * p_t
self.updates.append(K.update(m, m_t))
self.updates.append(K.update(v, v_t))
new_p = p_t
if getattr(p, 'constraint', None)is not None:
new_p = p.constraint(new_p)
 self.updates.append(K.update(p, new_p))
return self.updates
@property
def lr(self):
return self.learning_rate
@lr.setter
def lr(self, learning_rate):
self.learning_rate = learning_rate
def get_config(self):
config = {
'learning_rate': float(K.get_value(self.learning_rate)) ,
'beta_1': float(K.get_value(self.beta_1)) ,
'beta_2': float(K.get_value(self.beta_2)) ,
'decay': float(K.get_value(self.decay)) ,
'weight_decay': float(K.get_value(self.weight_decay)) ,
'epsilon': self.epsilon,
'amsgrad': self.amsgrad,
'total_steps': float(K.get_value(self.total_steps)) ,
'warmup_proportion': float(K.get_value(self.warmup_proportion)) ,
'min_lr': float(K.get_value(self.min_lr)) ,
}
base_config = super(RAdam, self ).get_config()
return dict(list(base_config.items())+ list(config.items()))
X=test_data[['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']]<predict_on_test>
def custom_log_loss(y_true, y_pred):
loss_val = tf.losses.log_loss(y_true, y_pred)
 return loss_val
predict=model.predict(X )<create_dataframe>
class CyclicLR(Callback):

 def __init__(self, base_lr=0.001, max_lr=0.006, step_size=2000., mode='triangular',
gamma=1., scale_fn=None, scale_mode='cycle'):
super(CyclicLR, self ).__init__()
self.base_lr = base_lr
self.max_lr = max_lr
self.step_size = step_size
self.mode = mode
self.gamma = gamma
if scale_fn == None:
if self.mode == 'triangular':
self.scale_fn = lambda x: 1.
 self.scale_mode = 'cycle'
elif self.mode == 'triangular2':
self.scale_fn = lambda x: 1/(2.**(x-1))
self.scale_mode = 'cycle'
elif self.mode == 'exp_range':
self.scale_fn = lambda x: gamma**(x)
 self.scale_mode = 'iterations'
else:
self.scale_fn = scale_fn
self.scale_mode = scale_mode
self.clr_iterations = 0.
 self.trn_iterations = 0.
 self.history = {}
self._reset()
def _reset(self, new_base_lr=None, new_max_lr=None,
new_step_size=None):

 if new_base_lr != None:
self.base_lr = new_base_lr
if new_max_lr != None:
self.max_lr = new_max_lr
if new_step_size != None:
self.step_size = new_step_size
self.clr_iterations = 0.
 def clr(self):
cycle = np.floor(1+self.clr_iterations/(2*self.step_size))
x = np.abs(self.clr_iterations/self.step_size - 2*cycle + 1)
 if self.scale_mode == 'cycle':
return self.base_lr +(self.max_lr-self.base_lr)*np.maximum(0,(1-x)) *self.scale_fn(cycle)
 else:
return self.base_lr +(self.max_lr-self.base_lr)*np.maximum(0,(1-x)) *self.scale_fn(self.clr_iterations)
 def on_train_begin(self, logs={}):
logs = logs or {}
if self.clr_iterations == 0:
K.set_value(self.model.optimizer.lr, self.base_lr)
 else:
K.set_value(self.model.optimizer.lr, self.clr())
 def on_batch_end(self, epoch, logs=None):
logs = logs or {}
self.trn_iterations += 1
self.clr_iterations += 1
self.history.setdefault('lr', [] ).append(K.get_value(self.model.optimizer.lr))
self.history.setdefault('iterations', [] ).append(self.trn_iterations)
 for k, v in logs.items() :
self.history.setdefault(k, [] ).append(v)
 K.set_value(self.model.optimizer.lr, self.clr())
 def f1(y_true, y_pred):

 def recall(y_true, y_pred):

 true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
 possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
 recall = true_positives /(possible_positives + K.epsilon())
 return recall
def precision(y_true, y_pred):

 true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
 predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
 precision = true_positives /(predicted_positives + K.epsilon())
 return precision
precision = precision(y_true, y_pred)
 recall = recall(y_true, y_pred)
 return 2*(( precision*recall)/(precision+recall+K.epsilon()))
clr = CyclicLR(base_lr=0.001, max_lr=0.009,
step_size=300., mode='exp_range',
gamma=0.99994 )
final_out=pd.DataFrame(columns=['PassengerId','Survived'] )<feature_engineering>
input_layer = Input(shape =(IMG_SIZE,IMG_SIZE,3))
base_model = ResNet50(weights = None,
include_top = False,
input_tensor = input_layer)
 base_model.load_weights('.. /input/resnet/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')
 x = GlobalAveragePooling2D()(base_model.output)
 x = Dropout(0.5 )(x)
 x = Dense(512, activation='relu' )(x)
 x = BatchNormalization()(x)
 x = Dropout(0.3 )(x)
 out = Dense(6, activation = 'sigmoid' )(x)
 model = Model(inputs = input_layer, outputs = out)
 model.summary()
final_out['PassengerId']=test_data['PassengerId']<prepare_output>
filepath = "resNet50_DS_5epoch.h5"
mc=ModelCheckpoint(filepath, monitor='custom_log_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='min')
 callback_list = [clr,mc]
model.compile(optimizer = optimizer, loss = custom_log_loss, metrics = ["accuracy",custom_log_loss])
 model.summary()
final_out['Survived']=list(predict )<feature_engineering>
class_weights = {0: 2.,
1: 1.,
2: 1.,
3: 1.,
4: 1.,
5: 1.}
final_out['Survived']=final_out['Survived'].fillna(method='ffill' )<feature_engineering>
%%time
history = model.fit_generator(generator = train_gen,
steps_per_epoch = len(train_gen),
epochs = 5,
validation_data = val_gen,
validation_steps = len(val_gen),
callbacks = callback_list,
class_weight=class_weights )
final_out['Survived']=final_out['Survived'].apply(lambda x:int(round(x[0])) )<save_to_csv>
model.save_weights("Weight_resNet50_DS_5epoch_2.h5")
 model.save('resNet50_DS_5epoch_2.h5' )
final_out.reset_index()
final_out.to_csv('./final_predictions.csv',index=False )<count_values>
y_test = model.predict_generator(
 test_gen,
steps=len(test_gen),
verbose=1
)
<import_modules><EOS> 
test_df_csv = test_df_csv.join(pd.DataFrame(y_test, columns=[
'any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural'
]))
test_df_csv = test_df_csv.melt(id_vars=['filename'])
 test_df_csv['ID'] = test_df_csv.filename.apply(lambda x: x.replace('.png', '')) + '_' + test_df_csv.variable
test_df_csv['Label'] = test_df_csv['value']
test_df_csv[['ID', 'Label']].to_csv('submission.csv', index=False )