CapsuleNetworkの論文読んだ

CapsuleNetworkの論文読んだので復習も兼ねてブログにまとめます。
分かってない部分も多々あるかもですが、参考にする場合はご了承ください。
計算方法とかに関してはあんまり強くないのでそこまで触れていません・・・。

1.CapsuleNetworkとは

大体半年前ぐらいに論文で発表された技術で、CNNとはまた異なる手法を使った技術。CNNはニューロンを使用しているが、CapsuleNetwork(CapsNet)ではカプセルを用いているのが特徴。
CNNでは画像内の最も特徴の強いピクセルを圧縮し続けて抽象化することである程度のロバスト性を獲得するが、CapsNetでは特徴の強い部分同士の空間的な相互関係を学習するものになっている。
これにより、CNNでは物体の変化に対応するためにある程度訓練時に様々な角度の画像が必要であったが、CapsNetでは特徴間を空間的に把握するため、訓練時に様々な角度の画像が必要なくなるといったことが言える。

MNISTではあまり精度の向上はうかがえないが、一応エラー率は従来のCNNよりも高い0.25%となっている。またこの論文で独自?にしようされたMultiMNISTと呼ばれる数字が2つ重なったデータセットを用いた結果、数字が重なっているためにCNNではほとんど判別不能だったが、CapsNetでは2つの数字を判別できるといった結果が出ている。

簡単に言えば、CapsNetは様々な角度の画像なしでもロバスト性があり、物体が重なっていても判別できるといったことが言えるかもしれない。

2.カプセルって何?

カプセルっていうのはニューロンを複数合わせたものを1つにしたもの?だと思っていたけど、ニューロンがスカラを使うのに対して、カプセルはベクトルを用いるというのが最大の特徴かも?
自分はベクトルを入出力としたニューロンということで認識している()
ベクトルを使うので、学習時に空間的な情報も扱えるから最強だよね!っていうことだと思うことにしました。(適当ですみません)
複数のニューロンの相互関係(向き)と特徴の強さ(値の大きさ)を使えるっていうことなのかな。


