キカベン
機械学習でより便利な世の中へ
G検定対策
お問い合わせ
   

音声処理と自然言語処理

thumb image

1. 学習目標🔝

音声と言語の時系列データをモデルで取り扱うためのニューラルネットワークモデルと最新の研究成果などを理解する。

  • データの扱い方
  • RNN(リカレントニューラルネットワーク)
  • Transformer
  • 自然言語処理におけるPre-trained Models

キーワードLSTMCECGRUBidirectional RNN(双方向RNN)RNN Encoder-DecoderBPTTAttentionA-D変換パルス符号変調器高速フーリエ変換スペクトル包絡メル周波数ケプストラム係数フォルマントフォルマント周波数音韻音素音声認識エンジン隠れマルコフモデルWaveNetメル尺度N-gramBag-of-Words(BoW)ワンホットベクトルTF-IDF単語埋め込み局所表現分散表現word2vecスキップグラムCBOWfastTextELMo、Sour言語モデル、CTCSeq2SeqSource-Target AttentionEncoder-Decoder AttentionSelf-Attention位置エンコーディングGPTGPT-2GPT-3BERTGLUEVision Transformer構文解析形態要素解析

2. データの扱い方🔝

2.1. 時系列データ🔝

時系列データ(時間依存のデータ)では、ある時刻の状態が、それ以前の時刻の状態に依存する。

例えば、株価の動きなど。

テキストデータも時系列データの一種とみなす。

つまり、すでに入力されたデータ(株価や単語など)がその後の予測に影響を与えるため時系列データと考えることができます。また、画像データの連続である動画データや音声データも同様に前後のデータの依存性があるため時系列データの一種として扱えます。

2.2. 音声データ🔝

音声データは連続的なアナログデータなのでA-D変換(analog to digital converision)によって離散的なデジタルデータに置き換えられる。パルス符号変調器(pulse code modulation、PCM)という手法が一般的に使われる。PCMは連続的な音波を一定時間ごとにサンプルし、離散的な値で近似する。

また、高速フーリエ変換(fast Fourier transform、FFT)は音声信号を周波数スペクトル(さまざまな三角関数の組み合わせ)に変換する。スペクトルとは音声信号などの強度を周波数毎に分解した分布を言います。横軸を周波数、縦軸を強度(大きさ)に分解したもの。

下図左が音声の入力データを時系列で表したもの。右がその周波数スペクトル。

画像元:wikipedia

音色の違いはスペクトル包絡(スペクトル上の緩やかな変動)の違いと解釈される。人間が感じる音高を測るものとしてメル尺度音高の知覚的尺度)があり、メル尺度の差が同じだと人間が感じる音高の差が同じになるのを意図している。このメル尺度を使ったスペクトル包絡はメル周波数ケプストラム係数(Mel-frequency cepstrum coefficients、MFCC)を用いる方法で求められる。MFCCは入力音のスペクトル包絡を係数列で表現できるので特徴量として扱うことができ、音声認識エンジンなどで使われる。

スペクトル包絡には周波数によって山(ピーク)と谷があり、ピークをフォルマントと呼び、その周波数をフォルマント周波数と呼ぶ。なお、音声の音韻(人間が発声する区別可能な音)が同じならばフォルマント周波数が近い値になる(個人差があり)。

音声認識モデル(音響モデル)としては、隠れマルコフモデル(hidden Markov model、HMM)がながらく標準だった。HMMは音素(言語に依存する最小区分の音)ごとに学習する。単語と音素列の対応辞書に従ってHMMを連結すれば、単語を認識するモデルとなる。

2.3. WaveNet🔝

人の音声を合成するWaveNetはディープラーニングを使って自然な音声を作り出す。これはアルファ碁で有名なDeep Mindが開発したもので、Android端末の「Google アシスタント」の合成音声として使用されている。

なお、WaveNetはRNNではなくCNNを使っている。PixelCNNというモデルをベースにしており、Dilated Causal Convolutionという層が深くなるにつれて受容野(時系列データのどこまでを取り入れるか)が広がっていく仕組みを利用しています。

