Kaggle competition: Bengali.AI Handwritten Grapheme Classification
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 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, num_parallel_reads = AUTO)
 dataset = dataset.with_options(ignore_order)
 dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord, num_parallel_calls = AUTO)
 return dataset
def data_augment(image, label):
image = tf.image.random_flip_left_right(image)
 image = tf.image.random_saturation(image, 0, 2)
 return image, label
def get_training_dataset() :
dataset = load_dataset(TRAINING_FILENAMES, labeled = True)
 dataset = dataset.map(data_augment, 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
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 = count_data_items(TRAINING_FILENAMES)
 NUM_VALIDATION_IMAGES = 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))<define_variables>
inputs = ["test_image_data_0.parquet","test_image_data_1.parquet","test_image_data_2.parquet","test_image_data_3.parquet"]
training_dataset = get_training_dataset()
training_dataset = training_dataset.unbatch().batch(20)
 train_batch = iter(training_dataset)
<create_dataframe>
DIR = ".. /input/bengaliai-cv19/"
test_dataset = get_test_dataset()
test_dataset = test_dataset.unbatch().batch(20)
 test_batch = iter(test_dataset)
<define_variables>
class EvalDataset(Dataset):
def __init__(self,df,transform=None,aug=None,norm=None):
self.norm = norm
self.df = df
self.data = 255 - self.df.iloc[:, 1:].values.reshape(-1, 137, 236 ).astype(np.uint8)
 self.transform = transform
self.aug = aug
def __getitem__(self, idx):
name = self.df.iloc[idx,0]
image_arr = cv2.resize(self.data[idx],(128,128))
image_arr = image_arr/255.0
if self.norm != None:
mean = self.norm['mean']
std = self.norm['std']
image_arr =(image_arr - mean)/std
image_arr = torch.from_numpy(image_arr.astype(np.float32))
return image_arr.unsqueeze(0 ).repeat(3,1,1),name
def __len__(self):
return len(self.data )
test_dataset = get_test_dataset()
test_dataset = test_dataset.unbatch().batch(20)
 test_batch = iter(test_dataset )<choose_model_class>
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20, restore_best_weights = True )<choose_model_class>
class SEModule(nn.Module):
def __init__(self, channels=2048, reduction=16):
super(SEModule, self ).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
 self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1,
padding=0)
 self.relu = nn.ReLU(inplace=True)
 self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1,
padding=0)
 self.sigmoid = nn.Sigmoid()
def forward(self, x):
module_input = x
x = self.avg_pool(x)
 x = self.fc1(x)
 x = self.relu(x)
 x = self.fc2(x)
 x = self.sigmoid(x)
 return module_input * x
class MyModel(nn.Module):
def __init__(self,pretrained=True):
super().__init__()
if pretrained:
self.model = pretrainedmodels.__dict__["se_resnext50_32x4d"](pretrained="imagenet")
 else:
self.model = pretrainedmodels.__dict__["se_resnext50_32x4d"](pretrained=None)
 self.model = nn.Sequential(*list(self.model.children())[:-2])
 self.se_g = SEModule()
self.se_v = SEModule()
self.se_c = SEModule()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
 self.fc_g = nn.Sequential(nn.Linear(2048,512), nn.ReLU() , nn.Dropout(p=0.2), nn.Linear(512,168))
self.fc_v = nn.Sequential(nn.Linear(2048,512), nn.ReLU() , nn.Dropout(p=0.2), nn.Linear(512,11))
self.fc_c = nn.Sequential(nn.Linear(2048,512), nn.ReLU() , nn.Dropout(p=0.2), nn.Linear(512,7))
def forward(self,x):
x = self.model(x)
 g = self.se_g(x)
 v = self.se_v(x)
 c = self.se_c(x)
 g = torch.flatten(self.avg_pool(g),1)
 v = torch.flatten(self.avg_pool(v),1)
 c = torch.flatten(self.avg_pool(c),1)
 g = self.fc_g(g)
 v = self.fc_v(v)
 c = self.fc_c(c)
 return g,v,c
def create_VGG16_model() :
pretrained_model = tf.keras.applications.VGG16(weights = 'imagenet', include_top = False, input_shape = [*IMAGE_SIZE, 3])
 pretrained_model.trainable = True
model = tf.keras.Sequential([
pretrained_model,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(len(CLASSES), activation = 'softmax')
 ])
 model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', metrics = ['sparse_categorical_accuracy'])
 return model<choose_model_class>
results = []
mean = 13.4/255
std = 40.8/255
model = MyModel(pretrained=False)
 model.load_state_dict(torch.load('.. /input/seresnext-50-train/seresnext_50.pth'))
model.to(device)
 for inp in inputs:
df = pd.read_parquet(DIR+inp)
 kaggle_dataset = EvalDataset(df,norm={'mean':mean,'std':std})
 dl = DataLoader(kaggle_dataset,batch_size=128,num_workers=4)
 img,gra,vow,con = kaggle_out(model,dl,device)
 for i in range(len(img)) :
results.append(( f"{img[i]}_grapheme_root",gra[i]))
results.append(( f"{img[i]}_vowel_diacritic",vow[i]))
results.append(( f"{img[i]}_consonant_diacritic",con[i]))
df2 = pd.DataFrame(results, columns=["row_id", "target"] )
def create_Xception_model() :
pretrained_model = tf.keras.applications.Xception(include_top = False, input_shape = [*IMAGE_SIZE, 3])
 pretrained_model.trainable = True
model = tf.keras.Sequential([
pretrained_model,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(len(CLASSES), activation = 'softmax')
 ])
 model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', metrics = ['sparse_categorical_accuracy'])
 return model<choose_model_class>
sub = df2
<choose_model_class><EOS> 
sub.to_csv("submission.csv", index=False )