{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\n# NCJ notebook, VGIS9 research mini project.\n# Original baseline kernel: https://www.kaggle.com/stpeteishii/landmark-recognition-conv2d\n\n# Imports for Deep Learning\n# baseline cnn model for mnist\nimport numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport random\n# import keras\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom tensorflow.keras.layers import Dense,Flatten,Dropout,Conv2D,MaxPooling2D,BatchNormalization\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.metrics import classification_report, log_loss, accuracy_score\nfrom sklearn.model_selection import train_test_split\nfrom tqdm import tqdm\nimport cv2\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n#import os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#   for filename in filenames:\n#        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\nprint('Starting up NC notebook')","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:05:59.650011Z","iopub.execute_input":"2021-11-15T07:05:59.650671Z","iopub.status.idle":"2021-11-15T07:06:01.522018Z","shell.execute_reply.started":"2021-11-15T07:05:59.650568Z","shell.execute_reply":"2021-11-15T07:06:01.521180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Loading dataset into initial variable\ntrain_dir = '../input/landmark-recognition-2021/train'\ntest_dir = '../input/landmark-recognition-2021/test'\ntrain=pd.read_csv('../input/landmark-recognition-2021/train.csv')\ntrain","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:06:02.369275Z","iopub.execute_input":"2021-11-15T07:06:02.369935Z","iopub.status.idle":"2021-11-15T07:06:03.335925Z","shell.execute_reply.started":"2021-11-15T07:06:02.369894Z","shell.execute_reply":"2021-11-15T07:06:03.335189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"1580470 images exsist in the dataset","metadata":{}},{"cell_type":"code","source":"# Getting landmark numberr\nName=[]\nfor landmark in train['landmark_id'].unique():\n    Name+=[landmark]\nprint(len(Name))\nn=len(Name)\n\n# Mapping directory\nN=list(range(n))\nnormal_mapping=dict(zip(Name,N)) \nreverse_mapping=dict(zip(N,Name)) ","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:06:06.041512Z","iopub.execute_input":"2021-11-15T07:06:06.041815Z","iopub.status.idle":"2021-11-15T07:06:06.106597Z","shell.execute_reply.started":"2021-11-15T07:06:06.041786Z","shell.execute_reply":"2021-11-15T07:06:06.105751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"81313 different classes exsist in the dataset, lanmark_id skips some numbers from 0 to 203092","metadata":{}},{"cell_type":"code","source":"trainX0=[]\ntrainY0=[]\n# Loop for making train image array and train labels.\nfor i in tqdm(range(25000)):   #Change to decide number of images\n    idt=train.loc[i,'id']+'.jpg'\n    landt=train.loc[i,'landmark_id']\n    path=os.path.join(train_dir,idt[0],idt[1],idt[2])\n    image=cv2.imread(os.path.join(path,idt))\n    image2=cv2.resize(image,dsize=(128,128),interpolation=cv2.INTER_CUBIC)  #Size is set to 128*128\n    trainX0+=[image2]\n    trainY0+=[landt] ","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:06:07.498566Z","iopub.execute_input":"2021-11-15T07:06:07.499471Z","iopub.status.idle":"2021-11-15T07:08:43.689535Z","shell.execute_reply.started":"2021-11-15T07:06:07.499427Z","shell.execute_reply":"2021-11-15T07:08:43.688781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Finding classes with less than 5, and between 5 and 10 images\nless_5_val = 0\nbetween_5_and_10_val = 0\nfor i in tqdm(range(203092)):\n    val = len(train.loc[train['landmark_id'] == i])\n    if(val < 5 and val > 0):\n        less_5_val = less_5_val+1\n    elif(val >= 5 and val <= 10):\n        between_5_and_10_val = between_5_and_10_val+1","metadata":{"_kg_hide-output":true,"_kg_hide-input":false,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(less_5_val)\nprint(between_5_and_10_val)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"17297 classes have less than five images in them, and 27348 classes has between 5 and 10 images","metadata":{}},{"cell_type":"code","source":"# Histogram of instances per class\n\nhist = plt.figure(figsize = (10, 10))\nax = plt.hist(train[\"landmark_id\"], bins = train[\"landmark_id\"].unique())\nplt.ylim([0, 100])\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plotting 4 * 4 images from different classes\ndef plot_four_im(im1,im2,im3,im4): \n\n    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)\n    fig\n    ax1.imshow(trainX0[im1])\n    fig\n    ax2.imshow(trainX0[im2])\n    fig\n    ax3.imshow(trainX0[im3])\n    fig\n    ax4.imshow(trainX0[im4])\n    \n    \ndef plot_im(indices,size_x,size_y): \n\n    fig = plt.figure(figsize=(10, 7))\n    \n    \nprint(train.loc[800:803,'landmark_id'])\nplot_four_im(800,801,802,803)\n\nprint(train.loc[0:3,'landmark_id'])\nplot_four_im(0,1,2,3)\n\nprint(train.loc[467:470,'landmark_id'])\nplot_four_im(467,468,469,470)\n\nprint(train.loc[55:58,'landmark_id'])\nplot_four_im(55,56,57,58)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now starts training of model, and testing of the model","metadata":{}},{"cell_type":"code","source":"#Image augmentation\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom numpy import expand_dims\n\ntrainX0_augmented=[]\n\n#Random Rotation\n#datagen = ImageDataGenerator(rotation_range=180)\n\n#Random Zoom augmentation\n#datagen = ImageDataGenerator(zoom_range=[0.3,1.0])\n\n#Random brightness augmentation\ndatagen = ImageDataGenerator(brightness_range=[0.3,1.0])\n\n\nfor x in tqdm(range(25000)):\n    \n    img = trainX0[x]\n    sample = expand_dims(img, 0)\n    it = datagen.flow(sample, batch_size=1)\n    batch = it.next()\n    image = batch[0].astype('uint8')\n    trainX0_augmented+=[image]\n\n    #print(trainX0_rotate)\n\nplt.imshow(trainX0_augmented[1])\ntrainX0 = trainX0_augmented\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare training data and test data, and the corresponding labels\ntrainX=np.array(trainX0)\n\ntrainX=np.array(trainX0)\ntrainY1=pd.Series(trainY0).map(normal_mapping)\ntrainY2=np.array(trainY1)\n\ntrainY3=to_categorical(trainY2)\nX_train=np.array(trainX0).reshape(-1,128,128,3)\ny_train=np.array(trainY3)\n\ntrainx,testx,trainy,testy=train_test_split(X_train,y_train,test_size=0.3,random_state=44) # Data is split into 70% training images mand 30% test images\n\nprint(trainx.shape)\nprint(testx.shape)\nprint(trainy.shape)\nprint(testy.shape)\nprint(trainy.shape[1])","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:10:01.781135Z","iopub.execute_input":"2021-11-15T07:10:01.781455Z","iopub.status.idle":"2021-11-15T07:10:03.518775Z","shell.execute_reply.started":"2021-11-15T07:10:01.781422Z","shell.execute_reply":"2021-11-15T07:10:03.517874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainY3.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Building model\nmodel = Sequential()\nmodel.add(Conv2D(32,(2,2),input_shape = (128,128,3),activation = 'relu'))\nmodel.add(Conv2D(32, (3, 3), padding=\"same\", activation=\"relu\"))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(64, (3, 3), padding=\"same\", activation=\"relu\"))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(128, (3, 3), padding=\"same\", activation=\"relu\"))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.2))\nmodel.add(Flatten())\nmodel.add(Dense(trainy.shape[1], activation='softmax'))\n\n#model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy']) \nmodel.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=1e-4),metrics=['accuracy']) \n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:10:11.242056Z","iopub.execute_input":"2021-11-15T07:10:11.242335Z","iopub.status.idle":"2021-11-15T07:10:12.425306Z","shell.execute_reply.started":"2021-11-15T07:10:11.242304Z","shell.execute_reply":"2021-11-15T07:10:12.424585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"his = model.fit(trainx, trainy, validation_split=0.2, epochs=20, batch_size=128, verbose=1) \n","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:10:21.711072Z","iopub.execute_input":"2021-11-15T07:10:21.711343Z","iopub.status.idle":"2021-11-15T07:12:45.408492Z","shell.execute_reply.started":"2021-11-15T07:10:21.711312Z","shell.execute_reply":"2021-11-15T07:12:45.407637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_acc = his.history['accuracy']\nvalue_acc = his.history['val_accuracy']\nget_loss = his.history['loss']\nvalidation_loss = his.history['val_loss']\n\nepochs = range(len(get_acc))\nplt.plot(epochs, get_acc, 'r', label='Accuracy of Training data')\nplt.plot(epochs, value_acc, 'b', label='Accuracy of Validation data')\nplt.title('Training vs validation accuracy')\nplt.legend(loc=0)\nplt.figure()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:12:48.813103Z","iopub.execute_input":"2021-11-15T07:12:48.813753Z","iopub.status.idle":"2021-11-15T07:12:49.034991Z","shell.execute_reply.started":"2021-11-15T07:12:48.813710Z","shell.execute_reply":"2021-11-15T07:12:49.034322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = range(len(get_loss))\nplt.plot(epochs, get_loss, 'r', label='Loss of Training data')\nplt.plot(epochs, validation_loss, 'b', label='Loss of Validation data')\nplt.title('Training vs validation loss')\nplt.legend(loc=0)\nplt.figure()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:12:51.350115Z","iopub.execute_input":"2021-11-15T07:12:51.351120Z","iopub.status.idle":"2021-11-15T07:12:51.562652Z","shell.execute_reply.started":"2021-11-15T07:12:51.351067Z","shell.execute_reply":"2021-11-15T07:12:51.561851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exploring classification results\n\ny_pred=model.predict(testx)  # Predict classes of each test image\npred=np.argmax(y_pred,axis=1)  # Make prediction list\nground = np.argmax(testy,axis=1) # Make ground truth label\n#print(classification_report(ground,pred))\n\n\n#imgplot = plt.imshow(testx[1])\n\n# Find images locations with the supplied label\nIndices_ground = np.where(ground==9)\nprint(Indices_ground)\n\n# Find images locations of a class, predicted by model\nIndices_pred = np.where(pred==9)\nprint(Indices_pred)\n\n# Print number of images per class for comparison\nprint(len(Indices_pred[0]))\nprint(len(Indices_ground[0]))\n\n#print(pred[0:20])\nimgplot = plt.imshow(testx[3494])\n#plot_figs(Indices_ground)\n\n\n# Show images to put into report\nprint(ground[9])\n\nplt.imshow(testx[7211])\n\n\"\"\"\n# Show images to put into report\nfig, axis = plt.subplots(2,3)\nfig\naxis[0,0].imshow(testx[424])\nfig\naxis[0,1].imshow(testx[1399])\nfig\naxis[0,2].imshow(testx[2242])\nfig\naxis[1,0].imshow(testx[2602])\nfig\naxis[1,1].imshow(testx[6408])\nfig\naxis[1,2].imshow(testx[6711])\n\n\n#print(pred[9]);\n\n\n#\n\n#print(len(Indices_pred[0]))\n#imgplot = plt.imshow(testx[56])\n#print(ground[99])\n#imgplot = plt.imshow(testx[706])\n\n#imgplot = plt.imshow(testx[1463])\n\nprint(pred[1640]); print(ground[1783])\n\n\"\"\"\n","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:27:48.684863Z","iopub.execute_input":"2021-11-15T07:27:48.685162Z","iopub.status.idle":"2021-11-15T07:27:50.284851Z","shell.execute_reply.started":"2021-11-15T07:27:48.685131Z","shell.execute_reply":"2021-11-15T07:27:50.284138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Print prediction report of each class. Overall accuracy in the bottom. Explore the results to see what sticks out\nprint(classification_report(ground,pred))\n","metadata":{"execution":{"iopub.status.busy":"2021-11-15T07:13:04.858606Z","iopub.execute_input":"2021-11-15T07:13:04.859165Z","iopub.status.idle":"2021-11-15T07:13:04.910848Z","shell.execute_reply.started":"2021-11-15T07:13:04.859128Z","shell.execute_reply":"2021-11-15T07:13:04.910026Z"},"trusted":true},"execution_count":null,"outputs":[]}]}