画像元:Deepmind

2.4. テキストデータ🔝

テキストデータを単語単位で扱うと、文章は複数個の単語を並べたものとして表現することができる。単語を一つずつ別に扱うのでユニグラム(uni-gram)と呼ばれる。単語を2つまとめて扱う場合はバイグラム(bi-gram)、3つではトライグラム(tri-gram)と呼ぶ。これら全てをn-gram(nはまとめる単語の個数)と称し、ユニグラムはn=1、バイグラムはn=2、トライグラムはn=3の場合となる。

# 文章例
'機械学習は楽しい'

# 単語単位ユニグラム
['機械学習', 'は', '楽しい']

# 単語単位バイグラム
['機械学習は', 'は楽しい']

また、もっと細かく文字ごとに扱う場合もn-gramの概念を適用することができる。

# 文章例
'機械学習は楽しい'

# 文字単位ユニグラム
['機', '械', '学', '習', 'は', '楽', 'し', 'い']

# 文字単位バイグラム
['機械', '械学', '学習', '習は', 'は楽', '楽し', 'しい']

文章の中の単語を数値として扱うためにIDを付与します。これをベクトルとして表現したものがワンホットベクトルです。簡単な例として3つの単語しかないケースで説明します。

# 単語にIDを付与
{'機械学習':0, 'は':1, '楽しい':2}

# ワンホットベクトルにする
'機械学習' => [1, 0, 0] # IDが0
'は'    => [0, 1, 0] # IDが1
'楽しい'  => [0, 0, 1] # IDが2

このベクトルを使って文章を単語の数で表現することができます。

# 文章
'機械学習は楽しい'

# ワンホットベクトルの足し算で表現
[1, 0, 0] + [0, 1, 0] + [0, 0, 1] = [1, 1, 1]

# 文章
'機械学習は楽しい楽しい'

# ワンホットベクトルの足し算で表現
[1, 0, 0] + [0, 1, 0] + [0, 0, 1] + [0, 0, 1] = [1, 1, 2]

このようにワンホットベクトルで文章内の単語の出現頻度をベクトルとして表現したものをBag-of-Words(BoW)と呼びます。単純なケースでは「楽しい」の頻度が高ければ、ハッピーな文章だと推測でき感情分析になります。BoWはスパムメールの推測にも使われました。ただし、たくさんの文章を扱うためにはワンホットベクトルのサイズはかなり大きなものになります。

BoWでは単語の位置は考慮しないので、単語の出現順序を考慮したい場合は、n-gram(n>1)を使ったBag-of-n-gramsを使うこともあります。

文章を1文ずつBowベクトルで表現し並べれば行列になり、線形代数を利用したさまざまな分析が可能となります。また、情報の圧縮なども可能になります。

文章同士の類似性(コサイン類似性)を計算することもできます。この場合、たくさん使われている単語でも重要ではないものがあるなどの理由から、単語の出現頻度よりもTF-IDF(term frequency – inverse document frequency)による単語の重要度を使います。

項目意味
TFある文章内における各単語の頻度ある文章(1000単語)で「機械学習」が20回出現。
頻度は2%なので$\text{TF}=0.02$
DFある単語が出現する文章の頻度100の文章のうち「機械学習」が25の文章に出現。
頻度は25%なので$\text{DF}=0.25$
IDFDFの逆数の対数$\log \frac{1}{\text{DF}} = \log_2 \frac{1}{0.25} = \log_2 4 = 2$
TF-IDFTFとIDFを掛け合わせたもの$\text{TF} \times \text{IDF} = 0.02 \times 2 = 0.04$

ある単語が比較的少ない文章で使われているとします。その単語がある文章で多くみられた場合、その単語がその文書において重要であると考えられます。これを数値で表したのがTF-IDFです。

