{
  "id": 172737,
  "title": "Landmark2019-1st-and-3rd-Place-Solution",
  "url": "/competitions/landmark-recognition-2020/discussion/172737",
  "author_name": "",
  "post_date": "2020-08-06T09:15:33.163673Z",
  "votes": 10,
  "comment_count": 3,
  "views": 0,
  "content": "<p><img src=\"https://user-images.githubusercontent.com/27487010/69476665-0858c880-0e20-11ea-9fb4-5292f61e9c12.png\" alt=\"\"></p>\n\n<p><a href=\"https://www.kaggle.com/c/landmark-recognition-2019\">https://www.kaggle.com/c/landmark-recognition-2019</a></p>\n\n<p>Published two papers regarding our solution. You can check from:</p>\n\n<ol>\n<li><a href=\"https://arxiv.org/abs/1906.04087\">Large-scale Landmark Retrieval/Recognition under a Noisy and Diverse Dataset</a>\nTech report describing our solution (4-pages)</li>\n<li><a href=\"https://arxiv.org/abs/2003.11211\">Two-stage Discriminative Re-ranking for Large-scale Landmark Retrieval</a>\nExtended version of above tech report, including more detailed explanation and additional experimental results (10-pages, CVPR Workshop 2020)</li>\n</ol>\n\n<h3>Environments</h3>\n\n<p>You can reproduce our environments using Dockerfile provided here <a href=\"https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile\">https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile</a></p>\n\n<h3>Data</h3>\n\n<ul>\n<li>Google Landmark Dataset v1 (GLD-v1): <a href=\"https://www.kaggle.com/google/google-landmarks-dataset\">https://www.kaggle.com/google/google-landmarks-dataset</a></li>\n<li>Google Landmark Dataset v2 (GLD-v2): <a href=\"https://github.com/cvdfoundation/google-landmark\">https://github.com/cvdfoundation/google-landmark</a></li>\n<li>Clean version of the v2 (Newly Released!): <a href=\"https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels\">https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels</a></li>\n</ul>\n\n<h3>Dataset statistics:</h3>\n\n<p>| Dataset (train split) | # Samples |# Labels  |\n| --- | --- | --- | \n| GLD-v1 | 1,225,029 | 14,951 | \n| GLD-v2 | 4,132,914 | 203,094 |\n|  GLD-v2 (clean)| 1,580,470|81,313|</p>\n\nPrepare cleaned subset\n\n<p>(You can skip this procedure to generate a cleaned subset. Pre-computed files are available on <a href=\"https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2\">kaggle dataset.</a>)</p>\n\n<p>Run scripts/prepare_cleaned_subset.sh for cleaning the GLD-v2 dataset. The cleaning code requires DELF library (<a href=\"https://github.com/tensorflow/models/blob/master/research/delf/INSTALL_INSTRUCTIONS.md\">install instructions</a>)</p>\n\n<h3>exp</h3>\n\n<p>Model training and inference are done in exp/ directory.</p>\n\n<p><code>#train models by various parameter settings with 4 gpus (each training is done with 2 gpus).\npython vX.py tuning -d 0,1,2,3 --n-gpu 2</code></p>\n\n<p><code># predict</code>\n<code>python vX.py predict -m vX/epX.pth -d 0'</code></p>\n\n<p><code># predict with multiple gpus</code>\n<code>python vX.py multigpu-predict -m vX/epX.pth --scale L2 --ms -b 32 -d 0,1</code></p>\n\n<h2>Results (retrieval challenge)</h2>\n\n<p>| Place| Team |Private  | Public |\n| --- | --- | --- | \n| 1st | smlyaka |37.23 | 35.69 | \n| 2nd | imagesearch |34.75 | 32.25 | \n|  3rd | Layer 6 AI |32.18 | 29.85 | </p>\n\n<h2>Reference</h2>\n\n<p><a href=\"https://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch\">https://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch</a>\n<a href=\"https://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py\">https://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py</a>\n<a href=\"https://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py\">https://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py</a>\n<a href=\"https://github.com/kevin-ssy/FishNet\">https://github.com/kevin-ssy/FishNet</a>\n<a href=\"https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py\">https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py</a></p>\n\n<h3>UPVOTE if it helps you 👍</h3>",
  "messages": [
    {
      "id": "960257",
      "postDate": "08/06/2020 09:15:33",
      "content": "<p><img src=\"https://user-images.githubusercontent.com/27487010/69476665-0858c880-0e20-11ea-9fb4-5292f61e9c12.png\" alt=\"\"></p>\n\n<p><a href=\"https://www.kaggle.com/c/landmark-recognition-2019\">https://www.kaggle.com/c/landmark-recognition-2019</a></p>\n\n<p>Published two papers regarding our solution. You can check from:</p>\n\n<ol>\n<li><a href=\"https://arxiv.org/abs/1906.04087\">Large-scale Landmark Retrieval/Recognition under a Noisy and Diverse Dataset</a>\nTech report describing our solution (4-pages)</li>\n<li><a href=\"https://arxiv.org/abs/2003.11211\">Two-stage Discriminative Re-ranking for Large-scale Landmark Retrieval</a>\nExtended version of above tech report, including more detailed explanation and additional experimental results (10-pages, CVPR Workshop 2020)</li>\n</ol>\n\n<h3>Environments</h3>\n\n<p>You can reproduce our environments using Dockerfile provided here <a href=\"https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile\">https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile</a></p>\n\n<h3>Data</h3>\n\n<ul>\n<li>Google Landmark Dataset v1 (GLD-v1): <a href=\"https://www.kaggle.com/google/google-landmarks-dataset\">https://www.kaggle.com/google/google-landmarks-dataset</a></li>\n<li>Google Landmark Dataset v2 (GLD-v2): <a href=\"https://github.com/cvdfoundation/google-landmark\">https://github.com/cvdfoundation/google-landmark</a></li>\n<li>Clean version of the v2 (Newly Released!): <a href=\"https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels\">https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels</a></li>\n</ul>\n\n<h3>Dataset statistics:</h3>\n\n<p>| Dataset (train split) | # Samples |# Labels  |\n| --- | --- | --- | \n| GLD-v1 | 1,225,029 | 14,951 | \n| GLD-v2 | 4,132,914 | 203,094 |\n|  GLD-v2 (clean)| 1,580,470|81,313|</p>\n\nPrepare cleaned subset\n\n<p>(You can skip this procedure to generate a cleaned subset. Pre-computed files are available on <a href=\"https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2\">kaggle dataset.</a>)</p>\n\n<p>Run scripts/prepare_cleaned_subset.sh for cleaning the GLD-v2 dataset. The cleaning code requires DELF library (<a href=\"https://github.com/tensorflow/models/blob/master/research/delf/INSTALL_INSTRUCTIONS.md\">install instructions</a>)</p>\n\n<h3>exp</h3>\n\n<p>Model training and inference are done in exp/ directory.</p>\n\n<p><code>#train models by various parameter settings with 4 gpus (each training is done with 2 gpus).\npython vX.py tuning -d 0,1,2,3 --n-gpu 2</code></p>\n\n<p><code># predict</code>\n<code>python vX.py predict -m vX/epX.pth -d 0'</code></p>\n\n<p><code># predict with multiple gpus</code>\n<code>python vX.py multigpu-predict -m vX/epX.pth --scale L2 --ms -b 32 -d 0,1</code></p>\n\n<h2>Results (retrieval challenge)</h2>\n\n<p>| Place| Team |Private  | Public |\n| --- | --- | --- | \n| 1st | smlyaka |37.23 | 35.69 | \n| 2nd | imagesearch |34.75 | 32.25 | \n|  3rd | Layer 6 AI |32.18 | 29.85 | </p>\n\n<h2>Reference</h2>\n\n<p><a href=\"https://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch\">https://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch</a>\n<a href=\"https://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py\">https://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py</a>\n<a href=\"https://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py\">https://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py</a>\n<a href=\"https://github.com/kevin-ssy/FishNet\">https://github.com/kevin-ssy/FishNet</a>\n<a href=\"https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py\">https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py</a></p>\n\n<h3>UPVOTE if it helps you 👍</h3>",
      "rawMarkdown": "![](https://user-images.githubusercontent.com/27487010/69476665-0858c880-0e20-11ea-9fb4-5292f61e9c12.png)\n\n\n\nhttps://www.kaggle.com/c/landmark-recognition-2019\n\nPublished two papers regarding our solution. You can check from:\n\n1. [Large-scale Landmark Retrieval/Recognition under a Noisy and Diverse Dataset](https://arxiv.org/abs/1906.04087)\nTech report describing our solution (4-pages)\n2. [Two-stage Discriminative Re-ranking for Large-scale Landmark Retrieval](https://arxiv.org/abs/2003.11211)\nExtended version of above tech report, including more detailed explanation and additional experimental results (10-pages, CVPR Workshop 2020)\n\n### Environments \n\nYou can reproduce our environments using Dockerfile provided here [https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile](https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile)\n\n### Data\n\n- Google Landmark Dataset v1 (GLD-v1): [https://www.kaggle.com/google/google-landmarks-dataset](https://www.kaggle.com/google/google-landmarks-dataset)\n- Google Landmark Dataset v2 (GLD-v2): [https://github.com/cvdfoundation/google-landmark](https://github.com/cvdfoundation/google-landmark)\n- Clean version of the v2 (Newly Released!): [https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels](https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels)\n\n### Dataset statistics:\n\n| Dataset (train split) | # Samples |# Labels  |\n| --- | --- | --- | \n| GLD-v1 | 1,225,029 | 14,951 | \n| GLD-v2 | 4,132,914 | 203,094 |\n|  GLD-v2 (clean)| 1,580,470|81,313|\n\n#### Prepare cleaned subset\n\n(You can skip this procedure to generate a cleaned subset. Pre-computed files are available on [kaggle dataset.](https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2))\n\nRun scripts/prepare_cleaned_subset.sh for cleaning the GLD-v2 dataset. The cleaning code requires DELF library ([install instructions](https://github.com/tensorflow/models/blob/master/research/delf/INSTALL_INSTRUCTIONS.md))\n\n### exp\n\nModel training and inference are done in exp/ directory.\n\n` #train models by various parameter settings with 4 gpus (each training is done with 2 gpus).\npython vX.py tuning -d 0,1,2,3 --n-gpu 2 `\n\n`# predict`\n`python vX.py predict -m vX/epX.pth -d 0'`\n\n`# predict with multiple gpus`\n`python vX.py multigpu-predict -m vX/epX.pth --scale L2 --ms -b 32 -d 0,1`\n\n## Results (retrieval challenge)\n\n| Place| Team |Private  | Public |\n| --- | --- | --- | \n| 1st | smlyaka |37.23 | 35.69 | \n| 2nd | imagesearch |34.75 | 32.25 | \n|  3rd | Layer 6 AI |32.18 | 29.85 | \n\n## Reference\n\nhttps://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch\nhttps://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py\nhttps://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py\nhttps://github.com/kevin-ssy/FishNet\nhttps://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py\n\n\n### UPVOTE if it helps you 👍",
      "votes": null
    },
    {
      "id": "960258",
      "postDate": "08/06/2020 09:17:14",
      "content": "<blockquote>\n  <h1>8th place solution</h1>\n  \n  <h1>Summary</h1>\n  \n  <ul>\n  <li><strong>Training set</strong>: Sub-set of 2018 Google Landmark Recognition</li>\n  <li><strong>Descriptor</strong>: Ensemble of DenseNet121-GeM-512FC (512x512, ArcFace) and ResNet101-GeM-2048FC (768x~, ContrastiveLoss)</li>\n  <li><strong>Landmark classifier</strong>: ResNet50 with T-scalling trained on OpenImages and Places. Remove images with less than 0.99 probability from train-set (4M-&gt;2.6M)</li>\n  <li><strong>Inference</strong>: Extract features for train and test set and compute the cosine similarity matrix between test and class centers. Then, apply K-NN to retrieve the 12 nearest neighbours and apply softmax on them.</li>\n  <li><strong>Re-rank 1</strong>: Multiply confidence score from inference by classification's score on test.</li>\n  <li><strong>Re-rank 2</strong>: Perform K-NN search (K=1750) of test set on itself and apply softmax. Multiply last score by this one.</li>\n  </ul>\n  \n  <h1>Long version</h1>\n  \n  <p>I believe two issues must be addressed to tackle this competition. The first is a similarity search problem, where we want to create a good descriptor that would allow us to correctly classify an image based on a K-NN search in a gallery (trainset).\n  The second part is a detection/re-rank of non-landmarks in both train (gallery) and test (query) sets. This is paramount since the GAP metric used in this competition penalize us if we make a prediction for a non-landmark with higher confidence score than any other landmark images.</p>\n  \n  <h2>Similarity search</h2>\n  \n  <h3>Descriptor</h3>\n  \n  <p>I reckon a metric learning approach is much more natural to this task than a pure classification one. This is because we have a huge number of classes (&gt; 200k) and some of them have just a few examples. Furthermore, in practice we would not be able to re-train our classifier every time we need to add a new landmark to the gallery.</p>\n  \n  <p>With this mindeset, I spent most of the time (until the last 2 weeks) training several models with ArcFace loss. I tried several types of pooling schemes such as SPoC, GeM and REMAP (my own re-implementation). Also tried several types of backbones like DenseNet121, ResNet101 and SEResNeXt101.</p>\n  \n  <p>The ones that worked best for me were DenseNet121-GeM-512FC (512x512) and SEResNeXt101-REMAP-2048FC (384x384). However, SEResNeXt101-REMAP was really slow so I only used DenseNet for the second stage.</p>\n  \n  <p>I trained on a sub-set of last years' competition, it was around 80k images of 15k classes. A margin of 0.8 for <a href=\"https://arxiv.org/abs/1801.07698\">ArcFace</a> loss was used and images were resized to the specified size. Weird as it may sound, I found it was better to squash it into a square than keeping the original aspect ratio with zero padding.</p>\n  \n  <p>I (unfortunately) spent most of my time here and the result were not so great. My best model only score around 0.33 on the image <strong>retrieval</strong> public LB (no QE, DBA or any re-rank). At this time I decided to give up ArcFace and go for the siamese approach.</p>\n  \n  <p>In the last weeks I trained a ResNet101-GeM-2048FC (768x~) following Radenovic's <a href=\"https://arxiv.org/abs/1711.02512\">paper</a> and despite I didn't submit to the retrieval competition (deadline was near) I believe it was considerably better than the other models I had trained so far.</p>\n  \n  <p>My final descriptor was an 2560-dim. ensemble of both models. I L2-normalized both and concatenated as follows: [1.5 * ResNet, 1 * DenseNet]. I didn't have enough time nor RAM to apply PCA on the resultant descriptor.</p>\n  \n  <h3>Landmark classifier</h3>\n  \n  <p>Since there were a lot of non-landmark images both in test and train sets I trained a landmark classifier using the descriptor's train set as landmark examples. For the non-landmarks, I used images from OpenImages and Places datasets. I used classes such as: sky, forest, bathroom, bedroom, restaurant, Human faces, food, etc...\n  It was important to use outdoor classes as negative examples, otherwise the model would be biased to predict any outdoor image as landmark. Finally, I used <a href=\"https://arxiv.org/pdf/1706.04599.pdf\">T-scalling</a> to scale the predictions.</p>\n  \n  <p>For the train set I removed all the images with classification score less than 0.99, which resulted in around 2.6M images.</p>\n  \n  <p>For test set, on the other hand, I did not remove any images but used the scores to re-rank the final submission's confidence scores. I did this because, if the conf. score is well ranked, there is no penalty for making predictions on non-landmark images.</p>\n  \n  <h3>Out-of-distribution images</h3>\n  \n  <p>Since the descriptor was only training on landmark images it is very bad in differentiating between images that are non-landmarks, e.g. human faces or types of food. As consequence of this fact, non-landmark images are matched with very high confidence scores, decreasing the GAP metric. In order to overcome this issue, three re-rank steps were used (will be explained later).</p>\n  \n  <h3>Extract features</h3>\n  \n  <p>The CNNs previously mentioned are used to extract features (descriptors) for both train and test sets. Then for the train set, the class centers are computed by averaging all the image descriptors that belong to the same class. Finally, both test and class centers descriptors are L2 normalized.</p>\n  \n  <h3>Search</h3>\n  \n  <p>The K-NN search was performed on the cosine distance matrix using <a href=\"https://github.com/facebookresearch/faiss\">Faiss</a> library. The top 12 NN were kept and softmax was applied on them.</p>\n  \n  <p>Even though we only need the first nearest neighbour, it was important to keep more of them to apply softmax and convert the cos. similarities into a probability distribution. By doing this we filter out some non-landmarks that have high similarity with a lot of classes in the gallery (train set). Without this or any other re-ranking steps, the score is likely to be close to zero even for a good descriptor.</p>\n  \n  <h3>Re-rank:</h3>\n  \n  <p>The second re-rank was very straightforward. The original confidence score was multiplied by the probability of being a landmark from the classifier. With this step many non-landmark images got their conf. score reduced.</p>\n  \n  <h3>Re-rank based on out-of-distribution similarity</h3>\n  \n  <p>For this step, the K-NN (K=1750) of the test set with itself was computed. The intuition here is that since our model is known to produce high similarity between out-of-distribution images, if we compute the similarity between the test set it is likely that non-landmark images will have much more similar neighbours than landmark ones. Thus, I apply the softmax and multiply by the confidence score from the last step.</p>\n  \n  <p>Hence, the final score is given by: <code>score = metric_learning_score * classifier_score * ood_score</code></p>\n  \n  <h1>Leaderboard progression (stage 2)</h1>\n  \n  <ul>\n  <li><strong>DenseNet121-GeM-512FC (cls re-rank)</strong>: 0.22379</li>\n  <li><strong>DenseNet121-GeM-512FC (cls and ood re-rank)</strong>: 0.23862</li>\n  <li><strong>ResNet101-GeM-2048FC (cls and ood re-rank</strong>): 0.26994</li>\n  <li><p><strong>Ensemble (cls and ood re-rank)</strong>: 0.28792</p>\n  \n  <h1>Resources</h1></li>\n  <li><p><strong>GPU</strong>: 1x Nvidia 1080ti (11GB)</p></li>\n  <li><strong>RAM</strong>: 32GB</li>\n  <li><strong>HD</strong>: 1TB SSD</li>\n  <li><strong>Processor</strong>: Intel i7 6800k</li>\n  </ul>\n  \n  <h1>Acknowledgments</h1>\n  \n  <p>Thanks Kaggle and Google for hosting this competition. Thanks as well to all the community and <a href=\"/filipradenovic\">@filipradenovic</a>  for opening his 2018 Google-Landmark-Retrieval solution.</p>\n</blockquote>",
      "rawMarkdown": "&gt; #8th place solution\n&gt; \n&gt; # Summary\n&gt; * **Training set**: Sub-set of 2018 Google Landmark Recognition\n&gt; * **Descriptor**: Ensemble of DenseNet121-GeM-512FC (512x512, ArcFace) and ResNet101-GeM-2048FC (768x~, ContrastiveLoss)\n&gt; * **Landmark classifier**: ResNet50 with T-scalling trained on OpenImages and Places. Remove images with less than 0.99 probability from train-set (4M-&gt;2.6M)\n&gt; * **Inference**: Extract features for train and test set and compute the cosine similarity matrix between test and class centers. Then, apply K-NN to retrieve the 12 nearest neighbours and apply softmax on them.\n&gt; * **Re-rank 1**: Multiply confidence score from inference by classification's score on test.\n&gt; * **Re-rank 2**: Perform K-NN search (K=1750) of test set on itself and apply softmax. Multiply last score by this one.\n&gt; \n&gt; # Long version\n&gt; I believe two issues must be addressed to tackle this competition. The first is a similarity search problem, where we want to create a good descriptor that would allow us to correctly classify an image based on a K-NN search in a gallery (trainset).\n&gt; The second part is a detection/re-rank of non-landmarks in both train (gallery) and test (query) sets. This is paramount since the GAP metric used in this competition penalize us if we make a prediction for a non-landmark with higher confidence score than any other landmark images.\n&gt; \n&gt; ## Similarity search\n&gt; ### Descriptor\n&gt; I reckon a metric learning approach is much more natural to this task than a pure classification one. This is because we have a huge number of classes (&gt; 200k) and some of them have just a few examples. Furthermore, in practice we would not be able to re-train our classifier every time we need to add a new landmark to the gallery.\n&gt; \n&gt; With this mindeset, I spent most of the time (until the last 2 weeks) training several models with ArcFace loss. I tried several types of pooling schemes such as SPoC, GeM and REMAP (my own re-implementation). Also tried several types of backbones like DenseNet121, ResNet101 and SEResNeXt101.\n&gt; \n&gt; The ones that worked best for me were DenseNet121-GeM-512FC (512x512) and SEResNeXt101-REMAP-2048FC (384x384). However, SEResNeXt101-REMAP was really slow so I only used DenseNet for the second stage.\n&gt; \n&gt; I trained on a sub-set of last years' competition, it was around 80k images of 15k classes. A margin of 0.8 for [ArcFace](https://arxiv.org/abs/1801.07698) loss was used and images were resized to the specified size. Weird as it may sound, I found it was better to squash it into a square than keeping the original aspect ratio with zero padding.\n&gt; \n&gt; I (unfortunately) spent most of my time here and the result were not so great. My best model only score around 0.33 on the image **retrieval** public LB (no QE, DBA or any re-rank). At this time I decided to give up ArcFace and go for the siamese approach.\n&gt; \n&gt; In the last weeks I trained a ResNet101-GeM-2048FC (768x~) following Radenovic's [paper](https://arxiv.org/abs/1711.02512) and despite I didn't submit to the retrieval competition (deadline was near) I believe it was considerably better than the other models I had trained so far.\n&gt; \n&gt; My final descriptor was an 2560-dim. ensemble of both models. I L2-normalized both and concatenated as follows: [1.5 * ResNet, 1 * DenseNet]. I didn't have enough time nor RAM to apply PCA on the resultant descriptor.\n&gt; \n&gt; ### Landmark classifier\n&gt; Since there were a lot of non-landmark images both in test and train sets I trained a landmark classifier using the descriptor's train set as landmark examples. For the non-landmarks, I used images from OpenImages and Places datasets. I used classes such as: sky, forest, bathroom, bedroom, restaurant, Human faces, food, etc...\n&gt; It was important to use outdoor classes as negative examples, otherwise the model would be biased to predict any outdoor image as landmark. Finally, I used [T-scalling](https://arxiv.org/pdf/1706.04599.pdf) to scale the predictions.\n&gt; \n&gt; For the train set I removed all the images with classification score less than 0.99, which resulted in around 2.6M images.\n&gt; \n&gt; For test set, on the other hand, I did not remove any images but used the scores to re-rank the final submission's confidence scores. I did this because, if the conf. score is well ranked, there is no penalty for making predictions on non-landmark images.\n&gt; \n&gt; ### Out-of-distribution images\n&gt; Since the descriptor was only training on landmark images it is very bad in differentiating between images that are non-landmarks, e.g. human faces or types of food. As consequence of this fact, non-landmark images are matched with very high confidence scores, decreasing the GAP metric. In order to overcome this issue, three re-rank steps were used (will be explained later).\n&gt; \n&gt; ### Extract features\n&gt; The CNNs previously mentioned are used to extract features (descriptors) for both train and test sets. Then for the train set, the class centers are computed by averaging all the image descriptors that belong to the same class. Finally, both test and class centers descriptors are L2 normalized.\n&gt; \n&gt; ### Search\n&gt; The K-NN search was performed on the cosine distance matrix using [Faiss](https://github.com/facebookresearch/faiss) library. The top 12 NN were kept and softmax was applied on them.\n&gt; \n&gt; Even though we only need the first nearest neighbour, it was important to keep more of them to apply softmax and convert the cos. similarities into a probability distribution. By doing this we filter out some non-landmarks that have high similarity with a lot of classes in the gallery (train set). Without this or any other re-ranking steps, the score is likely to be close to zero even for a good descriptor.\n&gt; \n&gt; ### Re-rank:\n&gt; The second re-rank was very straightforward. The original confidence score was multiplied by the probability of being a landmark from the classifier. With this step many non-landmark images got their conf. score reduced.\n&gt; \n&gt; ### Re-rank based on out-of-distribution similarity\n&gt; For this step, the K-NN (K=1750) of the test set with itself was computed. The intuition here is that since our model is known to produce high similarity between out-of-distribution images, if we compute the similarity between the test set it is likely that non-landmark images will have much more similar neighbours than landmark ones. Thus, I apply the softmax and multiply by the confidence score from the last step.\n&gt; \n&gt; Hence, the final score is given by: `score = metric_learning_score * classifier_score * ood_score`\n&gt; \n&gt; # Leaderboard progression (stage 2)\n&gt; * **DenseNet121-GeM-512FC (cls re-rank)**: 0.22379\n&gt; * **DenseNet121-GeM-512FC (cls and ood re-rank)**: 0.23862\n&gt; * **ResNet101-GeM-2048FC (cls and ood re-rank**): 0.26994\n&gt; * **Ensemble (cls and ood re-rank)**: 0.28792\n&gt; # Resources\n&gt; * **GPU**: 1x Nvidia 1080ti (11GB)\n&gt; * **RAM**: 32GB\n&gt; * **HD**: 1TB SSD\n&gt; * **Processor**: Intel i7 6800k\n&gt; \n&gt; #Acknowledgments\n&gt; Thanks Kaggle and Google for hosting this competition. Thanks as well to all the community and @filipradenovic  for opening his 2018 Google-Landmark-Retrieval solution.",
      "votes": null
    },
    {
      "id": "960261",
      "postDate": "08/06/2020 09:18:56",
      "content": "<h1>2nd Place solution to Kaggle Landmark Recognition and Retrieval Competition 2019</h1>\n\n<blockquote>\n  <p>arxiv link: <a href=\"https://arxiv.org/pdf/1906.03990.pdf\">https://arxiv.org/pdf/1906.03990.pdf</a>\n  source code: <a href=\"https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark\">https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark</a></p>\n</blockquote>",
      "rawMarkdown": "# 2nd Place solution to Kaggle Landmark Recognition and Retrieval Competition 2019\n\n&gt; arxiv link: https://arxiv.org/pdf/1906.03990.pdf\n&gt; source code: https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark",
      "votes": null
    },
    {
      "id": "965640",
      "postDate": "08/10/2020 18:31:12",
      "content": "<p>Thanks for sharing <a href=\"/arachauhan\">@arachauhan</a>. However, instead of copy-pasting from the source, you could have linked the original repo: <a href=\"https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution\">https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution</a>. \nDoing so will get you more upvotes next time!</p>",
      "rawMarkdown": "Thanks for sharing @arachauhan. However, instead of copy-pasting from the source, you could have linked the original repo: https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution. \nDoing so will get you more upvotes next time!",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 960258,
      "author_name": "arachauhan",
      "author_url": "",
      "post_date": "08/06/2020 09:17:14",
      "content": "<blockquote>\n  <h1>8th place solution</h1>\n  \n  <h1>Summary</h1>\n  \n  <ul>\n  <li><strong>Training set</strong>: Sub-set of 2018 Google Landmark Recognition</li>\n  <li><strong>Descriptor</strong>: Ensemble of DenseNet121-GeM-512FC (512x512, ArcFace) and ResNet101-GeM-2048FC (768x~, ContrastiveLoss)</li>\n  <li><strong>Landmark classifier</strong>: ResNet50 with T-scalling trained on OpenImages and Places. Remove images with less than 0.99 probability from train-set (4M-&gt;2.6M)</li>\n  <li><strong>Inference</strong>: Extract features for train and test set and compute the cosine similarity matrix between test and class centers. Then, apply K-NN to retrieve the 12 nearest neighbours and apply softmax on them.</li>\n  <li><strong>Re-rank 1</strong>: Multiply confidence score from inference by classification's score on test.</li>\n  <li><strong>Re-rank 2</strong>: Perform K-NN search (K=1750) of test set on itself and apply softmax. Multiply last score by this one.</li>\n  </ul>\n  \n  <h1>Long version</h1>\n  \n  <p>I believe two issues must be addressed to tackle this competition. The first is a similarity search problem, where we want to create a good descriptor that would allow us to correctly classify an image based on a K-NN search in a gallery (trainset).\n  The second part is a detection/re-rank of non-landmarks in both train (gallery) and test (query) sets. This is paramount since the GAP metric used in this competition penalize us if we make a prediction for a non-landmark with higher confidence score than any other landmark images.</p>\n  \n  <h2>Similarity search</h2>\n  \n  <h3>Descriptor</h3>\n  \n  <p>I reckon a metric learning approach is much more natural to this task than a pure classification one. This is because we have a huge number of classes (&gt; 200k) and some of them have just a few examples. Furthermore, in practice we would not be able to re-train our classifier every time we need to add a new landmark to the gallery.</p>\n  \n  <p>With this mindeset, I spent most of the time (until the last 2 weeks) training several models with ArcFace loss. I tried several types of pooling schemes such as SPoC, GeM and REMAP (my own re-implementation). Also tried several types of backbones like DenseNet121, ResNet101 and SEResNeXt101.</p>\n  \n  <p>The ones that worked best for me were DenseNet121-GeM-512FC (512x512) and SEResNeXt101-REMAP-2048FC (384x384). However, SEResNeXt101-REMAP was really slow so I only used DenseNet for the second stage.</p>\n  \n  <p>I trained on a sub-set of last years' competition, it was around 80k images of 15k classes. A margin of 0.8 for <a href=\"https://arxiv.org/abs/1801.07698\">ArcFace</a> loss was used and images were resized to the specified size. Weird as it may sound, I found it was better to squash it into a square than keeping the original aspect ratio with zero padding.</p>\n  \n  <p>I (unfortunately) spent most of my time here and the result were not so great. My best model only score around 0.33 on the image <strong>retrieval</strong> public LB (no QE, DBA or any re-rank). At this time I decided to give up ArcFace and go for the siamese approach.</p>\n  \n  <p>In the last weeks I trained a ResNet101-GeM-2048FC (768x~) following Radenovic's <a href=\"https://arxiv.org/abs/1711.02512\">paper</a> and despite I didn't submit to the retrieval competition (deadline was near) I believe it was considerably better than the other models I had trained so far.</p>\n  \n  <p>My final descriptor was an 2560-dim. ensemble of both models. I L2-normalized both and concatenated as follows: [1.5 * ResNet, 1 * DenseNet]. I didn't have enough time nor RAM to apply PCA on the resultant descriptor.</p>\n  \n  <h3>Landmark classifier</h3>\n  \n  <p>Since there were a lot of non-landmark images both in test and train sets I trained a landmark classifier using the descriptor's train set as landmark examples. For the non-landmarks, I used images from OpenImages and Places datasets. I used classes such as: sky, forest, bathroom, bedroom, restaurant, Human faces, food, etc...\n  It was important to use outdoor classes as negative examples, otherwise the model would be biased to predict any outdoor image as landmark. Finally, I used <a href=\"https://arxiv.org/pdf/1706.04599.pdf\">T-scalling</a> to scale the predictions.</p>\n  \n  <p>For the train set I removed all the images with classification score less than 0.99, which resulted in around 2.6M images.</p>\n  \n  <p>For test set, on the other hand, I did not remove any images but used the scores to re-rank the final submission's confidence scores. I did this because, if the conf. score is well ranked, there is no penalty for making predictions on non-landmark images.</p>\n  \n  <h3>Out-of-distribution images</h3>\n  \n  <p>Since the descriptor was only training on landmark images it is very bad in differentiating between images that are non-landmarks, e.g. human faces or types of food. As consequence of this fact, non-landmark images are matched with very high confidence scores, decreasing the GAP metric. In order to overcome this issue, three re-rank steps were used (will be explained later).</p>\n  \n  <h3>Extract features</h3>\n  \n  <p>The CNNs previously mentioned are used to extract features (descriptors) for both train and test sets. Then for the train set, the class centers are computed by averaging all the image descriptors that belong to the same class. Finally, both test and class centers descriptors are L2 normalized.</p>\n  \n  <h3>Search</h3>\n  \n  <p>The K-NN search was performed on the cosine distance matrix using <a href=\"https://github.com/facebookresearch/faiss\">Faiss</a> library. The top 12 NN were kept and softmax was applied on them.</p>\n  \n  <p>Even though we only need the first nearest neighbour, it was important to keep more of them to apply softmax and convert the cos. similarities into a probability distribution. By doing this we filter out some non-landmarks that have high similarity with a lot of classes in the gallery (train set). Without this or any other re-ranking steps, the score is likely to be close to zero even for a good descriptor.</p>\n  \n  <h3>Re-rank:</h3>\n  \n  <p>The second re-rank was very straightforward. The original confidence score was multiplied by the probability of being a landmark from the classifier. With this step many non-landmark images got their conf. score reduced.</p>\n  \n  <h3>Re-rank based on out-of-distribution similarity</h3>\n  \n  <p>For this step, the K-NN (K=1750) of the test set with itself was computed. The intuition here is that since our model is known to produce high similarity between out-of-distribution images, if we compute the similarity between the test set it is likely that non-landmark images will have much more similar neighbours than landmark ones. Thus, I apply the softmax and multiply by the confidence score from the last step.</p>\n  \n  <p>Hence, the final score is given by: <code>score = metric_learning_score * classifier_score * ood_score</code></p>\n  \n  <h1>Leaderboard progression (stage 2)</h1>\n  \n  <ul>\n  <li><strong>DenseNet121-GeM-512FC (cls re-rank)</strong>: 0.22379</li>\n  <li><strong>DenseNet121-GeM-512FC (cls and ood re-rank)</strong>: 0.23862</li>\n  <li><strong>ResNet101-GeM-2048FC (cls and ood re-rank</strong>): 0.26994</li>\n  <li><p><strong>Ensemble (cls and ood re-rank)</strong>: 0.28792</p>\n  \n  <h1>Resources</h1></li>\n  <li><p><strong>GPU</strong>: 1x Nvidia 1080ti (11GB)</p></li>\n  <li><strong>RAM</strong>: 32GB</li>\n  <li><strong>HD</strong>: 1TB SSD</li>\n  <li><strong>Processor</strong>: Intel i7 6800k</li>\n  </ul>\n  \n  <h1>Acknowledgments</h1>\n  \n  <p>Thanks Kaggle and Google for hosting this competition. Thanks as well to all the community and <a href=\"/filipradenovic\">@filipradenovic</a>  for opening his 2018 Google-Landmark-Retrieval solution.</p>\n</blockquote>",
      "votes": null,
      "replies": []
    },
    {
      "id": 960261,
      "author_name": "arachauhan",
      "author_url": "",
      "post_date": "08/06/2020 09:18:56",
      "content": "<h1>2nd Place solution to Kaggle Landmark Recognition and Retrieval Competition 2019</h1>\n\n<blockquote>\n  <p>arxiv link: <a href=\"https://arxiv.org/pdf/1906.03990.pdf\">https://arxiv.org/pdf/1906.03990.pdf</a>\n  source code: <a href=\"https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark\">https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark</a></p>\n</blockquote>",
      "votes": null,
      "replies": []
    },
    {
      "id": 965640,
      "author_name": "yassinealouini",
      "author_url": "",
      "post_date": "08/10/2020 18:31:12",
      "content": "<p>Thanks for sharing <a href=\"/arachauhan\">@arachauhan</a>. However, instead of copy-pasting from the source, you could have linked the original repo: <a href=\"https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution\">https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution</a>. \nDoing so will get you more upvotes next time!</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "960257": "![](https://user-images.githubusercontent.com/27487010/69476665-0858c880-0e20-11ea-9fb4-5292f61e9c12.png)\n\n\n\nhttps://www.kaggle.com/c/landmark-recognition-2019\n\nPublished two papers regarding our solution. You can check from:\n\n1. [Large-scale Landmark Retrieval/Recognition under a Noisy and Diverse Dataset](https://arxiv.org/abs/1906.04087)\nTech report describing our solution (4-pages)\n2. [Two-stage Discriminative Re-ranking for Large-scale Landmark Retrieval](https://arxiv.org/abs/2003.11211)\nExtended version of above tech report, including more detailed explanation and additional experimental results (10-pages, CVPR Workshop 2020)\n\n### Environments \n\nYou can reproduce our environments using Dockerfile provided here [https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile](https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution/blob/master/docker/Dockerfile)\n\n### Data\n\n- Google Landmark Dataset v1 (GLD-v1): [https://www.kaggle.com/google/google-landmarks-dataset](https://www.kaggle.com/google/google-landmarks-dataset)\n- Google Landmark Dataset v2 (GLD-v2): [https://github.com/cvdfoundation/google-landmark](https://github.com/cvdfoundation/google-landmark)\n- Clean version of the v2 (Newly Released!): [https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels](https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2/kernels)\n\n### Dataset statistics:\n\n| Dataset (train split) | # Samples |# Labels  |\n| --- | --- | --- | \n| GLD-v1 | 1,225,029 | 14,951 | \n| GLD-v2 | 4,132,914 | 203,094 |\n|  GLD-v2 (clean)| 1,580,470|81,313|\n\n#### Prepare cleaned subset\n\n(You can skip this procedure to generate a cleaned subset. Pre-computed files are available on [kaggle dataset.](https://www.kaggle.com/confirm/cleaned-subsets-of-google-landmarks-v2))\n\nRun scripts/prepare_cleaned_subset.sh for cleaning the GLD-v2 dataset. The cleaning code requires DELF library ([install instructions](https://github.com/tensorflow/models/blob/master/research/delf/INSTALL_INSTRUCTIONS.md))\n\n### exp\n\nModel training and inference are done in exp/ directory.\n\n` #train models by various parameter settings with 4 gpus (each training is done with 2 gpus).\npython vX.py tuning -d 0,1,2,3 --n-gpu 2 `\n\n`# predict`\n`python vX.py predict -m vX/epX.pth -d 0'`\n\n`# predict with multiple gpus`\n`python vX.py multigpu-predict -m vX/epX.pth --scale L2 --ms -b 32 -d 0,1`\n\n## Results (retrieval challenge)\n\n| Place| Team |Private  | Public |\n| --- | --- | --- | \n| 1st | smlyaka |37.23 | 35.69 | \n| 2nd | imagesearch |34.75 | 32.25 | \n|  3rd | Layer 6 AI |32.18 | 29.85 | \n\n## Reference\n\nhttps://github.com/filipradenovic/cnnimageretrieval-pytorch/tree/master/cirtorch\nhttps://github.com/ronghuaiyang/arcface-pytorch/blob/master/models/metrics.py\nhttps://github.com/4uiiurz1/pytorch-adacos/blob/master/metrics.py\nhttps://github.com/kevin-ssy/FishNet\nhttps://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/data/samplers/grouped_batch_sampler.py\n\n\n### UPVOTE if it helps you 👍",
    "960258": "&gt; #8th place solution\n&gt; \n&gt; # Summary\n&gt; * **Training set**: Sub-set of 2018 Google Landmark Recognition\n&gt; * **Descriptor**: Ensemble of DenseNet121-GeM-512FC (512x512, ArcFace) and ResNet101-GeM-2048FC (768x~, ContrastiveLoss)\n&gt; * **Landmark classifier**: ResNet50 with T-scalling trained on OpenImages and Places. Remove images with less than 0.99 probability from train-set (4M-&gt;2.6M)\n&gt; * **Inference**: Extract features for train and test set and compute the cosine similarity matrix between test and class centers. Then, apply K-NN to retrieve the 12 nearest neighbours and apply softmax on them.\n&gt; * **Re-rank 1**: Multiply confidence score from inference by classification's score on test.\n&gt; * **Re-rank 2**: Perform K-NN search (K=1750) of test set on itself and apply softmax. Multiply last score by this one.\n&gt; \n&gt; # Long version\n&gt; I believe two issues must be addressed to tackle this competition. The first is a similarity search problem, where we want to create a good descriptor that would allow us to correctly classify an image based on a K-NN search in a gallery (trainset).\n&gt; The second part is a detection/re-rank of non-landmarks in both train (gallery) and test (query) sets. This is paramount since the GAP metric used in this competition penalize us if we make a prediction for a non-landmark with higher confidence score than any other landmark images.\n&gt; \n&gt; ## Similarity search\n&gt; ### Descriptor\n&gt; I reckon a metric learning approach is much more natural to this task than a pure classification one. This is because we have a huge number of classes (&gt; 200k) and some of them have just a few examples. Furthermore, in practice we would not be able to re-train our classifier every time we need to add a new landmark to the gallery.\n&gt; \n&gt; With this mindeset, I spent most of the time (until the last 2 weeks) training several models with ArcFace loss. I tried several types of pooling schemes such as SPoC, GeM and REMAP (my own re-implementation). Also tried several types of backbones like DenseNet121, ResNet101 and SEResNeXt101.\n&gt; \n&gt; The ones that worked best for me were DenseNet121-GeM-512FC (512x512) and SEResNeXt101-REMAP-2048FC (384x384). However, SEResNeXt101-REMAP was really slow so I only used DenseNet for the second stage.\n&gt; \n&gt; I trained on a sub-set of last years' competition, it was around 80k images of 15k classes. A margin of 0.8 for [ArcFace](https://arxiv.org/abs/1801.07698) loss was used and images were resized to the specified size. Weird as it may sound, I found it was better to squash it into a square than keeping the original aspect ratio with zero padding.\n&gt; \n&gt; I (unfortunately) spent most of my time here and the result were not so great. My best model only score around 0.33 on the image **retrieval** public LB (no QE, DBA or any re-rank). At this time I decided to give up ArcFace and go for the siamese approach.\n&gt; \n&gt; In the last weeks I trained a ResNet101-GeM-2048FC (768x~) following Radenovic's [paper](https://arxiv.org/abs/1711.02512) and despite I didn't submit to the retrieval competition (deadline was near) I believe it was considerably better than the other models I had trained so far.\n&gt; \n&gt; My final descriptor was an 2560-dim. ensemble of both models. I L2-normalized both and concatenated as follows: [1.5 * ResNet, 1 * DenseNet]. I didn't have enough time nor RAM to apply PCA on the resultant descriptor.\n&gt; \n&gt; ### Landmark classifier\n&gt; Since there were a lot of non-landmark images both in test and train sets I trained a landmark classifier using the descriptor's train set as landmark examples. For the non-landmarks, I used images from OpenImages and Places datasets. I used classes such as: sky, forest, bathroom, bedroom, restaurant, Human faces, food, etc...\n&gt; It was important to use outdoor classes as negative examples, otherwise the model would be biased to predict any outdoor image as landmark. Finally, I used [T-scalling](https://arxiv.org/pdf/1706.04599.pdf) to scale the predictions.\n&gt; \n&gt; For the train set I removed all the images with classification score less than 0.99, which resulted in around 2.6M images.\n&gt; \n&gt; For test set, on the other hand, I did not remove any images but used the scores to re-rank the final submission's confidence scores. I did this because, if the conf. score is well ranked, there is no penalty for making predictions on non-landmark images.\n&gt; \n&gt; ### Out-of-distribution images\n&gt; Since the descriptor was only training on landmark images it is very bad in differentiating between images that are non-landmarks, e.g. human faces or types of food. As consequence of this fact, non-landmark images are matched with very high confidence scores, decreasing the GAP metric. In order to overcome this issue, three re-rank steps were used (will be explained later).\n&gt; \n&gt; ### Extract features\n&gt; The CNNs previously mentioned are used to extract features (descriptors) for both train and test sets. Then for the train set, the class centers are computed by averaging all the image descriptors that belong to the same class. Finally, both test and class centers descriptors are L2 normalized.\n&gt; \n&gt; ### Search\n&gt; The K-NN search was performed on the cosine distance matrix using [Faiss](https://github.com/facebookresearch/faiss) library. The top 12 NN were kept and softmax was applied on them.\n&gt; \n&gt; Even though we only need the first nearest neighbour, it was important to keep more of them to apply softmax and convert the cos. similarities into a probability distribution. By doing this we filter out some non-landmarks that have high similarity with a lot of classes in the gallery (train set). Without this or any other re-ranking steps, the score is likely to be close to zero even for a good descriptor.\n&gt; \n&gt; ### Re-rank:\n&gt; The second re-rank was very straightforward. The original confidence score was multiplied by the probability of being a landmark from the classifier. With this step many non-landmark images got their conf. score reduced.\n&gt; \n&gt; ### Re-rank based on out-of-distribution similarity\n&gt; For this step, the K-NN (K=1750) of the test set with itself was computed. The intuition here is that since our model is known to produce high similarity between out-of-distribution images, if we compute the similarity between the test set it is likely that non-landmark images will have much more similar neighbours than landmark ones. Thus, I apply the softmax and multiply by the confidence score from the last step.\n&gt; \n&gt; Hence, the final score is given by: `score = metric_learning_score * classifier_score * ood_score`\n&gt; \n&gt; # Leaderboard progression (stage 2)\n&gt; * **DenseNet121-GeM-512FC (cls re-rank)**: 0.22379\n&gt; * **DenseNet121-GeM-512FC (cls and ood re-rank)**: 0.23862\n&gt; * **ResNet101-GeM-2048FC (cls and ood re-rank**): 0.26994\n&gt; * **Ensemble (cls and ood re-rank)**: 0.28792\n&gt; # Resources\n&gt; * **GPU**: 1x Nvidia 1080ti (11GB)\n&gt; * **RAM**: 32GB\n&gt; * **HD**: 1TB SSD\n&gt; * **Processor**: Intel i7 6800k\n&gt; \n&gt; #Acknowledgments\n&gt; Thanks Kaggle and Google for hosting this competition. Thanks as well to all the community and @filipradenovic  for opening his 2018 Google-Landmark-Retrieval solution.",
    "960261": "# 2nd Place solution to Kaggle Landmark Recognition and Retrieval Competition 2019\n\n&gt; arxiv link: https://arxiv.org/pdf/1906.03990.pdf\n&gt; source code: https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/Research/landmark",
    "965640": "Thanks for sharing @arachauhan. However, instead of copy-pasting from the source, you could have linked the original repo: https://github.com/lyakaap/Landmark2019-1st-and-3rd-Place-Solution. \nDoing so will get you more upvotes next time!"
  },
  "source": "meta"
}