LSTM / Long Short Term Memory / 長期短期記憶

LSTMについて。

 

LSTMは、ニューラルネットワークのなかでもRNN(リカレントニューラルネットワーク)に分類されるものです。RNNは時系列データを学習するためのニューラルネットワークで、LSTMはRNNの中でも繰り返し改善が施されたもので、RNNの主流と言っても過言ではないでしょう。画像処理系のCNNとあわせて、昨今のニューラルネットワークの双璧をなしていると個人的には思っています。

 

主たる改善は、LSTM、Long Short Term Memory(長期短期記憶)という言葉が表すように、時系列データのなかから短期的な情報だけでなく、長期的な情報も取り込めるような設計が施されているところにあります。従来のRNNでは勾配消失問題が発生するため、長期的な情報をうまく取り込むことができませんでしたが、LSTMではこの問題が解決されています。

 

LSTMの歴史は(人口知能においては比較的)古く、1997年に論文が発表されています。

http://deeplearning.cs.cmu.edu/pdfs/Hochreiter97_lstm.pdf

その後、LSTMは複数回の改善(Forgate Gate、Peeple Connectioin、Full Gradient)がなされました。

このあたりは、非常に素晴らしい記事であるわかるLSTM ~ 最近の動向と共に - Qiita に詳しく記載されています。

 

LSTMにはLSTM Blockという概念が出てきます。前述までの改善は主にこのLSTM Blockに対してなされているものです。LSTM Blockは太陽系における惑星のようなもので、LSTMを理解するうえで非常に重要な概念ではありますが、これだけではLSTMを理解したというわけにはいきません。LSTMに対する理解の解像度を上げるのであれば、Blockで表示されるチャートで表現される意味を数式で理解することをお勧めします。また、実際にコードを書きたいのであれば、LSTMそのものの理解を実装ベースで深める必要があります。

 

前者についてはイメージはあるのですが、、少し書き出すのに時間がかかりそうです。後者については、TensorflowのLSTMのサンプルが有効だと思います。説明自体は

Recurrent Neural Networks

にあり、コードはGithubにあります。

github.com

特に以下のコードです。

tensorflow/ptb_word_lm.py at master · tensorflow/tensorflow · GitHub

 

2つの特徴的な関数がヒントになります。

BasicLSTMCell

https://www.tensorflow.org/versions/r0.9/api_docs/python/rnn_cell.html#BasicLSTMCell

MultiRNNCell

https://www.tensorflow.org/versions/r0.9/api_docs/python/rnn_cell.html#MultiRNNCell

 

関数を深掘りする前に、このチュートリアルが行っていることを説明しますと、特定の言語サンプルに対する、ある優秀な解析の再現を行っています。

 

特定の言語サンプルとは、PTB(Penn Tree Bank)のことです。以下のサイトで「Basic Examples」として提供されています。

rnnlm.org

該当する、simple-examples.tgzをダウンロードし、tar vxfzで展開すると、data/ ディレクトリの中に、ptb.test.txt (テストデータ) , ptb.train.txt (訓練データ) , ptb.valid.txt (開発データ、ハイパーパラメータの調整用) があります。ptb.test.txtの冒頭を見てみましょう。

no it was n't black monday    

but while the new york stock exchange did n't fall apart friday as the dow jones industrial average plunged N points most of it in the final hour it barely managed to stay this side of chaos ..

ブラックマンデーニューヨーク証券取引所と証券関連の言葉が綴られていますね。

PTBはコーパスというテキストを大量に集めてデータベース化した資料の1つで、データに構造を持たせたものになります。コンパクトにまとめられており、ベンチマークとしてよく利用されるそうです。やや話が逸れますが、日本語のコーパスとしては、小納言というサイトがあります。

KOTONOHA「現代日本語書き言葉均衡コーパス」 少納言

 

次に、ある優秀な解析の部分ですが、2014年に発表されたRNNの正則化に関するZarembaさんの論文に基づいています。

[1409.2329] Recurrent Neural Network Regularization 

 PDFはこちらです。

http://arxiv.org/pdf/1409.2329v5.pdf

 