なお、IDFで対数を使っているのは出現数が大きくなると数の差にあまり意味がなくなるからです。極端なケースでは「機械学数」が100万回出現する場合と200万回する場合では両方とも大量に出現しており重要度にあまり差がないと考えられます。

2.5. 単語埋め込み🔝

ワンホットベクトルは単語の数だけ次元が増えるので多くの文章を扱うには非常に高次元なものが必要となります。また、単語同士の意味の近さなどを計算することもできません。このように単語ごとに別々に表現する(1つの単語を1つの成分で表す)ことを局所表現(local representation)と呼びます。

逆に、1つの単語を複数の成分で表すことを分散表現(distributed representation)または単語埋め込み(word embedding)と呼びます。似た概念の単語が似た成分を持つようになるので意味の近さを計算することが可能となります。分散表現をするとワンホットベクトルよりも低い次元になるのも利点です。

word2vec(word to vectorの略)は分散表現の代表的な手法です。Googleのトマス・ミコロフらによって2013年に特許が取得され公開されました。word2vecでは分布仮説(単語の意味はその単語の周辺の単語によって定まる)をニューラルネットワークを用いた推論ベースの手法で表現しました。word2vecで単語の分散表現を生成する手法にはCBOW(continuous Bag-of-Words)とスキップグラム(skip-gram)の2種類があります。

CBOWでは各単語の文脈(周りの単語)を入力として、その文脈に当てはまる単語を予測・推論します。逆に、スキップグラムではある単語を入力として文脈を予測します。

画像元:論文

これらの手法で訓練されたニューラルネットワークにある単語を入力すると、隠れ状態(隠れ層からの出力をベクトルとして取り出したもの)がその単語の意味を示す値、つまりは分散表現(単語埋め込み)となります。

このようにして抽出された単語の意味ではベクトル演算をすることができます。有名な例は、「王様」ー「男性」+「女性」=「女王」があります。

また、国名と首都名のベクトル値の主成分分析(PCA)を行い2次元に次元圧縮した図で関係性を表すこともできます。

トマス・ミコロフらはword2vecをベースにfastTextを開発しました。fastTextでは単語の埋め込みの学習において文字列の情報も含めることで訓練データに存在しない単語(out of vocabulary、OOV)でも単語埋め込みの計算ができます。また、訓練に要する時間も短くなりました。

word2vecでは多義性(単語には1つ以上の意味がある)を扱うことができません。そこで、新たに提案されたELMo(embeddings from language models)では文脈を考慮した分散表現が得られるようになりました。

3. RNN(リカレントニューラルネットワーク)🔝

3.1. RNNの基本形🔝

RNN(recurrent neural networks)は時間や順序に依存するデータの特徴を抽出し予測などを行うニューラルネットワークです。時間に依存するデータを扱うので、過去に隠れ層から抽出されたものを現在の入力に追加します。

単純なRNNを数式で表します。活性化関数にはtanhを使っています。

$h_t = \text{RNN}(h_{t-1}, x_t) = \text{tanh}(h_{t-1} W_h + b_h + x_t W_x + b_x)$

  • $h_t$は隠れ層からの出力値(現在)
  • $h_{t-1}$は隠れ層からの出力値(過去。一つ前の時点)
  • $W_h$は隠れ層の出力値に対する隠れ層の重み
  • $x_t$は入力値(現在)
  • $W_x$は入力値に対する隠れ層の重み
  • $b_h$と$b_x$はバイアス

つまり、RNNでは隠れ層によって生み出される状態値$h_t$が次の時刻へと渡されることになり、状態あるいは記憶をもつニューラルネットワークだと言われます。ただし、状態の値がRNNの中に格納されているわけではありません。

図にすると以下のようになります。(tanhは省略してあります)

これを次の時間$_{t+1}$へ続けていくと次のようになります。

これを式で書くとこうなります。

$h_{t+1} = \text{RNN}(h_t, x_{t+1}) = \text{RNN}(\text{RNN}(h_{t-1}, x_t), x_{t+1})$

