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%を超えて飽和しつつあるので、今後はこのテストデータが広く使われることになるかもしれません。

交差エントロピー誤差が-∞になるのを防ぐ


機械学習の本を色々と読んでいるのですが、ふと交差エントロピーの数式を見て誤差が-∞になるじゃん、と今更気づいたので、実際に実装上どのようにして回避しているのかを調べました。

交差エントロピーは以下の式で表されます。

$$E=-\sum_{k}t_k\log {y_k}$$

結論から言うと、下記のサイトに答えはありました。どうやら、小さい数値を足しておくことでlog(0)を誤差に足してしまうことを防ぐようです。

「ゼロから作るDeep Leaning」4章:ニューラルネットワークの学習

つまりは以下のコードを誤差関数として利用するということでした。

def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    return (f(x+h) - f(x-h)) / (2*h)

以上です。理論と実装の狭間を少しずつ埋めていきたい。

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

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

Windowsで英文形態素解析ツールTreeTaggerを使う

日本語の形態素解析ツールといえばMeCabが有名だが、英文を形態素解析する場合はTreeTaggerというツールを使うのがメジャーなようだ。

TreeTagger
http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/

手元の環境がWindowsなので、今回はWindowsにTreeTaggerを導入する手順を書く。次回はPythonから使う方法を書く予定。

ActivePerlをインストール

https://www.activestate.com/activeperl/downloads

TreeTagger本体を導入

公式サイトからTreeTaggerをダウンロード

http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/

インストール手順は同梱のINSTALL.txtに書かれているので参照する。

TreeTaggerディレクトリをC:\直下に置く。他のディレクトリに置く場合はtag-*.batファイルの最初にあるpathを書き換えれば動く。

辞書データをダウンロード

公式サイトのChunker parameter files for PC の部分から必要なパラメータファイルをダウンロードして解凍する。

今回は英文を対象としたいので、Englihs chunker parameter fileをダウンロード。

解凍するとenglish-chunker.parというファイルが入っているので、これをenglish-utf8.parにリネームして、TreeTagger/libに保存する。

実行

C:\TreeTagger\bin に移動して、テスト用テキストtest.txtを作成する。

今回は、インストール手順書の中の文、「This is the Windows distribution of the TreeTagger.」を書いてみた

コマンドプロンプトを開き、以下のバッチファイルを実行すると形態素解析結果が表示される。

PS C:\TreeTagger\bin> .\tag-english.bat test.txt
reading parameters ...
tagging ...
This NN/B-NC This
is NN/B-NC is
the NN/B-NC the
Windows NN/B-NC Windows
distribution NN/B-NC distribution
of NN/B-NC of
the NN/B-NC the
TreeTagger NN/B-NC TreeTagger
. NN/B-NC .
finished.

結果の見方

形態素解析の結果については、以下のページが詳しい。

http://computer-technology.hateblo.jp/entry/20150824/p1

 

今後

次回はPythonから使う方法を見ていきたい。

ソフトウェアエンジニアの方向性を指し示す一冊:The Complete Software Developer’s Career Guide

Soft Skills で有名なJohn Sonmez氏による最新作、「The Complete Software Developer’s Career Guide: How to Learn Your Next Programming Language, Ace Your Programming Interview, and Land The Coding Job Of Your Dreams」を読んだ。

現時点で、アメリカのAmazonでレビューが265個ついて、そのうち92%が星5つという高評価。

内容はSoft Skillsと被る部分も多いが、メインはキャリア形成について書かれている。

対象読者はソフトウェアエンジニアを目指す人、もしくは自分のスキルを今後どうやってどの方向に伸ばしていこうかと考える若手エンジニアに向けて書かれているように感じた。

アメリカのソフトウェア業界が主眼で書かれているので、日本では事情が異なることもあるかと思うが、今後日本でもキャリア形成の方法はアメリカ的になっていくのではないかと思うので、今読んでおくことは意味があると思う。

例えば、給与交渉の章では、「給料を上げる一番良い方法は転職することだ」と書いており、これは徐々に日本でも浸透してきているのではないかと感じている。

その他にも、Job Securityの章では、「Even in Japan, where for a long time it was generally understood that once you started working for a company, you worked for that company for life, those ways are coming to an end.」と名指しで、日本社会でも終身雇用が終わりつつあることを述べている。

また、給与交渉の部分で、自己評価を書かされる場合は常にパーフェクトスコアを付けるようにと書いてあった。理由は、「自己評価は主観的な評価しかできない。上司に修正させられるか、そのまま受け入れられるかであり、最初から低評価を付けて上司が上げてくれるのを期待するよりも期待値が高い」という、面白いが納得させられるものだった。

