Kaggle competition: APTOS 2019 Blindness Detection
<SOS> metric: QuadraticWeightedKappa Kaggle data source: aptos-2019-blindness-detection<train_model>
import pandas as pd
import cv2
import time
import torchvision
import torch.nn as nn
from tqdm import tqdm_notebook as tqdm
import scipy as sp
from sklearn import metrics
from functools import partial
from PIL import Image, ImageFile
from torch.utils.data import Dataset
import torch
import torch.optim as optim
from torchvision import transforms
from torch.optim import lr_scheduler
import os
import numpy as np
from sklearn.model_selection import train_test_split, StratifiedKFold
from scipy import stats
import random
import albumentations
from albumentations import torch as AT
def get_xie29_raw_prediction(debug=False):
class FixedDropout(tf.keras.layers.Dropout):
def _get_noise_shape(self, inputs):
if self.noise_shape is None:
return self.noise_shape
symbolic_shape = tf.keras.backend.shape(inputs)
 noise_shape = [symbolic_shape[axis] if shape is None else shape
for axis, shape in enumerate(self.noise_shape)]
return tuple(noise_shape)
 class Generalized_mean_pooling2D(tf.keras.layers.Layer):
def __init__(self, p=3, epsilon=1e-6, name='', trainable=True, **kwargs):
super(Generalized_mean_pooling2D, self ).__init__()
self.init_p = p
self.epsilon = epsilon
def build(self, input_shape):
if isinstance(input_shape, list)or len(input_shape)!= 4:
raise ValueError('`GeM` pooling layer only allow 1 input with 4 dimensions(b, h, w, c)')
 self.build_shape = input_shape
self.p = self.add_weight(
 name='p',
shape=[1,],
initializer=tf.keras.initializers.Constant(value=self.init_p),
regularizer=None,
trainable=True,
dtype=tf.float32 
)
 self.built=True
def call(self, inputs):
input_shape = inputs.get_shape()
if isinstance(inputs, list)or len(input_shape)!= 4:
raise ValueError('`GeM` pooling layer only allow 1 input with 4 dimensions(b, h, w, c)')
 return(tf.reduce_mean(tf.abs(inputs**self.p), axis=[1,2], keepdims=False)+ self.epsilon)**(1.0/self.p)
 def get_config(self):
config = super().get_config().copy()
config.update({
'p': self.init_p,
'epsilon': self.epsilon
})
 return config
class TestGenerator(tf.keras.utils.Sequence):
def __init__(self,
image_shape,
batch_size,
load_dir,
test_df 
):
self.image_shape = image_shape
self.batch_size = batch_size
self.test_df = test_df
self.image_ids = test_df['image_id'].values
self.load_dir = load_dir
self.indices = range(test_df.shape[0])
 def __len__(self):
return self.test_df.shape[0] // self.batch_size
def __getitem__(self, index):
batch_indices = self.indices[self.batch_size * index : self.batch_size *(index+1)]
image_ids = self.image_ids[batch_indices]
batch_images = [self.__getimages__(image_id)for image_id in image_ids]
return np.stack(batch_images)
 def glue_tiles(self, images, y_tiles_num=3, x_tiles_num=4, sz=128):
glued_image = np.zeros(( sz*y_tiles_num, sz*x_tiles_num, 3), np.uint8)
 for i, image in enumerate(images):
y_start = int(i / x_tiles_num)* sz
y_end = y_start + sz
x_start = int(i % x_tiles_num)* sz
x_end = x_start + sz
glued_image[y_start:y_end, x_start:x_end, :] = image
return glued_image
def get_foreground(self, image):
grayscale = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
 _, thresh = cv2.threshold(grayscale, 200, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
 if np.sum(thresh)== 0:
return image
bbox = cv2.boundingRect(thresh)
 x, y, w, h = bbox
foreground = image[y:y+h, x:x+w]
return foreground
def __getimages__(self, img_id):
read_in_path = os.path.join(self.load_dir, img_id + '.tiff')
 img = skimage.io.MultiImage(read_in_path)[1]
shape = img.shape
pad0,pad1 =(sz - shape[0]%sz)%sz,(sz - shape[1]%sz)%sz
img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=255)
 img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)
 img = img.transpose(0,2,1,3,4 ).reshape(-1,sz,sz,3)
 if len(img)< N:
img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)
 idxs = np.argsort(img.reshape(img.shape[0],-1 ).sum(-1)) [:N]
