Kaggle competition: SIIM-ISIC Melanoma Classification
<SOS> metric: MCAUC Kaggle data source: siim-isic-melanoma-classification<choose_model_class>
!pip install yapl==0.1.2 efficientnet > /dev/null
!rm -rf *
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'] )<choose_model_class>
import yapl
import os
import re
import random
import pandas as pd
import numpy as np
import math
from sklearn.model_selection import KFold
from sklearn.metrics import roc_auc_score
import tensorflow as tf
import tensorflow.keras.backend as K
from kaggle_datasets import KaggleDatasets
import efficientnet.tfkeras as efn
from yapl.config.config import Config
import matplotlib.pyplot as plt
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc',
patience=3,
verbose=1,
factor=0.5,
min_lr=0.00001 )<init_hyperparams>
tf.keras.backend.clear_session()
datagen = ImageDataGenerator(
 featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=10,
zoom_range = 0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=False,
vertical_flip=False)
 datagen.fit(X_train )<train_model>
class configSetup(Config):
def __init__(self):
super().__init__()
self.IS_EXT = True
self.DO_VAL_SPLIT = True
self.EXPERIMENT_NAME = 'melanoma-detection-yapl-testing'
if self.IS_EXT:
self.GCS_DS_PATH = KaggleDatasets().get_gcs_path('melanoma-384x384')
 self.TOTAL_FILES = tf.io.gfile.glob(self.GCS_DS_PATH + '/train*.tfrec')
 self.TEST_FILES = tf.io.gfile.glob(self.GCS_DS_PATH + '/test*.tfrec')
 self.TRAIN_CSV = '.. /input/melanoma-128x128/train.csv'
else:
self.GCS_DS_PATH = KaggleDatasets().get_gcs_path('siim-isic-melanoma-classification')
 self.TOTAL_FILES = tf.io.gfile.glob(self.GCS_DS_PATH + '/train/*.tfrec')
 self.TEST_FILES = tf.io.gfile.glob(self.GCS_DS_PATH + '/test/*.tfrec')
 self.TRAIN_CSV = '.. /input/siim-isic-melanoma-classification/train.csv'
self.TEST_CSV = '.. /input/siim-isic-melanoma-classification/test.csv'
self.VALIDATION_CSV = ""
self.TOTAL_TRAIN_IMG = 0
self.TOTAL_TEST_IMG = 0
self.NEG_SMAPLE = 32542
self.POS_SMAPLE = 584
self.IMG_SIZE = [384, 384]
self.IMG_TRAIN_SHAPE = [384,384]
self.IMG_SHAPE =(384, 384, 3)
 self.DO_FINETUNE = True
self.BATCH_SIZE = 16
self.EPOCHES = 10
self.SEED = 127
self.FOLDS = 3
self.LOSS = tf.keras.losses.BinaryCrossentropy(label_smoothing = 0.05)
 self.OPTIMIZER = tf.keras.optimizers.Adam()
self.ACCURACY = ['AUC']
self.CALLBACKS = [
tf.keras.callbacks.EarlyStopping(
 monitor='val_auc', restore_best_weights=True, mode = 'max', patience = 3, verbose = 1, min_delta = 0.001, 
)
 ]
self.STRATEGY = None
epochs = 250
batch_size=64
history = model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),
epochs = epochs, validation_data =(X_test,Y_test),
verbose = 2, steps_per_epoch=X_train.shape[0] // batch_size
,callbacks=[learning_rate_reduction] )<predict_on_test>
configSetup().make_global()
yapl.backend = 'tf'
try:
tpu = tf.distribute.cluster_resolver.TPUClusterResolver()
print('Running on TPU ', tpu.master())
 except ValueError:
tpu = None
if tpu:
tf.config.experimental_connect_to_cluster(tpu)
 tf.tpu.experimental.initialize_tpu_system(tpu)
 strategy = tf.distribute.experimental.TPUStrategy(tpu)
 yapl.config.STRATEGY = strategy
yapl.config.BATCH_SIZE = 32 * strategy.num_replicas_in_sync
else:
strategy = tf.distribute.get_strategy()
yapl.config.TOTAL_TEST_IMG = len(pd.read_csv(yapl.config.TEST_CSV ).image_name)
 def count_data_items(filenames):
n = [int(re.compile(r"-([0-9]*)\." ).search(filename ).group(1)) for filename in filenames]
return np.sum(n )
predictions = model.predict(test)
 predictions = np.argmax(predictions,axis = 1)
 predictions = pd.Series(predictions,name="Label" )<save_to_csv>
train_df = pd.read_csv(yapl.config.TRAIN_CSV)
 train_df.head()
submission = pd.concat([pd.Series(range(1,28001),name = "ImageId"),predictions],axis = 1)
 submission.to_csv("submissions_mnist.csv",index=False)
 print("Your file is saved." )<set_options>