個人的にこの本から影響を受けたことは、自分の名前を売り込む方法とその重要性だ。

筆者はブログを書くことやカンファレンスで講演することなど、様々な部分を通じて自分をいかにして市場に売り込むかを重視している。

ブログも広範な内容を書くのではなく、とてもニッチな特定の分野に特化した内容を掘り下げて書くことを勧めている。

そして一番大事なことは書くのをやめないことだ、とも言っている。これはブログ以外の分野でも共通していることだが、小さく始めてとにかく続けること、これが大事だと様々な章で述べている。

とにかく内容が広範なので、まとめきれないが、著者が最後に述べている通り、読んだだけではなく一つずつ実践していくことがとても重要だ。

実際にこのブログ記事を書いてみたように、小さなことから少しでも始めていければと思う。

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でネットワーク構築を行うツールが出てくるかと思うので、差別化できる部分を実装して頑張って欲しいです。

「GE 巨人の復活」を読んだ

「GE 巨人の復活」を読んだ。素晴らしい本であった。


GEがデジタルトランスフォーメーションという標語を掲げて、近年事業を行っていることは何となく聞いたことがあった。
正直に言うと、せいぜい経営層が時代の流れに合わせて流行り言葉を並べているだけだろう、と思っていた。

この本を読んで、GEは本気でシリコンバレー流の仕事を行っているのだと分かった。
例えば、全従業員30万人にたいしてリーンスタートアップの手法を学ばせたり、ソフトウェアを内製に切り替える、シリコンバレーのエンジニアをスカウトしてくる、待遇を変える、人事評価手法を変える、失敗を許すカルチャーに変える、などなどドラスティックに企業文化を変えているのが驚きであった。

やはり以下にあるようにトップの強い意志が会社をここまで変えたのであろう。

“企業を形作っているのは、そこで働く人である。そして人を動かすのは、突き詰めれば「人の熱意」しかあり得ない。トップの熱意がなければ、戦略も文化も変わることはない。”

恐らくこの本は著者からの、日本の製造業の経営層へのメッセージであるのだと思う。
日本の製造業が復活するためには、従順にシリコンバレー方式の仕事へ転換する必要があり、もはやそこで失敗するとGEのような転換を上手く果たした企業に置いて行かれることになるだろう。

データサイエンス関係のpodcastをまとめてみた

最近盛り上がりを見せるデータサイエンス界隈。
様々なpodcastが存在しているが、あまり言及されることが無いようなのでここでまとめておく。
割と更新頻度が高いものを中心に選んだつもりなので、これらを購読すれば聞くものが無いという状態にはなかなかならないかと思う。

言語は英語なので、データサイエンスの最新動向を知るのとともに英語の勉強にも使えるかと思う。
日本の機械学習エンジニアと研究者が世界と戦うための一助になれば幸いです。

  • Super Data Science
番組ホストのKirill Eremenkoが毎週インタビュー形式のメインエピソードと、Tips的なショートエピソードを配信している。
英語は聞きやすいので、英語に自信が無い人はまずはショートエピソードから入ってみるのも良いかもしれない。
  • The AI Podcast

https://blogs.nvidia.com/ai-podcast/
 ご存知NVIDIAの提供で行われるPodcast。
Andrew NgとかIan Goodfellowなどのスーパースターがゲストで登場していたりしているので、それだけでも聞く価値はあるかと思う。

  • Linear Digressions

http://lineardigressions.com/
機械学習に関連するトピックを実例をもとに紹介する。
ディスカッション形式のポッドキャスト。

  • This Week in Machine Learning

 https://twimlai.com/

毎週、機械学習に関連する研究者や企業関係者へのインタビュー形式で配信されるポッドキャスト。
実際の応用事例が豊富に聞ける。
  • O’Reilly Data Show
ご存知O’Reillyの提供で行われるPodcast。
企業の研究者などへのインタビュー形式。
最新のエピソードではFacebookの研究者へのインタビューが行われた。
 
  • Not So Standard Deviation

 https://soundcloud.com/nssd-podcast

2人のホストが機械学習や統計に関連したトピックを話す形式のポッドキャスト。
 
  • Data Skeptic
技術的なトピックについて話し合うポッドキャスト。
MINIシリーズという形式の回は20分程度なので聞きやすい。

Abstractive Sentence Summarization with Attentive Recurrent Neural Networks

I read a paper about abstractive sentence summarization.
This is the link.

In this paper, the authors used attention mechanizm to decide where to focus when decoder outputs.
This neural network model is a modification of the state-of-the-art machine translation model.

This method outperformed the current text abstraction methods.
These days, the improvements of RNN method are heavily affecting Natural Language Processing areas.

I think abstractive sentece summarization is one of the promising areas for advancement of NLP.