img = img[idxs]
slim_images = []
for i in img:
i = self.get_foreground(i)
 slim_images.append(cv2.resize(i,(resize_sz, resize_sz), cv2.INTER_AREA))
del img
glued_image = self.glue_tiles(slim_images, y_tiles_num, x_tiles_num, resize_sz)

return glued_image/255.0
def prediction_decode(y_preds):
for i, pred in enumerate(y_preds):
if pred < 0.5:
y_preds[i] = 0
elif pred >= 0.5 and pred < 1.5:
y_preds[i] = 1
elif pred >= 1.5 and pred < 2.5:
y_preds[i] = 2
elif pred >= 2.5 and pred < 3.5:
y_preds[i] = 3
elif pred >= 3.5 and pred < 4.5:
y_preds[i] = 4
else:
y_preds[i] = 5
return y_preds.astype(np.int32)
 @tf.function
def inference_step(images):
preds = model(images, training=False)
 return preds
def inference(model, test_generator):
prediction = []
for step in range(test_generator.__len__()):
print('=', end='', flush=True)
 images = test_generator.__getitem__(step)
 preds = model(images, training=False)
 preds = preds[0].numpy()
for y_pred in preds:
prediction.append(y_pred)
 print('')
 return np.array(prediction, dtype=np.float32)
 get_custom_objects().update({'swish': tf.keras.layers.Activation(tf.nn.swish)})
 get_custom_objects().update({'FixedDropout':FixedDropout})
 get_custom_objects().update({'Generalized_mean_pooling2D':Generalized_mean_pooling2D})
 MAIN_DIR = '.. /input/prostate-cancer-grade-assessment'
sample_csv = pd.read_csv(os.path.join(MAIN_DIR, 'sample_submission.csv'))
main_folder = 'test'
if debug:
sample_csv = pd.read_csv(os.path.join(MAIN_DIR, 'train.csv')) [:100]
main_folder = 'train'
x_tiles_num = 12
y_tiles_num = 12
sz = 128
resize_sz = 128
IMG_DIM =(int(resize_sz*y_tiles_num), int(resize_sz*x_tiles_num))
CLASSES_NUM = 1
BATCH_SIZE = 32
N= 144
PRETRAIN_PATH = ['.. /input/panda-best-weights/fold0_b3_144tiles_128tilesize_mse_huber_0905kcv_0853rcv_0706.h5',
'.. /input/panda-best-weights/fold2_b3_144tiles_128tilesize_mse_huber_09174kcv_0841rcv_0719.h5']
raw_prediction = sample_csv['isup_grade'].values
print(f'folder using: {main_folder}')
 test_generator = TestGenerator(image_shape=IMG_DIM,
batch_size=1,
load_dir=os.path.join(MAIN_DIR, f'{main_folder}_images'),
test_df=sample_csv)
 for idx in range(len(PRETRAIN_PATH)) :
if PRETRAIN_PATH[idx]:
print('load xies model pretrain weights.. ')
 model = tf.keras.models.load_model(PRETRAIN_PATH[idx],
custom_objects={
'Generalized_mean_pooling2D' : Generalized_mean_pooling2D
})
 if os.path.exists(f'.. /input/prostate-cancer-grade-assessment/{main_folder}_images'):
if idx == 0:
raw_prediction = inference(model, test_generator)
 else:
raw_prediction += inference(model, test_generator)
 print('Clean usage memory of xie29...')
 del model
tf.keras.backend.clear_session()
gc.collect()
raw_prediction = raw_prediction / len(PRETRAIN_PATH)
 sample_csv['isup_grade'] = raw_prediction
return sample_csv<rename_columns>
device = torch.device("cuda:0")
 ImageFile.LOAD_TRUNCATED_IMAGES = True
DATA = '.. /input/prostate-cancer-grade-assessment/test_images'
if os.path.exists(DATA):
xie = get_xie29_raw_prediction(debug=False)
 res_drhb = res_drhb.rename(columns={'isup_grade': 'res_drhb'})
 res_igor = res_igor.rename(columns={'isup_grade': 'res_igor'})
 res_rs50 = res_rs50.rename(columns={'isup_grade': 'res_rs50'})
 res_ruef = res_ruef.rename(columns={'isup_grade': 'res_ruef'})
 xie = xie.rename(columns={'isup_grade': 'res_xief'})
 sub_df = reduce(lambda x,y: pd.merge(x,y, on='image_id'), [res_drhb, res_igor, res_rs50, res_ruef, xie])
 sub_df['med_level'] =(sub_df['res_drhb'] +
sub_df['res_igor'] +
sub_df['res_rs50'])/3
sub_df['isup_grade'] = predict(( sub_df['med_level'] +
sub_df['res_ruef' ] +
sub_df['res_xief' ])/3)
 sub_df = sub_df[['image_id', 'isup_grade']].copy()
