{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport os\nimport time, gc\nimport numpy as np\nimport pandas as pd\n\nimport tensorflow as tf\nimport keras\nfrom keras import backend as K\nfrom keras.models import Model, Input\nfrom keras.layers import Dense, Lambda\nfrom math import ceil\n\n!pip install '../input/kerasefficientnetb3/efficientnet-1.0.0-py3-none-any.whl' # Install EfficientNet\nimport efficientnet.keras as efn","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 137\nWIDTH = 236\nFACTOR = 0.60\nHEIGHT_NEW = int(HEIGHT * FACTOR)\nWIDTH_NEW = int(WIDTH * FACTOR)\nCHANNELS = 3\nBATCH_SIZE = 16\n\nDIR = '../input/bengaliai-cv19'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# IMAGE PROCESSING\nprint(HEIGHT_NEW) # Image Size Summary\nprint(WIDTH_NEW)\n\ndef resize_image(img, WIDTH_NEW, HEIGHT_NEW):          # Image Prep\n    img = 255 - img                                    # Invert\n    img = (img * (255.0 / img.max())).astype(np.uint8) # Normalize\n    img = img.reshape(HEIGHT, WIDTH) # Reshape\n    image_resized = cv2.resize(img, (WIDTH_NEW, HEIGHT_NEW), interpolation = cv2.INTER_AREA)\n    \n    return image_resized.reshape(-1)   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# CREATE MODEL\n# Generalized mean pool - GeM\ngm_exp = tf.Variable(3.0, dtype = tf.float32)\ndef generalized_mean_pool_2d(X):\n    pool = (tf.reduce_mean(tf.abs(X**(gm_exp)), axis = [1, 2], keepdims = False) + 1.e-7)**(1./gm_exp)\n    return pool","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create Model\ndef create_model(input_shape):\n    input = Input(shape = input_shape) # Input Layer\n    x_model = efn.EfficientNetB3(weights = None, include_top = False, input_tensor = input, pooling = None, classes = None) # Create and Compile Model and show Summary\n    \n    for layer in x_model.layers:   # UnFreeze all layers\n        layer.trainable = True\n    \n    lambda_layer = Lambda(generalized_mean_pool_2d) # GeM\n    lambda_layer.trainable_weights.extend([gm_exp])\n    x = lambda_layer(x_model.output)\n    \n    grapheme_root = Dense(168, activation = 'softmax', name = 'root')(x) # multi output\n    vowel_diacritic = Dense(11, activation = 'softmax', name = 'vowel')(x)\n    consonant_diacritic = Dense(7, activation = 'softmax', name = 'consonant')(x)\n   \n    model = Model(inputs = x_model.input, outputs = [grapheme_root, vowel_diacritic, consonant_diacritic])  # model\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create Model\nmodel1 = create_model(input_shape = (HEIGHT_NEW, WIDTH_NEW, CHANNELS))\nmodel2 = create_model(input_shape = (HEIGHT_NEW, WIDTH_NEW, CHANNELS))\nmodel3 = create_model(input_shape = (HEIGHT_NEW, WIDTH_NEW, CHANNELS))\nmodel4 = create_model(input_shape = (HEIGHT_NEW, WIDTH_NEW, CHANNELS))\nmodel5 = create_model(input_shape = (HEIGHT_NEW, WIDTH_NEW, CHANNELS))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load Model Weights\nmodel1.load_weights('../input/kerasefficientnetb3/Train1_model_59.h5') # LB 0.9681\nmodel2.load_weights('../input/kerasefficientnetb3/Train1_model_64.h5') # LB 0.9679\nmodel2.load_weights('../input/kerasefficientnetb3/Train1_model_66.h5') # LB 0.9685\nmodel3.load_weights('../input/kerasefficientnetb3/Train1_model_68.h5') # LB 0.9691\n# model4.load_weights('../input/kerasefficientnetb3/Train1_model_57.h5') # LB ??\nmodel5.load_weights('../input/kerasefficientnetb3/Train1_model_70.h5') # LB ??","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# DATA GENERATOR\nclass TestDataGenerator(keras.utils.Sequence):\n    def __init__(self, X, batch_size = 16, img_size = (512, 512, 3), *args, **kwargs):\n        self.X = X\n        self.indices = np.arange(len(self.X))\n        self.batch_size = batch_size\n        self.img_size = img_size\n                    \n    def __len__(self):\n        return int(ceil(len(self.X) / self.batch_size))\n\n    def __getitem__(self, index):\n        indices = self.indices[index*self.batch_size:(index+1)*self.batch_size]\n        X = self.__data_generation(indices)\n        return X\n    \n    def __data_generation(self, indices):\n        X = np.empty((self.batch_size, *self.img_size))\n        \n        for i, index in enumerate(indices):\n            image = self.X[index]\n            image = np.stack((image,)*CHANNELS, axis=-1)\n            image = image.reshape(-1, HEIGHT_NEW, WIDTH_NEW, CHANNELS)\n            \n            X[i,] = image\n        \n        return X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# PREDICT AND SUBMISSION\n\ntgt_cols = ['grapheme_root','vowel_diacritic','consonant_diacritic'] # Create Submission File\nrow_ids, targets = [], [] # Create Predictions\n\nfor i in range(0, 4): # Loop through Test Parquet files (X)\n    test_files = [] # Test Files Placeholder\n    df = pd.read_parquet(os.path.join(DIR, 'test_image_data_'+str(i)+'.parquet')) # Read Parquet file\n    image_ids = df['image_id'].values  # Get Image Id values\n    df = df.drop(['image_id'], axis = 1) # Drop Image_id column\n \n    X = [] # Loop over rows in Dataframe and generate images\n    for image_id, index in zip(image_ids, range(df.shape[0])):\n        test_files.append(image_id)\n        X.append(resize_image(df.loc[df.index[index]].values, WIDTH_NEW, HEIGHT_NEW))\n    \n    data_generator_test = TestDataGenerator(X, batch_size = BATCH_SIZE, img_size = (HEIGHT_NEW, WIDTH_NEW, CHANNELS)) # Data_Generator\n        \n    # Predict with all 3 models\n    preds1 = model1.predict_generator(data_generator_test, verbose = 1)\n    preds2 = model2.predict_generator(data_generator_test, verbose = 1)\n    preds3 = model3.predict_generator(data_generator_test, verbose = 1)\n    preds4 = model4.predict_generator(data_generator_test, verbose = 1)\n    preds5 = model5.predict_generator(data_generator_test, verbose = 1)\n    \n     \n    for i, image_id in zip(range(len(test_files)), test_files): # Loop over Preds  \n        for subi, col in zip(range(len(preds1)), tgt_cols):\n            sub_preds1 = preds1[subi]\n            sub_preds2 = preds2[subi]\n            sub_preds3 = preds3[subi]\n            sub_preds4 = preds4[subi]\n            sub_preds5 = preds5[subi]\n\n            row_ids.append(str(image_id)+'_'+col) # Set Prediction with average of 5 predictions\n            sub_pred_value = np.argmax((sub_preds1[i] + sub_preds2[i] + sub_preds3[i] + sub_preds4[i] + sub_preds5[i]) / 5)\n            targets.append(sub_pred_value)\n   \n    del df # Cleanup\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create and Save Submission File\nsubmit_df = pd.DataFrame({'row_id':row_ids,'target':targets}, columns = ['row_id','target'])\nsubmit_df.to_csv('submission.csv', index = False)\nprint(submit_df.head(40))","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}