Slide 1

Slide 1 text

Feedback Prizeコンペ反省会 島越 直人 データ本部 AI技術開発部 第三グループ 株式会社ディー・エヌ・エー © DeNA Co.,Ltd.

Slide 2

Slide 2 text

2 自己紹介 島越 直人 • 経歴 • 奈良県出身 • 京都大学 機械理工学専攻 卒業 • 2019/04 ~ DeNA新卒入社 • 2020/04 ~ MoT出向 • 2022/04 ~ 帰任、AI技術開発部第三G (New!) • Kaggle • 色々なドメインのデータに触れるのが好きです。 よくトリゴエと間違えられますがシマコシです @nt_4o54
 @shimacos


Slide 3

Slide 3 text

3 目次 Feedbackコンペについて 解法 (Public 10th -> Private 20th) 上位解法 TIPS 1 2 3 4

Slide 4

Slide 4 text

4 Feedbackコンペについて

Slide 5

Slide 5 text

5 はじめに 1 スライド中の用語を整理しておきます ● Word:単語 ( I am a Kaggle Grandmaster.) ○ 大体 sentence.split()で出てくるものと同義。 ● Character:文字 ( I a m a K a g g l e G r a n d m a s t e r . ) ● Token: tokenizerで文字を分割した単位。モデルによって様々。 ○ Robertaの場合:'I', 'Ġam', 'Ġa', 'ĠK', 'agg', 'le', 'ĠGrand', 'master', '.'

Slide 6

Slide 6 text

6 データ 1 アメリカの6年生から12年生までのレポートに対して要素毎に以下の分類を行う。 ● Lead: 序論 ● Position: 主題 ● Claim: 主張 ● Counterclaim: 主張に対する反論 ● Rebuttal: 反論に対する主張 ● Evidence: Claim, Counterclaim, Rebuttalに対する証拠 ● Concluding Statement: 結論

Slide 7

Slide 7 text

7 データ 1 レポートの長さ (Robertaのtokenベース) ラベルのつけられ方 ※ Robertaは最大512までしかtokenを入力にできない

Slide 8

Slide 8 text

8 データ 1 1文章あたりのラベル数 ラベルの長さ ラベル数 ● 要素が文章全体のどの位置にあるか ● どれくらいの要素が1文章に登場するか などは重要そう。 -> 文章全体をモデルに入力できることが重要 ?

Slide 9

Slide 9 text

9 評価指標 1 ● 特殊なmacro F1 score ○ 文章の中からラベルの単語開始indexと単語終了indexを予測する ○ 予測と正解の被りが0.5以上あればTP, 被りが発生していない予測はFP, 被りが 発生していない正解はFN ■ 複数の被りがある場合は、一番被りが大きいもののみ採用される ○ クラス毎のTP / ( TP + 0.5(FP + FN))の平均 TP TP FN TP TP TP FP FP FP TP FP TP FP FP

Slide 10

Slide 10 text

10 めんどくさいところ 1 ● モデルで学習させる時は、Token単位の入力 -> Token単位の出力になる。 ● 予測するのは単語単位なので、単語単位の予測値に直す必要がある。 ○ ラベルも同じで、Word単位のlabelをToken単位に直す必要がある。 ○ transformersを使っている場合は、offset_mappingを使うことで可能 ● アンサンブルする際にTokenizerが違う場合は、tokenが違うので注意 ○ CharacterベースでアンサンブルするかWordベースでアンサンブルするか ○ Characterベースでやる場合は、Notebookのメモリ管理に注意 ● 評価指標の計算やモデルの予測から提出の形にするのに時間がかかるので、 アンサンブルの重みとかを考えるだけでも計算コストがかかる

Slide 11

Slide 11 text

11 めんどくさいところ 1 元のデータセットのラベル (discourse_text)とKaggleのつけたラベルが一致しない。 ● 評価はKaggleのつけたラベル (predictioinstring)で行われる ● コンペ序盤でリバースエンジニアリングされた。 ● discourse_start, end -> predictionstringはできるが、 predictionstring -> discourse_start, end, textはできない ● 元データから個人情報などをmaskした際にズレが生じた (らしい) (例) ‘John Doe’ -> GENERIC_NAME 不一致 再現しない Characterベースの値 Wordベースの値

