Kaggle competition: APTOS 2019 Blindness Detection
<SOS> metric: QuadraticWeightedKappa Kaggle data source: aptos-2019-blindness-detection<choose_model_class>
import numpy as np
import pandas as pd
import os
import albumentations as ab
import matplotlib.pyplot as plt
import cv2
from sklearn.metrics import cohen_kappa_score
from sklearn.model_selection import train_test_split
from tqdm import tqdm
import seaborn as sns
from sklearn.utils import class_weight,shuffle
import keras as K
from keras.utils import to_categorical
from keras.models import Model
from keras.regularizers import l1
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import Callback,ModelCheckpoint,ReduceLROnPlateau
import imgaug.augmenters as iaa
import imgaug as ia
if TRAINING:
with strategy.scope() :
model2 = tf.keras.Sequential([
efn.EfficientNetB0(
 input_shape=(*IMAGE_SIZE, 3),
weights='imagenet',
include_top=False 
),
L.GlobalAveragePooling2D() ,
L.Dense(1, activation='sigmoid')
 ])
 model2.compile(
 optimizer='adam',
loss = 'binary_crossentropy',
metrics=['accuracy'] 
)
 model2.summary()<choose_model_class>
train_df_path='.. /input/aptos2019-blindness-detection/train.csv'
train_img_path='.. /input/aptos2019-blindness-detection/train_images/'
test_df_path='.. /input/aptos2019-blindness-detection/test.csv'
test_images_path='.. /input/aptos2019-blindness-detection/test_images/'
if TRAINING:
with strategy.scope() :
dnet201 = DenseNet201(
 input_shape=(*IMAGE_SIZE, 3),
weights='imagenet',
include_top=False 
)
 dnet201.trainable = True
model3 = tf.keras.Sequential([
dnet201,
L.GlobalAveragePooling2D() ,
L.Dense(1, activation='sigmoid')
 ])
 model3.compile(
 optimizer='adam',
loss = 'binary_crossentropy',
metrics=['accuracy'] 
)
 model3.summary()<find_best_params>
SIZE=224
batch_size=35
lrfn = build_lrfn()
lr_schedule = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=1 )<create_dataframe>
train_df=pd.read_csv(train_df_path)
 test_df=pd.read_csv(test_df_path )
train_dataset = get_training_dataset()
valid_dataset = get_validation_dataset()<train_model>
class_dict={0:'No DR',1:'Mild',2:'Moderate',3:'Severe',4:'Proliferative DR'}
if TRAINING:
history = model.fit(
 train_dataset,
epochs=EPOCHS,
callbacks=[lr_schedule],
steps_per_epoch=STEPS_PER_EPOCH,
validation_data=valid_dataset 
)
 model.save("efficientnetb7.h5" )<train_model>
new_id_col=[i+'.png' for i in train_df['id_code']]
new_diagnosis=[class_dict[i] for i in train_df['diagnosis']]
train_df['new_id_col']=new_id_col
train_df['new_diagnosis']=new_diagnosis
if TRAINING:
history2 = model2.fit(
 train_dataset,
epochs=EPOCHS,
callbacks=[lr_schedule],
steps_per_epoch=STEPS_PER_EPOCH,
validation_data=valid_dataset 
)
 model2.save("efficientnetb0.h5" )<prepare_output>
train_data,val_data=train_test_split(train_df,test_size=0.15)
 train_data,val_data=train_data.reset_index(drop=True),val_data.reset_index(drop=True )
sub1 = sub.copy()
sub2 = sub.copy()<predict_on_test>
class My_Generator(K.utils.Sequence):
def __init__(self, image_filenames, labels,
batch_size,path, is_train=True,
mix=False, augment=False):
self.image_filenames, self.labels = image_filenames, labels
self.batch_size = batch_size
self.is_train = is_train
self.is_augment = augment
self.path=path
if(self.is_train):
self.on_epoch_end()
self.is_mix = mix
def __len__(self):
return int(np.ceil(len(self.image_filenames)/ float(self.batch_size)))
 def __getitem__(self, idx):
batch_x = self.image_filenames[idx * self.batch_size:(idx + 1)* self.batch_size]
batch_y = self.labels[idx * self.batch_size:(idx + 1)* self.batch_size]
if(self.is_train):
return self.train_generate(batch_x, batch_y)
 return self.valid_generate(batch_x, batch_y)
 def on_epoch_end(self):
