{"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":"# Loading data\n\nfrom __future__ import print_function\nfrom __future__ import division\nimport os\nimport pandas as pd\nimport matplotlib as mpl\nimport numpy as np\nimport cv2\nfrom PIL import *\nfrom numpy import interp\n\nimport random\n\n\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nimport tensorflow as tf\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.python.keras.preprocessing.image import ImageDataGenerator\n\npath = '/kaggle/input/landmark-recognition-2021'\nos.listdir(path)\ntrain_images = f'{path}/train'\ntrain_df = pd.read_csv(f'{path}/train.csv')\ntrain_df['path'] = train_df['id'].apply(lambda f: os.path.join('../input/landmark-recognition-2021/train',f[0], f[1], f[2], f + '.jpg'))\ntest_images = f'{path}/test'\ntest_df = pd.read_csv(f'{path}/sample_submission.csv')\ntest_df['path'] = test_df['id'].apply(lambda f: os.path.join('../input/landmark-recognition-2021/test',f[0], f[1], f[2], f + '.jpg'))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-10-13T16:16:21.678523Z","iopub.execute_input":"2021-10-13T16:16:21.679069Z","iopub.status.idle":"2021-10-13T16:16:34.226624Z","shell.execute_reply.started":"2021-10-13T16:16:21.678959Z","shell.execute_reply":"2021-10-13T16:16:34.225829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### Exploring the dataset\n\nnum_classes = train_df['landmark_id'].nunique()\nprint('Number of classes:', num_classes)\nprint('Number of images in training set:', len(train_df))\n\nprint('Distribution of images in classes:')\ncounts = train_df['landmark_id'].value_counts()\nprint(counts.describe()) \n\n# Show a histogram of the number of instances per class\n# takes a while to compute\n#hist = plt.figure(figsi)\n#ax = train_df.plot.hist(bins=num_classes, alpha=1)\n#plt.ylim([0,800])\n#plt.show()\n\n# How many classes have less than 5 training samples? And between 5 and 10 training samples?\nlistoflists = train_df.groupby('landmark_id').apply(lambda g: g.index.tolist())\nlessthan5 = []\nbetween510 = []\nfor listi in listoflists:\n    if len(listi)<5:\n        lessthan5.append(listi)\n    if len(listi)>4 and len(listi)<11:\n        between510.append(listi)\n        \nprint (len(lessthan5), \"classes have less than 5 training samples\")\nprint (len(between510), \"classes have between 5 and 10 training samples\")\n\n#Show 4 sample images from 4 random classes (16 images in total)\nsamplelist = []\nfor i in range(0,4):\n    #select a random class\n    randclass = train_df[train_df['landmark_id'] == counts.iloc[[np.random.randint(0,num_classes)]].index[0]]\n    for j in range (0,4):\n        # select random images from class\n        randimg = randclass.iloc[np.random.randint(0,len(randclass))]\n        samplelist.append(randimg)\n\nplt.subplots(4, 4, figsize=(15, 15))\nfor i in range(len(samplelist)):\n    plt.subplot(4, 4, i + 1)\n    plt.axis('Off')\n    image = cv2.imread(samplelist[i][2])\n    plt.imshow(image)\n    plt.title(f'landmark id:{samplelist[i][1]} ', fontsize=10)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T16:16:34.228617Z","iopub.execute_input":"2021-10-13T16:16:34.228939Z","iopub.status.idle":"2021-10-13T16:16:37.66626Z","shell.execute_reply.started":"2021-10-13T16:16:34.228888Z","shell.execute_reply":"2021-10-13T16:16:37.665489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3.1.D Describe if/how you think the data distribution will affect training of a classifier:\nI think the the data distribution could make it very difficult to train a good classifier. The fact that a few classes contain so many images compared to others might make the model cheat by predicting only the class with many images, and the results will then appear good with high accuracy and loww loss from training until the prediction phase, where it will predict the same label for all testing images.","metadata":{}},{"cell_type":"code","source":"# Training a model\n\ndef PathToimages(pathlist):\n    images=[]\n    for imagefile in pathlist:\n        img_pix = cv2.imread(imagefile,1)\n        images.append(cv2.resize(img_pix, (image_size,image_size)))\n    \n    \n    return images\n\n# Parameters\n\nepochs = 30\nbatch_size = 16\nlearning_rate= 0.001\nimage_size = 128\ntrain_split = 0.7 # in percent\nval_split = 0.2 # in percent\nnum_of_classes = 50 # number of images determined based the number found in the classes\n\n\n\nimagelist = []\nactuallabels = []\ntemp_labels = []\n\n#get classes with similar amount of images\ni=0\nfor label in train_df['landmark_id'].unique():\n    if i ==num_of_classes:\n        break\n    if(len(train_df['path'][train_df['landmark_id'] == label].value_counts())>50 and len(train_df['path'][train_df['landmark_id'] == label].value_counts())<150):\n        for path in train_df['path'][train_df['landmark_id'] == label]:\n            imagelist.append(path)\n            actuallabels.append(label)\n            temp_labels.append(i)\n        i = i+1\n\n\n\nshuf = list(zip(imagelist,temp_labels))\nrandom.shuffle(shuf)\n\nimagelist, labels = zip(*shuf)\n\n\nimagenum = round(len(imagelist)*train_split)\n\ntrainimagelist = imagelist[:imagenum]\nprint(\"resizing \", len(trainimagelist), \"images\")\ntrain_data = PathToimages(trainimagelist)\ntrainlabels = labels[:imagenum]\n\n\n\n\n\n\nprint('Images: ', len(train_data))\nprint('Image labels: ', len(trainlabels))\n\nX_data = np.array(train_data) / 255\nY_data =  to_categorical(trainlabels, num_classes = num_of_classes) \n\nX_train, X_val, Y_train, Y_val = train_test_split(X_data, Y_data, test_size = val_split, random_state=101)\n\n\n\ndatagen = ImageDataGenerator(horizontal_flip=False,\n                             vertical_flip=False,\n                             rotation_range=0.0,\n                             zoom_range=0.2,\n                             width_shift_range=0.0,\n                             height_shift_range=0.0,\n                             shear_range=0.0,\n                             fill_mode=\"nearest\")\n\n\n\npretrained_model = tf.keras.applications.DenseNet201(input_shape=(image_size,image_size,3),\n                                                      include_top=False,\n                                                      weights='imagenet',\n                                                      pooling='avg')\n\n\ninputs = pretrained_model.input\n\ndrop_layer = tf.keras.layers.Dropout(0.25)(pretrained_model.output)\nx_layer = tf.keras.layers.Dense(512, activation='relu')(drop_layer)\nx_layer1 = tf.keras.layers.Dense(128, activation='relu')(x_layer)\ndrop_layer1 = tf.keras.layers.Dropout(0.20)(x_layer1)\n\nx_layer2 = tf.keras.layers.Dense(512, activation='relu')(drop_layer1)\nx_layer3 = tf.keras.layers.Dense(128, activation='relu')(x_layer2)\ndrop_layer5 = tf.keras.layers.Dropout(0.20)(x_layer3)\n\nx_layer4 = tf.keras.layers.Dense(512, activation='relu')(drop_layer5)\nx_layer5 = tf.keras.layers.Dense(128, activation='relu')(x_layer4)\ndrop_layer6 = tf.keras.layers.Dropout(0.20)(x_layer5)\n\n\noutput = tf.keras.layers.Dense(num_of_classes, activation='softmax')(drop_layer6)\n\nmodel = tf.keras.Model(inputs=inputs, outputs=output)\n\nmodel.compile(optimizer = tf.optimizers.Adam(lr=learning_rate),\n              loss=\"categorical_crossentropy\",\n              metrics=['acc'])\n\n#model.summary()\n\nhistory = model.fit(datagen.flow(X_train,Y_train,batch_size=batch_size),validation_data=(X_val,Y_val),epochs=epochs)\n","metadata":{"execution":{"iopub.status.busy":"2021-10-13T16:16:37.667266Z","iopub.execute_input":"2021-10-13T16:16:37.667492Z","iopub.status.idle":"2021-10-13T16:27:43.230224Z","shell.execute_reply.started":"2021-10-13T16:16:37.667464Z","shell.execute_reply":"2021-10-13T16:27:43.229275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot results\n\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'r', label='Training accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation accuracy')\nplt.title('Training and validation accuracy')\nplt.legend(loc=0)\nplt.figure()\nplt.savefig('/kaggle/working/accuracy.png')\n\nplt.show()\n\n\n\nplt.plot(epochs, loss, 'r', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend(loc=0)\nplt.figure()\nplt.savefig('/kaggle/working/loss.png')\n\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2021-10-13T16:27:43.232588Z","iopub.execute_input":"2021-10-13T16:27:43.232946Z","iopub.status.idle":"2021-10-13T16:27:43.704783Z","shell.execute_reply.started":"2021-10-13T16:27:43.232899Z","shell.execute_reply":"2021-10-13T16:27:43.704044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## predict\n\nfrom sklearn.metrics import precision_recall_fscore_support as score\nfrom sklearn import metrics\n\n\n\ntestimagelist = imagelist[len(trainimagelist):]\ntestimagelist = PathToimages(testimagelist)\ntestlabels = labels [len(trainlabels):]\n\ntest_data = np.array(testimagelist) / 255\npredictedlabels = model.predict(datagen.flow(test_data,batch_size=batch_size))\n\nhighestacc =[]\nhowconfident = []\nfor i in predictedlabels:\n    #highest = max(i)\n    howconfident.append(max(i))\n    highestacc.append(np.argmax(i))\n\n#print(highestacc)\n#label_ranking_average_precision_score((testlabels, 200), (highestacc,200))\nprecision, recall, fscore, support = score(testlabels, highestacc, labels=np.unique(highestacc))\n#print('precision: {}'.format(precision))\n#print('recall: {}'.format(recall))\n#print('fscore: {}'.format(fscore))\n#print('support: {}'.format(support))\n\n\nprint(metrics.confusion_matrix(testlabels, highestacc))\nprint(metrics.classification_report(testlabels, highestacc, digits=3))\n#print(results)\n\n\n\n\n\n#plt.subplots(4, 4, figsize=(15, 15))\nfor i in range(len(highestacc)):\n#    plt.subplot(4, 4, i + 1)\n#    plt.axis('Off')\n    #image =  cv2.imread(testimagelist[i],1)\n    plt.axis('Off')\n    #print (\"number:\", str(i), 'true label:' , str(testlabels[i]), 'predicted label:',  str(highestacc[i]),'confidence:' , str(howconfident[i]))\n    if (testlabels[i] == highestacc[i]):\n        print(\"success\")\n        title = ( 'true label: '  + str(testlabels[i]) + ' predicted label: '+  str(highestacc[i]) + ' confidence: ' + str(howconfident[i]))\n        plt.title(title, fontsize=10)\n        plt.imshow(testimagelist[i])\n        plt.show()\n        \n    elif(howconfident[i]>0.9):\n        title = ( 'true label: '  + str(testlabels[i]) + ' predicted label: '+  str(highestacc[i]) + ' confidence: ' + str(howconfident[i]))\n        plt.title(title, fontsize=10)\n        plt.imshow(testimagelist[i])\n        plt.show()\n        #print (\"number:\", str(i), 'true label:' , str(testlabels[i]), 'predicted label:',  str(highestacc[i]),'confidence:' , str(howconfident[i]))\n    \n    \n    #plt.imshow(image)\n#    title =  \"{'predicted label:' '%s','true label:' '%s'}\" % ( str(np.argmax(predictedlabels[i])) , str(testlabels[i]))\n#    plt.title( title, fontsize=10)\n    \n\n\n#loaded_model = pickle.load(open(filename, 'rb'))","metadata":{"execution":{"iopub.status.busy":"2021-10-13T16:27:43.707131Z","iopub.execute_input":"2021-10-13T16:27:43.707381Z","iopub.status.idle":"2021-10-13T16:28:21.768507Z","shell.execute_reply.started":"2021-10-13T16:27:43.707348Z","shell.execute_reply":"2021-10-13T16:28:21.767514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#dot_img_file = './model_1.png'\n#tf.keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T16:28:21.770167Z","iopub.execute_input":"2021-10-13T16:28:21.770475Z","iopub.status.idle":"2021-10-13T16:28:21.774526Z","shell.execute_reply.started":"2021-10-13T16:28:21.770438Z","shell.execute_reply":"2021-10-13T16:28:21.773434Z"},"trusted":true},"execution_count":null,"outputs":[]}]}