入力値$h_{t-1}, x_t, h_t, x_{t+1}$の関係がわかるように上図2つを結合して1つの図にします。

RNNの箱が2つありますが同じものです。さらに時系列に沿って延長できます。

入力値が$x_t, x_{t+1}, …, x_{t+n}$とある場合のRNNを図で示します。左から右へと順番にデータが流れます。

何らかの予測などを行う場合は、最後の出力値$h_{t+n}$をさらに全結合層や活性化関数などに通して最終的な出力値を計算します。例えば、過去5分間の株価から10秒後値段を予測するようなケースが考えられます。その際$_{t+n}$が現在時間で$_{t+n+1}$が未来の時間となります。実際にそんな単純に予測できるとは限りませんが。

なお、RNNに過去の隠れ層からの出力値を受け渡してはいますが、そのことを除けば通常のニューラルネットワークと同じです。記憶があるというより、我々が記憶を渡していると言った方が正確かもしれません。ただし、Pythonなどで実装する場合は、クラスメンバー変数に隠れ層からの値を格納したりするので、記憶しているという表現がより似合っています。

同じ図をより簡潔に描くこともできます。

このほうが時系列に入力値と隠れ状態(隠れ層からの値)が並んでおり分かりやすくもあります。なお、RNNの箱から次のRNNの箱へ直接の矢印が描かれるのも見かけますが、意味としては同じで隠れ状態(コピー)を渡しているということです。繰り返しますが、全ての箱は同じものです。

式で書き出すとこうなります。

$h_{t+n} = \text{RNN}(h_{t+n-1}, x_{t+n}) \\ \ \,\quad = \text{RNN}(\text{RNN}(h_{t+n-2}, x_{t+n-1}), x_{t+n}) \\ \ \,\quad = \text{RNN}(\text{RNN}(\text{RNN}(h_{t+n-3}, x_{t+n-2}), x_{t+n-1}), x_{t+n})\\ \ \,\quad = \text{RNN}(\text{RNN}(\text{RNN}(…\text{RNN}(\text{RNN}(\text{RNN}(h_{t-1}, x_{t}), x_{t+1}), x_{t+2}), …), x_{t+n-1}), x_{t+n}) \\ \ \,\quad = F(h_{t-1}, x_t, x_{t+1}, x_{t+2}, …, x_{t+n-1}, x_{t+n})$

RNNは$(h_{t-1}, x_t, x_{t+1}, x_{t+2}, …, x_{t+n-1}, x_{t+n})$が入力値の関数$F$と表現できるので活性化関数が微分可能であれば誤差逆伝播ができるのが分かります。時間軸に沿って誤差を反映していくのでBPTT(back-propagation through-time)と呼びます。

RNNを何層にも積み重ねることも可能です。

第1層のRNNからの隠れ層の値が第2層(青色)の入力になります。第2層からの出力$g_t, g_{t+1}, …, g_{t+n-1}, g_{t+n}$の値に結合層やソフトマックス関数などを追加すれば時間ごとの出力を得ることもできます。つまり、複数の入力に対して同じ数の出力を出すこともできます。

入力する値の数と出力する値の数が異なるときは、CTC(connectionist temporal classification)が使えます。例えば、音声データを時間軸に沿って入力した時に音声の音素を出力すると音声認識ができますが、音声データの数と音素の数は必ずしも一致するとは限りません。CTCでは予測された音素で連続しているものをまとめます。また、本当に連続した音素には空文字を間に挟むことで縮約しないようにします。

画像元:distill.pub

RNNでは時間軸を長く展開すると深いニューラルネットワークになり勾配消失問題が生じます。つまり、過去になればなるほど誤差を逆伝播しにくくなります。この問題を緩和するのに成功したのがLSTMになります。

3.2. LSTM🔝

LSTM(long short-term memory)はLSTMブロックを導入して必要な情報だけ次へと渡す(不要なものは忘れる)ようにコントロールできるようにしました。

RNNの図を違いが分かりやすいように描くと下図になります。黄色い箱はニューラルネットワークです。

