{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport keras\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport os\nimport sys\nimport csv\nimport time\nfrom scipy import stats\nimport shutil\nfrom keras.models import load_model\nfrom keras.models import Sequential\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras.layers import Activation, Dropout, Flatten, Dense","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"DATA EXPLORATION"},{"metadata":{"trusted":true},"cell_type":"code","source":"#number of images and landmarks\ntrain = pd.read_csv(\"../input/landmark-recognition-2020/train.csv\")\nprint('Train:\\t\\t', train.shape)\nprint('Landmarks:\\t', len(train['landmark_id'].unique()))\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#number of images in each of the classes\nlm = train[['landmark_id', 'id']].groupby('landmark_id').count().reset_index()\nlm = lm.sort_values('id', ascending=False)\nlm = lm.rename(columns={'id': 'count'}).reset_index(drop=True)\nprint(lm)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Landmark ID distribution\nplt.figure(figsize = (10, 8))\nplt.title('Landmark Image Distribution')\nsns.distplot(train['landmark_id'])\nplt.ylabel('ID')\nplt.xlabel('Number of Instances')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set()\nlandmarks_fold_sorted = pd.DataFrame(train['landmark_id'].value_counts())\nlandmarks_fold_sorted.reset_index(inplace=True)\nlandmarks_fold_sorted.columns = ['landmark_id','count']\nlandmarks_fold_sorted = landmarks_fold_sorted.sort_values('landmark_id')\nax = landmarks_fold_sorted.plot.scatter(\\\n     x='landmark_id',y='count',\n     title='Number of images per class(scatter plot)')\nlocs, labels = plt.xticks()\nplt.setp(labels, rotation=30)\nax.set(xlabel=\"Landmarks\", ylabel=\"Number of images\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of classes with less than 5 images\",(train['landmark_id'].value_counts() < 5).sum())\n\nival_x = (train['landmark_id'].value_counts() <= 10).sum()\nival_y = (train['landmark_id'].value_counts() <= 4).sum()\nival = ival_x - ival_y\nprint(\"Number of classes with images between 5 and 10:\" , ival)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#plot random images\nimport glob\nimages = glob.glob('../input/landmark-recognition-2020/train/*/*/*/*')\nplt.rcParams[\"axes.grid\"] = False\nf, axarr = plt.subplots(4, 4, figsize=(24, 22))\n\ncurrent_row = 0\nfor i in range(16):\n    exmpl = cv2.imread(images[i])\n    exmpl = exmpl[:,:,::-1]\n    \n    col = i%4\n    axarr[col, current_row].imshow(exmpl)\n    if col == 3:\n        current_row += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"MODEL TRAINING"},{"metadata":{"trusted":true},"cell_type":"code","source":"datagen = ImageDataGenerator(\n        rotation_range=40,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        rescale=1./255,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(32, (3, 3), input_shape=(150, 150, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(32, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(64, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors\nmodel.add(Dense(64))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1))\nmodel.add(Activation('sigmoid'))\n\nmodel.compile(loss='binary_crossentropy',\n              optimizer='rmsprop',\n              metrics=['accuracy'])\n\nbatch_size = 16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# this is the augmentation configuration used for training\ntrain_datagen = ImageDataGenerator(\n        rescale=1./255,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        validation_split=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# this is the augmentation configuration we will use for testing:\n# only rescaling\ntest_datagen = ImageDataGenerator(rescale=1./255)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(\n        \"../input/landmark-recognition-2020/train\",  #target directory\n        target_size=(150, 150),  #images resized to 150x150\n        batch_size=batch_size,\n        class_mode='binary')  \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_generator = test_datagen.flow_from_directory(\n        \"../input/landmark-recognition-2020/test\",\n        target_size=(150, 150),\n        batch_size=batch_size,\n        class_mode='binary')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# this is a similar generator, for validation data\nmodel.fit_generator(\n        train_generator,\n        steps_per_epoch=5000 // batch_size,\n        epochs=50,\n        validation_data=validation_generator,\n        validation_steps=800 // batch_size)\nmodel.save_weights('weights.h5')  #saving weights","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import csv\n# DEBUGGING PARAMS:\nNUM_PUBLIC_TRAIN_IMAGES = 1580470 # Used to detect if in session or re-run.\nMAX_NUM_EMBEDDINGS = -1  # Set to > 1 to subsample dataset while debugging.\n\n\nINPUT_DIR = os.path.join('..', 'input')\nDATASET_DIR = os.path.join(INPUT_DIR, 'landmark-recognition-2020')\nTEST_IMAGE_DIR = os.path.join(DATASET_DIR, 'test')\nTRAIN_IMAGE_DIR = os.path.join(DATASET_DIR, 'train')\nTRAIN_LABELMAP_PATH = os.path.join(DATASET_DIR, 'train.csv')\n\n\n\ndef load_labelmap():\n  with open(TRAIN_LABELMAP_PATH, mode='r') as csv_file:\n    csv_reader = csv.DictReader(csv_file)\n    labelmap = {row['id']: row['landmark_id'] for row in csv_reader}\n\n  return labelmap\n\ndef save_submission_csv(predictions=None):\n  \"\"\"Saves optional `predictions` as submission.csv.\n\n  The csv has columns {id, landmarks}. The landmarks column is a string\n  containing the label and score for the id, separated by a ws delimeter.\n\n  If `predictions` is `None` (default), submission.csv is copied from\n  sample_submission.csv in `IMAGE_DIR`.\n\n  Args:\n    predictions: Optional dict of image ids to dicts with keys {class, score}.\n  \"\"\"\n\n  if predictions is None:\n    # Dummy submission!\n    shutil.copyfile(\n        os.path.join(DATASET_DIR, 'sample_submission.csv'), 'submission.csv')\n    return\n\n  with open('submission.csv', 'w') as submission_csv:\n    csv_writer = csv.DictWriter(submission_csv, fieldnames=['id', 'landmarks'])\n    csv_writer.writeheader()\n    for image_id, prediction in predictions.items():\n      label = prediction['class']\n      score = prediction['score']\n      csv_writer.writerow({'id': image_id, 'landmarks': f'{label} {score}'})\n\n\ndef main():\n  labelmap = load_labelmap()\n  num_training_images = len(labelmap.keys())\n  print(f'Found {num_training_images} training images.')\n\n  if num_training_images == NUM_PUBLIC_TRAIN_IMAGES:\n    print(\n        f'Found {NUM_PUBLIC_TRAIN_IMAGES} training images. Copying sample submission.'\n    )\n    save_submission_csv()\n    return\n\n  _, post_verification_predictions = get_predictions(labelmap)\n  save_submission_csv(post_verification_predictions)\n\n\nif __name__ == '__main__':\n  main()","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}