LSTMでは、過学習を防止するために通常のドロップアウトがうまく機能しないことに対し、ドロップアウトの適応方法を紹介するものです。言語モデリングの応用事例として、上記のPTB(simple-examples)に適応した際の結果が紹介されている他、スピーチの認識、機械翻訳、画像キャプションの生成などへの適応が紹介されています。 

 

BasicLSTMCellについて

 

前置きが長くなりましたが、TensorflowのLSTMに関する関数の1つであるBasicLSTMCellで用いられているLSTMはこの論文に基づいて実装されています。Memory Cellの構造は以下のとおりです。

f:id:neuralnet:20160818220030p:plain

(転載については、Zarembaさんに許可を頂いております)

 

他、97年の初版LSTMに基づいたLSTMCellという関数もあります。

 

(続く)

LSTM/RNNとCNNの組み合わせ

複数言語の同時解釈への応用の観点から、以前からLSTM(もしくは単にRNN)とCNNの組み合わせについて興味がありましたので、調べました。3つほどそれらしい論文があったのでメモを取ります。

 

1. 画像認識と画像抽出のためのLong-term Reccurent Convolution Networks

[1411.4389] Long-term Recurrent Convolutional Networks for Visual Recognition and Description

PDFはこちら: https://arxiv.org/pdf/1411.4389.pdf

動画が対象になっています。動画は、基本的には画像なので、CNNによる処理が有効です。また、連続的なものですから、LSTMが関わってきます。基本的なアプローチはCNNをかけた後、LSTMで処理するモデルです。以下の3つのモデルが紹介されていました。

1)連続的な入力に対して、単一の意味を出力するモデル(動画から「走高跳び」と出力する)

2)単一の入力に対して、連続的な出力をするモデル(静止画から「人」「が」「走っている」と出力する)

3)連続的な入力に対して、連続的な出力をするモデル(動画から「人」「が」「高く」「飛んだ」と出力する)

3はCNNではなくCRFを使っていました。


2. 複数ラベルによる画像分類のための統合フレームワーク

[1604.04573] CNN-RNN: A Unified Framework for Multi-label Image Classification

PDF: https://arxiv.org/pdf/1604.04573.pdf

単一の画像に複数のラベル付けをするためのフレームワークとして、CNNにLSTMの概念を追加しているようですが、すみません、なぜLSTMを追加することで複数のラベルを扱えるようになっているかはあまりわかっていないです。

 

3. CONVOLUTIONAL, LONG SHORT-TERM MEMORY, FULLY CONNECTED DEEP NEURAL NETWORKS

CONVOLUTIONAL, LONG SHORT-TERM MEMORY, FULLY CONNECTED DEEP NEURAL NETWORKS - Patent application

PDF: 

http://static.googleusercontent.com/media/research.google.com/ja//pubs/archive/43455.pdf

タイトルの方は特許です。PDFは論文です。

複数のバラエティーがあるスピーチに対して認識をさせるためのものとして、CNN、LSTM、DNNの組み合わせを紹介しています。CLDNNという呼称を付けており、基本的な構造はConvolutional Layers => LSTM Layers => 全接続 Layersとなっています。英語のスピーチを学習データとして、CNN+LSTMのケース、LSTM+DNNのケースといった風に分析をかけています。

 

多言語、例えば、英語、ドイツ語、フランス語、日本語、中国語、韓国語などを同時に読み込ませ、そこから同時翻訳や文章予測に向けた解釈をするアルゴリズムができれば面白いなというのが、今回の調査のモチベーションでした。残念ながら該当する方法論に対する研究は見つけられませでしたが、近しいアプローチをしている方はそれなりにいるようです。いずれも「2016年」に何らかの動きがあるあたり、まさに今動いているテクノロジーという感じで興味深かったです。

 

自分自身でもロジックを組んでみようと思います。

 

Google Cloud Shellについて

Google Cloudには、Google Cloud Shellという、Shell環境がデフォルトで用意されています。

cloud.google.com

 

Google Cloudアカウントを開設すると、メニューバーからアクセスできるシェル環境で、Google Cloud SDK/gcloudがビルトインされていて便利です。

 

https://cloud.google.com/shell/docs/images/shell_icon.png

https://cloud.google.com/shell/docs/images/new-console.png

画像はgoogleより引用

 

以下、2016年07月26日の情報です。

基本的な特徴

* 一時的に利用できる仮想マシンインスタンスである。