LSTMブロックは下図になります。ピンクの$\tanh$は要素ごとに適応されます。

一番下の$c_{t-1}$(セル)が入力に加わりました。セルだけに注目してみるとこうなります。

セルによって状態が前から次へと運ばれていきます。このセルからデータを消去したりデータを入力したりすることで必要な情報をコントロールしていきます。情報の出入りをコントロールするネットワークをゲート(gate)と呼び、シグモイド関数($\sigma$)が使われているニューラルネットワークになっています。それぞれのゲートは$h_{t-1}$と$x_t$を入力とし各要素に対して0から1の値を出力します。

まず、$c_{t-1}$と忘却ゲートで要素ごとの積を計算し、$c_{t-1}$のどの要素をどのくらい忘れるか(覚えておくか)を決めます。$\bigotimes$は要素ごとの積を意味します。

忘却ゲートを式で書くとこうなります。

$f_t = \sigma(W_{f} \cdot [h_{t-1}, x_t] + b_f)$

$[h_{t-1}, x_t]$は$h_{t-1}$と$x_t$を連結したものです。

次に、$\tanh$(ネットワーク)の出力と入力ゲートで要素ごとの積を計算し、$c_{t-1}$のどの要素をどのくらいアップデートするかを決めます。$\bigoplus$は要素ごとの和(足し算)を意味します。

入力ゲートを式で書くとこうなります。

$i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)$

これと中間出力値である$\tilde{c}_t$との要素積を計算します。

$\tilde{c}_t = \tanh(W_c \cdot [h_{t-1}, x_t] + b_c)$

ここまでをまとめると、セルは以下のように更新されます。

$c_t = f_t \otimes c_{t-1} + i_t \otimes \tilde{c}_t$

最後に、更新されたセルを$\tanh$(関数)に通した値と出力ゲートで要素積を計算し$h_t$として次に渡す値を決めます。

出力ゲートを式で書くとこうなります。

$o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)$

よって、$h_t$は以下のように計算されます。

$h_t = o_t \otimes \tanh(c_t)$

このようにして必要な情報を伝播し不要なものは切り捨てるリカレントニューラルネットワークが出来ました。セルのお陰で勾配消失が生じにくくなっています。また、セルはCEC(constant error carousel)とも呼ばれます(誤差を内部にと止めるの意味)。端的に言うとセルによって長期に渡って必要な情報を記憶することが可能となりました。

さらに、LSTMはRNNにおける入力重み衝突(今は必要ないけど後で必要ある入力データがあると重さを一意に決められない)や出力重み衝突(今は必要ないけど後で必要ある出力データがあると重さを一意に決められない)を入力ゲートと出力ゲートで解決しました。

なお、LSTMにはさまざまなバリエーションがありますが、3つのゲートがあると言う点では同じです。

参照Understanding LSTM Networks(colah’s blog)

3.3. GRU🔝

GRU(gated recurrent unit)はLSTMを簡略化したものです。セル無しでもLSTMと似たようなモデルを作ることに成功しました。リセットゲートと更新ゲートの2つのゲートがありLSTMにおける3つのゲートの役割を果たしています。LSTMよりも重み(パラメータ)が少なくなるのでLSTMの代わりに用いられることもあります。ただし、LSTMの方が長期記憶性では優れています。

3.4. Bidirectional RNN(BiRNN)🔝

Bidirectional RNN(BiRNN、双方向RNN)は時間の進む方向だけでなく、逆方向も取り入れます。そうすることでより状況や文脈が組み込まれた情報を抽出できます。

順方向を扱うRNNをAとします。AはどのRNNでも構いません(LSTMやGRUなど)。

逆方向を扱うRNNをBとします。AもどのRNNでも構いませんが、よくある実装ではAとBは同じタイプになっています。逆方向からデータが流れていますが180度回転してみれば通常のRNNです。

順方向と逆方向それぞれの最終隠れ状態$h_n$と$g_n$を全結合層などに渡して何らかの予測や判断を行うこともできます。

