Kaggle competition: Cassava Leaf Disease Classification
<SOS> metric: CategorizationAccuracy Kaggle data source: cassava-leaf-disease-classification<define_variables>
!pip install --quiet.. /input/kerasapplications/keras-team-keras-applications-3b180cb
!pip install --quiet /kaggle/input/efficientnet-git
ls.. /input/cdl-cspresnext50-512/<define_variables>
Flatten,GlobalAveragePooling2D,BatchNormalization, Activation
print(tf.__version__ )
model_pths = [
'.. /input/cdl-cspresnext50-512/light_best_model_fold0.pth',
'.. /input/cdl-cspresnext50-512/light_best_model_fold1.pth',
'.. /input/cdl-cspresnext50-512/light_best_model_fold2.pth',
'.. /input/cdl-cspresnext50-512/light_best_model_fold3.pth',
'.. /input/cdl-cspresnext50-512/light_best_model_fold4.pth',
]<choose_model_class>
try:
tpu = tf.distribute.cluster_resolver.TPUClusterResolver()
print(f'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)
 else:
strategy = tf.distribute.get_strategy()
AUTO = tf.data.experimental.AUTOTUNE
REPLICAS = strategy.num_replicas_in_sync
print(f'REPLICAS: {REPLICAS}' )
class net(nn.Module):
def __init__(self, model_name=enet_type, pretrained=False):
super().__init__()
self.model = timm.create_model(model_name, pretrained=pretrained)
 n_features = self.model.head.fc.in_features
self.model.head.fc = nn.Linear(n_features, 5)
 def forward(self, x):
output = self.model(x)
 return output<categorify>
SEED = 100
DEBUG = False
WANDB = False
VALIDATION_SIZE = 0.2
BATCH_SIZE = 32 *REPLICAS
LEARNING_RATE = 3e-5 * REPLICAS
EPOCHS=40
MODEL_NAME = "EfficentNetB4"
N_FOLDS = 5
TTA = True
N_TTA = 7
T_1 = 0.2
T_2 = 1.2
SMOOTH_FRACTION = 0.01
N_ITER = 5
HEIGHT = 512
WIDTH = 512
HEIGHT_RS = 512
WIDTH_RS = 512
CHANNELS = 3
N_CLASSES = 5
MODEL_SAVE_PATH = ""
if DEBUG:
EPOCHS = 2
class LEAFDataset(Dataset):
def __init__(self, folder, transforms=None):
self.file_names = os.listdir(folder)
 self.transforms = transforms
def __len__(self):
return len(self.file_names)
 def __getitem__(self, index):
image_id = self.file_names[index]
image_file = os.path.join(image_folder, image_id)
 image = cv2.imread(image_file)
 image = image[:, :, ::-1]
if self.transforms is not None:
image = self.transforms(image=image)['image']
return image, image_id<concatenate>
def transform_rotation(image, height, rotation):
DIM = height
XDIM = DIM%2
rotation = rotation * tf.random.uniform([1],dtype='float32')
 rotation = math.pi * rotation / 180.
 c1 = tf.math.cos(rotation)
 s1 = tf.math.sin(rotation)
 one = tf.constant([1],dtype='float32')
 zero = tf.constant([0],dtype='float32')
 rotation_matrix = tf.reshape(tf.concat([c1,s1,zero, -s1,c1,zero, zero,zero,one],axis=0),[3,3])
 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(rotation_matrix,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])
 def transform_shear(image, height, shear):
DIM = height
XDIM = DIM%2
shear = shear * tf.random.uniform([1],dtype='float32')
 shear = math.pi * shear / 180.
 one = tf.constant([1],dtype='float32')
 zero = tf.constant([0],dtype='float32')
 c2 = tf.math.cos(shear)
 s2 = tf.math.sin(shear)
 shear_matrix = tf.reshape(tf.concat([one,s2,zero, zero,c2,zero, zero,zero,one],axis=0),[3,3])
 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(shear_matrix,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])
 def data_augment_cutout(image, min_mask_size=(int(HEIGHT *.1), int(HEIGHT *.1)) ,
max_mask_size=(int(HEIGHT *.125), int(HEIGHT *.125))):
p_cutout = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 if p_cutout >.85:
n_cutout = tf.random.uniform([], 10, 15, dtype=tf.int32)
 image = random_cutout(image, HEIGHT, WIDTH,
min_mask_size=min_mask_size, max_mask_size=max_mask_size, k=n_cutout)
 elif p_cutout >.6:
n_cutout = tf.random.uniform([], 5, 10, dtype=tf.int32)
 image = random_cutout(image, HEIGHT, WIDTH,
min_mask_size=min_mask_size, max_mask_size=max_mask_size, k=n_cutout)
 elif p_cutout >.25:
n_cutout = tf.random.uniform([], 2, 5, dtype=tf.int32)
 image = random_cutout(image, HEIGHT, WIDTH,
min_mask_size=min_mask_size, max_mask_size=max_mask_size, k=n_cutout)
 else:
image = random_cutout(image, HEIGHT, WIDTH,
min_mask_size=min_mask_size, max_mask_size=max_mask_size, k=1)
 return image
def random_cutout(image, height, width, channels=3, min_mask_size=(10, 10), max_mask_size=(80, 80), k=1):
assert height > min_mask_size[0]
assert width > min_mask_size[1]
assert height > max_mask_size[0]
assert width > max_mask_size[1]
for i in range(k):
mask_height = tf.random.uniform(shape=[], minval=min_mask_size[0], maxval=max_mask_size[0], dtype=tf.int32)
 mask_width = tf.random.uniform(shape=[], minval=min_mask_size[1], maxval=max_mask_size[1], dtype=tf.int32)
 pad_h = height - mask_height
