{"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)\nimport matplotlib.pyplot as plt\nimport plotly.graph_objs as go\nimport plotly.express as px\nimport math\nfrom plotly.subplots import make_subplots\nfrom PIL import Image, ImageDraw\nfrom sklearn.model_selection import train_test_split\nimport keras\nimport tensorflow as tf\nfrom keras.models import Sequential, Model,load_model\nfrom keras.applications import VGG19, VGG16, ResNet50\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D,BatchNormalization\nfrom keras.optimizers import RMSprop,Adam\nfrom keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D\nimport cv2\nfrom keras.initializers import glorot_uniform\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n\n\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/landmark-recognition-2021/train'):\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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-01T14:21:12.268667Z","iopub.execute_input":"2021-09-01T14:21:12.269006Z","iopub.status.idle":"2021-09-01T14:21:12.276571Z","shell.execute_reply.started":"2021-09-01T14:21:12.268972Z","shell.execute_reply":"2021-09-01T14:21:12.275595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#os.listdir('../input/landmark-recognition-2021/')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:12.360837Z","iopub.execute_input":"2021-09-01T14:21:12.361220Z","iopub.status.idle":"2021-09-01T14:21:12.365645Z","shell.execute_reply.started":"2021-09-01T14:21:12.361187Z","shell.execute_reply":"2021-09-01T14:21:12.364671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_dir = '../input/landmark-recognition-2021/train'\ntest_image_dir = '../input/landmark-recognition-2021/test'\ntrain = pd.read_csv(\"../input/landmark-recognition-2021/train.csv\")\nsample_submission = pd.read_csv('../input/landmark-recognition-2021/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:12.423463Z","iopub.execute_input":"2021-09-01T14:21:12.423807Z","iopub.status.idle":"2021-09-01T14:21:13.512551Z","shell.execute_reply.started":"2021-09-01T14:21:12.423750Z","shell.execute_reply":"2021-09-01T14:21:13.511619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.DataFrame()\ntest['id'] = sample_submission['id']","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.514116Z","iopub.execute_input":"2021-09-01T14:21:13.514503Z","iopub.status.idle":"2021-09-01T14:21:13.523732Z","shell.execute_reply.started":"2021-09-01T14:21:13.514464Z","shell.execute_reply":"2021-09-01T14:21:13.522673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.526110Z","iopub.execute_input":"2021-09-01T14:21:13.526465Z","iopub.status.idle":"2021-09-01T14:21:13.542070Z","shell.execute_reply.started":"2021-09-01T14:21:13.526430Z","shell.execute_reply":"2021-09-01T14:21:13.540994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.543847Z","iopub.execute_input":"2021-09-01T14:21:13.544221Z","iopub.status.idle":"2021-09-01T14:21:13.570350Z","shell.execute_reply.started":"2021-09-01T14:21:13.544185Z","shell.execute_reply":"2021-09-01T14:21:13.569421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.571893Z","iopub.execute_input":"2021-09-01T14:21:13.572316Z","iopub.status.idle":"2021-09-01T14:21:13.732786Z","shell.execute_reply.started":"2021-09-01T14:21:13.572280Z","shell.execute_reply":"2021-09-01T14:21:13.731679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['landmark_id'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.734370Z","iopub.execute_input":"2021-09-01T14:21:13.735000Z","iopub.status.idle":"2021-09-01T14:21:13.771031Z","shell.execute_reply.started":"2021-09-01T14:21:13.734951Z","shell.execute_reply":"2021-09-01T14:21:13.770069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['id_counts'] = train['landmark_id'].value_counts()[train['landmark_id'].values].values\nid_map = train.sort_values(by='id_counts',ascending=False).landmark_id.drop_duplicates().reset_index(drop=True)\n#id_map\nid_dict = {id_map[x]:x for x in range(len(id_map))}\n#id_dict\ntrain['encoded_id'] = train['landmark_id'].apply(lambda x: id_dict[x])\ntrain = train.sort_values(by = 'encoded_id', ascending=True)\ntrain","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:13.772650Z","iopub.execute_input":"2021-09-01T14:21:13.773021Z","iopub.status.idle":"2021-09-01T14:21:16.062658Z","shell.execute_reply.started":"2021-09-01T14:21:13.772984Z","shell.execute_reply":"2021-09-01T14:21:16.061552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"drop_df = train[train['id_counts']<5]\ndrop_df.shape","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.065769Z","iopub.execute_input":"2021-09-01T14:21:16.066150Z","iopub.status.idle":"2021-09-01T14:21:16.081308Z","shell.execute_reply.started":"2021-09-01T14:21:16.066113Z","shell.execute_reply":"2021-09-01T14:21:16.080320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.083421Z","iopub.execute_input":"2021-09-01T14:21:16.083778Z","iopub.status.idle":"2021-09-01T14:21:16.098424Z","shell.execute_reply.started":"2021-09-01T14:21:16.083743Z","shell.execute_reply":"2021-09-01T14:21:16.097505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nlandmark = train[\"landmark_id\"].value_counts()\nlandmark = pd.DataFrame({\"id\":landmark.index,\"frequency\":landmark.values})\nlandmark['landmark_id'] = landmark['id'].apply(lambda x: \"id_\"+str(x))\nlandmark\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.099795Z","iopub.execute_input":"2021-09-01T14:21:16.100166Z","iopub.status.idle":"2021-09-01T14:21:16.105849Z","shell.execute_reply.started":"2021-09-01T14:21:16.100132Z","shell.execute_reply":"2021-09-01T14:21:16.104850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nfig = px.bar(landmark.head(30),x=\"frequency\",y=\"landmark_id\",color=\"landmark_id\",height=1000,title=\"Number of images per landmark_id (Top 30 landmark_ids)\")\nfig.show()\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.107379Z","iopub.execute_input":"2021-09-01T14:21:16.108121Z","iopub.status.idle":"2021-09-01T14:21:16.117024Z","shell.execute_reply.started":"2021-09-01T14:21:16.108086Z","shell.execute_reply":"2021-09-01T14:21:16.115925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nfig = make_subplots(rows=1, cols=2)\ntrace1 = go.Histogram(x=landmark[\"frequency\"],xaxis=\"x1\",yaxis=\"y1\")\ntrace2 = go.Box(y=landmark['frequency'],xaxis=\"x2\",yaxis=\"y2\")\nlayout = go.Layout(\n    yaxis1=dict(\n        range=[0,100],\n        anchor=\"y1\"\n    ),\n    yaxis2=dict(\n        range=[0,100],\n        anchor=\"y2\"\n    )\n)\n\nfig.add_trace(trace1, row=1,col=1)\nfig.add_trace(trace2, row=1,col=2)\n#fig = px.histogram(landmark, x=\"frequency\",range_y=[0,100])\n#fig.update_layout(height=600, width=800, title_text=\"Side By Side Subplots\")\nfig.update_layout(layout)\nfig.show()\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.119407Z","iopub.execute_input":"2021-09-01T14:21:16.119971Z","iopub.status.idle":"2021-09-01T14:21:16.127275Z","shell.execute_reply.started":"2021-09-01T14:21:16.119922Z","shell.execute_reply":"2021-09-01T14:21:16.126279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#landmark['frequency'].describe()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.129167Z","iopub.execute_input":"2021-09-01T14:21:16.129566Z","iopub.status.idle":"2021-09-01T14:21:16.134757Z","shell.execute_reply.started":"2021-09-01T14:21:16.129531Z","shell.execute_reply":"2021-09-01T14:21:16.133752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#landmark[landmark['frequency']>100].shape[0]","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.136398Z","iopub.execute_input":"2021-09-01T14:21:16.137184Z","iopub.status.idle":"2021-09-01T14:21:16.142769Z","shell.execute_reply.started":"2021-09-01T14:21:16.137089Z","shell.execute_reply":"2021-09-01T14:21:16.141622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_image(names,title=None):\n    fig, axs = plt.subplots(4,4,figsize=(24,28))\n    if title:\n        fig.suptitle(title, fontsize = 30)\n    for i, image_name in enumerate(names):\n        image_path = os.path.join(train_image_dir,f\"{image_name[0]}/{image_name[1]}/{image_name[2]}/{image_name}.jpg\")\n        image = Image.open(image_path)\n        \n        axs[i//4, i%4].imshow(image) \n        image.close()       \n        axs[i//4, i%4].axis('off')\n        \n        id = train[train.id==image_name].landmark_id.values[0]\n        axs[i//4, i%4].set_title(f\"ID: {image_name}\\nLandmark_id: {id}\", fontsize=\"12\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.144663Z","iopub.execute_input":"2021-09-01T14:21:16.145511Z","iopub.status.idle":"2021-09-01T14:21:16.155867Z","shell.execute_reply.started":"2021-09-01T14:21:16.145413Z","shell.execute_reply":"2021-09-01T14:21:16.154845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#samples = train.sample(16).id.values\n#show_image(samples,'random')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.157439Z","iopub.execute_input":"2021-09-01T14:21:16.158319Z","iopub.status.idle":"2021-09-01T14:21:16.168589Z","shell.execute_reply.started":"2021-09-01T14:21:16.158276Z","shell.execute_reply":"2021-09-01T14:21:16.167514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#top1 = train[train.landmark_id==138982].sample(16).id.values\n#show_image(top1,'138982')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.170157Z","iopub.execute_input":"2021-09-01T14:21:16.170913Z","iopub.status.idle":"2021-09-01T14:21:16.177465Z","shell.execute_reply.started":"2021-09-01T14:21:16.170788Z","shell.execute_reply":"2021-09-01T14:21:16.176380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#top2 = train[train.landmark_id==126637].sample(16).id.values\n#show_image(top2,'126637')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.179042Z","iopub.execute_input":"2021-09-01T14:21:16.179741Z","iopub.status.idle":"2021-09-01T14:21:16.187178Z","shell.execute_reply.started":"2021-09-01T14:21:16.179704Z","shell.execute_reply":"2021-09-01T14:21:16.186294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#top3 = train[train.landmark_id==20409].sample(16).id.values\n#show_image(top3,'20409')","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.188777Z","iopub.execute_input":"2021-09-01T14:21:16.189553Z","iopub.status.idle":"2021-09-01T14:21:16.195506Z","shell.execute_reply.started":"2021-09-01T14:21:16.189516Z","shell.execute_reply":"2021-09-01T14:21:16.194524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['path'] = train['id'].apply(lambda x: os.path.join(train_image_dir,f\"{x[0]}/{x[1]}/{x[2]}/{x}.jpg\"))","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:16.197315Z","iopub.execute_input":"2021-09-01T14:21:16.198142Z","iopub.status.idle":"2021-09-01T14:21:19.778701Z","shell.execute_reply.started":"2021-09-01T14:21:16.198104Z","shell.execute_reply":"2021-09-01T14:21:19.777887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['path'] =  test['id'].apply(lambda x: os.path.join(test_image_dir,f\"{x[0]}/{x[1]}/{x[2]}/{x}.jpg\"))","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:19.780207Z","iopub.execute_input":"2021-09-01T14:21:19.780556Z","iopub.status.idle":"2021-09-01T14:21:19.814448Z","shell.execute_reply.started":"2021-09-01T14:21:19.780516Z","shell.execute_reply":"2021-09-01T14:21:19.813734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:19.815689Z","iopub.execute_input":"2021-09-01T14:21:19.816043Z","iopub.status.idle":"2021-09-01T14:21:19.829325Z","shell.execute_reply.started":"2021-09-01T14:21:19.816007Z","shell.execute_reply":"2021-09-01T14:21:19.828344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:19.834508Z","iopub.execute_input":"2021-09-01T14:21:19.835093Z","iopub.status.idle":"2021-09-01T14:21:19.855796Z","shell.execute_reply.started":"2021-09-01T14:21:19.835055Z","shell.execute_reply":"2021-09-01T14:21:19.855035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = len(list(train.index))-1","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:19.857460Z","iopub.execute_input":"2021-09-01T14:21:19.857948Z","iopub.status.idle":"2021-09-01T14:21:20.080253Z","shell.execute_reply.started":"2021-09-01T14:21:19.857908Z","shell.execute_reply":"2021-09-01T14:21:20.079115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.081657Z","iopub.execute_input":"2021-09-01T14:21:20.082142Z","iopub.status.idle":"2021-09-01T14:21:20.092909Z","shell.execute_reply.started":"2021-09-01T14:21:20.082097Z","shell.execute_reply":"2021-09-01T14:21:20.091614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DataGenerator(keras.utils.Sequence):\n    def __init__(self, path, list_IDs, data, img_size, img_channel, batch_size, augmentation=True):\n        self.path = path\n        self.list_IDs = list_IDs\n        self.data = data\n        #self.labels = labels\n        self.img_size = img_size\n        self.img_channel = img_channel\n        self.batch_size = batch_size\n        self.indexes = np.arange(len(self.list_IDs))\n        self.augmentation = augmentation\n    \n    def __len__(self):\n        len_ = int(math.ceil(len(self.list_IDs)/batch_size))\n        if len_*self.batch_size < len(self.list_IDs):\n            len_ += 1\n        return len_\n    \n    def __getitem__(self, index):\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        list_IDs_temp = [self.list_IDs[k] for k in indexes]\n        X, y = self.__data_generation(list_IDs_temp)\n        return X, y\n    \n    def __data_generation(self, list_IDs_temp):\n        batch_size_ = len(list_IDs_temp)\n        if self.augmentation:\n            batch_size_ = batch_size_ * 2\n        X = np.zeros((batch_size_, self.img_size, self.img_size, self.img_channel))\n        y = np.zeros((batch_size_,1))\n        \n        for i, ID in enumerate(list_IDs_temp):\n            img_id = self.data.loc[ID,'id']\n            img_path = self.data.loc[ID,'path']\n            img = np.float32(cv2.resize(cv2.imread(img_path),(self.img_size,self.img_size))/255)\n            #plt.imshow(img)\n                        \n            if self.augmentation:\n                img1 = self.__image_augmentation(img)\n                \n                X[i*2, ] = img\n                X[i*2+1, ] = img1\n                #X[i*3+2, ] = img2\n                #X[i*3+3, ] = img4\n                y[i*2, ] = self.data.loc[ID, 'encoded_id']\n                y[i*2+1, ] = self.data.loc[ID, 'encoded_id']\n                #y[i*3+2, ] = self.data.loc[ID, 'encoded_id']\n                #y[i*3+3, ] = self.data.loc[ID, 'encoded_id']\n                \n            else:\n                X[i,] = img\n                if self.path.find('train')>0:\n                    y[i,] = self.data.loc[ID, 'encoded_id']\n                else:\n                    y[i,] = 0\n            \n        return X, y\n    \n    def on_epoch_end(self):\n        np.random.shuffle(self.indexes)\n        #self.list_IDs = list(train_size - np.array(self.list_IDs))\n        \n        \n    def __image_augmentation(self, image):\n        \n        #aug_img1 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        #aug_img1 = cv2.cvtColor(aug_img1, cv2.COLOR_BGR2RGB)\n        \n        #M2 = cv2.getRotationMatrix2D(((self.img_size-1)/2.0,(self.img_size-1)/2.0),90,1)\n        #aug_img2 = cv2.warpAffine(image,M2,(self.img_size,self.img_size))\n        \n        #M3 = cv2.getRotationMatrix2D(((self.img_size-1)/2.0,(self.img_size-1)/2.0),315,1)\n        #aug_img3 = cv2.warpAffine(image,M3,(self.img_size,self.img_size))\n        \n        srcTri = np.array( [[0, 0], [image.shape[1] - 1, 0], [0, image.shape[0] - 1]] ).astype(np.float32)\n        dstTri = np.array( [[0, image.shape[1]*0.33], [image.shape[1]*0.85, image.shape[0]*0.25], [image.shape[1]*0.15, image.shape[0]*0.7]] ).astype(np.float32)\n        M4 = cv2.getAffineTransform(srcTri,dstTri)\n        aug_img4 = cv2.warpAffine(image,M4,(self.img_size,self.img_size))\n        \n        return aug_img4\n        \n    ","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.094753Z","iopub.execute_input":"2021-09-01T14:21:20.095214Z","iopub.status.idle":"2021-09-01T14:21:20.118597Z","shell.execute_reply.started":"2021-09-01T14:21:20.095178Z","shell.execute_reply":"2021-09-01T14:21:20.117634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IDs_train = list(train.index)[::4]","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.119974Z","iopub.execute_input":"2021-09-01T14:21:20.120335Z","iopub.status.idle":"2021-09-01T14:21:20.356928Z","shell.execute_reply.started":"2021-09-01T14:21:20.120299Z","shell.execute_reply":"2021-09-01T14:21:20.355912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#IDs_train,IDs_val = train_test_split(list(train.index)[:50000],test_size=0.3,random_state=0)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.358517Z","iopub.execute_input":"2021-09-01T14:21:20.358939Z","iopub.status.idle":"2021-09-01T14:21:20.366755Z","shell.execute_reply.started":"2021-09-01T14:21:20.358886Z","shell.execute_reply":"2021-09-01T14:21:20.365679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#len(IDs_train), len(IDs_val)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.368651Z","iopub.execute_input":"2021-09-01T14:21:20.369146Z","iopub.status.idle":"2021-09-01T14:21:20.375438Z","shell.execute_reply.started":"2021-09-01T14:21:20.369049Z","shell.execute_reply":"2021-09-01T14:21:20.374431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_size=32\nimg_channel=3\nbatch_size=256\nepochs = 15\nnum_classes = len(train['landmark_id'].value_counts())\n\ntrain_generator = DataGenerator(train_image_dir, IDs_train, train, img_size, img_channel, batch_size,augmentation=False)\n#val_generator = DataGenerator(train_image_dir, IDs_val, train, img_size, img_channel, batch_size,augmentation=False)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.377326Z","iopub.execute_input":"2021-09-01T14:21:20.377757Z","iopub.status.idle":"2021-09-01T14:21:20.416533Z","shell.execute_reply.started":"2021-09-01T14:21:20.377718Z","shell.execute_reply":"2021-09-01T14:21:20.415848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nconv_base = EfficientNetB0(include_top=False,weights=None,\n                     input_shape=(img_size, img_size, img_channel))\nconv_base.trainable = True\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.417709Z","iopub.execute_input":"2021-09-01T14:21:20.418060Z","iopub.status.idle":"2021-09-01T14:21:20.423770Z","shell.execute_reply.started":"2021-09-01T14:21:20.418024Z","shell.execute_reply":"2021-09-01T14:21:20.422883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nmodel = Sequential()\nmodel.add(conv_base)\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.3))\nmodel.add(Dense(num_classes, activation='softmax'))\n\nmodel.compile(optimizer = Adam(lr=1e-4),\n              loss=\"sparse_categorical_crossentropy\",\n              metrics=['sparse_categorical_accuracy'])\n\nmodel.summary()\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.425471Z","iopub.execute_input":"2021-09-01T14:21:20.426335Z","iopub.status.idle":"2021-09-01T14:21:20.434249Z","shell.execute_reply.started":"2021-09-01T14:21:20.426298Z","shell.execute_reply":"2021-09-01T14:21:20.433292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def identity_block(X, f, filters, stage, block):\n    \"\"\" \n    Arguments:\n    X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)\n    f -- integer, specifying the shape of the middle CONV's window for the main path\n    filters -- python list of integers, defining the number of filters in the CONV layers of the main path\n    stage -- integer, used to name the layers, depending on their position in the network\n    block -- string/character, used to name the layers, depending on their position in the network\n    \n    Returns:\n    X -- output of the identity block, tensor of shape (n_H, n_W, n_C)\n    \"\"\"\n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    # Retrieve Filters\n    F1, F2, F3 = filters\n    \n    # Save the input value. You'll need this later to add back to the main path. \n    X_shortcut = X\n    \n    # First component of main path\n    X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)\n    X = Activation('relu')(X)\n\n    \n    # Second component of main path (≈3 lines)\n    X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n    # Third component of main path (≈2 lines)\n    X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)\n\n    # Final step: Add shortcut value to main path, and pass it through a RELU activation (≈2 lines)\n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n    \n    \n    return X\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.435829Z","iopub.execute_input":"2021-09-01T14:21:20.436790Z","iopub.status.idle":"2021-09-01T14:21:20.451001Z","shell.execute_reply.started":"2021-09-01T14:21:20.436748Z","shell.execute_reply":"2021-09-01T14:21:20.449873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convolutional_block(X, f, filters, stage, block, s = 2):\n    \"\"\"\n    Arguments:\n    X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)\n    f -- integer, specifying the shape of the middle CONV's window for the main path\n    filters -- python list of integers, defining the number of filters in the CONV layers of the main path\n    stage -- integer, used to name the layers, depending on their position in the network\n    block -- string/character, used to name the layers, depending on their position in the network\n    s -- Integer, specifying the stride to be used\n    \n    Returns:\n    X -- output of the convolutional block, tensor of shape (n_H, n_W, n_C)\n    \"\"\"\n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    # Retrieve Filters\n    F1, F2, F3 = filters\n    \n    # Save the input value\n    X_shortcut = X\n\n\n    ##### MAIN PATH #####\n    # First component of main path \n    X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)\n    X = Activation('relu')(X)\n\n    # Second component of main path (≈3 lines)\n    X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = 'same', name = conv_name_base + '2b', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n\n    # Third component of main path (≈2 lines)\n    X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c', kernel_initializer = glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)\n\n\n    ##### SHORTCUT PATH #### (≈2 lines)\n    X_shortcut = Conv2D(filters = F3, kernel_size = (1, 1), strides = (s,s), padding = 'valid', name = conv_name_base + '1',\n                        kernel_initializer = glorot_uniform(seed=0))(X_shortcut)\n    X_shortcut = BatchNormalization(axis = 3, name = bn_name_base + '1')(X_shortcut)\n\n    # Final step: Add shortcut value to main path, and pass it through a RELU activation (≈2 lines)\n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n    \n    \n    return X","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.452600Z","iopub.execute_input":"2021-09-01T14:21:20.453003Z","iopub.status.idle":"2021-09-01T14:21:20.482864Z","shell.execute_reply.started":"2021-09-01T14:21:20.452966Z","shell.execute_reply":"2021-09-01T14:21:20.481834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_input = Input([img_size,img_size, img_channel])\nX = ZeroPadding2D((3, 3))(X_input)\n\nX = Conv2D(64, (7, 7), strides=(2, 2), name='conv1', kernel_initializer=glorot_uniform(seed=0))(X)\nX = BatchNormalization(axis=3, name='bn_conv1')(X)\nX = Activation('relu')(X)\nX = MaxPooling2D((3, 3), strides=(2, 2))(X)\n\nX = convolutional_block(X, f=3, filters=[64, 64, 128], stage=2, block='a', s=1)\nX = identity_block(X, 3, [64, 64, 128], stage=2, block='b')\nX = identity_block(X, 3, [64, 64, 128], stage=2, block='c')\n\nX = convolutional_block(X, f = 3, filters = [128, 128, 512], stage = 3, block='a', s = 2)\nX = identity_block(X, 3, [128, 128, 512], stage=3, block='b')\nX = identity_block(X, 3, [128, 128, 512], stage=3, block='c')\nX = identity_block(X, 3, [128, 128, 512], stage=3, block='d')\n\nX = convolutional_block(X, f=3, filters=[256, 256, 1024], stage=4, block='a', s=2)\nX = identity_block(X, 3, [256, 256, 1024], stage=4, block='b')\nX = identity_block(X, 3, [256, 256, 1024], stage=4, block='c')\nX = identity_block(X, 3, [256, 256, 1024], stage=4, block='d')\nX = identity_block(X, 3, [256, 256, 1024], stage=4, block='e')\nX = identity_block(X, 3, [256, 256, 1024], stage=4, block='f')\n\nX = AveragePooling2D((2,2), name=\"max_pool\")(X)\n\nX = Flatten()(X)\n\nX = Dense(1024, activation='relu', name='fc'+'-temporary',kernel_initializer = glorot_uniform(seed=0))(X)\nX = Dense(num_classes, activation='softmax', name='fc' + str(num_classes), kernel_initializer = glorot_uniform(seed=0))(X)\n\nmodel2 = Model(inputs = X_input, outputs = X, name='Simplified-ResNet50')\n\nmodel2.compile(optimizer = Adam(lr=1e-4),\n              loss=\"sparse_categorical_crossentropy\",\n              metrics=['sparse_categorical_accuracy'])\n\nmodel2.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:21:20.484178Z","iopub.execute_input":"2021-09-01T14:21:20.484818Z","iopub.status.idle":"2021-09-01T14:21:21.322619Z","shell.execute_reply.started":"2021-09-01T14:21:20.484776Z","shell.execute_reply":"2021-09-01T14:21:21.321634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nhistory = model2.fit_generator(generator=train_generator,\n                              #validation_data=val_generator,\n                              epochs = epochs, workers=32)\n","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:15.834462Z","iopub.execute_input":"2021-09-01T14:24:15.834798Z","iopub.status.idle":"2021-09-01T14:27:38.180384Z","shell.execute_reply.started":"2021-09-01T14:24:15.834765Z","shell.execute_reply":"2021-09-01T14:27:38.172346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import multiprocessing\nmultiprocessing.cpu_count()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.536028Z","iopub.status.idle":"2021-09-01T14:24:10.537860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#history = model.fit_generator(generator=train_generator,\n#                              epochs = epochs, workers=16)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.539667Z","iopub.status.idle":"2021-09-01T14:24:10.541812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subsize_len = 1000 \nencoded_results = []\nresults = []\nscores = []\ntest_len = len(list(test.index))\nif test_len > 1000:\n    for i in range(math.ceil(len(list(test.index))/subsize_len)):\n        IDs_test = list(test.index)[i*subsize_len:(i+1)*subsize_len]\n        test_generator = DataGenerator(test_image_dir, IDs_test, test, img_size, img_channel, batch_size, augmentation=False)\n\n\n        y_pred = model2.predict_generator(test_generator, verbose =1)\n\n        encoded_result = [np.argmax(s) for s in y_pred]\n        result = [id_map[er] for er in encoded_result]\n        score = [y_pred[i][encoded_result[i]].round(2) for i in range(len(encoded_result))]\n\n\n        encoded_results.extend(encoded_result)\n        results.extend(result)\n        scores.extend(score)\n\nelse:\n    IDs_test = list(test.index)\n    test_generator = DataGenerator(test_image_dir, IDs_test, test, img_size, img_channel, batch_size, augmentation=False)\n    y_pred = model2.predict_generator(test_generator, verbose =1)\n    encoded_result = [np.argmax(s) for s in y_pred]\n    result = [id_map[er] for er in encoded_result]\n    score = [y_pred[i][encoded_result[i]].round(2) for i in range(len(encoded_result))]\n    encoded_results.extend(encoded_result)\n    results.extend(result)\n    scores.extend(score)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.544317Z","iopub.status.idle":"2021-09-01T14:24:10.544871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['landmarks'] = [str(results[i])+' '+str(scores[i]) for i in range(len(scores))]","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.546273Z","iopub.status.idle":"2021-09-01T14:24:10.546889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.drop(['path'], axis=1,inplace=True)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.550004Z","iopub.status.idle":"2021-09-01T14:24:10.550506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.557985Z","iopub.status.idle":"2021-09-01T14:24:10.558548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T14:24:10.562491Z","iopub.status.idle":"2021-09-01T14:24:10.563143Z"},"trusted":true},"execution_count":null,"outputs":[]}]}