また、全ての値を使って時系列に沿った予測をしたい場合は両方の出力を合わせます。以下のように、2つのRNNからの出力を合わせたものが各時刻(ステップ)の入力値に対応しています。

つまりうわべ上は通常のRNNのように各入力値に対して隠れ層からの出力があるのと同じに見えます。この出力を全結合層(ここではOと呼びます)などに渡して最終的な出力とすれば時系列での予測になります。

PyTorchなどでは、LSTMのパラメータでbidirectional=Trueとすれば双方向のLSTMになります。

3.5. エンコーダ・デコーダ🔝

RNNのモデルの出力は1つだけの場合や複数の出力の場合(例えば、時系列による場合や言語の翻訳など)が可能です。特に複数の場合はSeq2Seq(sequence-to-sequence)と呼ばれます。また、機械翻訳では入力文と出力文の長さは必ずしも一致しません。

RNN Encoder-Decoderは2つのRNNを組み合わせることで可変の出力数に対応します。エンコーダ(encoder)が入力データを符合化(エンコード)した情報をデコーダ(decoder)が復号化(デコード)していきます。デコーダは予測した出力値を次の入力として使います。

一般的にエンコーダ・デコーダは、入力データを処理するネットワークをエンコーダ、出力を生成するネットワークをデコーダとして持つもので、必ずしも両方がRNNである必要はありません。用途によっていろんなパターンがあります。例えば、Image captioning(入力画像の説明文を生成する)ではエンコーダは入力画像を処理するCNNで、デコーダは説明文を生成(自然言語処理)するRNNになります。

このSeq2Seqの弱点としては、エンコーダの情報が1つのベクトルに押し込められているため入力情報が多くなると対応しきれなくなることです。この問題はAttentionを導入することで解決されました。

なお、訓練中は教師強制(teacher forcing)を使うこともあります。デコーダの予測出力を次回の入力値として渡すのではなく正解データ(教師データ)をデコーダの次の入力値として渡す手法です。利点としては学習が安定しやすく損失値の収束が速くなります。ただし、本番では予測出力を次の入力としてデコーダに渡すので予測誤差が累積する可能性が高くなります。

3.6. Attention🔝

AttentionあるいはAttention mechanism(注意機構)と呼ばれる仕組みではエンコーダから出力された全ての隠れ状態(隠れ層からの出力)をデコーダから利用できるようにします。

デコーダの各ステップでは必要な情報を選りすぐって使うのですが、その選別の仕方がAttentionという手法になります。デコーダからの第1出力の部分を拡大してAttentionを説明します。

まず、デコーダには通常通りエンコーダからの最終隠れ状態$h_n$と開始を知らせる値を入力値として渡します。そしてデコーダは隠れ状態$g_1$を出力します。

次に、この隠れ状態$g_1$と関連した情報を$h_1, h_2, …, h_n$から取り寄せます。そのため、$g_1$と各$h_i $でスコアを計算します。この計算にはニューラルネットワークやベクトルの内積などが使われますが、ここでは単に$\text{score}(h_i, g_1)$としておきます。値が大きいほど関連性が高くなります。

この値をソフトマックスで確率(重さ)に変換します。この重さはAttention weightと呼ばれ、各$h_i$に対して計算されるので$w_1, w_2, …, w_n$としておきます。これらの重さによって各$h_i$の$g_1$に対する関連性の優劣が分かります。

さらに、$w_1, w_2, …, w_n$と$h_1, h_2, …, h_n$とで加重平均($\sum_{i=1}^n w_i h_i$)を取ることでエンコーダの全ての隠れ状態から$g_1$に関連した情報を取り出すことが出来ます。

この一連の仕組みをAttentionと呼び、Attentionからの加重平均値のベクトルと$g_1$のベクトルを出力用のニューラルネットワーク(O)に渡すことで第1番目の出力が完成します。

Attentionを取り入れたRNN Encoder-Decoderは下図のようになります。