sub_df.to_csv("./submission.csv",index=False)
 print('Clean usage memory of xie29...' )<set_options>
class RetinopathyDataset_v2(Dataset):
def __init__(self, df, transform, train=True):
self.data = df.reset_index()
if train:
self.prefix = "train"
else:
self.prefix = "test"
self.transform = transform
def __len__(self):
return len(self.data)
 def __getitem__(self, idx):
img_name = os.path.join('.. /input/aptos2019-blindness-detection/{}_images'.format(self.prefix),
self.data.loc[idx, 'id_code'] + '.png')
 img = cv2.imread(img_name)
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 image = self.transform(image=img)
 image = image['image']
label = torch.tensor(self.data.loc[idx, 'diagnosis'])
 return {'image': image,
'labels': label
}
%matplotlib inline 
<set_options>
class RetinopathyDataset(Dataset):
def __init__(self, csv_file, transform, train=True):
self.data = pd.read_csv(csv_file)
 if train:
self.prefix = "train"
else:
self.prefix = "test"
self.transform = transform
def __len__(self):
return len(self.data)
 def __getitem__(self, idx):
img_name = os.path.join('.. /input/aptos2019-blindness-detection/{}_images'.format(self.prefix), self.data.loc[idx, 'id_code'] + '.png')
 img = cv2.imread(img_name)
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 image = self.transform(image=img)
 image = image['image']
label = torch.tensor(self.data.loc[idx, 'diagnosis'])
 return {'image': image,
'labels': label
}
try:
tpu = tf.distribute.cluster_resolver.TPUClusterResolver()
except ValueError:
tpu = None
gpus = tf.config.experimental.list_logical_devices('GPU')
 if tpu:
tf.config.experimental_connect_to_cluster(tpu)
 tf.tpu.experimental.initialize_tpu_system(tpu)
 strategy = tf.distribute.experimental.TPUStrategy(tpu)
 print("Running on TPU: " + str(tpu.master()))
elif len(gpus)> 0:
strategy = tf.distribute.MirroredStrategy(gpus)
 print("Running on ",len(gpus)," GPU(s)")
 else:
strategy = tf.distribute.get_strategy()
print("Running on CPU")
 print("Number of units: {}".format(strategy.num_replicas_in_sync))<init_hyperparams>
class OptimizedRounder(object):
def __init__(self):
self.coef_ = 0
def _kappa_loss(self, coef, X, y):
X_p = np.copy(X)
 for i, pred in enumerate(X_p):
if pred < coef[0]:
X_p[i] = 0
elif pred >= coef[0] and pred < coef[1]:
X_p[i] = 1
elif pred >= coef[1] and pred < coef[2]:
X_p[i] = 2
elif pred >= coef[2] and pred < coef[3]:
X_p[i] = 3
else:
X_p[i] = 4
ll = metrics.cohen_kappa_score(y, X_p, weights='quadratic')
 return -ll
def fit(self, X, y):
loss_partial = partial(self._kappa_loss, X=X, y=y)
 initial_coef = [0.5, 1.5, 2.5, 3.5]
self.coef_ = sp.optimize.minimize(loss_partial, initial_coef, method='nelder-mead')
 def predict(self, X, coef):
X_p = np.copy(X)
 for i, pred in enumerate(X_p):
if pred < coef[0]:
X_p[i] = 0
elif pred >= coef[0] and pred < coef[1]:
X_p[i] = 1
elif pred >= coef[1] and pred < coef[2]:
X_p[i] = 2
elif pred >= coef[2] and pred < coef[3]:
X_p[i] = 3
else:
X_p[i] = 4
return X_p
def coefficients(self):
return self.coef_['x']
AUTO = tf.data.experimental.AUTOTUNE
num_units = strategy.num_replicas_in_sync
if num_units == 8:
BATCH_SIZE = 16 * num_units
VALIDATION_BATCH_SIZE = 16 * num_units
start_lr = 0.00001
min_lr = 0.00001
max_lr = 0.00005 * num_units
rampup_epochs = 8
sustain_epochs = 0
exp_decay = 0.8
else:
BATCH_SIZE = 2
VALIDATION_BATCH_SIZE = 2
start_lr = 0.0003
min_lr = 0.000001
rampup_epochs = 8
sustain_epochs = 0
exp_decay = 0.7 
<define_variables>
model = torchvision.models.resnet101(pretrained=False)
 model.load_state_dict(torch.load(".. /input/fastai-pretrained-models/resnet101-5d3b4d8f.pth"))
