cedro-blog

BERTで文章のネガポジ判定と根拠の可視化をやってみる

1.はじめに

 前回のブログでは、事前学習済みBERTをファインチューニング無しでそのまま使って、センター試験や文章生成がどれくらい出来るかやらせてみました。

 今回は、事前学習済みBERTにファインチューニングを行って、文章のネガポジ判定をするタスクを解かせ、根拠を可視化してみたいと思います。

2.事前学習のおさらい

 BERTの事前学習では、2つのタスクを実行します。

 1つ目のタスクは、Masked Language Modelで、穴埋め問題を解かせることで前後の文脈を利用できるようにします。文全体の15%の単語を選び、その内80%マスク、10%を他の単語に置き換え、10%をそのままにします。15%に抑えているのは、この後のファインチューニングでマスクは登場しないのでギャップが大きいとファインチューニングが上手く行かないためです。

 2つ目のタスクは、Next Sentence Predictionで、2つの文が意味的に繋がっているかを判定するものです。

 これらのタスクを学習するには、かなり計算コストがかかり、TPUを4つ使っても4日間くらい掛かるらしいですが、誰かが1回やれば後はファインチューニングで様々なタスクが解けるネットワークができるわけです。

3.ファインチューニング

 ファインチューニングは、事前学習の重みを初期値として、ラベルありデータで行います。事前学習によって地頭が鍛えられているので、少ない文章データから性能の良いモデルが作成可能です。論文では、様々なタスクのファインチューニングの計算コストは、TPU1つで1時間以内で終わったということです。

 以下は、BERTがSoTAを記録した11個のNLPタスクです。

4.今回実装するモデル

 BERTにはモデルサイズの異なる2つのタイプがあり、今回使うのはBaseと呼ばれる小さい方のモデルです。

 BERTの出力は識別用トークンレベル用の2つあり、今回は識別用に全結合層を接続しネガポジ判定を行います。使用するデータセットは、映画のレビュー(英文)の内容がポジティブなのかネガティブなのかをまとめたIMDb(Internet Movie Database)です。

 モデルを学習させることによって、ある映画のレビューを入力したら、そのレビューがポジティブなのかネガティブなのかを判定し、レビューの単語の相互Attentionから判定の根拠にした単語を明示させるようにします。

5.モデルのコード

 BERTモデルを作成し、事前学習済みの重みパラメータをセットします。

 BERTモデルにIMDbのネガ・ポジを判定するLinearをつなげた class BertForIMDbを作成します。

 重みパラメータ更新の部分です。BertLayerの全部の層で行うとヘビーなので、12層ある内の最終層と追加したLinearのみで行います。そして、最適化手法と損失関数を定義します。

6.コード全体と実行

 コード全体は Google Colab で作成し Github に上げてありますので、自分でやってみたい方は、この 「リンク」 をクリックし表示されたシートの先頭にある「Colab on Web」ボタンをクリックすると動かせます。

 コードを実行するとたった2epochの学習で、テストデータの正解率は約90%に達します。

 判定根拠の明示は、HTMLを使ってAttentionが掛かっている単語に赤マーカーを付けます(Attentionの掛かり方が大きいほど濃い赤マーカーにします)。

 これはPositiveと推論した結果の例ですが、fabulous(素晴らしい), wonderful(素敵な), geatest(最高の)などにAttentionが掛かっていて、これを根拠にPositiveを判定していることが分かります。

(参考)
つくりながら学ぶ! PyTorchによる発展ディープラーニング
自然言語処理の王様「BERT」の論文を徹底解説