* ブラウザベースでアクセスできるCLI環境

* 5GBの永続的ストレージが用意されている。

* Java,Go,Pythonなどの言語をサポートしている。

* Webプレビュー機能

* gcloudを利用する際の認証が済んでいる

* tmuxサポート

一時的に利用できる仮想マシンインスタンス

読んで字のごとくですが、一時的に利用できる仮想マシンです。コマンドラインボタンを押すと、プロビジョニングされ、新たなインスタンスを立ち上げています。自分のディレクトリ(/home/username/)の情報は、5GBの永続的ストレージから読み込まれているようで情報が保持されますが、cronは引き継がないようですので、別の仕組みを用意する必要がありそうです。

ブラウザベースでアクセスできるCLI環境

 Compute Engineと同様にブラウザからアクセスできます。macのシェルからアクセスする必要がなくなりました。

5GBの永続的ストレージ

Google Cloud Shell用に5GBのストレージが用意されています。 APIを叩く等の小さな管理作業をするためのスペースとしては十分だと思います。それ以上の作業をする場合は、別のストレージに展開することになります。

Java,Go,Pythonなどの言語をサポート

対応している言語はこちらにあります

https://cloud.google.com/shell/docs/features#language_support

Java,Go,Python(2系のみ),Node.js,Ruby,PHPです。同じページにサポートしているシェルやエディタの情報があり、シェルはsh, bash、エディタは、emacs,vim,nanoに対応しています。他、make, pip , git , docker , mysql clientに対応しています。管理系で必要なものはだいたい入っているという印象です。

https://cloud.google.com/shell/docs/features

Webプレビュー

Webアプリケーションのプレビューができるようです。Ruby on Railsなどではテストサーバーを立ち上げてローカルで動作を確認しますが、そういった機能だと思います。

gcloudを利用する際の認証が済んでいる

gcloudの認証ができているので、立ち上げたCompute Engineに直接アクセスできるようです。まだ試していません。

tmuxサポート

tmuxをサポートしています。tmuxは作業中のセッションを保存したり、画面を複数端末で見れて便利なシェルのユーティリティですが、インスタンス自体が一時的なので、セッション保存がどこまで活用できるかはやや不明です。まだ試していません。

 

Google Cloud Plathome上にTensorflowを展開する

Tensorflowを使いはじめて、はや4ヶ月。そろそろ手元のMacbookではマシンパワーがおぼつかないケースが出てきました。

既存のAWSDebianに入れようかとも考えましたが、せっかくなので、Google Cloud Plathomeを使うことにしました。

申し込みからコードの実行まで1.5時間ぐらいでした。以下、その記録です。

1. 申し込む

cloud.google.comから申し込みます。

cloud.google.com

既存のGoogleアカウントでログインしましたが、再度住所等の情報を入力しました。60日、$300分の無料クレジットがついてきます。クレジットカードの入力が必要です。

 

2. 利用する

チュートリアルが表示されます。ゲーミフィケーションのような流れです。pythonによるHello, Worldチュートリアルがあったので、それに従ってみたところ、Webアプリケーションができてしまいました。App Engineというアプリケーション用のクラウドプラットホームを使っていたようです。Herokuに似ています。Webアプリケーションを構築するのであれば魅力的ですが、今回は違うようです。

 

少し調べるとGoogle Prediction APIというものがありましたが、Tensorflowではないようです。また、Cloud Machine LearningというJupyter Notebookが利用できるものもありましたが、Limited Previewでした。GoogleのサイトでJupyter Notebookを用いたデモを見たことがあり、こちらも興味深いのですが、今回は対話形式は特に必要としておらず、cronなどによるスケジュールなどをしたかったので、こちらの利用も見送りました。

 

結局、AWSのEC2のような、VMを作るタイプのCompute Engineというものを使うことにしました。 割とスタンダードなクラウド環境です。CPUとメモリのサイズをカスタマイズできるので、CPU=8コア , メモリ=7.2GBを選択しました。メモリはこんなに必要ないのですが、どうやらこれが最小サイズのようです。時代ですね。

 

3. ログイン

Compute Engine上で作成したインスタンスへのアクセスはブラウザベースで行えます。SSHのアイコンをクリックすると、ブラウザ上にエミュレートされたターミナルが立ち上がります。AWSのkey pairと比べると簡単にアクセスできる一方で、益々googleアカウントの重要性が増すなと思いました。

 

