自然言語処理 画像キャプションのデータセット Cornell NLVR

Hacker Newsで取り上げられていた自然言語処理のデータセット Cornell NLVRの紹介です。

公式ページ:http://lic.nlp.cornell.edu/nlvr/

データセット:https://github.com/clic-lab/nlvr

論文:http://alanesuhr.com/suhr2017.pdf

これは、色の付いた図形が複数描かれた画像とキャプションのセットが与えられて、そのキャプションが正しく図を説明しているかを true/ falseで判定するタスクのためのデータセットです。データ数は92,244個でクラウドソーシングでデータを集めたそうです。

例えば、以下の画像のキャプションとして「There is exactly one black triangle not touching any edge」(他のエッジに触れていない黒い三角形がただ一つある)が与えられており、この正解ラベルは「true」となっています。

他にも、例えば次の画像のキャプションとして「There is a box with multiple items and only one item has a different color」(複数アイテムとともに一つ箱があり、ただ一つのアイテムが異なった色を持つ)が与えられ、この正解ラベルは「false」といったようになっています。

 

現在の、トップのテスト精度は公開データに対して約67%程度であり、ランダムに答えた場合よりも少し良いといった程度でしょうか。まだまだ、発展させる余地があるテストデータのようです。

Rustで書かれたNeural Network実装:Jaggernaut

Rust言語で書かれたJaggernautというNeural Networkの実装を見つけた。WebAssemblyに変換されて、ブラウザ上で動作させることが出来る。

Juggernaut: Neural Networks in a web browser

デモページでは3種類のデータセットに対して、学習率とエポック数を設定して、データが分類されていく過程が見れる。デモの実装にはReactとD3.jsを使っているが、Neural Networkの学習部分にはJavaScriptは一切使っておらずRustのみで書かれているとのこと。

まだ機能的にはフィードフォワードネットワークのみ対応しているようだが、数種類の活性化関数やコスト関数を用意しているとのこと。

こういったアプリケーションが増えて、将来的にRustは果たしてC/C++を置き換える言語に成りえるのか見守っていきたい。

Kerasによるニューラルネットワーク本「Deep Learning with Keras」を読んだ

Deep Learningの基本的な仕組みなどについては大体把握してきたと思うので、実際に動くコードを書くにはどうすればよいのかということを学ぶために、Kerasによるニューラルネットワーク本、「Deep Learning with Keras」を読みました。

Kerasはご存知の通り、TensorflowやTheanoなどのDeep Learning基盤を使いやすくするためのフレームワークです。実際にKerasを使ってみると、難しそうなイメージがあるDeep Learningは積み木のように構築出来て、結構簡単じゃないかという自信を得られるので、一般的なユーザーには生のTensorflowを使うよりもお勧めです。

この本の内容は、Kerasのインストール、基本的なフィードフォワードNNから始まり、CNN、RNN、WordEmbedding、GAN、転移学習、強化学習、などと幅広くカバーされています。すべての内容にサンプルコードが付いているので、実際に動かすことができます。段々と後ろの章に進むにつれて、学習に時間がかかるコードが増えてくるので、手元の環境で動かそうとする場合にはGPUがあったほうが良いかと思います。サンプルコードはKeras2.0で書かれていますが、現在の最新版だと微妙にAPIが変わっている部分もあるようで修正が必要な個所もありましたが、調べればすぐに出てくるレベルの違いなので(少なくとも現時点では)特に大きな問題にはならないかと思います。

基本的にはサンプルはそんなに複雑な内容を扱っているわけではなく、コードを部分ごとに解説とともに説明されているので、Kerasの深い知識が無くてもサクサク読むことが出来ました。実際に自分が作りたいアプリケーションに向けて参考にするにはとても良いサンプルが揃っていると思います。

個人的にはGANについて概要レベルで仕組みを知ることが出来たのが大きな収穫でした。何となく理論は知っているんだけど、いざ実際にコードに落とすにはどうしたら良いのか?と思う方にはお勧めです。日本だとChainerがこの手のフレームワークとして人気だと聞きますが、世界的にみるとKerasの人気は強いとも聞きます。今後の開発がどのように進んでいくのかにもよりますが、こういったフレームワークは一つ手を付けておけば他のフレームワークを使う際も似た部分は多いかと思うので、応用が効くかと思います。

次はもう少し数学的な基礎を固めようかと思うので、統計の教科書やMurphy本あたりを読んでみようかと思っています。

Deep Learningによる自然言語処理の教科書「Neural Network Methods for Natural Language Processing」を読んだ

タイトルの通り、Deep Learningによる自然言語処理の教科書「Neural Network Methods for Natural Language Processing」を読みました。全体として色々と理解が深まった部分があるのでお勧めです。