FOLDS_DICT = {}
skf = KFold(n_splits=yapl.config.FOLDS,shuffle=True,random_state=yapl.config.SEED)
 for fold,(idxT,idxV)in enumerate(skf.split(np.arange(15))):
FOLDS_DICT['fold_{}'.format(fold+1)] = {
"trainfiles" : [yapl.config.TOTAL_FILES[x] for x in idxT],
"valfiles" : [yapl.config.TOTAL_FILES[x] for x in idxV]
}
%matplotlib inline
np.random.seed(0 )<load_from_csv>
def seed_everything() :
np.random.seed(yapl.config.SEED)
 tf.random.set_seed(yapl.config.SEED)
 random.seed(a=yapl.config.SEED)
 os.environ['PYTHONHASHSEED'] = str(yapl.config.SEED)
 seed_everything()
train = pd.read_csv(r'/kaggle/input/digit-recognizer/train.csv')
 test = pd.read_csv(r'/kaggle/input/digit-recognizer/test.csv' )<prepare_x_and_y>
ROT_ = 180.0
SHR_ = 2.0
HZOOM_ = 8.0
WZOOM_ = 8.0
HSHIFT_ = 8.0
WSHIFT_ = 8.0
def get_mat(rotation, shear, height_zoom, width_zoom, height_shift, width_shift):
rotation = math.pi * rotation / 180.
 shear = math.pi * shear / 180.
 def get_3x3_mat(lst):
return tf.reshape(tf.concat([lst],axis=0), [3,3])
 c1 = tf.math.cos(rotation)
 s1 = tf.math.sin(rotation)
 one = tf.constant([1],dtype='float32')
 zero = tf.constant([0],dtype='float32')
 rotation_matrix = get_3x3_mat([c1, s1, zero,
-s1, c1, zero,
zero, zero, one])
 c2 = tf.math.cos(shear)
 s2 = tf.math.sin(shear)
 shear_matrix = get_3x3_mat([one, s2, zero,
zero, c2, zero,
zero, zero, one])
 zoom_matrix = get_3x3_mat([one/height_zoom, zero, zero,
zero, one/width_zoom, zero,
zero, zero, one])
 shift_matrix = get_3x3_mat([one, zero, height_shift,
zero, one, width_shift,
zero, zero, one])
 return K.dot(K.dot(rotation_matrix, shear_matrix),
K.dot(zoom_matrix, shift_matrix))
def transform(image, DIM=256):
XDIM = DIM%2
rot = ROT_ * tf.random.normal([1], dtype='float32')
 shr = SHR_ * tf.random.normal([1], dtype='float32')
 h_zoom = 1.0 + tf.random.normal([1], dtype='float32')/ HZOOM_
