{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import albumentations as A\nimport cv2\nimport gc\nimport numpy as np\nimport os\nimport pandas as pd\nimport random\nimport sys\nfrom math import floor\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tqdm.notebook import tqdm\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.mixed_precision import experimental as mixed_precision\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MultiLabelBinarizer, LabelBinarizer\n!pip install '../input/glrec2020/Keras_Applications-1.0.8-py3-none-any.whl'\n!pip install '../input/glrec2020/efficientnet-1.1.0-py3-none-any.whl'\nimport efficientnet.tfkeras as efn\nos.chdir(\"../input/keras-vgg16-places365\")\nfrom vgg16_places_365 import VGG16_Places365\nos.chdir(\"/kaggle/working/\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import ReduceLROnPlateau","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SEED = 4249\nnp.random.seed(SEED)\ntf.random.set_seed(SEED)\nTEST_SIZE = 0.1\nSIZE = 256\nBATCH_SIZE = 64\nLR = 0.0001\nCHANNELS = 3\nSHAPE = (SIZE, SIZE, CHANNELS)\nTRAIN_ROOT_PATH = '../input/landmark-recognition-2020/train'\nTEST_ROOT_PATH = '../input/landmark-recognition-2020/test'\nsubmission = pd.read_csv('../input/landmark-recognition-2020/sample_submission.csv')\ntrain_data = pd.read_csv('../input/glrec2020/train.csv')\nINFERENCE = True\nPLACES = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_image(path, im_size, normalize_image = False):\n    img = cv2.imread(path, cv2.IMREAD_COLOR)  \n    img = cv2.resize(img, (im_size, im_size))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)\n    if normalize_image:\n        img /= 255.0 \n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_train_transforms():\n    return A.Compose([\n            A.HorizontalFlip(p = 0.15),\n            A.VerticalFlip(p = 0.25),\n            A.RandomRotate90(p = 0.3),\n            A.Transpose(p = 0.1),\n            A.ShiftScaleRotate(shift_limit = 0.05, scale_limit = 0.1, rotate_limit = 25, interpolation = 1, border_mode = 4, p = 0.15)\n        ], p = 0.9)\n\nclass TrainDataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, image_ids, labels, classes, batch_size = 16, augmentation = False, *args, **kwargs):\n        self.image_ids = image_ids\n        self.labels = labels\n        self.classes = classes\n        self.batch_size = batch_size\n        self.augmentation = augmentation\n        self.indices = range(len(self.image_ids))\n        self.indices = np.arange(len(self.image_ids))\n\n    def __len__(self):\n        return int(floor(len(self.image_ids) / self.batch_size))\n\n    def __getitem__(self, index):\n        indices = self.indices[index*self.batch_size:(index+1)*self.batch_size]\n        if self.augmentation:\n            augmentor = get_train_transforms()\n        X = np.empty((self.batch_size, *(SIZE, SIZE, CHANNELS)))\n        Y = np.empty((self.batch_size, self.classes))\n        for i, index in enumerate(indices):\n            image_id, label = self.image_ids[index], self.labels[index]\n            image = read_image(f\"{TRAIN_ROOT_PATH}/{image_id[0]}/{image_id[1]}/{image_id[2]}/{image_id}.jpg\", SIZE, normalize_image = True)\n            if self.augmentation:\n                data = {\"image\": image}\n                augmented = augmentor(**data)\n                image = augmented[\"image\"]\n            X[i,] = image\n            Y[i,] = label.toarray()\n        return X, Y ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_data.head())\nprint(train_data.shape)\ntrain_value_counts_regular = train_data['landmark_id'].value_counts()\nplt.figure(figsize=(12, 8))\nsns.distplot(train_value_counts_regular, hist = False, rug = False, label = \"Train Data normal value count distribution\")\nplt.xlabel(\"Value Counts\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def custom_sampler(df, min_samples, max_samples):\n    landmark_id_counts = df['landmark_id'].value_counts()\n    df1 = df[df['landmark_id'].isin(landmark_id_counts[(landmark_id_counts >= min_samples) & (landmark_id_counts <= max_samples)].index)]\n\n    for id in landmark_id_counts[landmark_id_counts > max_samples].index:\n        temp_df = df[df.landmark_id == id].sample(max_samples, random_state = SEED)\n        df1 = pd.concat([df1, temp_df], axis = 0)\n    return df1\ntrain_data = custom_sampler(train_data, min_samples = 12, max_samples = 140)\ntrain_value_counts_custom = train_data['landmark_id'].value_counts()\nplt.figure(figsize=(12, 8))\nsns.distplot(train_value_counts_custom, hist = False, rug = False, label = \"Train Data custom value count distribution\")\nplt.xlabel(\"Value Counts\")\nplt.show() ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_landmark_ids = train_data.landmark_id.unique().tolist()\nprint(f'Total number of classes sampled: {len(all_landmark_ids)}')\nALL_LABELS = np.sort(np.unique(all_landmark_ids))\nlb = LabelBinarizer(sparse_output = True)\nlb.fit(ALL_LABELS)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def batch_gap(y_t, y_p):\n    pred_cat = tf.argmax(y_p, axis=-1)    \n    y_t_cat = tf.argmax(y_t, axis=-1) * tf.cast(\n        tf.reduce_sum(y_t, axis=-1), tf.int64)\n    n_pred = tf.shape(pred_cat)[0]\n    is_c = tf.cast(tf.equal(pred_cat, y_t_cat), tf.float32)\n    GAP = tf.reduce_mean(\n          tf.cumsum(is_c) * is_c / tf.cast(\n              tf.range(1, n_pred + 1), \n              dtype=tf.float32))\n    return GAP\ndef ModelCheckpoint():\n    return tf.keras.callbacks.ModelCheckpoint(\n                            'Model_epoch{epoch:02d}_vl{val_loss:.4f}_va{val_acc:.4f}_vbg{val_batch_gap:.4f}.h5', \n                            monitor = 'val_loss', \n                            verbose = 1, \n                            save_best_only = False, \n                            save_weights_only = True, \n                            mode = 'min', \n                            save_freq = 'epoch')\ndef generalized_mean_pool_2d(X):\n    gm_exp = 3.0\n    pool = (tf.reduce_mean(tf.abs(X**(gm_exp)), \n                        axis = [1, 2], \n                        keepdims = False) + 1.e-7)**(1./gm_exp)\n    return pool\ndef create_model_gem(WEIGHTS, CLASSES): \n    input = tf.keras.layers.Input(shape = SHAPE)\n    effnet_model = efn.EfficientNetB2(weights = WEIGHTS, include_top = False, input_tensor = input, pooling = None , classes = None)\n    X = tf.keras.layers.Lambda(generalized_mean_pool_2d, name = 'gem')(effnet_model.output)\n    X = tf.keras.layers.Dropout(0.25)(X)\n    X = tf.keras.layers.Dense(1024, activation = 'relu')(X)\n    X = tf.keras.layers.BatchNormalization()(X)\n    X = tf.keras.layers.Dropout(0.25)(X)\n    preds = tf.keras.layers.Dense(CLASSES, activation = 'softmax')(X)\n    model = tf.keras.Model(inputs = effnet_model.input, outputs = preds)\n    for layer in model.layers:\n        layer.trainable = True\n    return model\ndef create_model(WEIGHTS, CLASSES): \n    input = tf.keras.layers.Input(shape = SHAPE)\n    effnet_model = efn.EfficientNetB2(weights = WEIGHTS, include_top = False, input_tensor = input, pooling = 'avg', classes = None)\n    X = tf.keras.layers.Dropout(0.25)(effnet_model.output)\n    X = tf.keras.layers.Dense(1024, activation = 'relu')(X)\n    X = tf.keras.layers.BatchNormalization()(X)\n    X = tf.keras.layers.Dropout(0.25)(X)\n    preds = tf.keras.layers.Dense(CLASSES, activation = 'softmax')(X)\n    model = tf.keras.Model(inputs = effnet_model.input, outputs = preds)\n    for layer in model.layers:\n        layer.trainable = True\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(all_landmark_ids))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_image_tta(im_res):\n        im_res_lr = np.fliplr(im_res)\n        return np.stack((im_res, im_res_lr))  \nmodel = create_model(None, len(all_landmark_ids))\nmodel.load_weights('../input/glrec2020/Model_epoch06_vl3.2417_va0.6774_vbg0.4803.h5')\nif PLACES:\n        model_places = VGG16_Places365(weights = '../input/keras-vgg16-places365/vgg16-places365_weights_tf_dim_ordering_tf_kernels.h5')\n        predictions_to_return = 6\n        places_classes = pd.read_csv('../input/keras-vgg16-places365/categories_places365_extended_v1.csv')\nprint('Start Creating Submission...')\nprediction = []\nfor index, row in tqdm(submission.iterrows(), total = submission.shape[0]):\n        image_id = row['id']\n        file_name = f\"{TEST_ROOT_PATH}/{image_id[0]}/{image_id[1]}/{image_id[2]}/{image_id}.jpg\"\n        image = read_image(file_name, SIZE, normalize_image = True)\n        if PLACES:\n            image_places = read_image(file_name, 224, normalize_image = False)\n            places_preds = model_places.predict(create_image_tta(image_places))\n            places_pred = np.mean(places_preds, axis = 0)\n            places_top_preds = np.argsort(places_pred)[::-1][0:predictions_to_return]\n            counter = 0 \n            if (places_classes.loc[places_classes['class'] == places_top_preds[0]].io == 1).bool():\n                counter +=1\n            if (places_classes.loc[places_classes['class'] == places_top_preds[1]].io == 1).bool():\n                counter +=1\n            if (places_classes.loc[places_classes['class'] == places_top_preds[2]].io == 1).bool():\n                counter +=1\n            if (places_classes.loc[places_classes['class'] == places_top_preds[3]].io == 1).bool():\n                counter +=1\n            if counter >= 3:\n                prediction.append(' ')                    \n            else:\n                pred = model.predict(create_image_tta(image))\n                max_value = np.max(np.mean(pred, axis = 0))\n                max_index = np.argmax(np.mean(pred, axis = 0))\n                prediction.append(str(ALL_LABELS[max_index]) + ' ' + str(max_value))\n        else:\n            pred = model.predict(create_image_tta(image))\n            max_value = np.max(np.mean(pred, axis = 0))\n            max_index = np.argmax(np.mean(pred, axis = 0))\n            prediction.append(str(ALL_LABELS[max_index]) + ' ' + str(max_value))\nsubmission['landmarks'] = np.array(prediction)\nsubmission.to_csv('submission.csv', index = False)\nprint(submission.head(25))","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}