Kaggle competition: Bengali.AI Handwritten Grapheme Classification
<SOS> metric: WeightedCategorizationAccuracy Kaggle data source: bengali.ai-handwritten-grapheme-classification<save_to_csv>
!pip install /kaggle/input/efficientnet-pytorch/efficientnet_pytorch-0.6.1-py3-none-any.whl
!pip install /kaggle/input/ptmodels/pretrainedmodels-0.7.4-py3-none-any.whl
test_ids_ds = test_dataset.map(lambda image, idnum:idnum ).unbatch()
test_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES)) ).numpy().astype('U')
 submission = pd.DataFrame(test_ids, columns=['id'])
 submission['label'] = test_preds
submission.to_csv('submission.csv', index=False)
 display(submission.head(10))<import_modules>
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
import re
import math
import numpy as np
import seaborn as sns
from kaggle_datasets import KaggleDatasets
from matplotlib import pyplot as plt
from sklearn.metrics import f1_score, precision_score, recall_score, confusion_matrix
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.callbacks import LearningRateScheduler
from tensorflow.keras.metrics import TruePositives, FalsePositives, FalseNegatives 
<install_modules>
class ResNet34(nn.Module):
def __init__(self, pretrained):
super(ResNet34, self ).__init__()
if pretrained is True:
self.model = pretrainedmodels.__dict__["resnet34"](pretrained="imagenet")
 else:
self.model = pretrainedmodels.__dict__["resnet34"](pretrained=None)
 self.l0 = nn.Linear(512, 168)
 self.l1 = nn.Linear(512, 11)
 self.l2 = nn.Linear(512, 7)
 def forward(self, x):
bs, _, _, _ = x.shape
x = self.model.features(x)
 x = F.adaptive_avg_pool2d(x, 1 ).reshape(bs, -1)
 l0 = self.l0(x)
 l1 = self.l1(x)
 l2 = self.l2(x)
 return l0, l1, l2
!pip install efficientnet 
<import_modules>
class EfficientNetWrapper(nn.Module):
def __init__(self, pretrained):
super(EfficientNetWrapper, self ).__init__()
self.effNet = EfficientNet.from_name('efficientnet-b3')
 self.fc_root = nn.Linear(in_features=1000, out_features=168)
 self.fc_vowel = nn.Linear(in_features=1000, out_features=11)
 self.fc_consonant = nn.Linear(in_features=1000, out_features=7)
 def forward(self, X):
output = self.effNet(X)
 output_root = self.fc_root(output)
 output_vowel = self.fc_vowel(output)
 output_consonant = self.fc_consonant(output)
 return output_root, output_vowel, output_consonant
AUTO = tf.data.experimental.AUTOTUNE
AUTO<choose_model_class>
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu" )
tpu = tf.distribute.cluster_resolver.TPUClusterResolver()
tf.config.experimental_connect_to_cluster(tpu)
 tf.tpu.experimental.initialize_tpu_system(tpu)
 strategy = tf.distribute.experimental.TPUStrategy(tpu )<define_variables>
MODEL_MEAN =(0.485, 0.456, 0.406)
 MODEL_STD =(0.229, 0.224, 0.225)
 IMG_HEIGHT = 137
IMG_WIDTH = 236
IMAGE_SIZE = [512, 512]
EPOCHS = 30
LEARNING_RATE = 1e-3
TTA_NUM = 5
BATCH_SIZE = 32 * strategy.num_replicas_in_sync
print("Batch size used: ", BATCH_SIZE)
<define_variables>
class BengaliDatasetTest:
def __init__(self, df, img_height, img_width, mean, std):
self.image_ids = df.image_id.values
self.img_arr = df.iloc[:, 1:].values
self.aug = albumentations.Compose([
albumentations.Resize(img_height, img_width, always_apply=True),
albumentations.Normalize(mean, std, always_apply=True)
 ])
 def __len__(self):
return len(self.image_ids)
 def __getitem__(self, item):
image = self.img_arr[item, :]
img_id = self.image_ids[item]
image = image.reshape(137, 236 ).astype(float)
 image = Image.fromarray(image ).convert("RGB")
 image = self.aug(image=np.array(image)) ["image"]
