汎用言語モデルBERTを使うだけ(前提編)

最近、街中でよく「BERT」って耳にしますよね?

だけど「BERTってよく分からない!どうやって使うの?」って人多いと思います。

そこで、BERTの概要とBERTの使い方について調べてまとめてみました!

(chainerでBERTを呼び出す記事が調べた時点で見つからなかったので書いてみました。)


この記事はBERTを利用するだけの人へ向けた前提を雑に解説する記事です。

BERTのモデル構造や理論を知りたい方は原論文や他の解説ページの方が良いです。

BERTを一言で言ってしまうと「自然言語で表された色々な物を上手く数値に変換するモデル」です。

自然言語といえば日本語とか英語とか、Pythonと比べたら自然だよねって言語が思い浮かぶと思います。

自然言語で表せるものには、単語とか、文章とか、繋がった文章とか色々ありますよね。

この色々な物をBERT突っ込むだけで、ベクトルや行列みたいな数値を返してくれます。

どんな文章だろうが、コンピュータで扱えるサイズの数値に変換できてしまえば機械学習タスクに投げられます。


機械学習タスクでできそうなことを下に書いてみます。

・文章分類

・文章に対する何かしら得点の予測(回帰)

・チャットボット等ような文章生成

・2文の関係性を分類

BERTはこう言う事をする場合の文章の読み方をコンピュータに教えるわけです。



これまでにも文章表現を出力する方法は色々あったらしいですが、

BERTが凄いのは

・文章の他の要素との関係性を利用することで、語の多義性やニュアンスの違いが分かる

・普通の文章から複数の文章まで入力に取れてしまう

の2点なんだと思います。



BERTを軽くイメージする例として「サマセット・モームを読んでいます」と言う文章を考えてみましょう。

この文章、「サマセット・モームの作品で一番好きなのは『人間の絆』です。」とはちょっと意味が違うとします。

同じサマセットモームでも「本の総称」なのか「著者自身」なのか、みたいな意味論チックな話です。

(僕の考えた中で極端な例を出してみたので、誤読だったなら教えてください。)


図は中の処理の概念的なイメージです。

入力文中でどの単語とどの単語が関係しているかの重みを計算し、重み付き和(ちょっと怪しい)をそれぞれの単語の表現にします。

この仕組み自体はBERTではなく、Attentionと呼ばれている物です。

Attentionを何層も積み重ねることで、文脈情報を上手く単語の表現に活用できるんだと思います。

何やっているか雑なイメージを書きましたが、実際使うだけなら入力と出力だけ考えれば良いですね。

まずはBERTの入力を考えてみましょう。

入力の形としては、

・[CLS]/サ/マ/セット/・/モー/ム/を/読/んで/います/。/[SEP]

・[CLS]/サ/マ/セット/・/モー/ム/を/読/んで/います/。/[SEP]/(略)/一番/好きな/のは/(略)/[SEP]

のような形が基本です。

「/」で区切っているのは、トークン分割と言う処理で、コンピュータに渡す最小単位です。

意味の最小単位である形態素に分割することもありますが、今回はsentencepieceと言う手法です。

sentencepieceを簡単に言ってしまうと、形態素よりも細かく分けることでコンピュータに「はい、こんな単語知りませーん!」などと言い訳をさせない仕組みです。


[CLS]や[SEP]は特殊なトークンです。

[SEP]があることで、2文以上の入力を扱えます。

[CLS]が重要になるのは出力時ですが、「文章全体の要素を一言で表すとコレ!」と言う出力になります。

次に、出力とモデルの関数との関係を考えましょう。出力の形は、使うべきタスクに合わせて色々あります。

・get_pooled_output

  入力時の[CLS]トークンに対応する特徴量を出力します。

  文章分類や文章についたスコアを回帰するタスクに利用

・get_sequence_output

  文章の単語に対応する数値を時系列で出力します。

  TransformerなどのEncoder-Decoderモデルと呼ばれる物のEncoderに対応します。

・get_embedding_output:

  BERTの内部で行われている単語分散表現(Word2Vecなどで検索するとわかりやすいです)を出力します。

・get_all_enconder_output:

  BERTの全層における出力をリスト型で出力します。

  (sequence_outputが大量に出てくるイメージ)

正直上二つ以外は何に使うのかよくわかりませんが、関数として存在しているようです。



BERTの導入からchainerで呼び出すまでを書くとさらに長くなるので、次回にします。


0コメント

  • 1000 / 1000