SIGNATE Student Cup 2022 入門編③【Bert以外のモデル・アンサンブル学習】

# 目次
[1.はじめに](#1-はじめに)
[2.Roberta](#2-Roberta)
[3.Deberta](#3-Deberta)
[4.XLnet](#4-XLnet)
[5.アンサンブル学習](#5-アンサンブル学習)
[6.最後に](#6-最後に)

# 1. はじめに
本記事は、[SIGNATE Student Cup 2022【予測部門】](https://signate.jp/competitions/724)に参加する方に向けて、一緒に取り組めればと思い作成しました！

今回からSIGNATEに挑戦したい！初めて自然言語処理を始めてみよう！という方に読んでもらいたいです！

【第一弾の記事】

https://qiita.com/yama09/items/f2f94b6bdf0ce8e83ddb

【第二弾の記事】

https://qiita.com/yama09/items/9a396e184591b500cb0a

第三弾は、BERT以外の学習モデルでの予測になります。学習モデルが変わることによって、予測結果が大きく変わることがあるので色々なモデルを試してみたいと思います！今回は、[Kaggle](https://www.kaggle.com/)でよく使われている有名なモデルを紹介します！！

# 2. Roberta
Robertaは、Bertよりも精度の高いモデルとして登場した学習モデルです。なぜ、Bertよりいいのかというと、大きく2点が改良されたからです。

:::note info
Robertaの改善点
- 事前学習のデータ量を多くしたこと
- 効率よく学習できるようになったこと
:::
しかし、Bertで注目されていた`Multi-Head Attention`を使用した構造は変わってないので基本的なシステムは類似しているようです。詳細は、以下のサイトをみてみてください！

> [RoBERTaを理解する](https://data-analytics.fun/2020/05/08/understanding-roberta/)
> [BERT派生モデルの論文紹介](https://qiita.com/kryouhei673/items/cd6d5537ea13f1015146)

それでは、具体的な実装に入っていきます。実装では、第二弾の記事で紹介したコードの変更点だけを紹介します。他の部分の詳細は、以下から確認してみてください！

https://qiita.com/yama09/items/9a396e184591b500cb0a

``` Python
MODEL_NAME = 'roberta-base'

class Classifier(nn.Module):
    def __init__(self, model_name, num_classes=4):
        super().__init__()

        self.bert = AutoModel.from_pretrained(model_name)
        self.dropout = nn.Dropout(0.1)
        self.linear = nn.Linear(768, num_classes)
        nn.init.normal_(self.linear.weight, std=0.02)
        nn.init.zeros_(self.linear.bias)

    def forward(self, input_ids, attention_mask, token_type_ids):
        output = self.bert(
                input_ids = input_ids,
                attention_mask = attention_mask,
                return_dict=False
                ) 
        
        # token_type_idsは使わない
        
        output = output[0]
        output = output[:, 0, :]
        output = self.dropout(output)
        output = self.linear(output)
        return output
```
筆者のPCで、今回のコンペのスコアを確認してみたところ以下のようになりました。
|CV （Stratified K Fold）|LB  |
|----|----|
|0.704|0.733 |

# 3. Deberta
Debertaは、最近Kaggleの自然言語処理で使用されているモデルです。Debertaを使用した学習モデルで上位を取ったり、Baselineで高いスコアを出したりと個人的に、注目している学習モデルの１つです。現在、[SIGNATE Student Cup 2022【予測部門】](https://signate.jp/competitions/724)に挑戦していますが、Debertaが1番安定していました。

さて、DebertaについてですがBertになかった新技術を３つ搭載しているようです。また、学習により使われるパラメータの数は、150億個と非常に多いです。詳細については、以下を参考にしてみてください。割と最近にMicrosoftから出されたモデルであるため、解説記事は少ないです...

> [GoogleとMicrosoftのAIモデル、言語理解ベンチマークにおいて人間の能力を凌駕](https://www.infoq.com/jp/news/2021/03/google-microsoft-superhuman/)


``` Python
MODEL_NAME = 'microsoft/deberta-base'

class Classifier(nn.Module):
    def __init__(self, model_name, num_classes=4):
        super().__init__()

        self.bert = AutoModel.from_pretrained(model_name)
        self.dropout = nn.Dropout(0.1)
        self.linear = nn.Linear(768, num_classes)
        nn.init.normal_(self.linear.weight, std=0.02)
        nn.init.zeros_(self.linear.bias)

    def forward(self, input_ids, attention_mask, token_type_ids):
        output = self.bert(
                input_ids = input_ids,
                attention_mask = attention_mask,
                return_dict=False
                )
        
        # token_type_idsは使わない

        output = output[0]
        output = output[:, 0, :]
        output = self.dropout(output)
        output = self.linear(output)
        return output
```
筆者のPCで、今回のコンペのスコアを確認してみたところ以下のようになりました。
|CV （Stratified K Fold）|LB  |
|----|----|
|0.723|0.731 |

# 4. XLnet
XLnetは、Bertの課題点であった事前学習時に間違った解釈をしてしまうことを防ぐために新たな学習方法を取り入れました。今までは、Masked LM という方法でしたが、それをやめて新たな学習モデルを組み込みました。それにより、Bertの`双方向から学習できる仕組み`を活かしながら精度を向上できるそうです。詳細については、以下を参考にしてみてください。

> [XLNetを理解する](https://data-analytics.fun/2020/05/06/understanding-xlnet/)
``` Python
MODEL_NAME = 'xlnet-base-cased'

class Classifier(nn.Module):
    def __init__(self, model_name, num_classes=4):
        super().__init__()

        self.bert = AutoModel.from_pretrained(model_name)
        self.dropout = nn.Dropout(0.1)
        self.linear = nn.Linear(768, num_classes)
        nn.init.normal_(self.linear.weight, std=0.02)
        nn.init.zeros_(self.linear.bias)

    def forward(self, input_ids, attention_mask, token_type_ids):
        output = self.bert(
            input_ids = input_ids,
            attention_mask = attention_mask,
            token_type_ids = token_type_ids,
        return_dict=False)

        # token_type_idsを使用する

        output = output[0]
        output = output[:, 0, :]
        output = self.dropout(output)
        output = self.linear(output)
        return output
```

筆者のPCで、今回のコンペのスコアを確認してみたところ以下のようになりました。
|CV （Stratified K Fold）|LB  |
|----|----|
|0.681|0.695 |

# 5. アンサンブル学習
これまで作成してきた学習モデルを組み合わせることで、それぞれの学習モデルに足りない部分を補う`アンサンブル学習`というのがあります。

アンサンブル学習にも色々と種類があるのですが、今回は`Voting`について紹介します。Votingとは、簡単にいうと多数決のようなイメージです。複数のモデルの予測の中で多数決を行い、最終結果を決めます。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759780/1fb839e0-d1a3-1a2c-aab9-6c1ec9b57874.png)

```Python
import pandas as pd
import numpy as np

bert = pd.read_csv("Bert.csv",header=None)
roberta = pd.read_csv("Roberta.csv",header=None)
deberta = pd.read_csv("Deberta.csv",header=None)


bert["bert"] = bert[1]
bert["roberta"] = roberta[1]
bert["deberta"] = deberta[1]

ens = bert[["bert","roberta","deberta"]].T

mode = ens.mode().T

bert["voting"] = mode[0].astype(int)

bert[[0,"voting"]].to_csv("Emsamble.csv",index=None,header=None)
```
# 6. 最後に
これでBERT以外のモデル・アンサンブル学習ができました。お疲れ様でした！

他にも多くのモデルがあるので、最適なものを探してみましょう。残り約1か月ほどありますが、一緒に頑張っていきましょう！モデルを探す際には、以下のサイトから探してみてください！

https://huggingface.co/models

本記事を気に入って頂けたら、「LGTMボタン、コンペのフォーラムでのいいね」をお願いします！