image = np.transpose(image,(2, 0, 1)).astype(np.float32)
 return {
"image": torch.tensor(image, dtype=torch.float),
"image_id": img_id
}
GCS_PATH = KaggleDatasets().get_gcs_path('tpu-getting-started')
 GCS_PATH_SELECT = {
192: GCS_PATH + '/tfrecords-jpeg-192x192',
224: GCS_PATH + '/tfrecords-jpeg-224x224',
331: GCS_PATH + '/tfrecords-jpeg-331x331',
512: GCS_PATH + '/tfrecords-jpeg-512x512'
}
GCS_FPATH = GCS_PATH_SELECT[IMAGE_SIZE[0]]<define_variables>
def model_predict() :
img_ids_list = []
FOLDS = 5
TEST_BATCH_SIZE = 12
final_img_ids = []
ffinal_g_pred = []
ffinal_v_pred = []
ffinal_c_pred = []
for file_idx in range(4):
final_g_pred = []
final_v_pred = []
final_c_pred = []
df = pd.read_parquet(f"/kaggle/input/bengaliai-cv19/test_image_data_{file_idx}.parquet")
 dataset = BengaliDatasetTest(df=df,
img_height=IMG_HEIGHT,
img_width=IMG_WIDTH,
mean=MODEL_MEAN,
std=MODEL_STD)
 del df
gc.collect()
torch.cuda.empty_cache()
data_loader = torch.utils.data.DataLoader(
 dataset=dataset,
batch_size= TEST_BATCH_SIZE,
shuffle=False 
)
 for fold in range(FOLDS):
model1 = EfficientNetWrapper(False)
 model2 = ResNet34(False)
 model3 = EfficientNetWrapper(False)
 g_pred1, v_pred1, c_pred1 = [], [], []
g_pred2, v_pred2, c_pred2 = [], [], []
g_pred3, v_pred3, c_pred3 = [], [], []
model1.load_state_dict(torch.load(f"/kaggle/input/bengaliaieffnetb3/efficientNet_fold{fold}.pth", map_location=DEVICE))
model1.to(DEVICE)
 model1.eval()
model2.load_state_dict(torch.load(f"/kaggle/input/resnet34originalsize/resnet34_fold{fold}.pth", map_location=DEVICE))
model2.to(DEVICE)
 model2.eval()
model3.load_state_dict(torch.load(f"/kaggle/input/effnetb3-cutmix-mixup/efficientNet_fold{fold}.pth", map_location=DEVICE))
model3.to(DEVICE)
 model3.eval()
for bi, d in tqdm(enumerate(data_loader)) :
image = d["image"]
img_id = d["image_id"]
image = image.to(DEVICE, dtype=torch.float32)
 g1, v1, c1 = model1(image)
 g2, v2, c2 = model2(image)
 g3, v3, c3 = model3(image)
 for ii, imid in enumerate(img_id):
g_pred1.append(g1[ii].cpu().detach().numpy())
 v_pred1.append(v1[ii].cpu().detach().numpy())
 c_pred1.append(c1[ii].cpu().detach().numpy())
 g_pred2.append(g2[ii].cpu().detach().numpy())
 v_pred2.append(v2[ii].cpu().detach().numpy())
 c_pred2.append(c2[ii].cpu().detach().numpy())
 g_pred3.append(g3[ii].cpu().detach().numpy())
 v_pred3.append(v3[ii].cpu().detach().numpy())
 c_pred3.append(c3[ii].cpu().detach().numpy())
 if fold == 0:
final_img_ids.append(imid)
 final_g_pred.append(g_pred1)
 final_v_pred.append(v_pred1)
 final_c_pred.append(c_pred1)
 final_g_pred.append(g_pred2)
 final_v_pred.append(v_pred2)
 final_c_pred.append(c_pred2)
 final_g_pred.append(g_pred3)
 final_v_pred.append(v_pred3)
 final_c_pred.append(c_pred3)
 del g_pred1
del g_pred2
del g_pred3
del c_pred1
del c_pred2
del c_pred3
del v_pred1
del v_pred2
del v_pred3
gc.collect()
torch.cuda.empty_cache()
ffinal_g_pred.append(final_g_pred)
 ffinal_v_pred.append(final_v_pred)
 ffinal_c_pred.append(final_c_pred)
 del final_g_pred
del final_v_pred
del final_c_pred
del data_loader
del dataset
gc.collect()
torch.cuda.empty_cache()
del model1
del model2
del model3
gc.collect()
torch.cuda.empty_cache()
return ffinal_g_pred, ffinal_v_pred, ffinal_c_pred, final_img_ids
TRAINING_FILENAMES = tf.io.gfile.glob(GCS_FPATH + '/train/*.tfrec')
 VALIDATION_FILENAMES = tf.io.gfile.glob(GCS_FPATH + '/val/*.tfrec')
 TEST_FILENAMES = tf.io.gfile.glob(GCS_FPATH + '/test/*.tfrec' )<define_variables>
