RNNとLSTMの構造



 自然言語データや時系列データは入力変数の中に系列依存関係の複雑さをもつので、このような系列依存データを用いた推論や予測問題は機械学習問題の中でも困難なもので、画像識別や物体検出問題よりも一段と複雑な課題になります。

 系列連鎖を持つデータの予測においては、各入力信号を独立した入力ではなく、ある種の関係性をもつ一連の入力データとして取り扱い、これらの入力信号に対応した一連の出力データとして出力することが必要となります。単純なニューラルネットワークでは、推論結果は最後の層からのアウトプットとしてのみ出力されるため、一連の入力に対して一連の出力という対応関係で出力することはできません。この課題に応えるために、ネットワークの出力を別のネットワークの入力として利用するような再帰的構造を持ったモデルを構築する必要があります。ここに、ある層の出力は、次の層の入力として利用されるだけでなく、その後の複数の層の入力データとしても利用できるネットワークモデルが登場します。こうしたモデルを Recurisive Neural Network と呼びます。多層パーセプトロン・モデルにフィードバック・ループを組み込んだ構造をしていると理解できます。

 このような Recursive Neural Network の一つのバージョンに Recurrent Neural Network (RNN) と呼ばれるモデルがあります。さらに、 Recurrent Neural Network の拡張バージョンに、Long Short-Term Memory (LSTM) と呼ばれるモデルが登場します。歴史的には、LSTM の第1世代は、AlexNetなどの CNN モデルの登場よりも15年以上前の、LeNetと同時期の1997年に、Hochreiter と Schmidhuber の論文で発表されました。その後、多数の研究者の努力によって開発がつづけられて、音声識別などの自然言語処理や時系列データの分析に応用されるようになっています。

 画像認識分野においては、性能向上を目的として、Alexnet(8層、2012年)、VGG(16または19層、2014年)、GoogLeNet(22層、2014年)、ResNet(152層、2015年)と年を追うごとにその層数を増加させてきました。しかし、層を増やせば増やすほど学習精度が向上するわけではないので、緻密なアーキテクチャの構築によって層数の増加、精度向上が図られました。一方で、RNNそのもののネットワーク構造はフィードバック・ループという再帰的ネットワークを1つ持つだけの単純な構造をしています。これを時系列方向に展開すると、その総数は時系列の長さに比例します。したがって、多くの時系列データは数百ステップ以上の長期のステップを扱うので、RNNの方が深い層数を扱っているとも言えます。

 このページでは、RNN および LSTM の構造を簡単に説明して、自然言語における感情分析やトピック類似性などの推測問題、時系列データの予測問題を処理するために、 RNN 及び LSTM ネットワークをどのように実装できるかを説明します。TensorFlow で RNN のコードを使用するための説明は、この公式サイトにあります。

関連記事
人工知能の入門編
畳み込みネットワークの基礎:CNNからDNNへ
Scikit-Learnを用いた機械学習
Keras を用いたディープラーニング
TensorFlow を用いた物体検出
Pytorch を用いた物体検出
LSTM を用いた時系列分析
MeCab と RNNを用いた自然言語処理
PythonのTutorials/Jupyter Notebook
GitHub repositories

Last updated: 2019.4.26


***********************************************************************
再帰型ニューラルネットワーク(RNN)モデルへの入門
***********************************************************************


