{"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":"markdown","source":"**Libraries**","metadata":{}},{"cell_type":"code","source":"import os\nimport seaborn as sns\nimport numpy as np\nimport pandas as pd\nimport matplotlib.image as mpimg\nimport os\nimport cv2\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm\nimport torchvision\nfrom torchvision import transforms \nimport random","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:53:55.319688Z","iopub.execute_input":"2023-06-11T23:53:55.320076Z","iopub.status.idle":"2023-06-11T23:53:55.327105Z","shell.execute_reply.started":"2023-06-11T23:53:55.320046Z","shell.execute_reply":"2023-06-11T23:53:55.325957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!wget https://raw.githubusercontent.com/colmap/colmap/dev/scripts/python/read_write_model.py","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:51:07.962288Z","iopub.execute_input":"2023-06-11T23:51:07.962937Z","iopub.status.idle":"2023-06-11T23:51:09.134224Z","shell.execute_reply.started":"2023-06-11T23:51:07.962904Z","shell.execute_reply":"2023-06-11T23:51:09.133081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import read_write_model","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:51:32.868563Z","iopub.execute_input":"2023-06-11T23:51:32.868960Z","iopub.status.idle":"2023-06-11T23:51:32.883866Z","shell.execute_reply.started":"2023-06-11T23:51:32.868928Z","shell.execute_reply":"2023-06-11T23:51:32.882973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root='/kaggle/input/image-matching-challenge-2023'\ntrain_label='train_labels.csv'\ntrain_path='/kaggle/input/image-matching-challenge-2023/train/'\ntest_path='kaggle/input/image-matching-challenge-2023/test/'","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:07:49.573929Z","iopub.execute_input":"2023-06-11T23:07:49.574270Z","iopub.status.idle":"2023-06-11T23:07:49.578942Z","shell.execute_reply.started":"2023-06-11T23:07:49.574243Z","shell.execute_reply":"2023-06-11T23:07:49.577643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels=pd.read_csv('/kaggle/input/image-matching-challenge-2023/train/train_labels.csv')\ntrain_labels.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:14:29.088868Z","iopub.execute_input":"2023-06-11T23:14:29.089222Z","iopub.status.idle":"2023-06-11T23:14:29.106787Z","shell.execute_reply.started":"2023-06-11T23:14:29.089193Z","shell.execute_reply":"2023-06-11T23:14:29.105744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_datasets(root,path):\n    file_path = os.path.join(root,path)\n    df = pd.read_csv(file_path)\n    return df","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:07:23.039894Z","iopub.execute_input":"2023-06-11T23:07:23.040240Z","iopub.status.idle":"2023-06-11T23:07:23.047689Z","shell.execute_reply.started":"2023-06-11T23:07:23.040213Z","shell.execute_reply":"2023-06-11T23:07:23.046806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#get_datasets(train_path,train_label).head()","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:08:07.483256Z","iopub.execute_input":"2023-06-11T23:08:07.483624Z","iopub.status.idle":"2023-06-11T23:08:07.489473Z","shell.execute_reply.started":"2023-06-11T23:08:07.483584Z","shell.execute_reply":"2023-06-11T23:08:07.486600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**EDA**","metadata":{}},{"cell_type":"code","source":"print(\"First few rows of train_labels:\")\nprint(train_labels.head()) \n\nprint(\"\\nInformation about train_labels dataset:\")\nprint(train_labels.info())\n\nprint(\"\\nMissing values in train_labels dataset:\")\nprint(train_labels.isnull().sum())\n\nnum_datasets=train_labels['dataset'].nunique()\nnum_scenes=train_labels['scene'].nunique()\nprint(\"\\nNumber of unique datasets:\", num_datasets)\nprint(\"Number of unique scenes:\", num_scenes)","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:18:33.052262Z","iopub.execute_input":"2023-06-11T23:18:33.052625Z","iopub.status.idle":"2023-06-11T23:18:33.070401Z","shell.execute_reply.started":"2023-06-11T23:18:33.052596Z","shell.execute_reply":"2023-06-11T23:18:33.069454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Plot**","metadata":{}},{"cell_type":"code","source":"sns.countplot(data=train_labels,x='dataset',palette=\"pastel\")\nsns.color_palette(\"pastel\")\nplt.title(\"Image per Dataset\")\nplt.show()\n\nplt.figure(figsize=(12,6))\nsns.countplot(data=train_labels,x='scene',palette=\"pastel\",order=train_labels['scene'].value_counts().index)\nplt.title(\"Images per Scene\")\nplt.xticks(rotation=90)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:58:10.190557Z","iopub.execute_input":"2023-06-12T01:58:10.190977Z","iopub.status.idle":"2023-06-12T01:58:10.700289Z","shell.execute_reply.started":"2023-06-12T01:58:10.190947Z","shell.execute_reply":"2023-06-12T01:58:10.699356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"paths=[]\nfiles=[]\n\nfor dirname,_,filenames in os.walk('/kaggle/input/image-matching-challenge-2023/train/heritage/cyprus/images'):\n    for filename in filenames:\n        paths +=[(os.path.join(dirname,filename))]\n        files +=[filename]\n        \nfig,axs=plt.subplots(4,6,figsize=(12,12)) \nfor i,ax in enumerate(axs.flat):\n    if i <len(paths):\n        img=mpimg.imread(paths[i])\n        ax.imshow(img)\n    ax.axis('off')\nplt.show()    ","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:34:33.994275Z","iopub.execute_input":"2023-06-11T23:34:33.994956Z","iopub.status.idle":"2023-06-11T23:35:34.129155Z","shell.execute_reply.started":"2023-06-11T23:34:33.994919Z","shell.execute_reply":"2023-06-11T23:35:34.127980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Rotate Imgages**","metadata":{}},{"cell_type":"code","source":"height,width = img.shape[:2]\ntheta_z = np.pi/6\n\nR_z = np.array([[np.cos(theta_z), -np.sin(theta_z), 0],\n                [np.sin(theta_z), np.cos(theta_z), 0],\n                [0, 0, 1]])\nrotated_img2 = cv2.warpAffine(img, R_z[:2,:], (width,height))\nplt.imshow(rotated_img2)\nplt.axis('off') \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:40:12.087513Z","iopub.execute_input":"2023-06-12T01:40:12.088520Z","iopub.status.idle":"2023-06-12T01:40:15.213919Z","shell.execute_reply.started":"2023-06-12T01:40:12.088480Z","shell.execute_reply":"2023-06-12T01:40:15.212996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**3D Reconstructions**","metadata":{}},{"cell_type":"code","source":"# def plot_sfm_3d_reconstruction(reconstruction, num_points=1000, num_cameras=50):\n#     fig = plt.figure()\n#     ax = fig.add_subplot(111, projection='3d')\n\n#     point3D_ids = list(reconstruction[2].keys())\n#     selected_point3D_ids = random.sample(point3D_ids, min(num_points, len(point3D_ids)))\n\n#     for point3D_id in selected_point3D_ids:\n#         point3D = reconstruction[2][point3D_id]\n#         ax.scatter(point3D.xyz[0], point3D.xyz[1], point3D.xyz[2], c='b', marker='o')\n\n#     image_ids = list(reconstruction[1].keys())\n#     selected_image_ids = random.sample(image_ids, min(num_cameras, len(image_ids)))\n\n#     for image_id in selected_image_ids:\n#         image = reconstruction[1][image_id]\n#         camera_center = -image.qvec2rotmat().T @ image.tvec\n#         ax.scatter(camera_center[0], camera_center[1], camera_center[2], c='r', marker='^')\n\n#     ax.set_xlabel('X')\n#     ax.set_ylabel('Y')\n#     ax.set_zlabel('Z')\n#     plt.show()\n\n\n# sample_sfm_folder = os.path.join(train_path, 'heritage/cyprus/sfm')\n# cameras, images, points3D = read_write_model.read_model(sample_sfm_folder)\n# reconstruction = (cameras, images, points3D)\n# plot_sfm_3d_reconstruction(reconstruction)\n        \n    \n        \n    \n    ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T02:17:53.424936Z","iopub.execute_input":"2023-06-12T02:17:53.425377Z","iopub.status.idle":"2023-06-12T02:17:53.433100Z","shell.execute_reply.started":"2023-06-12T02:17:53.425345Z","shell.execute_reply":"2023-06-12T02:17:53.430213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def string_to_matrix(matrix_string):\n    return np.array(list(map(float, matrix_string.split(';')))).reshape(3, 3)\n\ndef string_to_vector(vector_string):\n    return np.array(list(map(float, vector_string.split(';'))))","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:46:20.370497Z","iopub.execute_input":"2023-06-12T01:46:20.371628Z","iopub.status.idle":"2023-06-12T01:46:20.378533Z","shell.execute_reply.started":"2023-06-12T01:46:20.371580Z","shell.execute_reply":"2023-06-12T01:46:20.377301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rotation_matrices = train_labels['rotation_matrix'].apply(string_to_matrix)\ntranslation_vectors = train_labels['translation_vector'].apply(string_to_vector)\n\n# Calculate rotation angles (in degrees) for all images\nrotation_angles = [np.rad2deg(np.arccos((np.trace(R) - 1) / 2)) for R in rotation_matrices]","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:46:34.779879Z","iopub.execute_input":"2023-06-12T01:46:34.780247Z","iopub.status.idle":"2023-06-12T01:46:34.796162Z","shell.execute_reply.started":"2023-06-12T01:46:34.780218Z","shell.execute_reply":"2023-06-12T01:46:34.795099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure()\nplt.hist(rotation_angles, bins=50 ,color = \"lightgreen\" ,ec=\"yellow\")\nplt.xlabel('Rotation Angle (degrees)')\nplt.ylabel('Number of Images')\nplt.title('Distribution of Rotation Angles')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:50:14.648745Z","iopub.execute_input":"2023-06-12T01:50:14.649110Z","iopub.status.idle":"2023-06-12T01:50:14.988207Z","shell.execute_reply.started":"2023-06-12T01:50:14.649082Z","shell.execute_reply":"2023-06-12T01:50:14.987306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"translation_magnitudes = [np.linalg.norm(tvec) for tvec in translation_vectors]\n\nplt.figure()\nplt.hist(translation_magnitudes, bins=50 , color = \"lightgreen\" ,ec=\"yellow\")\nplt.xlabel('Translation Magnitude (meters)')\nplt.ylabel('Number of Images')\nplt.title('Distribution of Translation Magnitudes')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:50:59.829188Z","iopub.execute_input":"2023-06-12T01:50:59.829576Z","iopub.status.idle":"2023-06-12T01:51:00.210949Z","shell.execute_reply.started":"2023-06-12T01:50:59.829546Z","shell.execute_reply":"2023-06-12T01:51:00.210007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**transform data**","metadata":{}},{"cell_type":"code","source":"train_transform = A.Compose([\n    A.Resize(224,224),\n    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), max_pixel_value=255.0, always_apply=False, p=1.0),\n    ToTensorV2()\n   ])\nvalidation_transform = A.Compose([\n    A.Resize(224,224),\n    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), max_pixel_value=255.0, always_apply=False, p=1.0),\n    ToTensorV2()\n    ])","metadata":{"execution":{"iopub.status.busy":"2023-06-11T23:10:14.357869Z","iopub.execute_input":"2023-06-11T23:10:14.358649Z","iopub.status.idle":"2023-06-11T23:10:14.365376Z","shell.execute_reply.started":"2023-06-11T23:10:14.358610Z","shell.execute_reply":"2023-06-11T23:10:14.364500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Dataset Class**","metadata":{}},{"cell_type":"code","source":"class ImageDataset(Dataset):\n    \n    def __init__(self, root, img_path, rotation_label, translation_label, transforms=None):\n    \n        self.root=root \n        self.img_path=img_path \n        self.rotation_label = rotation_label \n        self.translation_label = translation_label\n        self.transforms = transforms\n        \n    def __getitem__(self,index):\n        \n        img_path=self.img_path[index]\n        img_path=self.root+img_path \n        image=cv2.imread(img_path)\n        \n        if self.transforms is not None:\n            \n            image=self.transforms(image=image)['image']\n            \n        rotation_label = self.rotation_label[index].split(\";\") \n        rotation_label=list(map(float, rotation_label))\n        \n        translation_label = self.translation_label[index].split(\";\")\n        translation_label = list(map(float, translation_label))\n        \n        return image,np.array(rotation_label),np.array(translation_label)\n    \n    def __len__(self):\n        return len(self.img_path)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:13:13.621824Z","iopub.execute_input":"2023-06-12T00:13:13.622211Z","iopub.status.idle":"2023-06-12T00:13:13.632913Z","shell.execute_reply.started":"2023-06-12T00:13:13.622180Z","shell.execute_reply":"2023-06-12T00:13:13.631843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_train_validation_set(df):\n    validtion_data = df.sample(frac=0.3)\n    training_data =  df[~df[\"image_path\"].isin(validtion_data[\"image_path\"])]\n    return training_data,validtion_data\n\n\ntraining_data,validation_data = get_train_validation_set(get_datasets(train_path,train_label))","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:21:51.823152Z","iopub.execute_input":"2023-06-12T00:21:51.823525Z","iopub.status.idle":"2023-06-12T00:21:51.836371Z","shell.execute_reply.started":"2023-06-12T00:21:51.823495Z","shell.execute_reply":"2023-06-12T00:21:51.835458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Roatation**","metadata":{}},{"cell_type":"code","source":"def get_translation_rotation(df):\n    \n    df[\"rotation_matrix_split\"] = df.apply(lambda x:list(map(float, x[\"rotation_matrix\"].split(\";\"))), axis=1)\n    df[\"translation_vector_split\"] = df.apply(lambda x:list(map(float, x[\"translation_vector\"].split(\";\"))), axis=1)\n    \n    rotation_value=np.array(df[\"rotation_matrix_split\"].tolist())\n    \n    translation_value = np.array(df[\"translation_vector_split\"].tolist())\n    \n    \n    return translation_value,rotation_value\n\ntranslation_value,rotation_value=get_translation_rotation(get_datasets(train_path,train_label))\n    ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:29:55.877201Z","iopub.execute_input":"2023-06-12T00:29:55.877592Z","iopub.status.idle":"2023-06-12T00:29:55.902036Z","shell.execute_reply.started":"2023-06-12T00:29:55.877558Z","shell.execute_reply":"2023-06-12T00:29:55.901170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Split Dataset**","metadata":{}},{"cell_type":"code","source":"def get_train_dataset(train_path,training_data):\n    \n    train_dataset=ImageDataset(train_path,training_data[\"image_path\"].tolist(),training_data[\"rotation_matrix\"].tolist(),training_data[\"translation_vector\"].tolist(),transforms=train_transform)\n    \n    return train_dataset ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:34:13.124183Z","iopub.execute_input":"2023-06-12T00:34:13.124597Z","iopub.status.idle":"2023-06-12T00:34:13.130498Z","shell.execute_reply.started":"2023-06-12T00:34:13.124562Z","shell.execute_reply":"2023-06-12T00:34:13.129593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_validation_dataset(train_path,validation_data):    \n    validation_dataset = ImageDataset(train_path, \n                        validation_data[\"image_path\"].tolist(), \n                        validation_data[\"rotation_matrix\"].tolist(), \n                        validation_data[\"translation_vector\"].tolist(), \n                        transforms=validation_transform)\n    return validation_dataset","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:34:56.074032Z","iopub.execute_input":"2023-06-12T00:34:56.074379Z","iopub.status.idle":"2023-06-12T00:34:56.079899Z","shell.execute_reply.started":"2023-06-12T00:34:56.074349Z","shell.execute_reply":"2023-06-12T00:34:56.078909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Dataloader**","metadata":{}},{"cell_type":"code","source":"def get_train_dataloader(train_dataset):\n    \n    train_loader=DataLoader(train_dataset,batch_size=4,shuffle=True,num_workers=2)\n    \n    return train_loader\n\ndef get_validation_dataloader(validation_dataset):\n    \n    validation_loader=DataLoader(validation_dataset,batch_size=4,shuffle=False)\n    \n    return validation_loader","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:41:55.418031Z","iopub.execute_input":"2023-06-12T00:41:55.418462Z","iopub.status.idle":"2023-06-12T00:41:55.424560Z","shell.execute_reply.started":"2023-06-12T00:41:55.418406Z","shell.execute_reply":"2023-06-12T00:41:55.423433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader=get_train_dataloader(get_train_dataset(train_path,training_data))\nvalidation_loader = get_validation_dataloader(get_validation_dataset(train_path,validation_data))\n","metadata":{"execution":{"iopub.status.busy":"2023-06-12T00:41:57.732154Z","iopub.execute_input":"2023-06-12T00:41:57.733067Z","iopub.status.idle":"2023-06-12T00:41:57.738481Z","shell.execute_reply.started":"2023-06-12T00:41:57.733035Z","shell.execute_reply":"2023-06-12T00:41:57.737479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Image Matching Model**","metadata":{}},{"cell_type":"code","source":"class ImagemtachingModel(torch.nn.Module):\n    \n    def __init__(self,dropout=0.2):\n        super(ImagemtachingModel, self).__init__()\n        self.layer_one = nn.Sequential(\n            nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n            nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1), \n            nn.BatchNorm2d(64), \n            nn.ReLU(),\n            nn.Dropout(dropout),\n            nn.MaxPool2d(kernel_size=2)\n        )\n        \n        self.layer_two=nn.Sequential(\n        \n            nn.Conv2d(64,128,kernel_size=3,stride=1,padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.Conv2d(128,128,kernel_size=3,stride=1,padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.Dropout(dropout),\n            nn.MaxPool2d(kernel_size=2)\n        \n        \n        )\n        \n        self.layer_three=nn.Sequential(\n        \n            nn.Conv2d(128,256,kernel_size=3,stride=1,padding=1),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.Conv2d(256,256,kernel_size=3,stride=1,padding=1),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.Dropout(dropout),\n            nn.MaxPool2d(kernel_size=2)\n        \n        \n        )\n        \n        self.layer_four=nn.Sequential(\n        \n            nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1), \n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(512), \n            nn.ReLU(), \n            nn.Dropout(dropout),\n            nn.MaxPool2d(kernel_size=2)\n        \n        \n        ) \n        \n        self.layer_five=nn.Sequential(\n        \n            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), \n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(512), \n            nn.ReLU(), \n            nn.Dropout(dropout),\n            nn.MaxPool2d(kernel_size=2), \n            nn.AvgPool2d(kernel_size=7)\n        \n        \n        )\n        \n        self.layer_six=nn.Sequential(\n            \n           nn.Linear(512,512),\n           nn.ReLU(), \n            \n        \n        )\n        self.rotation_out = nn.Linear(512, 9)\n        self.tanh = torch.nn.Tanh()\n        \n        self.translation_out = torch.nn.Linear(512, 3)\n        \n        \n    def forward(self,x):\n        \n        x=self.layer_one(x)\n        x = self.layer_two(x)\n        x = self.layer_three(x)\n        x = self.layer_four(x)\n        x = self.layer_five(x)\n        \n        #Flatten \n        x=x.view(-1,512)\n        \n        x=self.layer_six(x)\n        \n        rotation_out=self.rotation_out(x)\n        \n        #tanh\n        \n        rotation_out = self.tanh(rotation_out)\n        \n        translation_out = self.translation_out(x)\n        \n        return rotation_out, translation_out\n        ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:06:56.024724Z","iopub.execute_input":"2023-06-12T01:06:56.025081Z","iopub.status.idle":"2023-06-12T01:06:56.046252Z","shell.execute_reply.started":"2023-06-12T01:06:56.025053Z","shell.execute_reply":"2023-06-12T01:06:56.045321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Move Model To Cuda**","metadata":{}},{"cell_type":"code","source":"device=torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:04:55.810407Z","iopub.execute_input":"2023-06-12T01:04:55.810810Z","iopub.status.idle":"2023-06-12T01:04:55.842161Z","shell.execute_reply.started":"2023-06-12T01:04:55.810780Z","shell.execute_reply":"2023-06-12T01:04:55.841100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = ImagemtachingModel(dropout=0.2)\nmodel.to(device)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:07:02.040012Z","iopub.execute_input":"2023-06-12T01:07:02.040370Z","iopub.status.idle":"2023-06-12T01:07:05.072348Z","shell.execute_reply.started":"2023-06-12T01:07:02.040344Z","shell.execute_reply":"2023-06-12T01:07:05.071353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Optimization**","metadata":{}},{"cell_type":"code","source":"l1_distance=torch.nn.L1Loss()\noptimizer=torch.optim.Adam(params=model.parameters(),lr=0.001)\nscheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=2, threshold_mode='abs', min_lr=1e-8, verbose=True)\nbest_loss = 1000000000\nepochs = 10\nbest_model = None","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:09:13.175289Z","iopub.execute_input":"2023-06-12T01:09:13.175994Z","iopub.status.idle":"2023-06-12T01:09:13.183324Z","shell.execute_reply.started":"2023-06-12T01:09:13.175959Z","shell.execute_reply":"2023-06-12T01:09:13.182466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Training**","metadata":{}},{"cell_type":"code","source":"for epoch in range(1,epochs+1):\n    \n    train_loss=[]\n    rot_loss=[]\n    trans_loss=[]\n    \n    val_loss = []\n    val_rot_loss = []\n    val_trans_loss = []\n    \n    #train loader\n    \n    for imgs, rotation_labels, translation_labels in tqdm(train_loader):\n        \n        model.train()\n        optimizer.zero_grad()\n        \n        imgs=imgs.to(device)\n        rotation_labels = rotation_labels.to(device)\n        translation_labels = translation_labels.to(device)\n        \n        rotation_output ,translation_output=model(imgs)\n        \n        rotation_loss = l1_distance(rotation_output, rotation_labels)\n        \n        translation_loss = l1_distance(translation_output, translation_labels)\n        \n        loss=rotation_loss+translation_loss\n        \n        loss.backward()\n        \n        optimizer.step()\n        \n        train_loss.append(loss.item())\n        \n        rot_loss.append(rotation_loss.item())\n        trans_loss.append(translation_loss.item())\n        \n    # validation loader  \n        \n    for imgs, rotation_labels, translation_labels in tqdm(validation_loader):\n        model.eval()\n        \n        imgs = imgs.to(device)\n        rotation_labels = rotation_labels.to(device)\n        translation_labels = translation_labels.to(device)\n        \n        rotation_output, translation_output = model(imgs)\n        rotation_loss = l1_distance(rotation_output, rotation_labels)\n        translation_loss = l1_distance(translation_output, translation_labels)\n        loss = rotation_loss + translation_loss\n        \n        val_loss.append(loss.item())\n        val_rot_loss.append(rotation_loss.item())\n        val_trans_loss.append(translation_loss.item())\n        \n    #mean loss \n    \n    mtrain_loss=np.mean(train_loss)\n    mval_loss = np.mean(val_loss)\n    mtrain_rot_loss = np.mean(rot_loss)\n    mtrain_trans_loss = np.mean(trans_loss)\n    mval_rot_loss = np.mean(val_rot_loss)\n    mval_trans_loss = np.mean(val_trans_loss)\n    \n    \n    if scheduler is not None:\n        scheduler.step(mval_loss)\n\n    if best_loss < mval_loss:\n        best_loss = mval_loss\n        best_model = model\n        \n    print(f'Epoch [{epoch}], Train Loss : [{mtrain_loss:.5f}] \\\n    Train Rotation Loss : [{mtrain_rot_loss:.5f}] Train Translation Loss : [{mtrain_trans_loss:.5f}] \\\n          Val Loss : [{mval_loss:.5f}] Val Rotation Loss : [{mval_rot_loss:.5f}] Val Translation Loss : [{mval_trans_loss:.5f}]')     ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:21:52.759312Z","iopub.execute_input":"2023-06-12T01:21:52.760373Z","iopub.status.idle":"2023-06-12T01:28:42.962910Z","shell.execute_reply.started":"2023-06-12T01:21:52.760336Z","shell.execute_reply":"2023-06-12T01:28:42.961737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Prediction & Submission**","metadata":{}},{"cell_type":"code","source":"def arr_to_str(a):\n    return ';'.join([str(x) for x in a.reshape(-1)])","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:28:42.965405Z","iopub.execute_input":"2023-06-12T01:28:42.966182Z","iopub.status.idle":"2023-06-12T01:28:42.971780Z","shell.execute_reply.started":"2023-06-12T01:28:42.966141Z","shell.execute_reply":"2023-06-12T01:28:42.970556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/image-matching-challenge-2023/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:35:13.556468Z","iopub.execute_input":"2023-06-12T01:35:13.557479Z","iopub.status.idle":"2023-06-12T01:35:13.574902Z","shell.execute_reply.started":"2023-06-12T01:35:13.557436Z","shell.execute_reply":"2023-06-12T01:35:13.574005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_rotation_list=[]\ntest_translation_list=[]\ntest_img_list=[]\ntest_dataset_list = []\ntest_scene_list = []\n\nfor i in range(len(submission)):\n    \n    test_row=submission.iloc[i]\n    test_img=test_row[\"image_path\"]\n    test_dataset = test_row[\"dataset\"]\n    test_scene = test_row[\"scene\"]\n    img_path = f\"{root}/test/{test_img}\"\n    \n    try:\n        image=cv2.imread(img_path)\n        image=test_transforms(image=image)['image']\n        rotation = arr_to_str(rotation.detach().cpu().numpy())\n        translation = arr_to_str(translation.detach().cpu().numpy())\n        \n    except:\n        rotation = \"1.0;0.0;0.0;0.0;1.0;0.0;0.0;0.0;1.0\"\n        translation = \"0.0;0.0;0.0\"\n    \n    test_rotation_list.append(rotation)\n    test_translation_list.append(translation)\n    test_img_list.append(test_img)\n    test_dataset_list.append(test_dataset)\n    test_scene_list.append(test_scene) ","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:35:15.406940Z","iopub.execute_input":"2023-06-12T01:35:15.407739Z","iopub.status.idle":"2023-06-12T01:35:15.419586Z","shell.execute_reply.started":"2023-06-12T01:35:15.407696Z","shell.execute_reply":"2023-06-12T01:35:15.418562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_submission=pd.DataFrame()\nmy_submission[\"image_path\"]=test_img_list\nmy_submission[\"dataset\"] = test_dataset_list\nmy_submission[\"scene\"] = test_scene_list\nmy_submission[\"rotation_matrix\"] = test_rotation_list\nmy_submission[\"translation_vector\"] = test_translation_list\n\nmy_submission.to_csv(\"submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:35:21.919610Z","iopub.execute_input":"2023-06-12T01:35:21.919987Z","iopub.status.idle":"2023-06-12T01:35:21.933144Z","shell.execute_reply.started":"2023-06-12T01:35:21.919957Z","shell.execute_reply":"2023-06-12T01:35:21.932152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df=pd.read_csv(\"/kaggle/working/submission.csv\")\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T01:35:25.300119Z","iopub.execute_input":"2023-06-12T01:35:25.300519Z","iopub.status.idle":"2023-06-12T01:35:25.317200Z","shell.execute_reply.started":"2023-06-12T01:35:25.300486Z","shell.execute_reply":"2023-06-12T01:35:25.316281Z"},"trusted":true},"execution_count":null,"outputs":[]}]}