w_zoom = 1.0 + tf.random.normal([1], dtype='float32')/ WZOOM_
h_shift = HSHIFT_ * tf.random.normal([1], dtype='float32')
 w_shift = WSHIFT_ * tf.random.normal([1], dtype='float32')
 m = get_mat(rot,shr,h_zoom,w_zoom,h_shift,w_shift)
 x = tf.repeat(tf.range(DIM//2, -DIM//2,-1), DIM)
 y = tf.tile(tf.range(-DIM//2, DIM//2), [DIM])
 z = tf.ones([DIM*DIM], dtype='int32')
 idx = tf.stack([x,y,z])
 idx2 = K.dot(m, tf.cast(idx, dtype='float32'))
idx2 = K.cast(idx2, dtype='int32')
 idx2 = K.clip(idx2, -DIM//2+XDIM+1, DIM//2)
 idx3 = tf.stack([DIM//2-idx2[0,], DIM//2-1+idx2[1,]])
 d = tf.gather_nd(image, tf.transpose(idx3))
return tf.reshape(d,[DIM, DIM,3] )
Y = train['label']
X = train.drop('label',axis=1 )<feature_engineering>
def data_augment(image, label):
image = transform(image, DIM=yapl.config.IMG_SIZE[0])
 image = tf.image.random_flip_left_right(image)
 image = tf.image.rot90(image)
 return image, label
def process_training_data(data_file):
LABELED_TFREC_FORMAT = {
"image": tf.io.FixedLenFeature([], tf.string),
"target": tf.io.FixedLenFeature([], tf.int64),
}
data = tf.io.parse_single_example(data_file, LABELED_TFREC_FORMAT)
 img = tf.image.decode_jpeg(data['image'], channels=3)
 img = tf.cast(img, tf.float32)/ 255.0
img = tf.reshape(img, [*yapl.config.IMG_TRAIN_SHAPE, 3])
 label = tf.cast(data['target'], tf.int32)
 return img, label
def process_test_data(data_file):
LABELED_TFREC_FORMAT = {
"image": tf.io.FixedLenFeature([], tf.string),
"image_name": tf.io.FixedLenFeature([], tf.string),
}
data = tf.io.parse_single_example(data_file, LABELED_TFREC_FORMAT)
 img = tf.image.decode_jpeg(data['image'], channels=3)
 img = tf.cast(img, tf.float32)/ 255.0
img = tf.reshape(img, [*yapl.config.IMG_TRAIN_SHAPE, 3])
 idnum = data['image_name']
return img, idnum
X = X / 255.0
test = test / 255.0<categorify>
def build_lrfn(lr_start=0.000005, lr_max=0.000020,
lr_min=0.000001, lr_rampup_epochs=5,
lr_sustain_epochs=0, lr_exp_decay=.8):
if yapl.config.STRATEGY is not None:
lr_max = lr_max * yapl.config.STRATEGY.num_replicas_in_sync
def lrfn(epoch):
if epoch < lr_rampup_epochs:
lr =(lr_max - lr_start)/ lr_rampup_epochs * epoch + lr_start
elif epoch < lr_rampup_epochs + lr_sustain_epochs:
lr = lr_max
else:
lr =(lr_max - lr_min)* lr_exp_decay**(epoch - lr_rampup_epochs - lr_sustain_epochs)+ lr_min
return lr
return lrfn
def build_lrfn_l(lr_start=0.00001, lr_max=0.000075,
lr_min=0.000001, lr_rampup_epochs=20,
lr_sustain_epochs=0, lr_exp_decay=.8):
if yapl.config.STRATEGY is not None:
lr_max = lr_max * yapl.config.STRATEGY.num_replicas_in_sync
def lrfn(epoch):
if epoch < lr_rampup_epochs:
lr =(lr_max - lr_start)/ lr_rampup_epochs * epoch + lr_start
elif epoch < lr_rampup_epochs + lr_sustain_epochs:
lr = lr_max
else:
lr =(lr_max - lr_min)* lr_exp_decay**(epoch - lr_rampup_epochs - lr_sustain_epochs)+ lr_min
return lr
return lrfn
def build_lrfn_2() :
lr_start = 0.000005
lr_max = 0.000020
lr_min = 0.000001
lr_ramp_ep = 5
lr_sus_ep = 0
lr_decay = 0.8
if yapl.config.STRATEGY is not None:
lr_max = lr_max * yapl.config.BATCH_SIZE
def lrfn(epoch):
if epoch < lr_ramp_ep:
lr =(lr_max - lr_start)/ lr_ramp_ep * epoch + lr_start
elif epoch < lr_ramp_ep + lr_sus_ep:
lr = lr_max
else:
lr =(lr_max - lr_min)* lr_decay**(epoch - lr_ramp_ep - lr_sus_ep)+ lr_min
return lr
return lrfn
def get_cosine_schedule_with_warmup(lr = 0.00004, num_warmup_steps = 5 , num_training_steps = yapl.config.EPOCHES, num_cycles=0.5):
def lrfn(epoch):
if epoch < num_warmup_steps:
return(float(epoch)/ float(max(1, num_warmup_steps)))* lr
progress = float(epoch - num_warmup_steps)/ float(max(1, num_training_steps - num_warmup_steps))
return max(0.0, 0.5 *(1.0 + math.cos(math.pi * float(num_cycles)* 2.0 * progress)))* lr
return lrfn
lrfn = get_cosine_schedule_with_warmup()
lr_schedule = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=0)
 yapl.config.CALLBACKS.append(lr_schedule )
Y = to_categorical(Y,10 )<split>
def efficientnetbx() :
return tf.keras.Sequential([
efn.EfficientNetB0(
 input_shape=(*yapl.config.IMG_TRAIN_SHAPE, 3),
weights='imagenet',
include_top=False 
),
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(1, activation='sigmoid')
 ] )
<choose_model_class><EOS> 
def fitengine(model, traindataset, valdataset = None, istraining = True):
model.compile(
 optimizer = yapl.config.OPTIMIZER,
loss = yapl.config.LOSS,
metrics = yapl.config.ACCURACY 
)
 weight_for_0 =(1 / yapl.config.NEG_SMAPLE)*(yapl.config.TOTAL_TRAIN_IMG)/2.0
weight_for_1 =(1 / yapl.config.POS_SMAPLE)*(yapl.config.TOTAL_TRAIN_IMG)/2.0
class_weight = {0: weight_for_0, 1: weight_for_1}
history = model.fit(
 traindataset,
epochs = yapl.config.EPOCHES,
steps_per_epoch = yapl.config.TOTAL_TRAIN_IMG//yapl.config.BATCH_SIZE,
callbacks = yapl.config.CALLBACKS,
validation_data = valdataset,
validation_steps = yapl.config.TOTAL_VAL_IMG//yapl.config.BATCH_SIZE,
verbose = 0 
)
 return history