final_g_pred, final_v_pred, final_c_pred, final_img_ids = model_predict()
SKIP_VALIDATION = True
if SKIP_VALIDATION:
TRAINING_FILENAMES = TRAINING_FILENAMES + VALIDATION_FILENAMES<define_variables>
final_g = np.argmax(np.mean(np.array(final_g_pred), axis=1 ).reshape(-1, 168), axis=1)
 final_v = np.argmax(np.mean(np.array(final_v_pred), axis=1 ).reshape(-1, 11), axis=1)
 final_c = np.argmax(np.mean(np.array(final_c_pred), axis=1 ).reshape(-1, 7), axis=1 )
CLASSES = ['pink primrose', 'hard-leaved pocket orchid', 'canterbury bells', 'sweet pea', 'wild geranium', 'tiger lily', 'moon orchid', 'bird of paradise', 'monkshood', 'globe thistle',
'snapdragon', "colt's foot", 'king protea', 'spear thistle', 'yellow iris', 'globe-flower', 'purple coneflower', 'peruvian lily', 'balloon flower', 'giant white arum lily',
'fire lily', 'pincushion flower', 'fritillary', 'red ginger', 'grape hyacinth', 'corn poppy', 'prince of wales feathers', 'stemless gentian', 'artichoke', 'sweet william',
'carnation', 'garden phlox', 'love in the mist', 'cosmos', 'alpine sea holly', 'ruby-lipped cattleya', 'cape flower', 'great masterwort', 'siam tulip', 'lenten rose',
'barberton daisy', 'daffodil', 'sword lily', 'poinsettia', 'bolero deep blue', 'wallflower', 'marigold', 'buttercup', 'daisy', 'common dandelion',
'petunia', 'wild pansy', 'primula', 'sunflower', 'lilac hibiscus', 'bishop of llandaff', 'gaura', 'geranium', 'orange dahlia', 'pink-yellow dahlia',
'cautleya spicata', 'japanese anemone', 'black-eyed susan', 'silverbush', 'californian poppy', 'osteospermum', 'spring crocus', 'iris', 'windflower', 'tree poppy',
'gazania', 'azalea', 'water lily', 'rose', 'thorn apple', 'morning glory', 'passion flower', 'lotus', 'toad lily', 'anthurium',
'frangipani', 'clematis', 'hibiscus', 'columbine', 'desert-rose', 'tree mallow', 'magnolia', 'cyclamen ', 'watercress', 'canna lily',
'hippeastrum ', 'bee balm', 'pink quill', 'foxglove', 'bougainvillea', 'camellia', 'mallow', 'mexican petunia', 'bromelia', 'blanket flower',
'trumpet creeper', 'blackberry lily', 'common tulip', 'wild rose']
print(f"No of Flower classes in dataset: {len(CLASSES)}" )<choose_model_class>
del final_g_pred
del final_v_pred
del final_c_pred
gc.collect()
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 =.7
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)
 rng = [i for i in range(EPOCHS)]
y = [lrfn(x)for x in rng]
plt.plot(rng, y)
 print("Learning rate schedule: {:.3g} to {:.3g} to {:.3g}".format(y[0], max(y), y[-1])) 
<define_variables>
predictions = []
for ii, imid in enumerate(final_img_ids):
predictions.append(( f"{imid}_grapheme_root", final_g[ii]))
predictions.append(( f"{imid}_vowel_diacritic", final_v[ii]))
predictions.append(( f"{imid}_consonant_diacritic", final_c[ii]))
def display_batch_of_images(databatch, predictions=None):

 images, labels = batch_to_numpy_images_and_labels(databatch)
 if labels is None:
labels = [None for _ in enumerate(images)]
rows = int(math.sqrt(len(images)))
 cols = len(images)//rows
FIGSIZE = 13.0
SPACING = 0.1
subplot=(rows,cols,1)
 if rows < cols:
plt.figure(figsize=(FIGSIZE,FIGSIZE/cols*rows))
else:
plt.figure(figsize=(FIGSIZE/rows*cols,FIGSIZE))
for i,(image, label)in enumerate(zip(images[:rows*cols], labels[:rows*cols])) :
title = '' if label is None else CLASSES[label]
correct = True
if predictions is not None:
title, correct = title_from_label_and_target(predictions[i], label)
 dynamic_titlesize = FIGSIZE*SPACING/max(rows,cols)*40+3
subplot = display_one_flower(image, title, subplot, not correct, titlesize=dynamic_titlesize)
 plt.tight_layout()
if label is None and predictions is None:
plt.subplots_adjust(wspace=0, hspace=0)
 else:
plt.subplots_adjust(wspace=SPACING, hspace=SPACING)
 plt.show()<categorify>
del final_g
del final_v
del final_c
gc.collect()
<categorify><EOS> 
sub = pd.DataFrame(predictions, columns=["row_id", "target"])
 sub.to_csv("submission.csv", index=False)
 sub