if(self.is_train):
self.image_filenames, self.labels = shuffle(self.image_filenames, self.labels)
 else:
pass
def mix_up(self, x, y):
lam = np.random.beta(0.2, 0.4)
 ori_index = np.arange(int(len(x)))
 index_array = np.arange(int(len(x)))
 np.random.shuffle(index_array)
 mixed_x = lam * x[ori_index] +(1 - lam)* x[index_array]
mixed_y = lam * y[ori_index] +(1 - lam)* y[index_array]
return mixed_x, mixed_y
def train_generate(self, batch_x, batch_y):
batch_images = []
for(sample, label)in zip(batch_x, batch_y):
img = cv2.imread(os.path.join(self.path,sample))
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 img = cv2.resize(img,(SIZE, SIZE))
if(self.is_augment):
img = seq.augment_image(img)
 batch_images.append(img)
 batch_images = np.array(batch_images, np.float32)/ 255
batch_y = np.array(batch_y, np.float32)
 batch_y=to_categorical(batch_y,num_classes=5)
 if(self.is_mix):
batch_images, batch_y = self.mix_up(batch_images, batch_y)
 return batch_images, batch_y
def valid_generate(self, batch_x, batch_y):
batch_images = []
for(sample, label)in zip(batch_x, batch_y):
img = cv2.imread(os.path.join(self.path,sample))
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 img = cv2.resize(img,(SIZE, SIZE))
batch_images.append(img)
 batch_images = np.array(batch_images, np.float32)/ 255
batch_y = np.array(batch_y, np.float32)
 batch_y=to_categorical(batch_y,num_classes=5)
 return batch_images, batch_y
if TRAINING:
test_ds = get_test_dataset(ordered=True)
 print('Computing predictions...')
 test_images_ds = test_ds.map(lambda image, idnum: image)
 probabilities = model.predict(test_images_ds)
 probabilities2 = model2.predict(test_images_ds)
 print('Generating submission.csv file...')
 test_ids_ds = test_ds.map(lambda image, idnum: idnum ).unbatch()
test_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES)) ).numpy().astype('U' )<save_to_csv>
class QWKEvaluation(Callback):
def __init__(self, validation_data=() , batch_size=batch_size, interval=1):
super(Callback, self ).__init__()
self.interval = interval
self.batch_size = batch_size
self.valid_generator, self.y_val = validation_data
self.history = []
def on_epoch_end(self, epoch, logs={}):
if epoch % self.interval == 0:
y_pred = self.model.predict_generator(generator=self.valid_generator,
steps=np.ceil(float(len(self.y_val)) / float(self.batch_size)) ,
workers=1, use_multiprocessing=False,
verbose=1)
 def flatten(y):
