{
  "id": 90338,
  "title": "33rd place simple solution [LB 0.26663]",
  "content": "<p>Thanks everyone for the competition! This is my first NLP kaggle, so I'm quite happy with the results. Thanks my teammates, ods.ai and kaggle community for great ideas. \nNow I would like to tell you about our solution.</p>\n\n<h1>model</h1>\n\n<p>As a baseline we took this <a href=\"https://www.kaggle.com/gdoteof/pytorch-bert-baseline-wd-epochs-cnn-lstm\">kernel</a>, so text tokenization and model structure was similar, but we changed <strong>Head</strong> structure of our model. First thought was to make it more \"smooth\". Linear layers were 1024 * 3 -&gt; 1024 -&gt; ... -&gt; 1024 -&gt; 3 for BERT-large-cased. And we made it 1024 * 3 -&gt; 1024 -&gt; 512 -&gt; 64 -&gt; 3. And for BERT-base-cased 768 * 3 -&gt; 768 -&gt; 768 // 2 -&gt; 768 // 8 -&gt; 3. We also put Dropout(0.5) before each linear layer (and bn, relu, of course). \nIn both cases we didn't use the last BERT output layer. For base it was -2 and for large it was -4.</p>\n\n<h1>training process</h1>\n\n<p>One important step: we used cleared data, from <a href=\"https://www.kaggle.com/c/gendered-pronoun-resolution/discussion/81331#503094\">here</a>, because some samples were labeled wrongly and it could corrupted results.\nWe used 6 folds. On each model was trained with BertAdam optimizer(lr = 0.0001, weight_decay = 0.01) from <a href=\"https://github.com/huggingface/pytorch-pretrained-BERT\">pytorch-BERT repo</a>. And ReduceLROnPlateau scheduler with patience = 5 and alpha = 2. When we had no score improvement in 15 epochs we stopped training. We also tried CosineAnnealingLR after with RMSprop, but it didn't improved the score.\nCV is great for stacking, so we decided to build a second layer model, which was LGBM. We added both BERT-large and BERT-base + some features.</p>\n\n<h1>features</h1>\n\n<p>For features we used distance and url (as in this <a href=\"https://www.kaggle.com/chanhu/bert-score-layer-lb-0-475\">kernel</a>) and some statistic features, like 'num words', 'num unique words', 'num chars', 'num stopwords', 'num words upper' and encoded pronoun (just by number, ex. 'She': 1, 'he': 2, etc.). And that's it!</p>\n\n<h1>LGBM</h1>\n\n<p>For parameters search i used a powerful <a href=\"https://github.com/hyperopt/hyperopt\">hyperopt</a> framework. This is very useful and effective for randomized search.</p>\n\n<h1>fine-tuning BERT</h1>\n\n<p>We also tried BERT fine-tuning, like in examples from this <a href=\"https://github.com/huggingface/pytorch-pretrained-BERT/tree/master/examples/lm_finetuning\">example </a>, but it didn't seem to work, the score was worse. So if you succeeded in BERT fine-tuning, please tell in comments how you did it.</p>\n\n<p>Thanks for reading! 🥈 </p>",
  "comments": [
    {
      "id": 521735,
      "author_name": "",
      "author_url": "",
      "post_date": "2019-04-23T10:52:00.293000",
      "content": "<p>Congratulations for the medal and thanks for sharing!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 521498,
      "author_name": "Akash Ravichandran",
      "author_url": "",
      "post_date": "2019-04-23T01:21:04.467000",
      "content": "<p><strong>Congrats and Thanks for sharing <a href=\"/avens8\">@avens8</a></strong></p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 521494,
      "author_name": "SRK",
      "author_url": "",
      "post_date": "2019-04-23T01:17:12.337000",
      "content": "<p>Thanks Pavel for the write-up. We used the last 4 layers. It looks like we should have removed the last two layers and used only -3 and -4 in BERT. </p>",
      "votes": 1,
      "replies": [
        {
          "id": 521496,
          "author_name": "Yury Kashnitsky",
          "author_url": "",
          "post_date": "2019-04-23T01:19:33.737000",
          "content": "<p>Yes, it'd be interesting to explore which layer carries which information. We used -4, -5 and -6. </p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 521521,
          "author_name": "gui_yihan",
          "author_url": "",
          "post_date": "2019-04-23T01:54:07.157000",
          "content": "<p>We used layer -6 of Bert large and our final result was 0.2334 in stage 2.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 522335,
          "author_name": "Artur Ilichev",
          "author_url": "",
          "post_date": "2019-04-24T09:03:54.927000",
          "content": "<p>We tried using average of the last 4 layers, but it didn't improve our score. Concatenation of -3 and -4 layers also didn't work well.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 521538,
      "author_name": "Tsukasa Moritoki",
      "author_url": "",
      "post_date": "2019-04-23T02:53:09.130000",
      "content": "<p>I tried BERT-LARGE fine-tuning. Single model was unstable but average ensemble was good. There are three points for the fine-tuning to work, simple head, lower learning rate and removing top 2 layers. The last one is not necessary, only slight improvement over the full model(24 layers). See <a href=\"https://www.kaggle.com/tks0123456789/offsets-model\">Offsets model</a> for detail. </p>",
      "votes": 2,
      "replies": [
        {
          "id": 521668,
          "author_name": "Pavel Tsai",
          "author_url": "",
          "post_date": "2019-04-23T08:23:45.203000",
          "content": "<p>Lol, simple models without features give 0.20819. Thanks for sharing a very elegant solution!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 521877,
      "author_name": "dhaqui the kaggler",
      "author_url": "",
      "post_date": "2019-04-23T15:11:09.623000",
      "content": "<p>Thanks for sharing! Congratulations!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 521491,
      "author_name": "Yury Kashnitsky",
      "author_url": "",
      "post_date": "2019-04-23T01:14:45.263000",
      "content": "<p>Thanks for your overview, Pavel!</p>",
      "votes": 1,
      "replies": []
    }
  ],
  "comment_count": 10,
  "messages": [
    {
      "id": 521484,
      "postDate": "2019-04-23T00:59:59.453Z",
      "content": "<p>Thanks everyone for the competition! This is my first NLP kaggle, so I'm quite happy with the results. Thanks my teammates, ods.ai and kaggle community for great ideas. \nNow I would like to tell you about our solution.</p>\n\n<h1>model</h1>\n\n<p>As a baseline we took this <a href=\"https://www.kaggle.com/gdoteof/pytorch-bert-baseline-wd-epochs-cnn-lstm\">kernel</a>, so text tokenization and model structure was similar, but we changed <strong>Head</strong> structure of our model. First thought was to make it more \"smooth\". Linear layers were 1024 * 3 -&gt; 1024 -&gt; ... -&gt; 1024 -&gt; 3 for BERT-large-cased. And we made it 1024 * 3 -&gt; 1024 -&gt; 512 -&gt; 64 -&gt; 3. And for BERT-base-cased 768 * 3 -&gt; 768 -&gt; 768 // 2 -&gt; 768 // 8 -&gt; 3. We also put Dropout(0.5) before each linear layer (and bn, relu, of course). \nIn both cases we didn't use the last BERT output layer. For base it was -2 and for large it was -4.</p>\n\n<h1>training process</h1>\n\n<p>One important step: we used cleared data, from <a href=\"https://www.kaggle.com/c/gendered-pronoun-resolution/discussion/81331#503094\">here</a>, because some samples were labeled wrongly and it could corrupted results.\nWe used 6 folds. On each model was trained with BertAdam optimizer(lr = 0.0001, weight_decay = 0.01) from <a href=\"https://github.com/huggingface/pytorch-pretrained-BERT\">pytorch-BERT repo</a>. And ReduceLROnPlateau scheduler with patience = 5 and alpha = 2. When we had no score improvement in 15 epochs we stopped training. We also tried CosineAnnealingLR after with RMSprop, but it didn't improved the score.\nCV is great for stacking, so we decided to build a second layer model, which was LGBM. We added both BERT-large and BERT-base + some features.</p>\n\n<h1>features</h1>\n\n<p>For features we used distance and url (as in this <a href=\"https://www.kaggle.com/chanhu/bert-score-layer-lb-0-475\">kernel</a>) and some statistic features, like 'num words', 'num unique words', 'num chars', 'num stopwords', 'num words upper' and encoded pronoun (just by number, ex. 'She': 1, 'he': 2, etc.). And that's it!</p>\n\n<h1>LGBM</h1>\n\n<p>For parameters search i used a powerful <a href=\"https://github.com/hyperopt/hyperopt\">hyperopt</a> framework. This is very useful and effective for randomized search.</p>\n\n<h1>fine-tuning BERT</h1>\n\n<p>We also tried BERT fine-tuning, like in examples from this <a href=\"https://github.com/huggingface/pytorch-pretrained-BERT/tree/master/examples/lm_finetuning\">example </a>, but it didn't seem to work, the score was worse. So if you succeeded in BERT fine-tuning, please tell in comments how you did it.</p>\n\n<p>Thanks for reading! 🥈 </p>",
      "rawMarkdown": "Thanks everyone for the competition! This is my first NLP kaggle, so I'm quite happy with the results. Thanks my teammates, [ods.ai](ods.ai) and kaggle community for great ideas. \nNow I would like to tell you about our solution.\n# model\nAs a baseline we took this [kernel](https://www.kaggle.com/gdoteof/pytorch-bert-baseline-wd-epochs-cnn-lstm), so text tokenization and model structure was similar, but we changed **Head** structure of our model. First thought was to make it more \"smooth\". Linear layers were 1024 * 3 -&gt; 1024 -&gt; ... -&gt; 1024 -&gt; 3 for BERT-large-cased. And we made it 1024 * 3 -&gt; 1024 -&gt; 512 -&gt; 64 -&gt; 3. And for BERT-base-cased 768 * 3 -&gt; 768 -&gt; 768 // 2 -&gt; 768 // 8 -&gt; 3. We also put Dropout(0.5) before each linear layer (and bn, relu, of course). \nIn both cases we didn't use the last BERT output layer. For base it was -2 and for large it was -4.\n# training process\nOne important step: we used cleared data, from [here](https://www.kaggle.com/c/gendered-pronoun-resolution/discussion/81331#503094), because some samples were labeled wrongly and it could corrupted results.\nWe used 6 folds. On each model was trained with BertAdam optimizer(lr = 0.0001, weight_decay = 0.01) from [pytorch-BERT repo](https://github.com/huggingface/pytorch-pretrained-BERT). And ReduceLROnPlateau scheduler with patience = 5 and alpha = 2. When we had no score improvement in 15 epochs we stopped training. We also tried CosineAnnealingLR after with RMSprop, but it didn't improved the score.\nCV is great for stacking, so we decided to build a second layer model, which was LGBM. We added both BERT-large and BERT-base + some features.\n# features\nFor features we used distance and url (as in this [kernel](https://www.kaggle.com/chanhu/bert-score-layer-lb-0-475)) and some statistic features, like 'num words', 'num unique words', 'num chars', 'num stopwords', 'num words upper' and encoded pronoun (just by number, ex. 'She': 1, 'he': 2, etc.). And that's it!\n# LGBM\nFor parameters search i used a powerful [hyperopt](https://github.com/hyperopt/hyperopt) framework. This is very useful and effective for randomized search.\n# fine-tuning BERT\nWe also tried BERT fine-tuning, like in examples from this [example ](https://github.com/huggingface/pytorch-pretrained-BERT/tree/master/examples/lm_finetuning), but it didn't seem to work, the score was worse. So if you succeeded in BERT fine-tuning, please tell in comments how you did it.\n\nThanks for reading! 🥈 ",
      "votes": 13
    },
    {
      "id": 521735,
      "postDate": "2019-04-23T10:52:00.293Z",
      "content": "<p>Congratulations for the medal and thanks for sharing!</p>",
      "rawMarkdown": "Congratulations for the medal and thanks for sharing!",
      "votes": 1
    },
    {
      "id": 521498,
      "postDate": "2019-04-23T01:21:04.467Z",
      "content": "<p><strong>Congrats and Thanks for sharing <a href=\"/avens8\">@avens8</a></strong></p>",
      "rawMarkdown": "**Congrats and Thanks for sharing @avens8**",
      "votes": 1
    },
    {
      "id": 521494,
      "postDate": "2019-04-23T01:17:12.337Z",
      "content": "<p>Thanks Pavel for the write-up. We used the last 4 layers. It looks like we should have removed the last two layers and used only -3 and -4 in BERT. </p>",
      "rawMarkdown": "Thanks Pavel for the write-up. We used the last 4 layers. It looks like we should have removed the last two layers and used only -3 and -4 in BERT. ",
      "votes": 1,
      "replies": [
        {
          "id": 521496,
          "postDate": "2019-04-23T01:19:33.737Z",
          "content": "<p>Yes, it'd be interesting to explore which layer carries which information. We used -4, -5 and -6. </p>",
          "rawMarkdown": "Yes, it'd be interesting to explore which layer carries which information. We used -4, -5 and -6. ",
          "votes": 3
        },
        {
          "id": 521521,
          "postDate": "2019-04-23T01:54:07.157Z",
          "content": "<p>We used layer -6 of Bert large and our final result was 0.2334 in stage 2.</p>",
          "rawMarkdown": "We used layer -6 of Bert large and our final result was 0.2334 in stage 2.",
          "votes": 2
        },
        {
          "id": 522335,
          "postDate": "2019-04-24T09:03:54.927Z",
          "content": "<p>We tried using average of the last 4 layers, but it didn't improve our score. Concatenation of -3 and -4 layers also didn't work well.</p>",
          "rawMarkdown": "We tried using average of the last 4 layers, but it didn't improve our score. Concatenation of -3 and -4 layers also didn't work well."
        }
      ]
    },
    {
      "id": 521538,
      "postDate": "2019-04-23T02:53:09.130Z",
      "content": "<p>I tried BERT-LARGE fine-tuning. Single model was unstable but average ensemble was good. There are three points for the fine-tuning to work, simple head, lower learning rate and removing top 2 layers. The last one is not necessary, only slight improvement over the full model(24 layers). See <a href=\"https://www.kaggle.com/tks0123456789/offsets-model\">Offsets model</a> for detail. </p>",
      "rawMarkdown": "I tried BERT-LARGE fine-tuning. Single model was unstable but average ensemble was good. There are three points for the fine-tuning to work, simple head, lower learning rate and removing top 2 layers. The last one is not necessary, only slight improvement over the full model(24 layers). See [Offsets model](https://www.kaggle.com/tks0123456789/offsets-model) for detail. ",
      "votes": 2,
      "replies": [
        {
          "id": 521668,
          "postDate": "2019-04-23T08:23:45.203Z",
          "content": "<p>Lol, simple models without features give 0.20819. Thanks for sharing a very elegant solution!</p>",
          "rawMarkdown": "Lol, simple models without features give 0.20819. Thanks for sharing a very elegant solution!"
        }
      ]
    },
    {
      "id": 521877,
      "postDate": "2019-04-23T15:11:09.623Z",
      "content": "<p>Thanks for sharing! Congratulations!</p>",
      "rawMarkdown": "Thanks for sharing! Congratulations!",
      "votes": 1
    },
    {
      "id": 521491,
      "postDate": "2019-04-23T01:14:45.263Z",
      "content": "<p>Thanks for your overview, Pavel!</p>",
      "rawMarkdown": "Thanks for your overview, Pavel!",
      "votes": 1
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T22:45:17Z",
  "competition_id": 12797,
  "competition_slug": "gendered-pronoun-resolution",
  "team_id": 2962663,
  "solution_url": "/competitions/gendered-pronoun-resolution/writeups/ods-ai-gg-33rd-place-simple-solution-lb-0-26663"
}