Slide 12

Slide 12 text

12 めんどくさいところ 1 ラベルのつけ方もいろいろ考えられる ● 評価はpredictionstringでやられるので、predictionstringで作成 ○ 正規表現などで、Word -> Characterのmapping (discourse_start, end)が必要 ● 文章として成り立ってないと学習のノイズになるのでdiscourse_textで作成 ○ 正規表現などで、discourse_text -> Characterのmapping が必要 ● 不一致が発生するのは少数なので、無視してdiscourse_start, endでラベルを作成 不一致 再現しない Characterベースの値 Wordベースの値

Slide 13

Slide 13 text

13 データを見た感じのまとめ 1 ● Long Document + Token Classificationのタスク ● 評価指標 ○ macro F1なので、少数クラスも大事 ○ 予測値をみながらTPを増やしながら、FP, FNを減らすことが重要 ● モデルの目的変数や、出力をどう扱うかに工夫ポイントがありそう

Slide 14

Slide 14 text

14 2. 解法 (Public 10th -> Private 20th)

Slide 15

Slide 15 text

15 Overview (1/2) ラベルのつけ方 ● discourse_textからdiscourse_start, endを修正 -> BIOラベル 1st モデル (Teamメンバーと合同作業) ● Relative Positional Attention系 ○ DeBERTa (large, x-large), DeBERTaV2 (x-large), Funnel Transformer (large) ● Sinusoidal Positional Encoder系 ○ Longformer (large), Roberta (large) ● 入力:1536 token, 出力 1536 token ● 損失関数:Cross Entropy + (一部)SAM Optimizer 2

Slide 16

Slide 16 text

16 Overview (2/2) 1st モデルの予測 -> 文章を分割 ● ‘B-’ラベル以外の予測でも、クラスが違えば要素の開始点とする ○ 例) B-Lead, I-Lead, I-Position, I-Position の様な時にI-Positionでも分割 2nd モデル ● 分割した要素毎にTP or FPかを判定するLightGBMモデル ● 特徴量 ○ 文字数や文章の位置など ○ 分割単位でクラス毎のmin, max, mean, std, first, last ○ 上記aggregation特徴量のレポート全体で見たときのlag, lead, cumsum, rolling meanなど 2

Slide 17

Slide 17 text