以上、RNNの発展形をみてきました。しかし、RNNには並列処理ができないという問題があります。時間軸に沿って順番に処理する必要があるからです。また、遠く離れた単語間の関係を捉えるのが難しいのも難点です。

これらを克服するためにRNN以外の手法が研究されています。特に、Transformerは有名です。

4. Transformer🔝

Transformer(トランスフォーマー)は2017年に発表されました。並列処理ができ離れた単語間の関係もよく捉えられるニューラルネットワークです。TransformerはSelf-Attention(自己注意機構)とSource-Target Attention(あるいはEncoder-Decoder Attention)から成り立っておりRNNが排除されています。RNNよりも高速な学習が可能でしかも精度が高く、Googleの機械翻訳でも部分的に取り入れられています。

Self-Attentionはある文の単語間の関連度を計算したものになります。

例えば、「テスト勉強は今夜が山だ」と「明日は山に登る」の2つの文で「山」という単語が使われていますが、文脈が異なるので意味も違います。Self-Attentionを使うと「山」という単語の埋め込みだけでは捉えきれないものを文脈から抽出して埋め込みに追加することができます。また、Self-Attentionの計算は全ての単語に対して並列で処理できます。

Transformerはエンコーダ・デコーダの一種ですが、Self-Attentionを使うことでRNNを取り除きました。ただし、単語の順番は重要なので、位置エンコーディング(positional encoding)によって単語の位置を埋め込みに加えており、単語の位置関係も文脈と同時に捉えれれるようになっています。

Self-Attentionはデコーダでも使われますが、こちらは単語の文脈としてその単語以前に現れたものだけを考慮するようにしています。訓練の時に正解の文章を全て見せては意味がないのでそこは隠しておくということです。つまり、デコーダは単語を生成していくので将来現れるべき言葉をマスク(ゼロに)した文の埋め込みを使ってSelf-Attentionを計算します。

さらに、デコーダはエンコーダからのSelf-Attentionの出力を使って、2つの文の単語間の関連度を計算するSource-Target Attentionの処理を行います。これはRNNベースのエンコーダ・デコーダにAttentionを加えたのと同じ考えで、デコーダにもっと情報を与えることができます。

Transformerの全体図は以下のようになります。

画像元:論文

左側がエンコーダで右側がデコーダです。下から上に向かってデータが流れます。$N\times$となっているのは$N$回にわたって同じブロックが繰り返されているという意味で、論文では$N=6$となっています。

エンコーダから見ていきます。入力データが単語の埋め込みによって数値ベクトルに変換されます。単語一つの埋め込みの次元は512です。訓練ではバッチ形式で複数の文をまとめて入力します。よって入力バッチ全体は[バッチサイズ、入力文の最大長、512]となります。この埋め込みデータに位置エンコーディングの値が加算されます。

Multi-Head Attentionと書かれているのはSelf-Attentionの処理を行う部分です。Multi-Headと呼ばれる理由は512次元の値を8個の代表的な64次元空間へ投影した値を使うからです。イメージで言うと512次元からなる単語の空間をいくつかのグループに分けた感じになります。例えば、動詞のグループ、名詞のグループなどがありそうですが、これもネットワークによって決められます。こうしてそれぞれの単語に文脈からの意味などを加えたものがさらに全結合層やスキップ結合などを経ていくことを$N=6$回繰り返して出力したものをデコーダに渡します。

デコーダには正解データ(文)をバッチ形式[バッチサイズ、出力文の最大長、512]で与えます。エンコーダと同様に単語埋め込みと位置エンコーディングの処理が施されます。

Masked Multi-Head AttentionもMulti-Head Attentionと同じ処理ですが、各単語に対してその単語以降の単語をマスク(全ての要素を0に)します。よってまだ予測していない単語の文脈を与えることがないようになります。この結果とエンコーダからの出力とでSource-Target Attentionの処理をし、さらに全結合層やスキップ結合などの処理が施されます。これが$N=6$回繰り返されて最終的な出力が予測として出ます。出力形式は、[バッチサイズ、出力文の最大長、全単語数]です。全単語数のところはどの単語が出力されるべきかの確率になります。仮に、出力文の最大長が5だとして、使える単語の数が1000だとすると、1単語につき1000個の単語からどれを選ぶべきかの確率を出すことになり、全部で5000個の数値がバッチサイズ分出力されます。