for param in model.parameters() :
param.requires_grad = False
model.fc = nn.Sequential(
 nn.Linear(in_features=2048, out_features=1, bias=True), 
)
 model = model.to(device )
BASE = '.. /input/prostate-cancer-grade-assessment/'
TEST_PATH = '.. /input/prostate-cancer-grade-assessment/test_images'
test_csv_path = '.. /input/prostate-cancer-grade-assessment/sample_submission.csv'<load_from_csv>
transforms_train = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.HorizontalFlip() ,
albumentations.VerticalFlip() ,
albumentations.RandomBrightness() ,
albumentations.ShiftScaleRotate(rotate_limit=20, scale_limit=0.10),
albumentations.Normalize() ,
AT.ToTensor()
])
 transforms_validation = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.Normalize() ,
AT.ToTensor()
])
 transforms_test = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.Rotate(limit=10),
albumentations.Normalize() ,
AT.ToTensor()
] )
train = pd.read_csv(BASE + 'train.csv')
 test = pd.read_csv(BASE + 'test.csv' )<define_variables>
train_df = pd.read_csv('.. /input/aptos2019-blindness-detection/train.csv')
 test_df = pd.read_csv('.. /input/aptos2019-blindness-detection/test.csv')
 skf = StratifiedKFold(n_splits=10, random_state=2052)
 for i,(train_index, val_index)in enumerate(skf.split(train_df['diagnosis'], train_df['diagnosis'])) :
if i == 0:
validation_df = train_df.iloc[val_index]
train_df = train_df.iloc[train_index]
train_dataset = RetinopathyDataset_v2(df=train_df, train=True, transform=transforms_train)
 validation_dataset = RetinopathyDataset_v2(df=validation_df, train=True, transform=transforms_validation)
 test_dataset = RetinopathyDataset(csv_file='.. /input/aptos2019-blindness-detection/sample_submission.csv',
transform=transforms_test, train=False )
image_paths = [BASE + 'train_images/' + x + '.tiff' for x in train['image_id'].values.tolist() ]<normalization>
def weighted_mse_loss(preds, target, weight):
return torch.sum(weight *(preds - target)** 2 )
def read_image(image_path, resize_ratio=1):
if not(isinstance(image_path, str)) :
image_path = image_path.numpy().decode('utf-8')
 image_level_1 = skimage.io.MultiImage(image_path)[1]
if resize_ratio != 1:
new_w = int(image_level_1.shape[1]*resize_ratio)
 new_h = int(image_level_1.shape[0]*resize_ratio)
 image_level_1 = cv2.resize(
 image_level_1,(new_w, new_h), interpolation=cv2.INTER_AREA)
 return image_level_1<categorify>
data_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
 data_loader_val = torch.utils.data.DataLoader(validation_dataset, batch_size=32, shuffle=True, num_workers=4)
 num_epochs = 25
optimizer = optim.Adam(model.parameters() , lr=0.0002)
 alpha_mixup = 0.3
n_freeze = 2
weight_pow = 0.3
label_counts = train_df['diagnosis'].value_counts().values
label_weights =(label_counts[:] / label_counts.sum())**(-weight_pow)
 label_weights /= label_weights[0]
print(label_weights )
def _pad_image(image, pad_len, pad_val):

 if image is None:
return None
elif image.ndim == 2:
return np.pad(
 image,(( pad_len, pad_len),(pad_len, pad_len)) , pad_val)
 elif image.ndim == 3:
return np.pad(
 image,(( pad_len, pad_len),(pad_len, pad_len),(0, 0)) , pad_val)
 return None
def _transpose_image(image):

 if image is None:
return None
elif image.ndim == 2:
return np.transpose(image,(1, 0)).copy()
elif image.ndim == 3:
return np.transpose(image,(1, 0, 2)).copy()
return None
def _get_tissue_parts_indices(tissue, min_consec_info):

 split_points = np.where(np.diff(tissue)!= 1)[0]+1
tissue_parts = np.split(tissue, split_points)
 return [
tp for tp in tissue_parts if len(tp)>= min_consec_info
]
def _get_tissue_subparts_coords(subtissue, patch_size, min_decimal_keep):

 start, end = subtissue[0], subtissue[-1]
num_subparts =(end-start)/patch_size
if num_subparts % 1 < min_decimal_keep and num_subparts >= 1:
num_subparts = math.floor(num_subparts)
 else:
num_subparts = math.ceil(num_subparts)
 excess =(num_subparts*patch_size)-(end-start)
 shift = excess // 2
return [
i * patch_size + start - shift
for i in range(num_subparts)
 ]
def _eval_and_append_xy_coords(coords,
image,
mask,
patch_size,
x, y,
min_patch_info,
transposed,
precompute):

 patch_1d =(
 image[y: y+patch_size, x:x+patch_size, :] 
.mean(axis=2)
.reshape(-1)
)
 idx_tissue = np.where(patch_1d <= 210)[0]
idx_black = np.where(patch_1d < 5)[0]
idx_background = np.where(patch_1d > 210)[0]
if len(idx_tissue)> 0:
patch_1d[idx_black] = 210
patch_1d[idx_background] = 210
val1 = int(patch_1d.mean())
 val2 = mask[y:y+patch_size, x:x+patch_size].mean()
if val2 > min_patch_info:
if precompute:
if transposed:
coords = np.concatenate([
coords, [[val1, x-patch_size, y-patch_size]]
])
 else:
coords = np.concatenate([
coords, [[val1, y-patch_size, x-patch_size]]
])
 else:
coords = np.concatenate([
coords, [[val1, y, x]]
])
 return coords
def compute_coords(image,
patch_size=256,
precompute=False,
min_patch_info=0.35,
min_axis_info=0.35,
min_consec_axis_info=0.35,
min_decimal_keep=0.7 
):

 if type(image)!= np.ndarray:
image = image.numpy()
mask = _mask_tissue(image)
 coords = np.zeros([0, 3], dtype=int)
 image = _pad_image(image, patch_size, 'maximum')
 mask = _pad_image(mask, patch_size, 'minimum')
 y_sum = mask.sum(axis=1)
 x_sum = mask.sum(axis=0)
 if len(np.where(x_sum > 0)[0])> len(np.where(y_sum > 0)[0]):
image = _transpose_image(image)
 mask = _transpose_image(mask)
 y_sum, _ = x_sum, y_sum
transposed = True
else:
transposed = False
y_tissue = np.where(y_sum >=(patch_size*min_axis_info)) [0]
if len(y_tissue)< 1:
warnings.warn("Not enough tissue in image(y-dim)", RuntimeWarning)
 if precompute: return [(0, 0, 0)]
else: return image, [(0, 0, 0)]
y_tissue_parts_indices = _get_tissue_parts_indices(
 y_tissue, patch_size*min_consec_axis_info)
 if len(y_tissue_parts_indices)< 1:
warnings.warn("Not enough tissue in image(y-dim)", RuntimeWarning)
 if precompute: return [(0, 0, 0)]
else: return image, [(0, 0, 0)]
for yidx in y_tissue_parts_indices:
y_tissue_subparts_coords = _get_tissue_subparts_coords(
 yidx, patch_size, min_decimal_keep)
 for y in y_tissue_subparts_coords:
x_slice_sum = mask[y:y+patch_size, :].sum(axis=0)
 x_tissue = np.where(x_slice_sum >=(patch_size*min_axis_info)) [0]
x_tissue_parts_indices = _get_tissue_parts_indices(
 x_tissue, patch_size*min_consec_axis_info)
 for xidx in x_tissue_parts_indices:
x_tissue_subparts_coords = _get_tissue_subparts_coords(
 xidx, patch_size, min_decimal_keep)
 for x in x_tissue_subparts_coords:
coords = _eval_and_append_xy_coords(
 coords, image, mask, patch_size, x, y,
min_patch_info, transposed, precompute 
)
 if len(coords)< 1:
warnings.warn("Not enough tissue in image(x-dim)", RuntimeWarning)
 if precompute: return [(0, 0, 0)]
