Kaggle competition: Bengali.AI Handwritten Grapheme Classification
def get_mat(rotation, shear, height_zoom, width_zoom, height_shift, width_shift):
rotation = math.pi * rotation / 180.
 shear = math.pi * shear / 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])
 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])
 zoom_matrix = tf.reshape(tf.concat([one/height_zoom,zero,zero, zero,one/width_zoom,zero, zero,zero,one],axis=0),[3,3])
 shift_matrix = tf.reshape(tf.concat([one,zero,height_shift, zero,one,width_shift, zero,zero,one],axis=0),[3,3])
 return K.dot(K.dot(rotation_matrix, shear_matrix), K.dot(zoom_matrix, shift_matrix))<categorify>
import torch
from torch import nn
import pandas as pd
import numpy as np
import cv2
from torch.utils.data import Dataset, DataLoader
from collections import OrderedDict
import torch.nn as nn
import torch.nn.functional as F
import torch
import gc
def transform(image,label):
DIM = IMAGE_SIZE[0]
XDIM = DIM%2
rot = 15.* tf.random.normal([1],dtype='float32')
 shr = 5.* tf.random.normal([1],dtype='float32')
 h_zoom = 1.0 + tf.random.normal([1],dtype='float32')/10.
 w_zoom = 1.0 + tf.random.normal([1],dtype='float32')/10.
 h_shift = 16.* tf.random.normal([1],dtype='float32')
 w_shift = 16.* 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]),label<categorify>
BATCH_SIZE=512
TEST_FILE_PATH='/kaggle/input/bengaliai-cv19/test.csv'
DATA_DIR='/kaggle/input/bengaliai-cv19/'
MODEL_PATH='/kaggle/input/12345678/checkpoint-epoch50.pth'
def decode_image(image_data):
image = tf.image.decode_jpeg(image_data, channels=3)
 image = tf.cast(image, tf.float32)/ 255.0
image = tf.reshape(image, [*IMAGE_SIZE, 3])
 return image
def read_labeled_tfrecord(example):
LABELED_TFREC_FORMAT = {
"image": tf.io.FixedLenFeature([], tf.string),
"class": tf.io.FixedLenFeature([], tf.int64),
}
example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)
 image = decode_image(example['image'])
 label = tf.cast(example['class'], tf.int32)
 return image, label
def read_unlabeled_tfrecord(example):
UNLABELED_TFREC_FORMAT = {
"image": tf.io.FixedLenFeature([], tf.string),
"id": tf.io.FixedLenFeature([], tf.string),
}
example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)
 image = decode_image(example['image'])
 idnum = example['id']
return image, idnum
def data_augment(image, label):
image = tf.image.random_flip_left_right(image)
 image = tf.image.random_brightness(image, 0.2)
 return image, label
def load_dataset(filenames, labeled=True, ordered=False):
ignore_order = tf.data.Options()
if not ordered:
ignore_order.experimental_deterministic = False
dataset = tf.data.TFRecordDataset(filenames)
 dataset = dataset.with_options(ignore_order)
 dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord)
 return dataset
def get_dataset(filenames, augment=True, shuffle=True, repeat=True, labeled=True, ordered=False):
dataset = load_dataset(filenames, labeled=labeled, ordered=ordered)
 if augment:
dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
 dataset = dataset.map(transform, num_parallel_calls=AUTO)
 if repeat:
dataset = dataset.repeat()
if shuffle:
dataset = dataset.shuffle(2048)
 dataset = dataset.batch(BATCH_SIZE)
 dataset = dataset.prefetch(AUTO)
 return dataset
def get_training_dataset() :
dataset = load_dataset(TRAINING_FILENAMES, labeled=True)
 dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
 dataset = dataset.map(transform, num_parallel_calls=AUTO)
 dataset = dataset.repeat()
dataset = dataset.shuffle(2048)
 dataset = dataset.batch(BATCH_SIZE)
 dataset = dataset.prefetch(AUTO)
 return dataset
def get_validation_dataset(ordered=False):
dataset = load_dataset(VALIDATION_FILENAMES, labeled=True, ordered=ordered)
 dataset = dataset.batch(BATCH_SIZE)
 dataset = dataset.cache()
dataset = dataset.prefetch(AUTO)
 return dataset
def get_test_dataset(ordered=False):
dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)
 dataset = dataset.batch(BATCH_SIZE)
 dataset = dataset.prefetch(AUTO)
 return dataset
training_dataset = get_training_dataset()
validation_dataset = get_validation_dataset()
def count_data_items(filenames):
n = [int(re.compile(r"-([0-9]*)\." ).search(filename ).group(1)) for filename in filenames]
return np.sum(n)
 NUM_TRAINING_IMAGES = int(count_data_items(TRAINING_FILENAMES))
NUM_VALIDATION_IMAGES = int(count_data_items(VALIDATION_FILENAMES))
NUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)
 STEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE
print('Dataset: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES, NUM_VALIDATION_IMAGES, NUM_TEST_IMAGES))<install_modules>
class test_dataset(torch.utils.data.Dataset):
def __init__(self,test_dir):
self.dir=test_dir
self.data=pd.read_parquet(self.dir)
 def __len__(self):
return self.data.shape[0]
def __getitem__(self,idx):
data=(self.data.iloc[idx].to_numpy() [1:].reshape([1, 137, 236])/255 ).astype('float')
 data=torch.from_numpy(data ).cuda().float()
return {'data':data,'id':torch.tensor(idx ).cuda() }
!pip install efficientnet 
<choose_model_class>
class efficientnet_b1(nn.Module):
def __init__(self):
super(efficientnet_b1, self ).__init__()
model = EfficientNet.from_name('efficientnet-b1')
 self.conv1 = torch.nn.Conv2d(1, 32,(3, 3))
self.layer0 = model._bn0
self.layer1 = model._blocks
self.layer2 = model._conv_head
self.layer3 = model._bn1
self.layer4 = model._avg_pooling
self.layer5 = model._dropout
self.fc1 = torch.nn.Linear(1280, 168)
 self.fc2 = torch.nn.Linear(1280, 11)
 self.fc3 = torch.nn.Linear(1280, 7)
 def forward(self, x):
x = self.conv1(x)
 x = self.layer0(x)
 for layer in self.layer1:
x=layer(x)
 x = self.layer2(x)
 x = self.layer3(x)
 x = self.layer4(x)
 x = self.layer5(x)
 x = torch.flatten(x, 1)
 x1 = self.fc1(x)
 x2 = self.fc2(x)
 x3 = self.fc3(x)
 return [x1, x2, x3]
LR_START = 0.00001
LR_MAX = 0.00005 * strategy.num_replicas_in_sync
LR_MIN = 0.00001
LR_RAMPUP_EPOCHS = 5
LR_SUSTAIN_EPOCHS = 0
LR_EXP_DECAY =.8
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
lr_callback = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose = True )<train_on_grid>
torch.cuda.empty_cache()
with torch.no_grad() :
model1=efficientnet_b1()
model1=torch.nn.DataParallel(model1,device_ids=[0])
 model1.eval()
model1.load_state_dict(torch.load('/kaggle/input/all-models/checkpoint-epoch23.pth'))
with strategy.scope() :
pretrained_model = efn.EfficientNetB7(weights='imagenet', include_top=False, input_shape=[*IMAGE_SIZE, 3])
 pretrained_model.trainable = True
model1 = tf.keras.Sequential([
pretrained_model,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(104, activation='softmax')
 ])
 model1.compile(
 optimizer='adam',
loss = 'sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'] 
)
 historical = model1.fit(training_dataset,
steps_per_epoch=STEPS_PER_EPOCH,
epochs=EPOCHS,
callbacks = [lr_callback],
validation_data=validation_dataset )<train_on_grid>
gc.collect()
test_data=['test_image_data_0.parquet','test_image_data_1.parquet','test_image_data_2.parquet','test_image_data_3.parquet']
test_id_answer={}
grapheme_root_list=[]
vowel_diacritic_list=[]
consonant_diacritic_list=[]
with torch.no_grad() :
for data_dir in test_data:
dataset=pd.read_parquet(DATA_DIR+data_dir ).iloc[:,1:].to_numpy().reshape([-1,1,137,236])
 dataset=np.array_split(dataset, 50210//128)
 for data in dataset:
input_data=torch.from_numpy(data/255 ).float().cuda()
print(input_data.size())
 output=model1(input_data)
 grapheme_root_list.extend(np.argmax(output[0].cpu().detach().numpy() ,axis=1))
vowel_diacritic_list.extend(np.argmax(output[1].cpu().detach().numpy() ,axis=1))
consonant_diacritic_list.extend(np.argmax(output[2].cpu().detach().numpy() ,axis=1))
del input_data,output
gc.collect()
torch.cuda.empty_cache()
del dataset
gc.collect()
with strategy.scope() :
densenet = tf.keras.applications.DenseNet201(input_shape=[*IMAGE_SIZE, 3], weights='imagenet', include_top=False)
 densenet.trainable = True
model2 = tf.keras.Sequential([
densenet,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(104, activation='softmax')
 ])
 model2.compile(
 optimizer='adam',
loss = 'sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'] 
)
 model2.summary()
historical = model2.fit(training_dataset,
steps_per_epoch=STEPS_PER_EPOCH,
epochs=EPOCHS,
callbacks = [lr_callback],
validation_data=validation_dataset )<predict_on_test>
z=len(consonant_diacritic_list)
 row_id=[]
target=[]
for i in range(z):
row_id.append('Test_{}_consonant_diacritic'.format(i))
row_id.append('Test_{}_grapheme_root'.format(i))
row_id.append('Test_{}_vowel_diacritic'.format(i))
target.append(consonant_diacritic_list[i])
 target.append(grapheme_root_list[i])
 target.append(vowel_diacritic_list[i] )
cmdataset = get_validation_dataset(ordered=True)
 images_ds = cmdataset.map(lambda image, label: image)
 labels_ds = cmdataset.map(lambda image, label: label ).unbatch()
cm_correct_labels = next(iter(labels_ds.batch(NUM_VALIDATION_IMAGES)) ).numpy()
m1 = model1.predict(images_ds)
 m2 = model2.predict(images_ds)
 scores = []
for alpha in np.linspace(0,1,100):
cm_probabilities = alpha*m1+(1-alpha)*m2
cm_predictions = np.argmax(cm_probabilities, axis=-1)
 scores.append(f1_score(cm_correct_labels, cm_predictions, labels=range(104), average='macro'))
best_alpha = np.argmax(scores)/100
print('Best alpha: ' + str(best_alpha))<predict_on_test>
final_file=pd.DataFrame({'row_id':row_id, 'target':target},columns = ['row_id','target'] )
<set_options><EOS> 
final_file.to_csv('submission.csv',index=False )