Chromeを使っている場合(私がそうだったのですが)、ターミナル・プラグインのインストールを勧められます。これを利用することで、ほぼターミナルと遜色のない環境になります。

 

4.Tensorflowをインストールする

 ここから先は、おなじみの作業です。私はanacondaを使っているので、

www.continuum.io

Anacondaをダウンロードし、インストールします。

user$ wget http://repo.continuum.io/archive/Anaconda3-4.1.1-Linux-x86_64.sh
user$ chmod u+x Anaconda3-4.1.1-Linux-x86_64.sh
user$ ./Anaconda3-4.1.1-Linux-x86_64.sh

Cloud Plathomeで用意されたdebianはコンパクトなものでしたので、インストール途中でbzip2がないと警告を受けました。apt-get update、apt-get install bzip2したのち、再度anacondaを入れました。

root# apt-get update 
root# apt-get install bzip2

その後、tensorflowを以下を参考に入れます。

Download and Setup

といっても今回は環境切り分けを特にしないので、pip install --upgrade でおしまいです。 

user$ touch 

~/anaconda3/lib/python3.5/site-packages/easy-install.pth

user$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl

user$ pip install --upgrade $TF_BINARY_URL

5. 実行

まずは単純にpythonのコードを実行するだけをしました。実行中にCPUの使用率を見ると、該当するプロセスの利用率がおおよそ230%と3コアしか利用できていませんでした。この辺りの指定の仕方は、もう少し調べようと思います。今回は、学習パラメータを複数持たせた結果を知りたかったので、4つのプロセスを同時に走らせました。

6. その他

ずうっとマシンリソースを使い続けるわけではないので、動的に仮想マシンを制御することになります。少し調べたところ、gcloudというツールで制御できるようです。

更に、プリエンプティブル VMという仮想マシンを利用することで、よりリーズナブルに利用できそうです。

cloud.google.com

 

データ分析の為にPandasを利用する その2

前回の記事では、Pandasの簡単な操作をしました。面白いのでもう少し続けてみます。

今度はcsvを2つ用意しました。

$ cat tmp01.csv 
,a,b,c
1,1,10,100
2,2,,200
3,4,30,300
$ cat tmp02.csv 
,d
1,3
3,9

まずは普通に読みます。

$ python
>>> import pandas as pd
>>> tmp_data01 = pd.read_csv("tmp01.csv")
>>> tmp_data01
   Unnamed: 0  a     b    c
0           1  1  10.0  100
1           2  2   NaN  200
2           3  4  30.0  300

先頭をインデックスとして読みます。

>>> tmp_data01 = pd.read_csv("tmp01.csv",index_col=0)
>>> tmp_data01
   a     b    c
1  1  10.0  100
2  2   NaN  200
3  4  30.0  300

欠損データを前のデータでパディングします。

>>> tmp_data01 = pd.read_csv("tmp01.csv",index_col=0).fillna(method="pad")
>>> tmp_data01
   a     b    c
1  1  10.0  100
2  2  10.0  200
3  4  30.0  300

tmp02を読みます。

>>> tmp_data02 = pd.read_csv("tmp02.csv",index_col=0)
>>> tmp_data02
   d
1  3
3  9

tmp01とtmp02をつなげます。http://pandas.pydata.org/pandas-docs/stable/merging.html を参考にしました。

>>> data = pd.concat([tmp_data01,tmp_data02],axis=1)
>>> data
   a     b    c    d
1  1  10.0  100  3.0
2  2  10.0  200  NaN
3  4  30.0  300  9.0

パディングではなく、線形補完してみます。

>>> data = pd.concat([tmp_data01,tmp_data02],axis=1).interpolate(method='linear')
>>> data
   a     b    c    d
1  1  10.0  100  3.0
2  2  10.0  200  6.0
3  4  30.0  300  9.0

1つだけくりぬいてみます

>>> a_data = data["a"]
>>> a_data
1    1
2    2
3    4
Name: a, dtype: int64

前項との和を計算します。

>>> a_plus_data = a_data + a_data.shift()
>>> a_plus_data
1    NaN
2    3.0
3    6.0
Name: a, dtype: float64