else: return image, [(0, 0, 0)]
if precompute:
return coords
else:
return image, coords<normalization>
since = time.time()
criterion = weighted_mse_loss
best = 0
nep = 0
best_coeff = []
month_day = time.gmtime() [1:3]
for epoch in range(num_epochs):
print('Epoch {}/{}'.format(epoch, num_epochs - 1))
print('-' * 10)
 model.train()
running_loss = 0.0
tk0 = tqdm(data_loader, total=int(len(data_loader)))
 counter = 0
if epoch == n_freeze:
for param in model.parameters() :
param.requires_grad = True
for bi, d in enumerate(tk0):
inputs = d["image"]
labels = d["labels"].view(-1, 1)
 weights = labels[:, 0].clone()
for i in range(len(label_weights)) :
weights[labels[:, 0] == i] = label_weights[i]
shuffled_index = list(range(inputs.shape[0]))
random.shuffle(shuffled_index)
 mixed_up_inputs = inputs[shuffled_index, :, :, :]
mixed_up_labels = labels[shuffled_index, :]
mixed_up_weights = mixed_up_labels[:, 0].clone()
for i in range(len(label_weights)) :
mixed_up_weights[mixed_up_labels[:, 0] == i] = label_weights[i]
l_mixup = stats.beta.rvs(a=alpha_mixup, b=alpha_mixup, size=inputs.shape[0])
 inputs = torch.as_tensor(l_mixup, dtype=torch.float ).view(-1, 1, 1, 1)* inputs
inputs += torch.as_tensor(1.- l_mixup, dtype=torch.float ).view(-1, 1, 1, 1)* mixed_up_inputs
labels = labels.float()
mixed_up_labels = mixed_up_labels.float()
labels = torch.as_tensor(l_mixup, dtype=torch.float ).view(-1, 1)* labels
labels += torch.as_tensor(1.- l_mixup, dtype=torch.float ).view(-1, 1)* mixed_up_labels
weights = weights.float()
mixed_up_weights = mixed_up_weights.float()
weights = torch.as_tensor(l_mixup, dtype=torch.float ).view(-1, 1)* weights
weights += torch.as_tensor(1.- l_mixup, dtype=torch.float ).view(-1, 1)* mixed_up_weights
inputs = inputs.to(device, dtype=torch.float)
 labels = labels.to(device, dtype=torch.float)
 weights = weights.to(device, dtype=torch.float)
 optimizer.zero_grad()
with torch.set_grad_enabled(True):
outputs = model(inputs)
 loss = criterion(outputs, labels, weights)
 loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
 counter += 1
tk0.set_postfix(loss=(running_loss /(counter * data_loader.batch_size)))
 epoch_loss = running_loss / len(data_loader)
 print('Training Loss: {:.4f}'.format(epoch_loss))
model.eval()
counter = 0
val_loss = 0.0
preds = []
full_labels = []
for d in data_loader_val:
inputs = d["image"]
labels = d["labels"].view(-1, 1)
 inputs = inputs.to(device, dtype=torch.float)
 with torch.set_grad_enabled(False):
outputs = model(inputs)
 preds.append(outputs.cpu().numpy())
 full_labels.append(labels.numpy())
 preds = np.vstack(preds)[:, 0]
full_labels = np.vstack(full_labels)[:, 0]
optR = OptimizedRounder()
optR.fit(preds, full_labels)
 coefficients = optR.coefficients()
valid_predictions = optR.predict(preds, coefficients)
 val_loss = metrics.cohen_kappa_score(valid_predictions, full_labels, weights='quadratic')
 print('Validation Loss: {:.4f}'.format(val_loss))
if val_loss > best:
best = val_loss
nep = epoch
best_coeff = coefficients[:]
print('Current best', best, nep, best_coeff)
 torch.save(model.state_dict() , "model_best.pth")
 time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
def _patch_augment(patch, p=0.5):

 r1 = tf.random.uniform(
 shape=(4,), minval=0, maxval=1)
 r2 = tf.random.uniform(
 shape=() , minval=0, maxval=4, dtype=tf.int32)
 if r1[0] >(1-p):
patch = tf.image.rot90(patch, k=r2)
 if r1[1] >(1-p):
patch = tf.image.random_flip_left_right(patch)
 if r1[2] >(1-p):
patch = tf.image.random_flip_up_down(patch)
 if r1[3] >(1-p):
