{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\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\nimport 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","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":0.053169,"end_time":"2021-06-24T01:59:33.773802","exception":false,"start_time":"2021-06-24T01:59:33.720633","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:05.335551Z","iopub.execute_input":"2021-08-09T18:01:05.335928Z","iopub.status.idle":"2021-08-09T18:01:05.347774Z","shell.execute_reply.started":"2021-08-09T18:01:05.335855Z","shell.execute_reply":"2021-08-09T18:01:05.346882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ntrain_csv = pd.read_csv('/kaggle/input/landmark-recognition-2020/train.csv')\ntrain_csv.head(10)","metadata":{"papermill":{"duration":1.761795,"end_time":"2021-06-24T01:59:35.57376","exception":false,"start_time":"2021-06-24T01:59:33.811965","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:10.044551Z","iopub.execute_input":"2021-08-09T18:01:10.044942Z","iopub.status.idle":"2021-08-09T18:01:11.507082Z","shell.execute_reply.started":"2021-08-09T18:01:10.044913Z","shell.execute_reply":"2021-08-09T18:01:11.506310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_csv)","metadata":{"papermill":{"duration":0.052466,"end_time":"2021-06-24T01:59:35.686078","exception":false,"start_time":"2021-06-24T01:59:35.633612","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:11.508382Z","iopub.execute_input":"2021-08-09T18:01:11.508712Z","iopub.status.idle":"2021-08-09T18:01:11.513345Z","shell.execute_reply.started":"2021-08-09T18:01:11.508679Z","shell.execute_reply":"2021-08-09T18:01:11.512584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_csv['landmark_id'].unique())","metadata":{"papermill":{"duration":0.085248,"end_time":"2021-06-24T01:59:35.809262","exception":false,"start_time":"2021-06-24T01:59:35.724014","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:13.003302Z","iopub.execute_input":"2021-08-09T18:01:13.003711Z","iopub.status.idle":"2021-08-09T18:01:13.027910Z","shell.execute_reply.started":"2021-08-09T18:01:13.003677Z","shell.execute_reply":"2021-08-09T18:01:13.026975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.image as img\nimport matplotlib.pyplot as plt\ndef show_img(file_name):\n    image = img.imread('/kaggle/input/landmark-recognition-2020/train/'+file_name[0]+'/'+file_name[1]+'/'+file_name[2]+'/'+file_name)\n    plt.imshow(image)\n    plt.show()","metadata":{"papermill":{"duration":0.05489,"end_time":"2021-06-24T01:59:35.914146","exception":false,"start_time":"2021-06-24T01:59:35.859256","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:16.046221Z","iopub.execute_input":"2021-08-09T18:01:16.046612Z","iopub.status.idle":"2021-08-09T18:01:16.051287Z","shell.execute_reply.started":"2021-08-09T18:01:16.046582Z","shell.execute_reply":"2021-08-09T18:01:16.050487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_img('0000059611c7d079.jpg')","metadata":{"papermill":{"duration":0.288948,"end_time":"2021-06-24T01:59:36.241197","exception":false,"start_time":"2021-06-24T01:59:35.952249","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:20.120110Z","iopub.execute_input":"2021-08-09T18:01:20.120464Z","iopub.status.idle":"2021-08-09T18:01:20.335555Z","shell.execute_reply.started":"2021-08-09T18:01:20.120431Z","shell.execute_reply":"2021-08-09T18:01:20.334723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain_csv = pd.read_csv('/kaggle/input/landmark-recognition-2020/train.csv')\ntrain_csv.head(10)\n\n# put .jpg into the file name\ndef add_txt(fn):\n    return fn+'.jpg'\n\ntrain_csv['id'] = train_csv['id'].apply(add_txt)\n\n","metadata":{"papermill":{"duration":0.038049,"end_time":"2021-06-24T01:59:36.318129","exception":false,"start_time":"2021-06-24T01:59:36.28008","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-08-09T18:01:21.922105Z","iopub.execute_input":"2021-08-09T18:01:21.922440Z","iopub.status.idle":"2021-08-09T18:01:23.307121Z","shell.execute_reply.started":"2021-08-09T18:01:21.922389Z","shell.execute_reply":"2021-08-09T18:01:23.306200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{"papermill":{"duration":0.042818,"end_time":"2021-06-24T02:02:41.058437","exception":false,"start_time":"2021-06-24T02:02:41.015619","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# model.save('/kaggle/working/MNet.h5')","metadata":{"execution":{"iopub.status.busy":"2021-08-09T18:01:24.869093Z","iopub.execute_input":"2021-08-09T18:01:24.869413Z","iopub.status.idle":"2021-08-09T18:01:24.873956Z","shell.execute_reply.started":"2021-08-09T18:01:24.869368Z","shell.execute_reply":"2021-08-09T18:01:24.872764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# choose those labels with more than 200 images, and choose the first 200 images of each label\n# move every training files to the same folder\n%cd /kaggle/working\nif not os.path.exists('T1'):\n    os.mkdir('T1')\nif not os.path.exists('T2'):\n    os.mkdir('T2')\nif not os.path.exists('Val'):\n    os.mkdir('Val')\nif not os.path.exists('Tes'):\n    os.mkdir('Tes')    \n\n\nimport shutil\nimport random\n\nlabel_list = train_csv['landmark_id'].unique()\ncnt = 0\nfinal_label_list = []\n\nfor label in list(label_list): # label order by random\n    file_list = list(train_csv['id'][train_csv['landmark_id']==label])\n    if len(file_list) >= 200:\n        final_label_list.append(label)\n        if not os.path.exists('/kaggle/working/T1/'+str(label)):\n            os.mkdir('/kaggle/working/T1/'+str(label))\n        if not os.path.exists('/kaggle/working/T2/'+str(label)):\n            os.mkdir('/kaggle/working/T2/'+str(label))\n        if not os.path.exists('/kaggle/working/Val/'+str(label)):\n            os.mkdir('/kaggle/working/Val/'+str(label))\n        if not os.path.exists('/kaggle/working/Tes/'+str(label)):\n            os.mkdir('/kaggle/working/Tes/'+str(label))\n        \n        for file in file_list[:80]:  # 80 files for training\n            src = '/kaggle/input/landmark-recognition-2020/train/'+file[0]+'/'+file[1]+'/'+file[2]+'/'+file\n            dst = '/kaggle/working/T1/'+str(label)+'/'+file\n            if not os.path.exists(dst):\n                shutil.copyfile(src, dst)\n        for file in file_list[:160]: # 160 files for testing\n            src = '/kaggle/input/landmark-recognition-2020/train/'+file[0]+'/'+file[1]+'/'+file[2]+'/'+file\n            dst = '/kaggle/working/T2/'+str(label)+'/'+file\n            if not os.path.exists(dst):\n                shutil.copyfile(src, dst)\n        for file in file_list[160:180]: # 20 files for validation\n            src = '/kaggle/input/landmark-recognition-2020/train/'+file[0]+'/'+file[1]+'/'+file[2]+'/'+file\n            dst = '/kaggle/working/Val/'+str(label)+'/'+file\n            if not os.path.exists(dst):\n                shutil.copyfile(src, dst)\n        for file in file_list[180:200]: # 20 files for testing\n            src = '/kaggle/input/landmark-recognition-2020/train/'+file[0]+'/'+file[1]+'/'+file[2]+'/'+file\n            dst = '/kaggle/working/Tes/'+str(label)+'/'+file\n            if not os.path.exists(dst):\n                shutil.copyfile(src, dst)\n        \n        cnt += 1\n    if cnt == 100: # only need 100 labels\n        break\n# 20,000 files in total","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2021-08-09T18:01:26.957999Z","iopub.execute_input":"2021-08-09T18:01:26.958395Z","iopub.status.idle":"2021-08-09T18:04:35.237771Z","shell.execute_reply.started":"2021-08-09T18:01:26.958346Z","shell.execute_reply":"2021-08-09T18:04:35.236913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\nT1_train_dir = '/kaggle/working/T1'\nT2_train_dir = '/kaggle/working/T2'\nvalidation_dir = '/kaggle/working/Val'\ntest_dir = '/kaggle/working/Tes'\n\nT1_train_generator = train_datagen.flow_from_directory(\n    T1_train_dir,\n    target_size=(256, 256),\n    batch_size = 32,\n    class_mode='categorical',\n    seed=42)\n\nT2_train_generator = train_datagen.flow_from_directory(\n    T2_train_dir,\n    target_size=(256, 256),\n    batch_size = 32,\n    class_mode='categorical',\n    seed=42)\n\nvalidation_generator = test_datagen.flow_from_directory(\n    validation_dir,\n    target_size=(256, 256),\n    batch_size = 32,\n    class_mode='categorical',\n    seed=42)\n\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(256, 256),\n    batch_size = 1,\n    class_mode='categorical',\n    seed=42)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T18:04:42.147775Z","iopub.execute_input":"2021-08-09T18:04:42.148104Z","iopub.status.idle":"2021-08-09T18:04:48.060948Z","shell.execute_reply.started":"2021-08-09T18:04:42.148075Z","shell.execute_reply":"2021-08-09T18:04:48.060176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications import EfficientNetB3  \n\nconv_base = EfficientNetB3(include_top=False,\n                        weights=\"imagenet\",\n                        input_shape=(256, 256, 3)\n)\n\nconv_base.trainable = True\n\n# conv_base.summary()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T18:04:48.062296Z","iopub.execute_input":"2021-08-09T18:04:48.062601Z","iopub.status.idle":"2021-08-09T18:04:53.332804Z","shell.execute_reply.started":"2021-08-09T18:04:48.062572Z","shell.execute_reply":"2021-08-09T18:04:53.331858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.layers import Dense, Dropout, MaxPooling2D, GlobalAveragePooling2D, Flatten, Conv2D, Input\nfrom keras.models import Sequential\nfrom keras import optimizers\nimport tensorflow as tf\n\nmodel = Sequential()\nmodel.add(conv_base)\nmodel.add(GlobalAveragePooling2D())\nmodel.add(Dense(100, activation='softmax'))\nmodel.compile(optimizer=optimizers.RMSprop(lr=2e-5),\n              loss = 'categorical_crossentropy',\n              metrics=['accuracy'])\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-08-09T18:05:33.628312Z","iopub.execute_input":"2021-08-09T18:05:33.628707Z","iopub.status.idle":"2021-08-09T18:05:34.600160Z","shell.execute_reply.started":"2021-08-09T18:05:33.628676Z","shell.execute_reply":"2021-08-09T18:05:34.599129Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    T1_train_generator,\n    epochs=20, \n    validation_data=validation_generator,\n    verbose=1\n)","metadata":{"execution":{"iopub.status.busy":"2021-08-09T18:05:46.636031Z","iopub.execute_input":"2021-08-09T18:05:46.636343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('/kaggle/working/MNet.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc)+1)\n\nplt.plot(epochs, acc, '#21466C', label='Training acc')\nplt.plot(epochs, val_acc, '#ff0051', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, '#21466C', label='Training loss')\nplt.plot(epochs, val_loss, '#ff0051', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scores = model.evaluate(test_generator)\nprint('loss:', scores[0])\nprint('accuracy:', scores[1])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Sequential, load_model\nmodel=load_model('/kaggle/working/MNet.h5')\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    if layer.name != \"dense\":\n        layer.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_2 = model.fit(\n    T2_train_generator,\n    epochs=20, \n    validation_data=validation_generator,\n    verbose=1\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('/kaggle/working/MNet_2.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history_2.history['accuracy']\nval_acc = history_2.history['val_accuracy']\nloss = history_2.history['loss']\nval_loss = history_2.history['val_loss']\n\nepochs = range(1, len(acc)+1)\n\nplt.plot(epochs, acc, '#21466C', label='Training acc')\nplt.plot(epochs, val_acc, '#ff0051', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, '#21466C', label='Training loss')\nplt.plot(epochs, val_loss, '#ff0051', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ****","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}