Logもとってみましょう。

>>> import numpy as np
>>> d_data = data["d"]
>>> d_data
1    3.0
2    6.0
3    9.0
Name: d, dtype: float64
>>> d_log_data = np.log(d_data/d_data.shift())
>>> d_log_data
1         NaN
2    0.693147
3    0.405465
Name: d, dtype: float64

便利ですね。

データ分析の為にPandasを利用する

Jupyter Notebookを使いたくて、Anacondaをインストールしたところ、データ分析の為のツールであるPandasもインストールされていたので使ってみました。存外便利でしたので、メモをとります。

 

以下のようなcsvファイルを用意しました。

$cat tmp.csv 
a,b,c
1,1,1
2,,2
3,3,3

pandaをimportして、csvファイルを読みます。

$ python
>>> import pandas as pd
>>> tmp_data = pd.read_csv("tmp.csv")
>>> tmp_data
   a    b  c
0  1  1.0  1
1  2  NaN  2
2  3  3.0  3

欠損データを前のデータでパディングしてみます。

>>> tmp_data = pd.read_csv("tmp.csv").fillna(method="pad")
>>> tmp_data
   a    b  c
0  1  1.0  1
1  2  1.0  2
2  3  3.0  3

fillna(0)でゼロパディングもできます。

describeでデータの数、平均値などの情報を取得します。

>>> tmp_data.describe()
         a         b    c
count  3.0  3.000000  3.0
mean   2.0  2.333333  2.0
std    1.0  1.154701  1.0
min    1.0  1.000000  1.0
25%    1.5  2.000000  1.5
50%    2.0  3.000000  2.0
75%    2.5  3.000000  2.5
max    3.0  3.000000  3.0
>>> 

その2では、もう少し複雑なことをやってみたいと思います。

企業が人工知能(またはディープラーニング)を始めるのに必要なヒト、モノ、コト

企業が、自社のビジネスに人工知能を取り込むには、どんなリソースがあればよいかまとめてみました。

1) ニューラルネットワーク開発部隊 (ヒト)
2) 分散システムのインフラストラクチャ (モノ)
3) ビジネスモデリング (コト)

 

1) ニューラルネットワーク開発部隊 (ヒト)

 

ビジネス要件から適切なネットワークを選択できる人材

動体検知や文字認識などの画像処理であれば畳み込みネットワーク、文字認識や時系列データであればリカレントニューラルネットワーク等、ニューラルネットワークは応用したい分野毎に異なります。目的に応じて最適なネットワークを選択できる人材がまずはなにより必要です。

 IT開発でいう「SE」の領域にあたりますし、後述の通りニューラルネットワークで求められる人材は、従来のIT開発のメンバーと親和性が高いので、従来までの「SE」と同じスキルセットと見なされやすいですが、少し違うと思います。

IT革命により、近年のIT開発の技術選択は体系化がなされた知識を学ぶ事で進行可能でしたが、人工知能の場合は、まだ発展途上な面もあり、数理的な知識が求められます。加えて、適切なITシステムを選択するセンスも従来通り求められてくるでしょう。プロセスマネジメントは別のメンバーに任せて、ビジネス要件に最適なテクノロジーを追い求めることに特化した方が、当面の間は効率的だと思います。

 

- 数学的な理解/知識

既に確立されている仕組みを使うのであれば、理系大学程度の基礎的な知識でいけると思います。これは高校時代に数学が好きだった理系出身ならある程度は標準搭載している知識です。

ただし(少し前の私を含め)多くの社会人は学生時代の学びの記憶を忘却の彼方においやってしまっているので、高校数学あたりからノートを片手に数週間復習するような機会を取る必要はあると思います。

分野としては、行列計算や偏微分などの知識になると思います。代数や複素解析はあまり出てこないです。

新しいロジックを考えたり、ロジックを組み合わせる必要がある領域に手を出す必要があれば、より詳しい数学的な知識を持つ人材がやはり重要になってきます。競合する企業も人工知能を採用しているような分野なら、体系的な学問を更に深く習得している人材までが求められるでしょう。

 

- 人工知能フレームワーク

この章はヒトをテーマにまとめましたが、人工知能フレームワークはソフトウェアの重要な概念なのでここで紹介させてください。