RNNの大きな特徴の一つは、時系列上のある時点の入力信号が、それ以降の出力データに影響を及ぼす、ということです。過去の情報を基に予測できるということにあります。言い換えると、隠れ層の値を再び隠れ層に入力するというネットワーク構造にしたのが、RNNです。下の図は、この隠れ層に戻すという操作を、時間軸方向に展開した図になります。入力信号の時系列データを \[ x_1, x_2, . . , x_n \] とし、それに対応した出力データを \[ y_1, y_2, . . . ,y_n \] とします。以下の図のように処理されます。
RNN.gif
Recursive Neural Network(https://deepinsider.jp/tutor/introtensorflow/whatisrnnから引用)

Recursive Neural Networkの中でも、図のように隠れ層同士の結合が時系列に沿って直線的であり、かつその隠れ層が同一構造であるような場合を「RNN」と言います。 \( x_1 \) の矢印をたどっていくと、 \( y_1 \)から\( y_n \) まで到達する。つまり \( y_1 \)から\( y_n \) に影響する。同様に\( x_2 \)は\( y_2 \)から\(y_n \) に影響しています。 RNNの隠れ層において、再帰的に出現する同一のネットワーク構造のことをセル(cell)と呼びます。図の中の黒く塗りつぶした四角形の部分です。時刻\( t \)に対応する、このセルを含む隠れ層の出力を\( h_t \)とし、入力信号を\( x_t \)と表記します。このとき、隠れ層の出力は \[ h_t = \tanh (h_{t-1} W_h + x_t W_x + b) \] と計算されます。活性化関数は通常はSigmoid 関数ですが、ここでは、\( \tanh \)関数を使用しています。RNN には重みが2種類あり、入力信号を変換する重み\( W_x \)と、一つ前の時刻での隠れ層の出力\( h_{t-1} \)を次の時刻の出力に変換するための重り\( W_h \)です。\( b \)はバイアスです。\(h_t, x_t \)は行ベクトルとします。

 RNNは、時間的構造の表現を取り扱えるので、自然言語や時系列データなど、連続性のあるデータの識別や生成に使われています。機械翻訳や、音声認識してテキスト化するサービス、文章の生成などで使用されています。原論文は、このサイトからダウンロードできます。


****************************************************************
LSTM(Long Short Term Memory)モデルへの入門
****************************************************************


 LSTMは現在Google Voiceの基盤技術をはじめとした最先端の分野でも利用されていますが、その登場は1997年とそのイメージとは裏腹に長い歴史を持つモデルです。LSTM(Long short-term memory)は、RNN(Recurrent Neural Network)の拡張として登場した時系列データ(sequential data)に対するモデル、あるいは構造(architecture)の1種です。なので、LSTM(Long Short-Term Memory)はRNNの欠点を解消し、長期の時系列データを学習することができる強力なモデルです。その名は、Long term memory(長期記憶)とShort term memory(短期記憶)という神経科学における用語から取られています。LSTMはRNNの中間層のユニットをLSTM blockと呼ばれるメモリセルと3つのゲートを持つブロックに置き換えることで実現されています。LSTMブロックの中身は概略的には下のグラフの様になっています。
lstm.png LSTM ブロック

 LSTMはデータ\( x_t \)を受け取ると、1ステップ前の自身の出力\( h_{t−1} \)と\( x_t \)を使い内部で計算を行い、今回の出力\( h_t \)とします。さらに、\( h_t \)は次回の出力\( h_{t+1} \)を使うためにも使います。これが、過去の出力を自身の入力にフィードバックしていた原始的なリカレントネットワークの隠れ層の部分です。入力側には、4つの矢印で表記されたエッジがあります。もっとも下の矢印(ゲート)から入る経路がこれです。output gate と呼ばれます。そこでの計算は \[ o_t=\sigma (x_t \cdot W_o+h_{t−1} \cdot R_o+b_o) \] となります。ここで、\( \sigma \)は活性化関数です。\( W_o, R_o \)は重み行列です。

 入力側の一番上位に位置する矢印が forget gate と呼ばれるゲートで、そこから入った信号は \[ f_t=\sigma (x_t \cdot W_f + h_{t-1} \cdot R_f + b_f) \] の計算で処理されて、メモリセルの方向に送られます。メモリセルにあるデータ(\( c_{t-1} \))を用いて \[ c_{t−1}\otimes f_t \] という計算が行われます。ここで、\( \otimes \)はアダマール積を表記します。上から2番目の矢印が input gate と呼ばれるゲートで、 \[ i_t=\sigma (x_t \cdot W_i + h_{t-1} \cdot R_i + b_i) \] と処理されます。その下のゲートから入った信号は \[ z_t=\tanh (x_t \cdot W_z + h_{t-1} \cdot R_z + b_z) \] と計算されます。この計算結果は input gate から送られた情報とともに、 \[ c_t=i_t \otimes z_t+c_{t−1} \otimes f_t \] という計算で処理されます。このデータがメモリセルに追加されます。ここで、\( c_{t-1} \)は、メモリセルにある過去、時刻\( t-1 \)のデータを表します。メモリーセルから出てくる点線は\( c_{t−1} \)という前の時刻の値を出しています。メモリセルは、\( c_t \)という値を次の計算に渡したり、\( c_{t−1} \)という値を保持するという役割を持っているだけで、特別な計算はしません。最後に、LSTMの出力が \[ h_t=o_t \otimes \tanh(c_t) \] と計算されます。

 LSTMのその最も大きな特長は、従来のRNNでは学習できなかった長期依存(long-term dependencies)を学習可能であるところにあります。例えば、下のような時系列 \[ (z,x_1,x_2,⋯,x_p,z) \] を受け取り、次のステップ値の入力を予測するような学習器を考えます。\( z \)が入力されたのち\( p \)ステップ後に再び\( z \)を受け取っています。この系列を正しく学習するためには、最初の要素の情報を少なくともp ステップ維持する機能を持つようにネットワークの重みを更新する必要があります。通常のRNNでも数十ステップの短期依存(short-term dependencies)には対応できるのですが、1000ステップのような長期の系列は学習することができませんでした。LSTMはこのような系列に対しても適切な出力を行うことができます。

 時系列データの代表例として想定できるものは、電波、音声波形、株価指数、為替レート、気温変化などです。通念では時系列データとして想定されないものとして、文章(単語列)などがあります。電波の波形なら一定の時間間隔でのサンプル値になりますし、文章なら単語を前から並べたときの番号になります。文章生成ならば、今までの単語列を入力として、もっともらしい次の単語を予測することが課題となります。正しい文章
the monkey ate the apple
を繰り返しLSTMに覚えさせる(重みベクトルを更新する)ことで、"monkey"の後に"ate"が来るようなルールを学習することができます。音素・音声認識の場合、今までの音声波形(orその特徴量)を入力として、その時点で発話されている音素を予測することが課題になります。

____ 準備中 ____

LSTM を用いた時系列分析
RNNを用いた自然言語処理のページへ
畳み込みネットワークの説明のページへ
トップ・ページに戻る