5. 自然言語処理におけるPre-trained Models🔝

自然言語処理の分野でも画像処理分野と同じように事前学習したモデルを使って転移学習をすることができます。例えば、以下のようなタスクを行います。

タスク説明
自然言語推論(natural language inference, NLI)
含意関係認識(recognizing textual entailment, RTE)
2つの文章の内容に矛盾があるか。
一方が他方を含意するかなどを判断する。
質疑応答(question answering)
常識推論(commonsense reasoning)
ある文章に対して質問が与えられる。
複数の解答から答えを選択する。
意味的類似度判定(semantic similarity)2つの文の意味が同じかどうかを判断する。
文書分類(document classification)
評判分析
文書のクラスを推定する。

これらのタスクでは文章の内容や背景を理解する必要があり、言語理解タスクと呼ばれます。また、言語理解タスクを評価するためにGLUE(general language understanding evaluation)というベンチマークがあります。

5.1. GPT🔝

GPT(generative pre-training)はOpen AIによって開発された事前学習モデルです。大規模なコーパスを使って言語モデルの学習を行い、Transformerのデコーダのような構造を持ったネットワークになっています。GPTにある文を与えて出力された状態を使って予測などのタスクを行えるように転移学習を行うことができます。例えば、感情分析(sentiment analysis)など。

5.2. BERT🔝

BERT(bidirectional encoder representations from Transformers)はGoogleが開発した事前学習モデルです。名前にある通りTransformerのエンコーダを利用しています。また、双方向(bidirectional)の情報を使います。

BERTの事前学習ではMasked Language Model(MLM)とNext Sentence Prediction (NSP)という手法を使います。MLMは文の一部をマスクしておいて、そのマスクされた単語を予測するタスクです。NSPは2つの文を与えて、その2つの文が連続したものかどうかを判断するタスクです。

これらのタスクで学習することで文章から情報の抽出を行えるようになり、それを転移学習で使うことができます。例えば、単語の最終状態を使って品詞のタグ付(part-of-speech tagging、名詞、動詞、冠詞など識別する)をしたり、固有表現解析(固有名詞、日付、時間など辞書になり言葉を識別する)を行ったりできます。また、SQuAD(Stanford question answering dataset)のように文章内の複数の単語を使って質問に答えるタスクも行えます。

また、BERTを使った日本語の構文解析形態要素解析なども行われています。

形態要素解析、あるいは形態素解析とは文章などを意味を持つ最小単位(形態素)に分割することです。品詞による語尾の変化なども考えて区別するので単なる単語とも異なります。また、英語ではスペースがあるので形態素に分割されているように見えますが、品詞情報などを付与する必要があるので形態素解析は必要となります。造語新語を確認するための辞書(情報登録なども含め)があるとより正確に解析できます。

5.3. Pre-trained Modelの発展🔝

GPTのパラメータ数は約1億。BERTは約3億。その後、精度を落とさずにパラメータ数を削減するためにALBERTDistilBERTが提案されました。

その一方で、2019年2月に登場したGPT-2のパラメータ数は約15億で機械翻訳もできるようになりました。2019年9月に登場したNVIDIAのMegatron-LMは約83億のパラメータを持ち、2020年2月に登場したMicrosoftのTuring-NLGは170億のパラメータを持ちました。さらに、2020年5月に登場したGPT-3はパラメータ数は1750億になって言語生成が非常に高精度に行えるようになりました。

また、Transformerを応用したVision Transformer(ViT)はCNNを使わない画像処理分野の事前学習モデルとして提案されました。



コメントを残す

メールアドレスは公開されません。