まさにタイトルの通り、自然言語処理とDeep Learningに特化した本でした。そもそもニューラルネットワークとは、というようなところから始まっているのでDeep Learningの深い知識が無くても読み始めることは可能だと思います。

また、自然言語処理の部分についても適宜基本的な内容が解説されながら進んでいくので読みやすいと思います。

図が多いので、CNNやRNNなどのネットワーク構造がどのようになっているのかというのも理解しやすいです。個人的にはこの本で、モヤモヤしていたLSTMやGRUといった内容やAttention機構がどういった仕組みであるかが理解できたのが収穫でした。

最近出たばかりの本なので、いまだ発展途上であるDeep Learningによる自然言語処理という分野で数多くの論文が参照されており、新しいものだと2017年に出た論文もカバーされているところが素晴らしいと思います。

どちらかというと理論的な面が重視して解説されているので、ここからどのように実装に落とし込んでいくかは別途TensorflowやKerasなどの記事を読むことになるかと思います。

 

Fashion MNISTをKerasでCNNを使って分類してみた

ファッションアイテムを識別するタスクであるFashion MNISTというデータセットが登場しました。
https://github.com/zalandoresearch/fashion-mnist


(画像は上記githubページより)

このデータセットが登場した目的は、MNISTが簡単すぎる、MNISTは使われすぎ、MNISTは最近のコンピュータビジョンのタスクを表現していない、などの理由からだそうです。

まずは、データセットをダウンロードします。

git clone https://github.com/zalandoresearch/fashion-mnist.git

データの形式などはMNISTと同じで、分類するクラスも10個(Tシャツ、サンダル、バッグなど)です。

このデータをKerasを使って分類してみようと思います。バックエンドはTensorflowを使っています。
ネットワークの構造はLeNetを構築しています。

from keras import backend as K
from utils.mnist_reader import load_mnist
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, Flatten, Dense
from keras.models import Sequential
from keras.utils import np_utils
from keras.initializers import Constant
from keras.optimizers import Adam
import matplotlib.pyplot as plt

#load_mnistはutilsにある
X_train, y_train = load_mnist('data/fashion', kind='train')
X_test, y_test = load_mnist('data/fashion', kind='t10k')

X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)

y_test = np_utils.to_categorical(y_test, 10)
y_train = np_utils.to_categorical(y_train, 10)

K.set_image_dim_ordering("th")
#LeNetを構築する
model = Sequential()
model.add(Conv2D(20, kernel_size=5, padding="same", input_shape=(1,28,28)))
model.add(Activation("relu"))
model.add(MaxPooling2D())