簡単な構造の画像は以下になります。
f:id:sizuruna-193:20180914194353p:plain
(引用:https://qiita.com/hiyoko9t/items/f426cba38b6ca1a7aa2b
左がカプセル、右がニューロン

3.学習方法(アルゴリズム

CapsNetではDynamic Routingという手法を使う。これが一番重要・・・。
抽象的に言うと、カプセル同士の繋がり(重み)を学習する。
この学習方法のおかげでCapsuleNetworkの最大の利点である特徴間の空間的な相互関係が学習できる
Dynamicなのは、学習過程でカプセル間の繋がりを強くしたり、弱くしたりするために、構造が動的に変化するからだと思われる。(CNNでも同じことしてるじゃない?なんて一瞬思った)

自分なりに翻訳したアルゴリズムは以下になります。(画像の数字とその下の数字は関連してないので注意してください。)

f:id:sizuruna-193:20180914193845p:plain

(1)まずl層目のi個のカプセルと(l+1)層目のj個のカプセルとの間の変数bijを0で初期化する
(2)l層目のi個のカプセルより、SoftMax(bij)で「繋がり度合いcij」を計算する
(3)(l+1)層目のj個のカプセルより、cij*uij(uiはl層目のi番目の出力ベクトル)の総和であるsjを計算する
(4)(l+1)層目のj個のカプセルより、繋がりが強い場合は1、そうでない場合は0に近づける活性化関数Squash(sj)を計算する
(5)カプセル間の変数bijを更新する bij←bij + uji*vj
(6)2~5をルーティングしたい回数繰り返す

これを実際の顔画像で例えるなら
l層目の下位カプセルは目、鼻、口を示していて、l+1層目は顔や花、建物といった上位カプセルと考える。
入力画像に顔があったとき、目があって顔が存在し、鼻があって顔が存在するが、目が花や建物には存在しない。
このとき目と花といったカプセルは繋がりが弱いと判断し、目と顔のカプセル間は繋がりを強くするという学習を行う。
(この繋がりの強さを1~0と考えるとして、Squash関数を用いて弱い場合は0に近づけ、強い場合は1に近づける)

f:id:sizuruna-193:20180914194956p:plain

4.CapsNetの構造

f:id:sizuruna-193:20180914200528p:plain

左から順に
・入力画像(MNIST)
・Conv1
・PrimaryCaps
・DigitCaps
・一番右は再構成ネットワーク?だと思われる(後で解説)

CapsNetでも畳み込み層は使用しているそうです。(CNNはプーリング層が情報をそぎ落とす欠点だった)
Conv1で画像の特徴を抽出して、
PrimaryCapsとDigitCapsの間で先ほどのDynamic Routingのアルゴリズムを使用して画像の空間的関係を学習する。
パラメータに関してはいじってみたのですが正直まだわかっていないのでスルーします・・・。扱う入力画像によって変わると思うのでモノクロやカラーだとどうなるのか調査してみたいところ。

5.損失関数

もちろん、CapsNetでも損失関数はあります。この論文ではMarginLoss関数と呼んでました。

f:id:sizuruna-193:20180914201234p:plain

・Tkはデータがクラスk(存在すれば)1、そうでなければ0
・vkはカプセルの出力
・λは0.5 m+は0.9 m-は0.1
・kは0,1,2,3...9のどれか(MNISTの10クラス分)

つまり、クラスkが存在した場合は左側の計算、存在しない場合は右側の計算を行うといった損失関数になっています。
λとかmの値に関しては論文で既に設定されていました。これが一番適切らしい。

6.再構成損失

先ほどのネットワーク構造の画像の一番右について解説します。
この技術はぶっちゃけ多分CapsNetとは関係ないと思われるのですが、使ってみたらうまくいっちゃった!みたいな感じで紹介されていたので多分そうだと思う()

f:id:sizuruna-193:20180914201643p:plain

カプセルの出力から画像を再構成することで、入力画像と再構成した画像の差異を損失として先ほどのMarginLossに加えるというもの。
要するに、このネットワークが思い出して入力画像を作ることができるかどうかを確かめているということだと思っています。うまく作れれば損失は少なくなるし、そうでなければ損失が高くなる(まだ学習できてないからもっと学習することになる)

もちろんこの技術はMarginLossに加えることができるといったので、学習する段階で再構成するかしないかを選択することは可能です。

ちなみに計算方法は訓練データ(入力)と再構成した画像とのズレを最小二乗法で計算してます。

これを行うことで過学習の防止、性能の向上が見込めるので使わないに越したことはないでしょう。
ちなみにこれを使うか使わないかでどのくらい学習時間が変わるのか調べてみたのですが、MNISTぐらいの画像だと対して変わりませんでした()カラー画像だともしかしたら結構違いが出るかもしれない。

7.所感

カプセルネットワークはかなり人間の脳に近い動きをするネットワークということはなんとなくわかりました。CNNだと訓練時に多くの角度のデータが必要になるけれど、人間の目は正面で見た物体は斜めからみたところで大体同じものだと認識できるので、かなりカプセルネットワークは人間の脳に近いことがわかりました。
論文だとモノクロ画像のMNISTしか使ってなかったのですがそれでもCNNと比較するとかなり物体認識に安定感があるなあと思いました。
しかし、実際に動かしてみたのですが、学習データが少なくなっても学習時間はCNNと比べると4倍ぐらい掛かってしまいました・・・。この部分に関してはCNNが研究されまくってきたからというのもありそうなので、今後に期待ですね・・・。
カプセルネットワークはグーグルみたいな大企業で研究するところよりも、個人で研究している人向けかもしれませんね。学習データが少なくなるのはかなりうれしいと思いました。

参考文献など
カプセルネットワークはニューラルネットワークを超えるか。
Dynamic Routing Between Capsulesを読む - データサイエンティスト(仮)
https://arxiv.org/pdf/1710.09829.pdf

ソースコード
github.com

NNC(NeuralNetworkConsole)で学習させたパラメータを用いて推論してみた(Python・NNabla使用)

 

SONYが出してるNNC(ニューラルネットワーク コンソール)を使って簡単に今流行りのディープラーニングが体感できることはわかった。

けれども、NNCだけだとどうやら不十分らしい。ただ画像を学習してそれを評価することしか出来ません。いやこれでも個人的にはすごいと思ってしまうけれども・・・。
とにかく、NNCだけでは世の中に出ているようなロボットが画像を認識するとか、株価の予測とか、そう言ったニューラルネットワーク を応用した開発は出来ないみたいです。

そこで、NNCが利用しているライブラリであるNNabla(ニューラルネットワーク ライブラリ)というものを使ってコードを書くということが必要になってくる。

今回はプログラムの基礎はある程度知っているけれど、ライブラリを利用してプログラムを作ったりしたことが全くほとんどない素人プログラマが、NNCが作ってくれたNNを利用してMNIST0~9の文字認識を行ってみました。(ほとんどのコードもネットから引っ張ってきてます)
もしかしたら全然違うことをやってるかもしれないですが、勉強メモとして残したいのでまとめてみました。(言い訳)

前提として、MacWindowsにすでにNNCとNNablaが入ってることにします(導入とか、書くのがめんどくさかった・・・)

参考サイトは次の通りです。とてもわかりやすいので絶対にそちらをみながらやった方がいいと思います。
NNabla(Neural Network Libraries)で学習済のパラメータのSAVEとLOADをやってみる。 - アラカン"BOKU"のITな日常
ライブラリーを使わずにPythonでニューラルネットワークを構築してみる - Qiita

 

公式リファレンス
Neural Network Libraries — Neural Network Libraries 0.9.9 documentation

あと参考書として以下のものを利用しました

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

 

 

NNablaとは?
そもそもNNablaとはなんなのか
SONYが開発した、ニューラルネットワーク をかなり短めなコードだけで簡単に記述することができる便利なライブラリのこと。
他にはGoogleが出してるTensorFlowだったり、PrefferedNetworkが開発したChainerがあります。NNablaはSONYが出したもの。

NNabla以外は名前ぐらいしかわからないです()

特徴は公式サイトに書いてあるのでそちらを参考に。
nnabla.org

NNablaはC++Pythonが利用できるみたいです。今勉強中なのはPythonなのでPythonでやっていきます。

自分の開発環境?(適当)
・Python3.6が入ってるMac
・ターミナルで実行してる
・NNCを実行したのはWindowsのゲーミングパソコン
(性能低いとNNCの学習から評価までものすごく時間がかかる)

 

必要なこと、もの
・データセットの準備・読み込みする部分のコードの記述
・ネットワークの構築
・パラメータ作成

・推論部分の構築

とりあえずこの4つを作ることができればできるっぽい。
この中の青字はNNC側は作ってくれるので、実際に頑張るのはデータセットの準備とか推論部分の構築ぐらい。

1.NNCでCNNを構築してMNISTを学習させる
チュートリアルの「02_binary_cnn」で学習させます。これに関してはいろんなサイトで既に書かれていたりするので下にネットワークの画像を載せつつここでは割愛します。

f:id:gen-193:20180501084055p:plain

2.データセットの準備・読み込みする部分のコードの記述
NNCで学習させたデータセットCSVファイルを呼び出すためのコードを記述します。

まずはインポート部分。

#import部分
#データの読み込みで使用する
from args import get_args
from data_iterator import data_iterator_csv_dataset
import nnabla.solvers as S
from cnn_network import network
#ネットワーク構築で使用している
import nnabla as nn
import nnabla.functions as F
import nnabla.parametric_functions as PF

#データ読み込み
test_data = data_iterator_csv_dataset("mnist_test.csvが入っているパスを記述",1,shuffle=False)

以下のサイトから必要なファイルをダウンロードします
https://github.com/sony/nnabla/tree/master/python/src/nnabla/utils

ってまあこれがわかったのは以下のサイトのおかげです。助かりました。ほとんどこちらを参考にしちゃっていいと思います。
cedro3.com

データセットなんですが、NNCがCSVファイルとしてまとめてくれています。
neural_network_console_110/samples/sample_dataset/MNIST/mnist_test.csv

ここまででデータセットの読み込みの準備は完了です。

3.ネットワークの構築
最初にMNISTの学習をさせたネットワークをPythonのコードにします。

EDITの画面の中で右クリックしてExportを選択。「Python Code(NNabla)」を選択するとクリップボードにコピーされます。
新しいpythonファイルを作成して、何でもいいので名前をつけます。とりあえず「cnn_network」とでも名付けます。

import nnabla as nn
import nnabla.functions as F
import nnabla.parametric_functions as PF

def network(x, y, test=False):
    # Input -> 1,32,32
    # Convolution -> 16,28,28
    with nn.parameter_scope('Convolution'):
        h = PF.convolution(x, 16, (5,5), (0,0))
    # MaxPooling -> 16,14,14
    h = F.max_pooling(h, (2,2), (2,2), True)
    # Tanh
    h = F.tanh(h)
    # Convolution_2 -> 8,10,10
    with nn.parameter_scope('Convolution_2'):
        h = PF.convolution(h, 8, (5,5), (0,0))
    # MaxPooling_2 -> 8,5,5
    h = F.max_pooling(h, (2,2), (2,2), True)
    # Tanh_2
    h = F.tanh(h)
    # Affine -> 73
    with nn.parameter_scope('Affine'):
        h = PF.affine(h, (73,))
    # Tanh_3
    h = F.tanh(h)
    # Softmax
    h = F.softmax(h)
    # CategoricalCrossEntropy -> 1
    #h = F.categorical_cross_entropy(h, y)
    return h

貼り付けるとこんな感じのファイルになってるはずです。楽チンですね・・・。
よく見てみるとちゃんとnnablaのライブラリを使用してネットワークが書かれているのがわかると思います。
Convolutionが2つ、MaxPoolingも2つあるし、きちんとEDITで作成したネットワークと同様になってれば大丈夫です。

ネットワークの構築もこれで終わり。

4.パラメータの作成と推論の記述
作成といっても実は既に作成されています()1の段階でNNCで学習させたネットワークのパラメータを使えば終わりです。
neural_network_console_110/samples/sample_project/tutorial/basics/02_binary_cnn.files/学習させた日付/parameters.h5

この「parameters.h5」というファイルが多分学習パラメータが入ってるファイルなんだと思います(詳しくはわかってない)
このファイルを見つけたらファイルパス名はコピーしておきましょう
以下の記述を行います。

mch = 0 #初期化
nn.clear_parameters() #パラメータの初期化?必ずネットワーク構築前に記述
x=nn.Variable((1,1,28,28)) #バッチサイズ,size1、28*28
t=nn.Variable((1,1))
y = network(x,t)
#学習済みのパラメータ取得
nn.parameter.load_parameters("Parameters/h5があるパス名を記述");
#推論(一件ずつデータを検証し、カウントする)
for i in range(test_data.size):
    x.d, t.d = test_data.next()
    y.forward()
    if t.d == y.d.argmax(axis=1) :
        mch += 1

print("Accuracy:{}".format(mch / test_data.size))


5.実行
ということで実行して見ます。

f:id:gen-193:20180501102417p:plain

といっても実行するだけなので書くことないですね・・・とりあえず実行はできてるっぽいです。
まあこれだけだとあんまり出来てるのか実感が湧かないのでそのうち自分で書いた数字を認識させて見たいですね。

参考サイト
http://nnabla.readthedocs.io/en/latest/
NNablaでニューラルネットワークコンソールで学習済のパラメータを利用して推論のみを行う。 - アラカン"BOKU"のITな日常
http://cedro3.com/ai/nnabla-original-dataset/

【読了】GOSICKs Ⅳ 冬のサクリファイス 読む順番間違えた

そう、読んだのは短編集のしかもⅣ、つまり外伝的には4番目に読むべき小説でした・・・。
と、読み終わってから気づきました。時すでに遅し。

まあ、けどあんまり知らない人物とか出てこなかったし、本編ではあんまり関係がなさそうな感じがしたのでよかったです。というか普通に面白かった。外伝だからそこまで真剣に読まなくてもいいと思うし。

今回は聖マルグリット学園の冬休み?直前の出来事。生徒たちと先生とかグレヴィールとかが学校のイベントであるチェス大会に参加して遊んでて、すごい楽しそうな雰囲気を出してるんだけど、なーんか不穏な感じがちょっとだけ垣間見得てるのが怖い。

別にチェス大会がメインな訳ではなく、特定の人物の回想とかをちょっとずつ挟んでいく感じで物語が進行していく感じです。

個人的にはセシル先生とゾフィの掛け合いだとか結構好きです。女同士の躊躇いのない感じの会話?というのが。結構ズバズバ言い合う感じがなんか面白い。そこまでこの二人が重要そうな人物ではないだけに、二人のシーンはなんかミステリ小説を少しだけ忘れさせてくれるのがよかった。

あとはグレヴィールの頭の秘密だったりだとか、その部下二人がどうして手を繋ぐ必要があったのかだとかも明らかになります。

ブライアンがコルデリアを助けにくる話だったりとかも。

今回は外伝だったので結構適当に読んでた()でもちょくちょく物語の内容を忘れちゃうのでこうした外伝を読むと思い出させてくれるのでやっぱりいいですね。

【読書感想】GOSICK Ⅴ トリック解説が楽しかった

どうも、最近お絵かきが楽しくなってて勉強時間がうまく取れない193です。めっちゃ楽しい。
あと、最近Xamarinを使ったアプリ開発はちょっと諦めて、まずはネイティブ開発しようって思ったのでswiftとxcode使ってアプリ開発してます。簡単なアラームアプリなのですが、とりあえずそのネタはまた今度話そうと思います。

今回はGOSICK Ⅴを読んでみました。1~4とsシリーズを1つ読んでますが、やっぱり頭のいいキャラとそれをサポートするキャラの組み合わせってすごい好きです。読んでて個人的にどんどんこの二人を応援したくなってしまう。

今までのGOSICKもトリックとかそのネタ解説はあったのですが、Ⅴは特に力が入ってて思わず驚きが出てしまったぐらいです。

どんなお話だったか
今回はヴィクトリカが不在の学園からスタートします。どうやらベルゼブブ頭蓋と呼ばれるお城に拉致られた?みたいで、一弥はヴィクトリカを連れ戻しにそのお城に向かいます。
そのベルゼブブのお城で起こる殺害事件を解決、というかネタ明かししていくという感じでしょうか。

ⅤではGOSICKの全体的な勢力図というか、そういうのが分かる結構大事なお話だったかもしれないです。ヴィクトリカの母親もここで登場します。ブライアンやブロワ侯爵だったり、ヴィクトリカの出生や、オカルト省と科学アカデミーの対立などが結構語られます。


トリック解説が結構面白かった
個人的には今まで読んだシリーズの中で一番解説に力が入ってたんじゃないかなーって感じました。
チェスドールの仕組みや錫と水銀で作った銃弾、最後にスリップノットと呼ばれる紐の結び方はとても面白かったです。

チェスドールの自動人形については以下のサイトを参考に
www.tokyomagic.jp

道中、一弥がこのチェスドールに叩かれる?シーンが会ったのですが、こういうトリックを使うことで可能にしていたんですね。
中身を見ても、機械仕掛けになってる部分は動かすことが出来るので、それを動かせば中にいる人は見えないため本当に機械が自分の意思で動いてると錯覚してしまいます。


錫という金属は初めて知りました。どうやら柔らかいものらしく、衝撃を少し加えるだけで凹んだりと結構脆い金属にあるようです。脆いので、これを混ぜて作った銃弾はトリックに使うのにぴったりなんですね・・・。
錫で作られた器で飲むと結構美味しくなるらしく、錫製のタンブラーなども売られてるみたいです。

錫に関して詳しい内容とかが書かれているサイトは以下になります。普通に面白い。
sake.science


スリップノットと呼ばれる結び方は以下のサイトから
knots.starrypages.net
これを利用することで人前でも、アリバイを作りつつ人を傷つけることが可能・・・。特にGOSICKの世界観では抜群に有効だったでしょうね・・・。科学とオカルトがまだ共存していた時代なので。

というかこの結び方すごい!って思ったのですが、もしかしたら知らず知らずに利用していたかもしれないですねw
調べてて気づきました。



というわけで、個人的にはお話もかなり重要だったのですが、トリックの解説がとても面白かったなーっていう印象が強かったGOSICKⅤでした!

【読書感想】人魚に嘘はつけない

どうも、193です。今日は人魚に嘘はつけないという小説を読んだので、その感想なんかをつらつら書いていきたいと思います~
全体を通して思ったのは、各パートの内容は薄かったかなーという印象がありました。幼馴染とか親友、主人公や人魚の悩みが各パートに書かれているんですが、事の重大さに対して解決が一瞬すぎて、ちょっと微妙でした。
文章を読んでて思ったのは、非常に頭の中で情景が思い浮かびやすかったというところですね。シンプルな文章ですごく想像しやすかったので読みやすかった反面、情景の文章が多すぎて内容が薄かったかなあといった印象でした。
細かいところは続きへ・・・(ネタバレあり) 続きを読む

近況

どうも、193です。
4月から大学が再スタートするので、研究の前準備として2月はPythonと数学を主に勉強してます。
英語はTOEICで確認できるように一応申し込みは完了してますが、数学とかPythonも何か指標みたいなのがあればいいなあ。探してみます。

ツイッターとかネットでPythonの勉強方法について調べたところ、”Progate”というプログラミングサイトが良いようで、今はそれを活用して勉強してます。
一応CとかC#とかJavaの基本部分は把握してるので、なんだかんだ今は余裕な感じで進んでます。

2月は高校数学とPythonTOEICに向けての英文法とリスニングを勉強して(短期バイトも入って)
3月は行列の勉強(線形数学)とPython使ってプログラムを作ってみたりだとか、してみたいなあ。あと小旅行。

地味にPythonでゲームとか作れるっぽいですね・・・この言語すごくシンプルでわかりやすいからCよりも初学に向いてるかもしれない、って思ってます。
ただまあCは早くてメモリ管理がどうのこうの(知らない)だとかコンピュータの中身について触れることができるからそれはそれでいいのかもしれないけれど。

あと地味に絵も描いてます。ブログのプロフィール欄にPixivのリンクがあるので良ければ見ていってください。

【勉強】高校3年分の英文法が10日間で身につく<コツと法則>

高校3年分の英文法が10日間で身につく<コツと法則> (アスカカルチャー)

高校3年分の英文法が10日間で身につく<コツと法則> (アスカカルチャー)

正直言って解説が独特すぎて自分には無理だと思った。というのが正直な感想です。
半分まで読んだけど、どうしてこうなるのかとか、とりあえずこういう風になるから覚えておけ!みたいな感じで理屈じゃなくて覚えろという風に感じられた。

なんというか、これを読んでて面白い!って思えないからペースが進まない・・・。読むのは大人が大半だから、昔勉強したこの文法ってこんな理屈でこういうようになってたのか!っていうのがわかると面白くなって勉強できると思うから、自分にはこの本は向いてなかったかなって思った。

数学の初めから始めるシリーズを使って今勉強しているけど、大人になって数学をやり直してみると、この本は結構詳しく解説があるから面白くなってどんどん進んじゃう。

また文法の本を探そうと思うけど、普通に高校生向きの本でいいかなって思ったので、次からは注意して探そうと思う。