目次
1.はじめに
2.Roberta
3.Deberta
4.XLnet
5.アンサンブル学習
6.最後に
1. はじめに
本記事は、SIGNATE Student Cup 2022【予測部門】に参加する方に向けて、一緒に取り組めればと思い作成しました!
今回からSIGNATEに挑戦したい!初めて自然言語処理を始めてみよう!という方に読んでもらいたいです!
【第一弾の記事】
【第二弾の記事】
第三弾は、BERT以外の学習モデルでの予測になります。学習モデルが変わることによって、予測結果が大きく変わることがあるので色々なモデルを試してみたいと思います!今回は、Kaggleでよく使われている有名なモデルを紹介します!!
2. Roberta
Robertaは、Bertよりも精度の高いモデルとして登場した学習モデルです。なぜ、Bertよりいいのかというと、大きく2点が改良されたからです。
Robertaの改善点
- 事前学習のデータ量を多くしたこと
- 効率よく学習できるようになったこと
しかし、Bertで注目されていたMulti-Head Attention
を使用した構造は変わってないので基本的なシステムは類似しているようです。詳細は、以下のサイトをみてみてください!
それでは、具体的な実装に入っていきます。実装では、第二弾の記事で紹介したコードの変更点だけを紹介します。他の部分の詳細は、以下から確認してみてください!
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で高いスコアを出したりと個人的に、注目している学習モデルの1つです。現在、SIGNATE Student Cup 2022【予測部門】に挑戦していますが、Debertaが1番安定していました。
さて、DebertaについてですがBertになかった新技術を3つ搭載しているようです。また、学習により使われるパラメータの数は、150億個と非常に多いです。詳細については、以下を参考にしてみてください。割と最近にMicrosoftから出されたモデルであるため、解説記事は少ないです...
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の双方向から学習できる仕組み
を活かしながら精度を向上できるそうです。詳細については、以下を参考にしてみてください。
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とは、簡単にいうと多数決のようなイメージです。複数のモデルの予測の中で多数決を行い、最終結果を決めます。
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か月ほどありますが、一緒に頑張っていきましょう!モデルを探す際には、以下のサイトから探してみてください!
本記事を気に入って頂けたら、「LGTMボタン、コンペのフォーラムでのいいね」をお願いします!