{"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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q pytorch-metric-learning[with-hooks]\n!pip install umap-learn","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_ids = pd.read_csv('/kaggle/input/sample-ids/Samples 1000.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_ids = sample_ids['landmark_id']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_ids.columns = ['landmark_id']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data = pd.read_csv('/kaggle/input/landmark-recognition-2020/train.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_data = data.loc[data['landmark_id'].isin(sample_ids['landmark_id'].values)]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_data = sample_data.reset_index()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_data.loc[sample_data['landmark_id'].value_counts() == 2]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_path = '/kaggle/input/landmark-recognition-2020/train/'\n# file_paths = []\n# for root, dirs, files in os.walk(train_path):\n#     for file in files:\n#         file_paths.append(os.path.join(root,file))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# len(file_paths)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_paths[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_name = [idx.split('/')[-1].split('.')[0] for idx in file_paths]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_df = pd.DataFrame(file_name, columns=['id'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_df['file_path'] = file_paths","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_files = file_df.loc[file_df['id'].isin(sample_data['id'])]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df = pd.merge(sample_data, sample_files)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df.iloc[0]['id']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df.iloc[0]['file_path']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df.to_csv('/kaggle/working/sample_df')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib inline\nfrom pytorch_metric_learning import losses, miners, samplers, trainers, testers\nfrom pytorch_metric_learning.utils import common_functions\nimport pytorch_metric_learning.utils.logging_presets as logging_presets\nfrom pytorch_metric_learning.utils.accuracy_calculator import AccuracyCalculator\nimport numpy as np\nimport torchvision\nfrom torchvision import datasets, transforms\nimport torch\nimport torch.nn as nn\nfrom PIL import Image\nimport logging\nimport matplotlib.pyplot as plt\nimport umap\nfrom cycler import cycler\nimport record_keeper\nimport pytorch_metric_learning\nimport cv2\nfrom PIL import Image\nimport pandas as pd\nfrom sklearn.model_selection import StratifiedShuffleSplit\nlogging.getLogger().setLevel(logging.INFO)\nlogging.info(\"VERSION %s\"%pytorch_metric_learning.__version__)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df = pd.read_csv('/kaggle/input/sample-ids/sample_df')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MLP(nn.Module):\n    # layer_sizes[0] is the dimension of the input\n    # layer_sizes[-1] is the dimension of the output\n    def __init__(self, layer_sizes, final_relu=False):\n        super().__init__()\n        layer_list = []\n        layer_sizes = [int(x) for x in layer_sizes]\n        num_layers = len(layer_sizes) - 1\n        final_relu_layer = num_layers if final_relu else num_layers - 1\n        for i in range(len(layer_sizes) - 1):\n            input_size = layer_sizes[i]\n            curr_size = layer_sizes[i + 1]\n            if i < final_relu_layer:\n                layer_list.append(nn.ReLU(inplace=False))\n            layer_list.append(nn.Linear(input_size, curr_size))\n        self.net = nn.Sequential(*layer_list)\n        self.last_linear = self.net[-1]\n\n    def forward(self, x):\n        return self.net(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install timm","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import timm","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!pip install git+https://github.com/qubvel/classification_models.git","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for keras\n#from classification_models.keras import Classifiers\n\n# for tensorflow keras\n#from classification_models.tfkeras import Classifiers\n\n#Classifiers.models_names()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#SeResNeXT101, preprocess_input = Classifiers.get('seresnext101')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Set trunk model and replace the softmax layer with an identity function\ntrunk = timm.create_model('seresnet101', pretrained=True)\n#trunk = SeResNeXT101(include_top = False, input_shape=(224, 224, 3), weights='imagenet')\n#trunk = torchvision.models.resnet50(pretrained=True)\ntrunk_output_size = trunk.fc.in_features\ntrunk.fc = common_functions.Identity()\ntrunk = torch.nn.DataParallel(trunk.to(device))\n\n# Set embedder model. This takes in the output of the trunk and outputs 64 dimensional embeddings\nembedder = torch.nn.DataParallel(MLP([trunk_output_size, 256]).to(device))\n\n# Set optimizers\ntrunk_optimizer = torch.optim.Adam(trunk.parameters(), lr=0.0001, weight_decay=0.0001)\nembedder_optimizer = torch.optim.Adam(embedder.parameters(), lr=0.0001, weight_decay=0.0001)\n\n# Set the image transforms\ntransform = transforms.Compose([transforms.Resize((224, 224)),\n                                    transforms.ToTensor(),\n                                    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ct = 0\n# for param in trunk.parameters():\n#     if ct <=150:\n#         param.requires_grad = False  \n#     ct+=1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trunk_output_size","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for param in trunk.parameters():\n#     print(param.requires_grad)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class create_dataset(torch.utils.data.Dataset):\n    def __init__(self, data_df, transform):\n        self.data_df = data_df\n        self.transform = transform \n    \n    def __len__(self):\n        return self.data_df.shape[0]\n    \n    def __getitem__(self, idx):\n        try:\n            img = Image.open(self.data_df.iloc[idx]['file_path'])\n            target = self.data_df.iloc[idx]['landmark_id']\n\n            if self.transform is not None:\n                img = self.transform(img)\n\n            return img, target\n        except:\n            pass","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"c = create_dataset(sample_df, transform)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, target = c.__getitem__(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(np.moveaxis(np.asarray(img), 0, -1))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"StratifiedShuffleSplit()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df['train'] = 1\n\nfor train_index, val_index in sss.split(sample_df, sample_df['landmark_id']):\n    sample_df['train'].iloc[val_index] = 0","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_df = sample_df.loc[sample_df['train'] == 0]\ntrain_df = sample_df.loc[sample_df['train'] == 1]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = create_dataset(train_df, transform)\nval_dataset = create_dataset(val_df, transform)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataset.data_df['landmark_id'].nunique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"embedder.parameters","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss = losses.TripletMarginLoss(margin=2.0)\n\n# Set the mining function\nminer = miners.BatchEasyHardMiner()\n\n# Set the dataloader sampler\n# sampler = samplers.MPerClassSampler(train_dataset.targets, m=4, length_before_new_iter=len(train_dataset))\n\n# Set other training parameters\nbatch_size = 64\nnum_epochs = 30\n\n# Package the above stuff into dictionaries.\nmodels = {\"trunk\": trunk, \"embedder\": embedder}\noptimizers = {\"trunk_optimizer\": trunk_optimizer, \"embedder_optimizer\": embedder_optimizer}\nloss_funcs = {\"metric_loss\": loss}\nmining_funcs = {\"tuple_miner\": miner}\n# mining_funcs = {}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"record_keeper, _, _ = logging_presets.get_record_keeper(\"example_logs\", \"example_tensorboard\")\nhooks = logging_presets.get_hook_container(record_keeper)\ndataset_dict = {\"val\": val_dataset}\nmodel_folder = \"example_saved_models\"\n\ntester = testers.GlobalEmbeddingSpaceTester(end_of_testing_hook = hooks.end_of_testing_hook, \n                                            dataloader_num_workers = 32,\n                                            accuracy_calculator=AccuracyCalculator(k=\"max_bin_count\"))\n\n\nend_of_epoch_hook = hooks.end_of_epoch_hook(tester, \n                                            dataset_dict, \n                                            model_folder, \n                                            test_interval = 1,\n                                            patience = 1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = trainers.MetricLossOnly(models,\n                                optimizers,\n                                batch_size,\n                                loss_funcs,\n                                mining_funcs,\n                                train_dataset,\n                                dataloader_num_workers = 32,\n                                end_of_iteration_hook = hooks.end_of_iteration_hook,\n                                end_of_epoch_hook = end_of_epoch_hook)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_df['landmark_id'].nunique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.train(num_epochs=num_epochs)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}