pad_top = tf.random.uniform(shape=[], minval=0, maxval=pad_h, dtype=tf.int32)
 pad_bottom = pad_h - pad_top
pad_w = width - mask_width
pad_left = tf.random.uniform(shape=[], minval=0, maxval=pad_w, dtype=tf.int32)
 pad_right = pad_w - pad_left
cutout_area = tf.zeros(shape=[mask_height, mask_width, channels], dtype=tf.uint8)
 cutout_mask = tf.pad([cutout_area], [[0,0],[pad_top, pad_bottom], [pad_left, pad_right], [0,0]], constant_values=1)
 cutout_mask = tf.squeeze(cutout_mask, axis=0)
 image = tf.multiply(tf.cast(image, tf.float32), tf.cast(cutout_mask, tf.float32))
return image
transform = albumentations.Compose([
albumentations.Resize(image_size, image_size),
albumentations.Normalize() ,
ToTensorV2()
] )<load_pretrained>
def data_augment(image, label):
p_rotation = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_spatial = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_rotate = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_pixel_1 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_pixel_2 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_pixel_3 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_shear = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_crop = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 p_cutout = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 flip_left = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 flip_right = tf.random.uniform([], 0, 1.0, dtype=tf.float32)
 if p_rotation >.2:
if p_rotation >.6:
image = transform_rotation(image, HEIGHT, rotation=10.)
else:
image = transform_rotation(image, HEIGHT, rotation=-10.)
if flip_left>0.5:
image = tf.image.random_flip_left_right(image)
 if flip_right>0.5 :
image = tf.image.random_flip_up_down(image)
 image = tf.image.resize(image, size=[HEIGHT, WIDTH])
 return image, label
res = []
for model_pth in model_pths:
model = net(enet_type)
 model.load_state_dict(torch.load(model_pth))
model.eval()
model.to(device)
 test_dataset = LEAFDataset(image_folder, transforms=transform)
 test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, num_workers=num_workers)
 single_model_probs = []
image_ids_list = []
with torch.no_grad() :
for idx,(images, image_ids)in enumerate(tqdm(test_loader)) :
outputs = model(images.to(device))
pred = outputs.detach().softmax(1 ).cpu().numpy()
single_model_probs.append(pred)
 image_ids_list.append(image_ids)
 single_model_probs = np.concatenate(single_model_probs)
 image_ids_list = np.concatenate(image_ids_list)
 res.append(single_model_probs)
 del model
torch.cuda.empty_cache()
res = sum(res)/ len(model_pths)
 probs = res.argmax(1 )<prepare_output>
copyfile(src = ".. /input/bitempered-logistic-loss-tensorflow-v2/bi_tempered_loss.py", dst = ".. /working/loss.py")
sub = pd.DataFrame({'image_id': image_ids_list, 'label': probs});sub.head()<save_to_csv>
with strategy.scope() :
class BiTemperedLogisticLoss(tf.keras.losses.Loss):
def __init__(self, t1, t2, lbl_smth, n_iter):
super(BiTemperedLogisticLoss, self ).__init__()
self.t1 = t1
self.t2 = t2
self.lbl_smth = lbl_smth
self.n_iter = n_iter
def call(self, y_true, y_pred):
return bi_tempered_logistic_loss(y_pred, y_true, self.t1, self.t2, self.lbl_smth, self.n_iter )
sub.to_csv('submission.csv', index=False )<save_to_csv>
files_path = '.. /input/cassava-leaf-disease-classification/test_images'
TEST_FILENAMES = tf.io.gfile.glob('.. /input/cassava-leaf-disease-classification/test_tfrecords/*')
 model_base_path = '.. /input/cassava-efficientnetb4'
model_path_list = os.listdir(model_base_path)
 model_path_list = ['EfficentNet4_best_btl_fold_0_.h5',
'EfficentNet4_best_btl_fold_1_.h5',
'EfficentNet4_best_btl_fold_2_.h5',
]
test_preds = np.zeros(( len(os.listdir(files_path)) , N_CLASSES))
for model_path in model_path_list:
print("Model: ", model_path)
 tf.keras.backend.clear_session()
model = tf.keras.models.load_model(os.path.join(model_base_path,model_path),
custom_objects={'loss': BiTemperedLogisticLoss(t1=T_1, t2=T_2, lbl_smth=SMOOTH_FRACTION, n_iter=N_ITER)},
compile=False)
 if TTA:
for step in range(N_TTA):
print(f"TTA step: {step+1}/{N_TTA}")
 test_ds = get_dataset(TEST_FILENAMES, labeled=False, ordered=True, augment = True)
 x_test = test_ds.map(lambda image, image_name: image)
 test_preds += model.predict(x_test)/len(model_path_list)
 else:
test_ds = get_dataset(TEST_FILENAMES, labeled=False, ordered=True)
 x_test = test_ds.map(lambda image, image_name: image)
 test_preds += model.predict(x_test)/len(model_path_list )
<define_variables><EOS> 
test_preds = np.argmax(test_preds, axis=-1)
 image_names = [img_name.numpy().decode('utf-8')for img, img_name in iter(test_ds.unbatch())]
submission = pd.DataFrame({'image_id': image_names, 'label': test_preds})
 submission.to_csv('submission.csv', index=False)
 display(submission.head() )