{
  "id": 248253,
  "title": "1st solution: Matching the <MASK>: Context Similarity via Deep Metric Learning and Beyond",
  "url": "/competitions/coleridgeinitiative-show-us-the-data/discussion/248253",
  "author_name": "",
  "post_date": "2021-06-23T00:59:44.599741100Z",
  "votes": 80,
  "comment_count": 22,
  "views": 0,
  "content": "<p>Thanks Kaggle for this exciting competition and our team (@suicaokhoailang). Congrats to me to become Kaggle Master and <a href=\"https://www.kaggle.com/suicaokhoailang\" target=\"_blank\">@suicaokhoailang</a> to become Kaggle GM. Congratulate all winners -- we have learned a lot from this competition and all winners’ solutions !!. </p>\n<p><img src=\"https://i.imgur.com/9nuyRxE.png\" alt=\"\"></p>\n<p>Here Is a summary of my solution:</p>\n<ul>\n<li>A shared Bert model for extract Context Embedding and Sequence Tokens Embedding.</li>\n<li>An ArcFace Loss for training Mask/NoMask Embedding.</li>\n<li>A BCE loss for training NER model to detect dataset citation in the input string.</li>\n</ul>\n<p>Bellow is the most important question that we should answer for ourselves before deciding on an approach.</p>\n<h3>Do we need a context?</h3>\n<p>Yes, a semantic context is very important for this kind of problem. As you can see, there are some solutions that don’t need semantic context and only needs dataset title. But those solutions are only suitable for this contest data since almost the dataset title includes keywords such as Study, Survey, Database, Dataset, … then the dataset title itself is good enough to classify if it’s a real dataset title or not. In this competition, we aim for a general solution that uses a semantic context to detect a dataset citation.</p>\n<h3>How my model was trained?</h3>\n<ol>\n<li>An input text is randomly split into Support Set and Query Set.</li>\n<li>In Support Set, we use a <strong>MASK</strong> token to replace all dataset titles in an input text.</li>\n<li>Pass all input text from Support Set into a BertModel and extract <strong>MASK</strong>/<strong>NoMASK</strong> embedding.</li>\n<li>In Query Set, we pass a raw input into a shared BertModel used for Support Set to extract a sequence tokens embedding.</li>\n<li><strong>MASK</strong> and <strong>NoMask</strong> embedding from Support/Query Set is passed into an ArcFace Metric Learning layer.</li>\n<li>A <strong>MASK</strong> embedding from the Support Set contains only a semantic context feature is used to calculate l2 norm cosine similarity with every token feature from the input text in the Query Set.</li>\n<li>A l2 norm cosine similarity will range from (-1, 1), we scale it into a range (-10, 10) then apply sigmoid activation before use it for training the NER model via BCE loss.</li>\n</ol>\n<h3>How to use my trained model for the inference?</h3>\n<ol>\n<li>Pre-extract all <strong>MASK</strong> embedding from the given training set.</li>\n<li>Random selection K <strong>MASK</strong> embedding then average them to obtain the semantic context vector and perform step (6), (7) from the above training process.</li>\n</ol>\n<h3>Post-Processing</h3>\n<p>As <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> said in his solution, a dataset is probably referenced by multiple documents so the more frequently they’re referenced, the more likely they’re a hit and not a spurious find. We use a threshold frequency of 2, which means if our model can detect that dataset title twice, we will get that dataset. We choose 2 because, in training data, there are many dataset titles mentioned only 1-2 times, we are afraid in the private dataset, such dataset titles will be many but we seem to be wrong, a higher threshold frequency gives better results on public and private leaderboards.</p>\n<p>Here is a summary of my solution, there are a few string rules-based that were used but did not affect the final result too much. The final submission is based on an ensemble of allenai/scibert and allenai/biomed_roberta. The code is done on Tensorflow 2.4 with V100 16gb version in AWS EC2. </p>\n<p><strong>Inference Kernel</strong>: <a href=\"https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\" target=\"_blank\">https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base</a></p>\n<h5>Thanks for reading !</h5>",
  "messages": [
    {
      "id": "1361626",
      "postDate": "06/23/2021 00:59:44",
      "content": "<p>Thanks Kaggle for this exciting competition and our team (@suicaokhoailang). Congrats to me to become Kaggle Master and <a href=\"https://www.kaggle.com/suicaokhoailang\" target=\"_blank\">@suicaokhoailang</a> to become Kaggle GM. Congratulate all winners -- we have learned a lot from this competition and all winners’ solutions !!. </p>\n<p><img src=\"https://i.imgur.com/9nuyRxE.png\" alt=\"\"></p>\n<p>Here Is a summary of my solution:</p>\n<ul>\n<li>A shared Bert model for extract Context Embedding and Sequence Tokens Embedding.</li>\n<li>An ArcFace Loss for training Mask/NoMask Embedding.</li>\n<li>A BCE loss for training NER model to detect dataset citation in the input string.</li>\n</ul>\n<p>Bellow is the most important question that we should answer for ourselves before deciding on an approach.</p>\n<h3>Do we need a context?</h3>\n<p>Yes, a semantic context is very important for this kind of problem. As you can see, there are some solutions that don’t need semantic context and only needs dataset title. But those solutions are only suitable for this contest data since almost the dataset title includes keywords such as Study, Survey, Database, Dataset, … then the dataset title itself is good enough to classify if it’s a real dataset title or not. In this competition, we aim for a general solution that uses a semantic context to detect a dataset citation.</p>\n<h3>How my model was trained?</h3>\n<ol>\n<li>An input text is randomly split into Support Set and Query Set.</li>\n<li>In Support Set, we use a <strong>MASK</strong> token to replace all dataset titles in an input text.</li>\n<li>Pass all input text from Support Set into a BertModel and extract <strong>MASK</strong>/<strong>NoMASK</strong> embedding.</li>\n<li>In Query Set, we pass a raw input into a shared BertModel used for Support Set to extract a sequence tokens embedding.</li>\n<li><strong>MASK</strong> and <strong>NoMask</strong> embedding from Support/Query Set is passed into an ArcFace Metric Learning layer.</li>\n<li>A <strong>MASK</strong> embedding from the Support Set contains only a semantic context feature is used to calculate l2 norm cosine similarity with every token feature from the input text in the Query Set.</li>\n<li>A l2 norm cosine similarity will range from (-1, 1), we scale it into a range (-10, 10) then apply sigmoid activation before use it for training the NER model via BCE loss.</li>\n</ol>\n<h3>How to use my trained model for the inference?</h3>\n<ol>\n<li>Pre-extract all <strong>MASK</strong> embedding from the given training set.</li>\n<li>Random selection K <strong>MASK</strong> embedding then average them to obtain the semantic context vector and perform step (6), (7) from the above training process.</li>\n</ol>\n<h3>Post-Processing</h3>\n<p>As <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> said in his solution, a dataset is probably referenced by multiple documents so the more frequently they’re referenced, the more likely they’re a hit and not a spurious find. We use a threshold frequency of 2, which means if our model can detect that dataset title twice, we will get that dataset. We choose 2 because, in training data, there are many dataset titles mentioned only 1-2 times, we are afraid in the private dataset, such dataset titles will be many but we seem to be wrong, a higher threshold frequency gives better results on public and private leaderboards.</p>\n<p>Here is a summary of my solution, there are a few string rules-based that were used but did not affect the final result too much. The final submission is based on an ensemble of allenai/scibert and allenai/biomed_roberta. The code is done on Tensorflow 2.4 with V100 16gb version in AWS EC2. </p>\n<p><strong>Inference Kernel</strong>: <a href=\"https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\" target=\"_blank\">https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base</a></p>\n<h5>Thanks for reading !</h5>",
      "rawMarkdown": "Thanks Kaggle for this exciting competition and our team (@suicaokhoailang). Congrats to me to become Kaggle Master and @suicaokhoailang to become Kaggle GM. Congratulate all winners -- we have learned a lot from this competition and all winners’ solutions !!. \n\n![](https://i.imgur.com/9nuyRxE.png)\n\nHere Is a summary of my solution:\n- A shared Bert model for extract Context Embedding and Sequence Tokens Embedding.\n- An ArcFace Loss for training Mask/NoMask Embedding.\n- A BCE loss for training NER model to detect dataset citation in the input string.\n\nBellow is the most important question that we should answer for ourselves before deciding on an approach.\n\n### Do we need a context?\n\nYes, a semantic context is very important for this kind of problem. As you can see, there are some solutions that don’t need semantic context and only needs dataset title. But those solutions are only suitable for this contest data since almost the dataset title includes keywords such as Study, Survey, Database, Dataset, … then the dataset title itself is good enough to classify if it’s a real dataset title or not. In this competition, we aim for a general solution that uses a semantic context to detect a dataset citation.\n\n\n### How my model was trained?\n\n1. An input text is randomly split into Support Set and Query Set.\n2. In Support Set, we use a **MASK** token to replace all dataset titles in an input text.\n3. Pass all input text from Support Set into a BertModel and extract **MASK**/**NoMASK** embedding.\n4. In Query Set, we pass a raw input into a shared BertModel used for Support Set to extract a sequence tokens embedding.\n5. **MASK** and **NoMask** embedding from Support/Query Set is passed into an ArcFace Metric Learning layer.\n6. A **MASK** embedding from the Support Set contains only a semantic context feature is used to calculate l2 norm cosine similarity with every token feature from the input text in the Query Set.\n7. A l2 norm cosine similarity will range from (-1, 1), we scale it into a range (-10, 10) then apply sigmoid activation before use it for training the NER model via BCE loss.\n\n\n### How to use my trained model for the inference?\n\n1. Pre-extract all **MASK** embedding from the given training set.\n2. Random selection K **MASK** embedding then average them to obtain the semantic context vector and perform step (6), (7) from the above training process.\n \n\n### Post-Processing\n\nAs @leecming said in his solution, a dataset is probably referenced by multiple documents so the more frequently they’re referenced, the more likely they’re a hit and not a spurious find. We use a threshold frequency of 2, which means if our model can detect that dataset title twice, we will get that dataset. We choose 2 because, in training data, there are many dataset titles mentioned only 1-2 times, we are afraid in the private dataset, such dataset titles will be many but we seem to be wrong, a higher threshold frequency gives better results on public and private leaderboards.\n\nHere is a summary of my solution, there are a few string rules-based that were used but did not affect the final result too much. The final submission is based on an ensemble of allenai/scibert and allenai/biomed_roberta. The code is done on Tensorflow 2.4 with V100 16gb version in AWS EC2. \n\n\n**Inference Kernel**: https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\n\n##### Thanks for reading !",
      "votes": null
    },
    {
      "id": "1361640",
      "postDate": "06/23/2021 01:19:53",
      "content": "<p>Congratulations! Cố lên anh ơi!</p>",
      "rawMarkdown": "Congratulations! Cố lên anh ơi!",
      "votes": null
    },
    {
      "id": "1361671",
      "postDate": "06/23/2021 02:09:40",
      "content": "<p>Congrats on your hardwork paying off!</p>",
      "rawMarkdown": "Congrats on your hardwork paying off!",
      "votes": null
    },
    {
      "id": "1361704",
      "postDate": "06/23/2021 02:57:45",
      "content": "<p>Congrats ✊</p>",
      "rawMarkdown": "Congrats ✊",
      "votes": null
    },
    {
      "id": "1361768",
      "postDate": "06/23/2021 04:00:37",
      "content": "<p>Nghỉ mấy hôm rồi quay lại nhanh nha :))</p>",
      "rawMarkdown": "Nghỉ mấy hôm rồi quay lại nhanh nha :))",
      "votes": null
    },
    {
      "id": "1361824",
      "postDate": "06/23/2021 04:40:53",
      "content": "<p>Congrats to the 1st place.</p>",
      "rawMarkdown": "Congrats to the 1st place.",
      "votes": null
    },
    {
      "id": "1362169",
      "postDate": "06/23/2021 08:49:12",
      "content": "<p>Thanks <a href=\"https://www.kaggle.com/suicaokhoailang\" target=\"_blank\">@suicaokhoailang</a> :D. </p>",
      "rawMarkdown": "Thanks @suicaokhoailang :D.",
      "votes": null
    },
    {
      "id": "1362178",
      "postDate": "06/23/2021 08:54:57",
      "content": "<p>Wow amazing solution! Thanks for sharing! </p>",
      "rawMarkdown": "Wow amazing solution! Thanks for sharing!",
      "votes": null
    },
    {
      "id": "1362197",
      "postDate": "06/23/2021 09:14:37",
      "content": "<p>Amazing work 😍! Congrats<br>\nP/s: rep me idol Anh Minh</p>",
      "rawMarkdown": "Amazing work 😍! Congrats\nP/s: rep me idol Anh Minh",
      "votes": null
    },
    {
      "id": "1362222",
      "postDate": "06/23/2021 09:32:03",
      "content": "<p>great work. hope to collaborate with you again soon ^^</p>",
      "rawMarkdown": "great work. hope to collaborate with you again soon ^^",
      "votes": null
    },
    {
      "id": "1362223",
      "postDate": "06/23/2021 09:32:06",
      "content": "<p>Just to understand few things: Is purpose of ARcFace loss is to ensure that embeddings for mask and statement from same document should be similar. What is the shape of Mask/No mask embeddings?<br>\nTrying to understand. Any description around intuition will help.<br>\nYour solution is quite innovative.</p>",
      "rawMarkdown": "Just to understand few things: Is purpose of ARcFace loss is to ensure that embeddings for mask and statement from same document should be similar. What is the shape of Mask/No mask embeddings?\nTrying to understand. Any description around intuition will help.\nYour solution is quite innovative.",
      "votes": null
    },
    {
      "id": "1362266",
      "postDate": "06/23/2021 10:27:15",
      "content": "<p>Congrats 💪</p>",
      "rawMarkdown": "Congrats 💪",
      "votes": null
    },
    {
      "id": "1362307",
      "postDate": "06/23/2021 11:19:48",
      "content": "<p>Very cool solution <a href=\"https://www.kaggle.com/dathudeptrai\" target=\"_blank\">@dathudeptrai</a>, congratz on the win !</p>",
      "rawMarkdown": "Very cool solution @dathudeptrai, congratz on the win !",
      "votes": null
    },
    {
      "id": "1362538",
      "postDate": "06/23/2021 13:55:13",
      "content": "<p>Congratulations!</p>",
      "rawMarkdown": "Congratulations!",
      "votes": null
    },
    {
      "id": "1363146",
      "postDate": "06/24/2021 00:43:39",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/adityakumarsinha\" target=\"_blank\">@adityakumarsinha</a> , the purpose of Arcface loss is to ensure that the embeddings for the MASK from all positive samples are similar. The shape of Mask/NoMask Embedding is [B, F], which is an average feature of all MASK/NoMASK token in the input text. </p>",
      "rawMarkdown": "Hi @adityakumarsinha , the purpose of Arcface loss is to ensure that the embeddings for the MASK from all positive samples are similar. The shape of Mask/NoMask Embedding is [B, F], which is an average feature of all MASK/NoMASK token in the input text.",
      "votes": null
    },
    {
      "id": "1363148",
      "postDate": "06/24/2021 00:44:09",
      "content": "<p>Thanks <a href=\"https://www.kaggle.com/theoviel\" target=\"_blank\">@theoviel</a>, hope to work with you again soon :D </p>",
      "rawMarkdown": "Thanks @theoviel, hope to work with you again soon :D",
      "votes": null
    },
    {
      "id": "1363163",
      "postDate": "06/24/2021 01:39:26",
      "content": "<p>Congrats and nice solution !</p>",
      "rawMarkdown": "Congrats and nice solution !",
      "votes": null
    },
    {
      "id": "1363182",
      "postDate": "06/24/2021 02:01:34",
      "content": "<p><a href=\"https://www.kaggle.com/quanbk\" target=\"_blank\">@quanbk</a> Thanks, hope we can work together in the future :)))</p>",
      "rawMarkdown": "quanbk Thanks, hope we can work together in the future :)))",
      "votes": null
    },
    {
      "id": "1364178",
      "postDate": "06/24/2021 17:19:11",
      "content": "<p>Update: Surprisingly, remove the label from scispacy got a better result (0.588 on private), we should trust only our model :D. <a href=\"https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\" target=\"_blank\">https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base</a></p>",
      "rawMarkdown": "Update: Surprisingly, remove the label from scispacy got a better result (0.588 on private), we should trust only our model :D. https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base",
      "votes": null
    },
    {
      "id": "1367021",
      "postDate": "06/27/2021 11:51:32",
      "content": "<p>Congrats! Nice solution!</p>",
      "rawMarkdown": "Congrats! Nice solution!",
      "votes": null
    },
    {
      "id": "1370095",
      "postDate": "06/29/2021 22:47:50",
      "content": "<p>Interesting solution, congrats!</p>",
      "rawMarkdown": "Interesting solution, congrats!",
      "votes": null
    },
    {
      "id": "1370898",
      "postDate": "06/30/2021 13:27:37",
      "content": "<p>Nice solution, Congratulations!!</p>",
      "rawMarkdown": "Nice solution, Congratulations!!",
      "votes": null
    },
    {
      "id": "1371506",
      "postDate": "07/01/2021 04:07:07",
      "content": "<p>Nice, congratulations…</p>",
      "rawMarkdown": "Nice, congratulations...",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1361640,
      "author_name": "ktgiahieu",
      "author_url": "",
      "post_date": "06/23/2021 01:19:53",
      "content": "<p>Congratulations! Cố lên anh ơi!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1361671,
      "author_name": "leecming",
      "author_url": "",
      "post_date": "06/23/2021 02:09:40",
      "content": "<p>Congrats on your hardwork paying off!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1361704,
      "author_name": "truonghoang",
      "author_url": "",
      "post_date": "06/23/2021 02:57:45",
      "content": "<p>Congrats ✊</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1361768,
      "author_name": "duykhanh99",
      "author_url": "",
      "post_date": "06/23/2021 04:00:37",
      "content": "<p>Nghỉ mấy hôm rồi quay lại nhanh nha :))</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1361824,
      "author_name": "youzi2016",
      "author_url": "",
      "post_date": "06/23/2021 04:40:53",
      "content": "<p>Congrats to the 1st place.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1362169,
      "author_name": "dathudeptrai",
      "author_url": "",
      "post_date": "06/23/2021 08:49:12",
      "content": "<p>Thanks <a href=\"https://www.kaggle.com/suicaokhoailang\" target=\"_blank\">@suicaokhoailang</a> :D. </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1362178,
      "author_name": "duykhanh99",
      "author_url": "",
      "post_date": "06/23/2021 08:54:57",
      "content": "<p>Wow amazing solution! Thanks for sharing! </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1362197,
      "author_name": "quanbk",
      "author_url": "",
      "post_date": "06/23/2021 09:14:37",
      "content": "<p>Amazing work 😍! Congrats<br>\nP/s: rep me idol Anh Minh</p>",
      "votes": null,
      "replies": [
        {
          "id": 1363182,
          "author_name": "dathudeptrai",
          "author_url": "",
          "post_date": "06/24/2021 02:01:34",
          "content": "<p><a href=\"https://www.kaggle.com/quanbk\" target=\"_blank\">@quanbk</a> Thanks, hope we can work together in the future :)))</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1362222,
      "author_name": "nddung",
      "author_url": "",
      "post_date": "06/23/2021 09:32:03",
      "content": "<p>great work. hope to collaborate with you again soon ^^</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1362223,
      "author_name": "adityakumarsinha",
      "author_url": "",
      "post_date": "06/23/2021 09:32:06",
      "content": "<p>Just to understand few things: Is purpose of ARcFace loss is to ensure that embeddings for mask and statement from same document should be similar. What is the shape of Mask/No mask embeddings?<br>\nTrying to understand. Any description around intuition will help.<br>\nYour solution is quite innovative.</p>",
      "votes": null,
      "replies": [
        {
          "id": 1363146,
          "author_name": "dathudeptrai",
          "author_url": "",
          "post_date": "06/24/2021 00:43:39",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/adityakumarsinha\" target=\"_blank\">@adityakumarsinha</a> , the purpose of Arcface loss is to ensure that the embeddings for the MASK from all positive samples are similar. The shape of Mask/NoMask Embedding is [B, F], which is an average feature of all MASK/NoMASK token in the input text. </p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1362266,
      "author_name": "rin2401",
      "author_url": "",
      "post_date": "06/23/2021 10:27:15",
      "content": "<p>Congrats 💪</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1362307,
      "author_name": "theoviel",
      "author_url": "",
      "post_date": "06/23/2021 11:19:48",
      "content": "<p>Very cool solution <a href=\"https://www.kaggle.com/dathudeptrai\" target=\"_blank\">@dathudeptrai</a>, congratz on the win !</p>",
      "votes": null,
      "replies": [
        {
          "id": 1363148,
          "author_name": "dathudeptrai",
          "author_url": "",
          "post_date": "06/24/2021 00:44:09",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/theoviel\" target=\"_blank\">@theoviel</a>, hope to work with you again soon :D </p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1362538,
      "author_name": "ramesh084",
      "author_url": "",
      "post_date": "06/23/2021 13:55:13",
      "content": "<p>Congratulations!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1363163,
      "author_name": "mcggood",
      "author_url": "",
      "post_date": "06/24/2021 01:39:26",
      "content": "<p>Congrats and nice solution !</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1364178,
      "author_name": "dathudeptrai",
      "author_url": "",
      "post_date": "06/24/2021 17:19:11",
      "content": "<p>Update: Surprisingly, remove the label from scispacy got a better result (0.588 on private), we should trust only our model :D. <a href=\"https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\" target=\"_blank\">https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base</a></p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1367021,
      "author_name": "duongprovipvip",
      "author_url": "",
      "post_date": "06/27/2021 11:51:32",
      "content": "<p>Congrats! Nice solution!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1370095,
      "author_name": "antonmaster007",
      "author_url": "",
      "post_date": "06/29/2021 22:47:50",
      "content": "<p>Interesting solution, congrats!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1370898,
      "author_name": "samarthgupta39",
      "author_url": "",
      "post_date": "06/30/2021 13:27:37",
      "content": "<p>Nice solution, Congratulations!!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1371506,
      "author_name": "laxmankusuma",
      "author_url": "",
      "post_date": "07/01/2021 04:07:07",
      "content": "<p>Nice, congratulations…</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1361626": "Thanks Kaggle for this exciting competition and our team (@suicaokhoailang). Congrats to me to become Kaggle Master and @suicaokhoailang to become Kaggle GM. Congratulate all winners -- we have learned a lot from this competition and all winners’ solutions !!. \n\n![](https://i.imgur.com/9nuyRxE.png)\n\nHere Is a summary of my solution:\n- A shared Bert model for extract Context Embedding and Sequence Tokens Embedding.\n- An ArcFace Loss for training Mask/NoMask Embedding.\n- A BCE loss for training NER model to detect dataset citation in the input string.\n\nBellow is the most important question that we should answer for ourselves before deciding on an approach.\n\n### Do we need a context?\n\nYes, a semantic context is very important for this kind of problem. As you can see, there are some solutions that don’t need semantic context and only needs dataset title. But those solutions are only suitable for this contest data since almost the dataset title includes keywords such as Study, Survey, Database, Dataset, … then the dataset title itself is good enough to classify if it’s a real dataset title or not. In this competition, we aim for a general solution that uses a semantic context to detect a dataset citation.\n\n\n### How my model was trained?\n\n1. An input text is randomly split into Support Set and Query Set.\n2. In Support Set, we use a **MASK** token to replace all dataset titles in an input text.\n3. Pass all input text from Support Set into a BertModel and extract **MASK**/**NoMASK** embedding.\n4. In Query Set, we pass a raw input into a shared BertModel used for Support Set to extract a sequence tokens embedding.\n5. **MASK** and **NoMask** embedding from Support/Query Set is passed into an ArcFace Metric Learning layer.\n6. A **MASK** embedding from the Support Set contains only a semantic context feature is used to calculate l2 norm cosine similarity with every token feature from the input text in the Query Set.\n7. A l2 norm cosine similarity will range from (-1, 1), we scale it into a range (-10, 10) then apply sigmoid activation before use it for training the NER model via BCE loss.\n\n\n### How to use my trained model for the inference?\n\n1. Pre-extract all **MASK** embedding from the given training set.\n2. Random selection K **MASK** embedding then average them to obtain the semantic context vector and perform step (6), (7) from the above training process.\n \n\n### Post-Processing\n\nAs @leecming said in his solution, a dataset is probably referenced by multiple documents so the more frequently they’re referenced, the more likely they’re a hit and not a spurious find. We use a threshold frequency of 2, which means if our model can detect that dataset title twice, we will get that dataset. We choose 2 because, in training data, there are many dataset titles mentioned only 1-2 times, we are afraid in the private dataset, such dataset titles will be many but we seem to be wrong, a higher threshold frequency gives better results on public and private leaderboards.\n\nHere is a summary of my solution, there are a few string rules-based that were used but did not affect the final result too much. The final submission is based on an ensemble of allenai/scibert and allenai/biomed_roberta. The code is done on Tensorflow 2.4 with V100 16gb version in AWS EC2. \n\n\n**Inference Kernel**: https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base\n\n##### Thanks for reading !",
    "1361640": "Congratulations! Cố lên anh ơi!",
    "1361671": "Congrats on your hardwork paying off!",
    "1361704": "Congrats ✊",
    "1361768": "Nghỉ mấy hôm rồi quay lại nhanh nha :))",
    "1361824": "Congrats to the 1st place.",
    "1362169": "Thanks @suicaokhoailang :D.",
    "1362178": "Wow amazing solution! Thanks for sharing!",
    "1362197": "Amazing work 😍! Congrats\nP/s: rep me idol Anh Minh",
    "1362222": "great work. hope to collaborate with you again soon ^^",
    "1362223": "Just to understand few things: Is purpose of ARcFace loss is to ensure that embeddings for mask and statement from same document should be similar. What is the shape of Mask/No mask embeddings?\nTrying to understand. Any description around intuition will help.\nYour solution is quite innovative.",
    "1362266": "Congrats 💪",
    "1362307": "Very cool solution @dathudeptrai, congratz on the win !",
    "1362538": "Congratulations!",
    "1363146": "Hi @adityakumarsinha , the purpose of Arcface loss is to ensure that the embeddings for the MASK from all positive samples are similar. The shape of Mask/NoMask Embedding is [B, F], which is an average feature of all MASK/NoMASK token in the input text.",
    "1363148": "Thanks @theoviel, hope to work with you again soon :D",
    "1363163": "Congrats and nice solution !",
    "1363182": "quanbk Thanks, hope we can work together in the future :)))",
    "1364178": "Update: Surprisingly, remove the label from scispacy got a better result (0.588 on private), we should trust only our model :D. https://www.kaggle.com/dathudeptrai/biomed-roberta-scibert-base",
    "1367021": "Congrats! Nice solution!",
    "1370095": "Interesting solution, congrats!",
    "1370898": "Nice solution, Congratulations!!",
    "1371506": "Nice, congratulations..."
  },
  "source": "meta"
}