patch = tf.transpose(patch,(1, 0, 2))
return patch
def _excess_coords_filtering(coords, sample_size, proportion=0.25):

 if len(coords)> sample_size:
c = tf.transpose(coords)
 v = tf.gather(c, 0)
 num = tf.cast(len(v), tf.float32)
 sample_size = tf.cast(sample_size, tf.float32)
 indices_reduced = int(tf.math.ceil(
 num *(1 -(( num - sample_size)/ num)* proportion)
))
v_argsort = tf.argsort(v)
 indices = tf.gather(v_argsort, tf.range(indices_reduced))
indices = tf.sort(indices)
 coords = tf.gather(coords, indices)
 return coords
@tf.function
def patch_image(image, coords, sample_size=36, patch_size=256):
l = tf.cast(tf.math.sqrt(tf.cast(sample_size, tf.float32)) , tf.int32)
 coords = _excess_coords_filtering(coords, sample_size)
 if len(coords)< sample_size:
indices = tf.tile(
 tf.range(len(coords)) , [tf.math.ceil(sample_size/len(coords)) ])
 indices = indices[:sample_size]
else:
indices = tf.range(sample_size)
 coords = tf.gather(coords, indices)
 coords = tf.random.shuffle(coords)
 patched_image = tf.zeros(
 [0, patch_size, patch_size, 3], dtype=tf.dtypes.uint8)
 for i in range(sample_size):
y = tf.gather_nd(coords, [i, 1])
 x = tf.gather_nd(coords, [i, 2])
 shape = tf.shape(image)
 h = tf.gather(shape, 0)
 w = tf.gather(shape, 1)
 if y < 0: y = 0
if x < 0: x = 0
if y > h-patch_size: y = h-patch_size
if x > w-patch_size: x = w-patch_size
patch = tf.slice(
 image,
tf.stack([y, x, 0]),
tf.stack([patch_size, patch_size, -1]))
patched_image = tf.concat([
patched_image, tf.expand_dims(patch, 0)], axis=0)
 patched_image = tf.reshape(patched_image,(-1, patch_size*l, patch_size, 3))
patched_image = tf.transpose(patched_image,(0, 2, 1, 3))
patched_image = tf.reshape(patched_image,(patch_size*l, patch_size*l, 3))
return patched_image<feature_engineering>
if best_coeff[-1] < 3.0:
best_coeff[-1] = 3.0
auto = tf.data.experimental.AUTOTUNE<import_modules>
del inputs, labels, weights, mixed_up_inputs, mixed_up_labels, mixed_up_weights, outputs
del train_dataset, train_df, validation_dataset, validation_df
torch.cuda.empty_cache()
import keras.applications<import_modules>
model.load_state_dict(torch.load("model_best.pth"))
model.eval()
import tensorflow as tf
from tensorflow import keras
import keras.backend as k
from tensorflow.keras.layers import Conv2D, Dense, Dropout, GlobalAveragePooling2D, BatchNormalization
from tensorflow.keras import Sequential
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint 
<load_pretrained>
n_tta = 10
bsize = 4
model = keras.models.load_model('.. /input/finall/effnetb0model9.h5', compile = False,custom_objects = {
'FixedDropout':FixedDropout} )<load_from_csv>
test_data_loader = torch.utils.data.DataLoader(test_dataset, batch_size=bsize, shuffle=False, num_workers=4)
 test_preds = np.zeros(( len(test_dataset), 1))
for j in range(n_tta):
tk0 = tqdm(test_data_loader)
 for i, x_batch in enumerate(tk0):
x_batch = x_batch["image"]
pred = model(x_batch.to(device))
test_preds[i * bsize:(i + 1)* bsize] += pred.detach().cpu().squeeze().numpy().ravel().reshape(-1, 1)
 test_preds /= n_tta
<set_options><EOS> 
for i, pred in enumerate(test_preds):
if pred < best_coeff[0]:
test_preds[i] = 0
elif pred >= best_coeff[0] and pred < best_coeff[1]:
test_preds[i] = 1
elif pred >= best_coeff[1] and pred < best_coeff[2]:
test_preds[i] = 2
elif pred >= best_coeff[2] and pred < best_coeff[3]:
test_preds[i] = 3
else:
test_preds[i] = 4
sample = pd.read_csv(".. /input/aptos2019-blindness-detection/sample_submission.csv")
 sample.diagnosis = test_preds.astype(int)
 sample.to_csv("submission.csv", index=False )