model.add(Conv2D(50, kernel_size=5, border_mode="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D())

model.add(Flatten())
model.add(Dense(500))
model.add(Activation("relu"))

model.add(Dense(10))
model.add(Activation("softmax"))

model.compile(loss="categorical_crossentropy", optimizer=Adam(), metrics=["accuracy"])
history = model.fit(X_train, y_train, batch_size=128, epochs=20, verbose=1, validation_split=0.2)

score = model.evaluate(X_test, y_test, verbose=1)
print("Test score:", score[0])
print("Test accuracy:", score[1])
print(history.history.keys())

#グラフの表示
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

テスト精度は92.16%でした。MNISTだと99%程度の精度が出るネットワーク構造なので、MNISTより難しくなっているというのは本当のようです。

48000/48000 [==============================] - 259s - loss: 0.4973 - acc: 0.8208 - val_loss: 0.3587 - val_acc: 0.8742
Epoch 2/20
48000/48000 [==============================] - 260s - loss: 0.3178 - acc: 0.8861 - val_loss: 0.3043 - val_acc: 0.8893
Epoch 3/20
48000/48000 [==============================] - 258s - loss: 0.2735 - acc: 0.9013 - val_loss: 0.2783 - val_acc: 0.9025
Epoch 4/20
48000/48000 [==============================] - 256s - loss: 0.2397 - acc: 0.9124 - val_loss: 0.2502 - val_acc: 0.9110
Epoch 5/20
48000/48000 [==============================] - 256s - loss: 0.2122 - acc: 0.9229 - val_loss: 0.2716 - val_acc: 0.9058
Epoch 6/20
48000/48000 [==============================] - 266s - loss: 0.1897 - acc: 0.9308 - val_loss: 0.2683 - val_acc: 0.9053
Epoch 7/20
48000/48000 [==============================] - 259s - loss: 0.1679 - acc: 0.9381 - val_loss: 0.2570 - val_acc: 0.9118
Epoch 8/20
48000/48000 [==============================] - 260s - loss: 0.1489 - acc: 0.9460 - val_loss: 0.2557 - val_acc: 0.9114
Epoch 9/20
48000/48000 [==============================] - 260s - loss: 0.1277 - acc: 0.9524 - val_loss: 0.2430 - val_acc: 0.9195
Epoch 10/20
48000/48000 [==============================] - 260s - loss: 0.1156 - acc: 0.9568 - val_loss: 0.2435 - val_acc: 0.9198
Epoch 11/20
48000/48000 [==============================] - 260s - loss: 0.0965 - acc: 0.9639 - val_loss: 0.2452 - val_acc: 0.9183
Epoch 12/20
48000/48000 [==============================] - 259s - loss: 0.0824 - acc: 0.9696 - val_loss: 0.2705 - val_acc: 0.9159
Epoch 13/20
48000/48000 [==============================] - 261s - loss: 0.0689 - acc: 0.9752 - val_loss: 0.2851 - val_acc: 0.9148
Epoch 14/20
48000/48000 [==============================] - 258s - loss: 0.0588 - acc: 0.9790 - val_loss: 0.3054 - val_acc: 0.9178
Epoch 15/20
48000/48000 [==============================] - 275s - loss: 0.0506 - acc: 0.9823 - val_loss: 0.3397 - val_acc: 0.9215
Epoch 16/20
48000/48000 [==============================] - 313s - loss: 0.0423 - acc: 0.9858 - val_loss: 0.3490 - val_acc: 0.9161
Epoch 17/20
48000/48000 [==============================] - 296s - loss: 0.0376 - acc: 0.9866 - val_loss: 0.3412 - val_acc: 0.9215
Epoch 18/20
48000/48000 [==============================] - 289s - loss: 0.0299 - acc: 0.9894 - val_loss: 0.3668 - val_acc: 0.9173
Epoch 19/20
48000/48000 [==============================] - 291s - loss: 0.0313 - acc: 0.9887 - val_loss: 0.3972 - val_acc: 0.9141
Epoch 20/20
48000/48000 [==============================] - 268s - loss: 0.0251 - acc: 0.9911 - val_loss: 0.3806 - val_acc: 0.9194
 9984/10000 [============================>.] - ETA: 0sTest score: 0.362425664179
Test accuracy: 0.9216

出力されたグラフは次の通り。

以上です。MNISTの精度が99%を超えて飽和しつつあるので、今後はこのテストデータが広く使われることになるかもしれません。

A Neural Network Playground を使ってみた

Tensorflow グループが A Neural Network Playground というブラウザ上でDeep Neural Networkの動きを可視化するツールを出しています。少しいじってみたので、参考までに書きます。

提供されているデータセットは4種。ノイズパラメータをいじることで、複雑なデータにすることもできます。

UIは直感的なので、色々といじってみると分かるかと思いますが、入力のフィーチャーを選択して、隠れ層の段数や個数を調整して、活性化関数や正則化の方法を選択するなどして左上の再生ボタンを押すとアニメーションでNNがどのようにしてデータを分類しているのかが分かります。

活性化関数を変えてみると、収束までにかかるエポック数が変化するのが分かります。例えばSigmoid関数を使うと収束は遅くなり、最近はSigmoidがあまり使われないというのも納得できるようになります。

その他にも、線形分離可能でないデータ(例えば1番目のデータ)は最初のフィーチャーの選択によっては正しく分類できない場合があることが分かります。(フィーチャーとしてX11とX22を選ぶと円形で分離できるようになりました)

 

何となくDeep Learningがどういうものか分かってきた人が、実際に動かしてイメージをつかむのに良いツールであると思いました。

データサイエンスと機械学習を学ぶのに最適なMOOC

HackerNewsに上がっていた、データサイエンスと機械学習を学ぶのに最適なMOOCというのを抜粋してみます。

https://news.ycombinator.com/item?id=15073441

個人的には、このリストの上から進めていくのが初心者には良いのかなと思います。

Andrew Ng: Machine Learning

https://www.coursera.org/course/ml

ご存知、Andrew Ng先生の機械学習コース。私も実際に修了しましたが、実用例が多く紹介されており、数学的に難しくないので初心者が始めるのに最適だと思います。

Hasti/Tivshirani: Elements of Statical Learning

http://statweb.stanford.edu/~tibs/ElemStatLearn/

これは、私は書籍の方を読みました。数式が結構出てきますが、内容はそれほど高度ではないです。動画と合わせて本を読んでいくことで理解が進みやすいと思います。

Yaser Abu-Mostafa: Learning From Data

https://www.edx.org/course/caltechx/caltechx-cs1156x-learning-data-1120

こちらも私は本を読み終えています。上記二つを終えていれば概念的に難しい内容はそれほどないと思います。数学的にしっかりと、訓練誤差の話などがコンパクトにまとめられているので、こちらも本と合わせて動画を見ることで内容理解が深まるかと思います。

Geoff Hinton: Neural Nets for Machine Learning

https://www.coursera.org/course/neuralnets

私はこのコースを修了しましたが、はっきり言って難しかったです。後半はあまりよく理解できませんでした。動画も、Andrew Ng先生のようなものを期待していたのですが、スライドをただ読んでいく感じで理解するのが難しい部分がかなりありました。

Andrew Ng先生がCourseraで新しくDeepLearningのコースが始まるようなので、このコースよりはそちらを受けてみるのが良いかもしれません。

Hugo Larochelle: Neural Net lectures

YouTubeに上がっている動画コース。見ていないのであまりコメントできませんがNeuralNetsとDeepLearningにフォーカスしている内容のようです。

Daphne Koller: Probabilistic Graphical Models

https://www.coursera.org/course/pgm

このコースも受けてみたいなと思いつつ受けていません。コメントによると他の授業には無い内容が多いが、結構難しいみたいです。

Sony製 Deep Learning Framework: Neural Network Consoleを試してみた

ソニーがGUIでDeep Learningアプリケーションを作成するツールを公開しました。

ソニー、ニューラルネットをGUIで設計できる深層学習の統合開発ツールを無償公開

 

ネットワークを構築する部分がGUIで書けるようで、どれくらい便利なのかを試してみることにしました。
個人的にはKerasやTensorflowを使ったとしても、ネットワーク構築の部分は積み木のような感覚なのでそれほど難しいとは思わないので、GUIで出来るというのがどれほどメリットがあるのか懐疑的でした。

実際に試してみると、直感的に使えるので試行錯誤の段階には意外と便利かもしれないと感じました。

ダウンロード

以下のページからダウンロードをします。まずはメールアドレスを登録すると、ダウンロード先のリンクが送られてきます。

https://dl.sony.com/

ファイルサイズは900MBほどあります。ちなみに現時点ではWindowsのみ対応しています。

ディレクトリ構造

ディレクトリ構造は以下の通りです。

実行

neural_network_console.exeをダブルクリックで実行できる。

最初にライセンス規約が表示されるので、同意する。

すると以下のような画面が表示される。色々とサンプルが用意されているようだ。

 

とりあえず、2番目のMNISTサンプル(手書き数字認識)をクリックしてみるとMNISTデータのダウンロードが始まります。

ダウンロードが終わるとサンプルのネットワークが表示されます。このサンプルは画像が9かどうかを判定するサンプルのようです。

直感的に分かりやすい。ConvolutionとMaxPoolingを2回やって、Affine変換を2回やって、最後はBinaryCrossEntropyで評価ね、と分かります。

F5を押すとトレーニングが始まる。トレーニング中はエポックごとに評価関数の推移がグラフで表示される。TrainingErrorとValidationErrorが表示されるので、テストセットの分離は勝手にやってくれているのだろうか?

 

せっかくなので、ネットワークを少しいじってみようと思います。色々と試してみましたが、In/Outの行列サイズが表示されるのが便利だと感じました。

ここでは単純に活性化関数をtanhからReLUにしてみました。

左側のツールボックスからブロックを選択して繋ぎかえるだけなので、直感的に操作できます。

(ちなみに畳み込み層を1層追加しようとしたのですが、デフォルトのフィルターサイズが5×5だったためサイズが合わないという警告がグラフ上に出て初心者には分かりやすいと思いました)

過去の試行錯誤結果は保存されているため、色々なネットワークで試して一番良いものを使うことが出来ます。

Validation結果が一番良かったものを使って、テストデータを動かしてみます。F6でテストデータの評価が始まります。

各テスト画像に対しての結果とConfusion Matrixが作成されます。

Presicision, Recall, F値が表示されて分かりやすいです。

結論

ドキュメントを読まなくても結構直感的に使えて、機械学習初心者に向いているのではないかと感じました。

GUI部分もよく出来ていてストレスを感じることなく使えます。ネットワーク作成に使う要素も、一通りのものが揃っているので手軽にやりたいことを始めるのには良いのでないかと思います。

 

現実的にはユーザー数の規模では、世界的に見たら既存のフレームワークが圧倒している状況だと思います。

今後、他のDeep LearningフレームワークでもGUIでネットワーク構築を行うツールが出てくるかと思うので、差別化できる部分を実装して頑張って欲しいです。

Deep Learning 第1章

ディープラーニングは、多層構造のニューラルネットワークだよという紹介。
この本は学部・院生向けと今まで機械学習に取り組んでこなかったソフトウェアエンジニア向けに書かれている。
数学的な内容は前半の方で解説されるが、基本的なコンピュータサイエンスの知識やプログラミングの知識は前提として進んでいく。

ニューラルネットワーク自体の歴史は古く、なぜ最近着目されるようになったのかという点については計算能力の向上とデータの増大が挙げられている。
特に興味深いのは、ディープラーニングは脳を模倣している「のではない」、という点。
この辺は読んでいくと分かるようになるのかな。

次の2章は線形代数について。