実際にデータを扱い、開発を効率的に進めていく為には、人工知能に向けた開発フレームワークを利用することになります。ニューラルネットワークでよく使う関数などがビルトインされているツールがあれば、毎回作らずに済むので便利だからです。TensorFlow、Chainerなどの実装があります。 

フレームワークは少なからず実装に影響を及ぼします。例えば、文字認識などで利用されるリカレントニューラルネットワークの1つであるLSTMををとっても、幾つかの種類があり、ツールにより実装されているものが異なるようです。私は当面、TensorFlowを使おうと思います。

 

-プログラマ

言語はフレームワークがサポートしているプログラミング言語を使えばよいです。昔はC言語や業界に特化した言語が使われており、言語自体の知識が求められましたが、最近はWeb開発などで積極的に使われてきたライトウェト系の言語(Pythonなど)でも扱えるのでとっつきやすくなっています。Web開発の経験があるレベルでも手をつけることができると思います。数学的な知識と合わせて、「高校時代に数学が好きだった理系出身のWebプログラマ」であれば戦える分野になりました。

ただし、プロダクトレベルに耐え得るようにするには、開発を効率に進める為にも、また開発したプロダクトに問題が発生しない為にも、テストや開発の方法論(MVCのようないわゆる開発フレームワーク)といったプログラミング開発における実装上の課題に取り組めることが重要になっていきす。

 

2) 分散システムのインフラストラクチャ (モノ)

 

- ハードウェア 

マシンリソース、CPU&GPUです。処理すべきデータと処理するネットワークの構造により変わってきます。チュートリアルであつかうMNIST程度のものを扱うにはラップトップでも可能ですが、膨大なデータを複雑なロジックで計算する際は、クラウドを利用することになります。

自社でインフラを構築するのは、少なくとも組織を構築する直後にはあまり得策ではないと思います。Webのように常にリソースを使い続けるものと比較しても、資産化しておく意味があまりないからです。

 

- 分散フレームワーク

 

Map&Reduce / Hardoopのようなものを指しています。複数のハードウェアを同時に
扱う為には必要です。既存のフレームワークを採用しても、自社で構築するとするとそれなりに労を要します。

 

- データベース

 

データを格納する為に、DBを使います。初期においては、ポータブルに使えるという意味でcsvsqliteのようなものを使ってもいいかもしれません。また、従来からLAMPなどで開発をしていたWebエンジニアであれば、MySQLのような馴染みのあるDBを使ってもいいと思いますが、あらかじめ膨大なデータを扱うことを前提として、NoSQL系がよく利用されているようです。

総じて言えば、ローカル環境で試験的なアプローチをするのであれば、ラップトップでも問題ありません。それを超えるタイミングで、スケールアウト可能なクラウドのシステムを採用するのが、分散システムの賢い採用方式だと思います。

 

3) ビジネスモデリング (コト)

 

従来から数理的なアプローチ存在する分野、例えば金融や画像処理といった分野では、方法論が揃いつつあります。また、ビジネス上の適応目的も明らかになっていますので、応用も比較的容易です。

Google Cloud Plathomeには、金融に対して適応するデモがありますが、これは従来まで市場間分析などで利用されていた自己相関分析に対してニューラルネットワークを応用した例です。

Machine Learning with Financial Time Series Data - Solutions — Google Cloud Platform

 

余談ですが、この例ではフィードフォワードネットワークと呼ばれるディープラーニングの中でも比較的シンプルなものを採用しています。それでもそれなりのパフォーマンスが出ているあたり、人工知能の未来を感じさせてくれます。

今まであまり適応されていない分野に向けた適応となると、ビジネスモデルを発見するようなセンスも必要になります。IT技術とビジネスの両方を経験されたスペシャリストを見つけることが近道かもしれません。

いままでは人間の経験と勘(あるいはその道の天才)に頼っていた部分を機械化することで、新たなビジネスチャンスを生み出せることが人工知能の本質です。自社への適応を検討する企業としては、この本質に向けて目的意識を持ち続けておくことが、ビジネスへの応用向けた近道だと思います。

ニューラルネットワークを使っているかは不明ですが、Dentsu Media LabとPanasonicによる東京オリンピックに向けたアプローチはこういった意味で興味深いと思います。

blogs.yahoo.co.jp