17 BIO ラベル ● NERでよく使われるラベル ● ラベルのつけ方 ○ クラスの開始点のToken’を’B-{Class}’ (Begin) クラスとする。 ○ 開始点以外のTokenを’I-{Class}’ (Internal) クラスとする。 ○ どのクラスにも属さない要素を’O’ (Other) クラスとする。 ● Decodeの仕方 (一般的なやり方は知らない ○ ‘B-’クラスを開始点として、次に’O’ or ‘B-’が始まるまでを そのクラスに所属する予測とする ○ (今回の場合は) 違うクラスの‘I-’の場合も開始点とした。 2

Slide 18

Slide 18 text

18 1st Model / DeBERTa ● Relative Positionを使ったAttention Moduleなので、max_lengthは512で 事前学習しているが、512以上のtoken lengthを扱うことができる。 ○ i番目のpositionとj番目のpositionの間の相対位置を要素にもつ 行列 P を用いたAttention計算を行う (詳しくは論文で 2 https://arxiv.org/pdf/2006.03654.pdf

Slide 19

Slide 19 text

19 1st Model / DeBERTa ● Relative Positionを使ったAttention Moduleなので、max_lengthは512で 事前学習しているが、512以上のtoken lengthを扱うことができる。 ○ 実装だと単純に端を0, 512に押し込めているだけっぽい? (roundした方が良さそうな気がする) ○ これくらいならSinusoidal Positional Encoderのモデルにも応用できそう。 2

Slide 20

Slide 20 text

20 1st Model / Funnel Transformer ● UNet的なアーキテクチャにして、Attention中に全長を保持しなくて済むので 効率的なアーキテクチャになっている ● 絶対位置のEncodingだとPoolingによって情報が死んでしまうのか、 Relative Attentionに比べて結構GLUEスコアが落ちてる ○ Transformer-XLのRelative Attentionを用いている (論文のA-2に実装 ○ (多分)各LayerのAttentionに同様に絶対位置情報を与えたら改善するはず 2 https://arxiv.org/pdf/2006.03236.pdf

Slide 21

Slide 21 text

21 1st Model / LongFormer ● Attentionモジュールを工夫することで、4096のtoken lengthで事前学習すること に成功。 ○ [CLS] tokenは全部にAttentionするなど重要なものだけ重みをもつ Global Attention と Sliding Window Attentionの組み合わせ ○ 特に気にせずそのままinputできるので序盤から人気 2 https://arxiv.org/pdf/2004.05150.pdf

Slide 22

Slide 22 text

22 1st Model / Roberta ● そのままだとmax_length=512で事前学習されているので、 文章全体を入力にできない。 ● 以下の様に、Slideさせて推論しTokenごとに平均を取った ○ LongFormerと遜色ないくらいの精度は出る (が、実装はめんどくさい ○ 予測の仕方が他のものと異なるのでアンサンブルに役立った ○ 1位も同じことをしたRobertaをアンサンブルに組み込んでいた 2 https://www.kaggle.com/competitions/feedback-prize-2021/discussion/313177

Slide 23

Slide 23 text

23 1st Modelの予測値から分割を作成 ● 予測値はCharacter単位でMean (重みを最適化するコストが高かった ● ‘B-’ラベル以外の予測でも、クラスが違えば要素の開始点とする ● Notebookとかだとfor文を二回して一つ一つの文章に対して予測していたが、 (汚かったり)次のモデルに渡す特徴量が作りにくかったり効率的でないので、 Pandasでいい感じに処理 ○ 以下の様にsplit_id作っておけば、このidでgroupbyするだけ 2

Slide 24

Slide 24 text

24 2nd Model / LightGBM (LB + 0.03 - 0.05) ● 前述のsplit_id単位で予測値をgroupbyして統計量を算出 ● 出した統計量をさらに文章全体を時系列として時系列系の特徴を算出 ○ lag, lead, rolling, cumsum ● class分類よりTP/FPの分類の方が良かった。 ○ ここの閾値はクラス毎にNelder-Meadで決定 2 特徴量重要度上位

Slide 25

Slide 25 text

25 効かなかったこと ● BILOUラベル (若干は改善したが、再学習に時間がかかるので断念 ● サンプル数やラベルの長さに対して重みをつけたCross Entropy / Focal Lossなど ● ビームサーチで候補を出して元の予測との被りが0.5より少なかった場合にLGBMの 入力候補に加える (若干良くなるが、微改善) ● 分割は合ってるがクラス判定ミスしているような予測なども LGBMの入力候補に加えてTP/FP分類でなく、クラス分類を行う ● 2nd ModelをLSTMにしたり、Bertにしたり、Word2Vec的な特徴加えたり ● HeadにCRF、LSTMなど ● BARTはシングルはあまり強くないが、アンサンブルには効いた ● この辺りのFinetuningテクニック ● etc, etc... 2

Slide 26

Slide 26 text

26 3. 上位解法

Slide 27

Slide 27 text

27 概要 ● 基本的に(1名を除いて) 以下の三要素に分けられる 1. Token levelのモデル学習の工夫 2. Ensembleの工夫 3. Postprocessの工夫 3

Slide 28

Slide 28 text

28 Single Modelの精度向上 (1/2) ● Adversarial Weight Perturbation (1st) ● Copy and Paste Augmentation (3rd) ● B, I, Oの3クラスのSegmentation LossとNERのLossのMulti Task (5th) ● Cross-Entropy with dynamic cosine-based class weights (5th) ● 連続でClassが登場しないものの’B-’ラベルを無くして10クラス分類 (5th) 3

Slide 29

Slide 29 text

29 Single Modelの精度向上 (2/2) ● B + 各クラス + Oのラベルで学習し、TokenをDropout (7th, 9th) ● Shorter Model ○ 単純にModelを時間方向にconcatして対応 (7th) ○ SlideさせてMean (1st) ○ Slideさせて時間方向にconcatさせてGRU (3rd) ● Mean Teacher (8th) ● SWA (8th) ● Deberta V2(3)のTokenizerに’\n’を加える (4th, 9th) ● torch.scatter_addを使い、TransformerのheadにWord単位のLSTMをつける。 後段の処理も楽になるし賢い!(9th) 3

Slide 30

Slide 30 text

30 Ensemble ● Weighted Box Fusion (2nd, 5th) ● Optunaで重み調整 (7th) ● 近くのTokenも合わせて(恐らくwindow幅を持たせて) Ensembleする (11th) 3

Slide 31

Slide 31 text

31 Postprocess (1/2) ● 予測した’B-’タグから一つずつ長さを増やしていって、LGBMの入力候補を複数出す (1st, 3rd) ○ この候補でRecall 90%くらい出るらしい ○ 推論時に同様に全ての候補を出すのは大変なので、 予測の確率値で(恐らく)65%くらいのRecallが出る様に閾値を決めている。 ○ 自分と同じ統計量に加えてテキスト系の特徴などたくさん作っている ○ 同じB-に対する予測は基本的にsortして予測確率が高いものを選択 3 B-Lead 正解 候補1 候補2 候補N

Slide 32

Slide 32 text

32 Postprocess (2/2) ● Lead, Position, Concluding Statementなどは大体1文章に1つなので、予測値が 最大のもののみを選択 (2nd) ● 予測したクラスの長さによっては、後ろにいくらかずらす (2nd) ● Beam Searchで候補を複数出した後に、予測範囲が50%以上被っているものを同 じグループとして扱い、その中で予測値を平均する (4th) ● 自分と同様にLightGBMなどで最後のTP / FPの部分のみ最適化 (10th, 11th) 3

Slide 33

Slide 33 text

33 その他 (6th Place) ● YOLOの問題として定式化し、以下のラベルを作成 ○ foregroundかbackgroundかのbinary label ○ クラスの開始点と終了点までの距離のRegressionラベル ○ クラス分類のラベル ● Token単位の予測をWord単位に変換するためにRoIAlignを使用 ● Object Detectionでは、物体の真ん中をforegroundとするが、今回はクラスの 開始点をforegroundとした ● NMSで予測を絞り、WBFでアンサンブル 3

Slide 34

Slide 34 text

34 まとめ + 反省 ● 珍しいほどコードが公開されているので、今後もめちゃくちゃ参考になりそう ● アンサンブルはNLPにおいて大事だが、 それにかまけてSingle Modelの改善を怠ると負ける ● Object Detectionなどの他分野の知識も持っておくと有利なことも往々にしてあ る。 ● Do Everything ○ Notebookで1stのアイデアは出てたが、コードが汚い + データセット作成 に数時間かかるみたいな感じで諦めてしまった ○ 1stはコードも綺麗にしてjitなどで高速化していた 3

Slide 35

Slide 35 text

35 4. TIPS

Slide 36

Slide 36 text

36 コンペ中に使ったちょっとしたTIPS 4 ● Notebookコンペで複数種類のモデルをEnsembleしようとすると 特にNLPコンペだとすぐにメモリエラーになってしまう。 ○ %%python で1modelずつ実行することで、毎回メモリを解放してくれる ○ util系も毎回呼び出さなきゃいけないので、Notebookが長くなりがち。 datasetにコードをあげておくと便利。 ○ /tmp ディレクトリを活用して、中間出力などを保存する ● Deberta-xlargeなどの大きいモデルで長いシーケンスを学習させたい ○ Longformerと違って最適化されていないので、メモリ使用量が高い ○ DeepSpeedがいい感じになっていて、メモリ消費量を抑えられる。 ■ pytorch-lightningやtransformersでも提供されている

Slide 37

Slide 37 text

● undetected-chromedriverを使うとseleniumのログイン認証を突破できて、 Submission時間の監視をできる。 ● 上を応用してKaggle Datasetを自動的に削除することも可能 ○ コンペ終了後にKFさんに教えてもらったが、NotebookにGCPアカウント をつないで、GCSからmodelをDownload -> Notebookのoutputにすると Kaggle Datasetの容量を圧迫しないで済む 37 コンペ中に使ったちょっとしたTIPS 4