{"cells":[{"metadata":{},"cell_type":"markdown","source":"Installing the needed libraries."},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -q efficientnet","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Importing all the needed libraries which will be needed in this notebook.**"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\nimport plotly.express as px\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport PIL\nfrom PIL import Image, ImageDraw\nimport glob\nimport cv2\nimport random\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import layers\nfrom keras import Sequential\nfrom keras import models\nimport tensorflow as tf\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers import *\nfrom keras.optimizers import RMSprop\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom keras.applications import VGG19\nimport efficientnet.tfkeras as efn\nfrom keras.callbacks import ModelCheckpoint\nfrom tensorflow import keras\nfrom keras.models import load_model\nimport seaborn as sns\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Printing the number of images in the given dataset."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images_count = sum([len(files) for r, d, files in os.walk('../input/landmark-recognition-2020/train')])\nprint('The number of train images is :', train_images_count)\ntest_images_count = sum([len(files) for r, d, files in os.walk('../input/landmark-recognition-2020/test')])\nprint('The number of test images is :', test_images_count)\nprint('The total number of images is :', train_images_count+test_images_count)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Reading the dataset and taking a part of the training data (20000 samples), and then adding two extra columns (filename/path and label as string) which will be used later to know which file does each landmark_id refers to\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"Base_path = '../input/landmark-recognition-2020/'\nTrain_DIR = f'{Base_path}/train'\nTest_DIR = f'{Base_path}/test'\ntrain = pd.read_csv(f'{Base_path}/train.csv')\nsubmission = pd.read_csv(f'{Base_path}/sample_submission.csv')\nprint('Reading data completed')\n\nsamples = 20000\nmy_train_data = train.loc[:samples,:]\nmy_test_data = submission\nmy_train_data[\"filename\"] = my_train_data.id.str[0]+\"/\"+my_train_data.id.str[1]+\"/\"+my_train_data.id.str[2]+\"/\"+my_train_data.id+\".jpg\"\nmy_train_data[\"label\"] = my_train_data.landmark_id.astype(str)\nprint(samples ,' will be used in this notebook')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"display(train.head())\nprint(\"Shape of train_data :\", train.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**The number of unique classes with a histogram**"},{"metadata":{"trusted":true},"cell_type":"code","source":"number_of_classes = len(my_train_data['landmark_id'].unique())\nprint('Number of unique classes in training images:',number_of_classes)\nnb_images_pr_class= pd.DataFrame(train.landmark_id.value_counts())\nnb_images_pr_class.reset_index(inplace=True)\nnb_images_pr_class.columns = ['landmark_id','count']\nprint(nb_images_pr_class)\n                \nfig=plt.figure(figsize=(18, 3))\nn = plt.hist(my_train_data[\"landmark_id\"],bins=my_train_data[\"landmark_id\"].unique())\n#plt.ylim(top=250)\nplt.title(\"Distribution of labels\")\nplt.xlabel(\"Landmark_id\")\nplt.ylabel(\"Number of images\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**How many classes have less than 5 training samples? And between 5 and 10 training samples?**"},{"metadata":{"trusted":true},"cell_type":"code","source":"less_than_five = 0\nbetween_five_and_ten = 0\nfor x in n[0]:\n    if(x<5):\n        less_than_five+=1\n    elif(x<10):\n        between_five_and_ten+=1\n    \nprint('Number of classes that have less than 5 training samples :',less_than_five)\nprint('Number of classes that have between 5 and 10 training samples :',between_five_and_ten)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Show 4 sample images from 4 random classes**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_list = glob.glob('../input/landmark-recognition-2020/train/*/*/*/*')\nplt.rcParams[\"axes.grid\"] = False\nf, axarr = plt.subplots(2, 2, figsize=(10, 8))\n\ncurr_row = 0\nfor i in range(4):\n    example = cv2.imread(train_list[random.randint(0,len(train_list)-1)])\n    example = example[:,:,::-1]\n    \n    col = i%2\n    axarr[col, curr_row].imshow(example)\n    if col == 1:\n        curr_row += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**The data distribution**"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (10, 8))\nplt.title('Landmark ID Distribuition')\nsns.distplot(my_train_data['landmark_id'])\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**The network structure**"},{"metadata":{"trusted":true},"cell_type":"code","source":"nb_valid_samples = 0.2 # The percentage of the validation data\nepochs = 10 # The maximum number of epochs\nbatch_size = 32 # The batch size\nopt = 'RMSprop' # The used optimizer  \nloss_function = 'categorical_crossentropy' # The loss function","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Network settings\n\n\ngen = ImageDataGenerator(validation_split=nb_valid_samples)\n# train_datagen = ImageDataGenerator(\n#     rescale=1./255,\n#     shear_range=0.2,\n#     zoom_range=0.2,\n#     horizontal_flip=True)\n\ntrain_gen = gen.flow_from_dataframe(\n    my_train_data,\n    directory='../input/landmark-recognition-2020/train/',\n    x_col='filename',\n    y_col='label',\n    weight_col=None,\n    target_size=(256,256),\n    color_mode='rgb',\n    classes=None,\n    class_mode='categorical',\n    batch_size=batch_size,\n    shuffle=True,\n    subset='training',\n    interpolation='nearest',\n    validate_filenames=False)\n\nval_gen = gen.flow_from_dataframe(\n    my_train_data,\n    directory='../input/landmark-recognition-2020/train/',\n    x_col='filename',\n    y_col='label',\n    weight_col=None,\n    target_size=(256,256),\n    color_mode='rgb',\n    classes=None,\n    class_mode='categorical',\n    batch_size=batch_size,\n    shuffle=True,\n    subset='validation',\n    interpolation='nearest',\n    validate_filenames=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Using a pretrained model that was trained using the known imageNet dataset "},{"metadata":{"trusted":true},"cell_type":"code","source":"model = tf.keras.Sequential([\n    efn.EfficientNetB2(\n        input_shape=(256, 256, 3),\n        weights='imagenet',\n        include_top=False\n    ),\n    GlobalAveragePooling2D(),\n    Dense(number_of_classes, activation='softmax')\n])\n\nmodel.compile(opt, loss_function, metrics=['categorical_accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_steps = int(len(my_train_data)*(1-nb_valid_samples))//batch_size\nval_steps = int(len(my_train_data)*nb_valid_samples)//batch_size\n\nmodel_checkpoint = ModelCheckpoint(\"best_model.h5\", save_best_only=True, verbose=1)\n\n\nhistory = model.fit_generator(train_gen, steps_per_epoch=train_steps, epochs=epochs,\n                              validation_data=val_gen, validation_steps=val_steps,\n                              callbacks=[EarlyStopping(patience = 3, restore_best_weights = True),model_checkpoint])\n\nmodel.save(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The performance of the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(history.history.keys())\nplt.plot(history.history['categorical_accuracy'])\nplt.plot(history.history['val_categorical_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()\n# summarize history for loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Testing the performance of the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"my_sub = pd.read_csv(\"/kaggle/input/landmark-recognition-2020/sample_submission.csv\")\nmy_sub[\"filename\"] = my_sub.id.str[0]+\"/\"+my_sub.id.str[1]+\"/\"+my_sub.id.str[2]+\"/\"+my_sub.id+\".jpg\"\nprint(my_sub)\n\n\nbest_model = load_model(\"best_model.h5\")\n\ntest_gen = ImageDataGenerator().flow_from_dataframe(\n    my_sub,\n    directory=\"/kaggle/input/landmark-recognition-2020/test/\",\n    x_col=\"filename\",\n    y_col=None,\n    weight_col=None,\n    target_size=(256, 256),\n    color_mode=\"rgb\",\n    classes=None,\n    class_mode=None,\n    batch_size=1,\n    shuffle=True,\n    subset=None,\n    interpolation=\"nearest\",\n    validate_filenames=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_sub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred_one_hot = best_model.predict_generator(test_gen, verbose=1, steps=len(my_sub))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = np.argmax(y_pred_one_hot, axis=-1)\ny_prob = np.max(y_pred_one_hot, axis=-1)\nprint(y_pred.shape, y_prob.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_uniq = np.unique(my_train_data.landmark_id.values)\n\ny_pred = [y_uniq[Y] for Y in y_pred]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_sub\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(len(my_sub)):\n    my_sub.loc[i, \"landmarks\"] = str(y_pred[i])+\" \"+str(y_prob[i])\n#my_sub = my_sub.drop(columns=\"filename\")\nmy_sub.to_csv(\"submission.csv\", index=False)\nmy_sub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}