return np.argmax(y, axis=1 ).reshape(-1)
 score = cohen_kappa_score(self.y_val,
flatten(y_pred),
labels=[0,1,2,3,4],
weights='quadratic')
 print("
epoch: %d - QWK_score: %.6f
" %(epoch+1, score))
self.history.append(score)
 if score >= max(self.history):
print('saving checkpoint: ', score)
 self.model.save('.. /working/classifier_6.h5')
if TRAINING:
pred_df = pd.DataFrame({'image_name': test_ids, 'target': np.concatenate(probabilities)})
 pred_df2 = pd.DataFrame({'image_name': test_ids, 'target': np.concatenate(probabilities2)})
 del sub1['target']
sub1 = sub1.merge(pred_df, on='image_name')
 sub1.to_csv('submission_efficientnetb7.csv', index=False)
 del sub2['target']
sub2 = sub2.merge(pred_df2, on='image_name')
 sub2.to_csv('submission_efficientnetb0.csv', index=False )<save_to_csv>
train_generator=My_Generator(np.asarray(train_data['new_id_col']),np.asarray(train_data['diagnosis']),
batch_size=batch_size,path=train_img_path,is_train=True,mix=False,augment=True)
 val_generator=My_Generator(np.asarray(val_data['new_id_col']),np.asarray(val_data['diagnosis']),
batch_size=batch_size,path=train_img_path,is_train=False,mix=False,augment=False )
if TRAINING:
sub_es = sub1[['image_name']]
sub_es['target'] = 0.5*sub1['target'] + 0.5*sub2['target']
sub_es.to_csv('submission_blend.csv', index=False)
 sub_es.head()<import_modules>
qwk = QWKEvaluation(validation_data=(val_generator, np.asarray(val_data['diagnosis'])) ,
batch_size=batch_size, interval=1 )
import seaborn as sns<define_variables>
reg = l1(0.001 )
sub_path = ".. /input/siimisic-submission-files"
all_files = os.listdir(sub_path)
 all_files<load_from_csv>
base_layer=K.applications.densenet.DenseNet169(input_shape=(224,224,3),include_top=False,
weights='.. /input/densenet-keras/DenseNet-BC-169-32-no-top.h5')
 for layer in base_layer.layers:
layer.trainable=True
lstm_=K.layers.Reshape([7*7,1664] )(base_layer.output)
 lstm_=K.layers.Bidirectional(K.layers.LSTM(832,recurrent_dropout=0.2))(lstm_)
 x=K.layers.Dense(1024,activation='relu',activity_regularizer=reg )(lstm_)
 x=K.layers.Dropout(0.3 )(x)
 out=K.layers.Dense(5,activation='softmax' )(x )
outs = [pd.read_csv(os.path.join(sub_path, f), index_col=0)for f in all_files]
concat_sub = pd.concat(outs, axis=1)
 cols = list(map(lambda x: "target" + str(x), range(len(concat_sub.columns))))
concat_sub.columns = cols
concat_sub.reset_index(inplace=True)
 concat_sub.head()
ncol = concat_sub.shape[1]<feature_engineering>
model.compile(loss='categorical_crossentropy',optimizer=Adam(0.0001))
concat_sub['target_max'] = concat_sub.iloc[:, 1:ncol].max(axis=1)
 concat_sub['target_min'] = concat_sub.iloc[:, 1:ncol].min(axis=1)
 concat_sub['target_mean'] = concat_sub.iloc[:, 1:ncol].mean(axis=1)
 concat_sub['target_median'] = concat_sub.iloc[:, 1:ncol].median(axis=1 )<define_variables>
rp=ReduceLROnPlateau(monitor='val_loss',factor=0.2,min_lr=0.00000001,patience=3,verbose=1)
 mc=ModelCheckpoint('.. /working/classifier_6.h5',monitor='val_loss',mode='min',period=1,save_best_only=True )
cutoff_lo = 0.002
cutoff_hi = 0.11<save_to_csv>
history=model.fit_generator(train_generator,epochs=30,steps_per_epoch=int(np.ceil(len(train_data)/batch_size)) ,
validation_data=val_generator,
validation_steps=int(np.ceil(len(val_data)/batch_size)) ,callbacks=[qwk,rp]
,class_weight=class_weights )
concat_sub['target'] = concat_sub['target_mean']
concat_sub[['image_name', 'target']].to_csv('submission_mean.csv',
index=False, float_format='%.6f' )<save_to_csv>
del train_generator,val_generator,train_data,val_data
concat_sub['target'] = concat_sub['target_median']
concat_sub[['image_name', 'target']].to_csv('submission_median.csv',
index=False, float_format='%.6f' )<save_to_csv>
model.load_weights('.. /working/classifier_6.h5')
 print('Weights Restored' )
concat_sub['target'] = np.where(np.all(concat_sub.iloc[:,1:ncol] > cutoff_lo, axis=1), 1,
np.where(np.all(concat_sub.iloc[:,1:ncol] < cutoff_hi, axis=1),
0, concat_sub['target_median']))
concat_sub[['image_name', 'target']].to_csv('submission_pushout_median.csv',
index=False, float_format='%.6f' )<feature_engineering>
test_df=pd.read_csv('.. /input/aptos2019-blindness-detection/sample_submission.csv')
 predictions=[]
for id_ in tqdm(test_df['id_code']):
img = cv2.imread(os.path.join(test_images_path,id_+'.png'))
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
 img = cv2.resize(img,(SIZE, SIZE))
img=img/255.0
img=np.expand_dims(img,0)
 predictions.extend(model.predict(img))
concat_sub['target'] = np.where(np.all(concat_sub.iloc[:,1:ncol] > cutoff_lo, axis=1),
concat_sub['target_max'],
np.where(np.all(concat_sub.iloc[:,1:ncol] < cutoff_hi, axis=1),
concat_sub['target_min'],
concat_sub['target_mean']))
concat_sub[['image_name', 'target']].to_csv('submission_minmax_mean.csv',
index=False, float_format='%.6f' )<feature_engineering>
predictions=np.argmax(predictions,1)
 sub=pd.DataFrame({'id_code':test_df['id_code'],'diagnosis':predictions})
 sub.to_csv('submission.csv',index=False )