crash.academy · 来たるべきai新時代に向けて...

331
ディープラーニング入門 集中講義 丸山不二夫

Upload: others

Post on 20-May-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

ディープラーニング入門集中講義

丸山不二夫

Part Iニューラルネットワークの基礎Part IIニューラルネットワークは、どう「学習」するのか?Part III ニューラルネットワークによる画像認識技術

本集中講座の構成

Part I

ニューラルネットワークの基礎

ディープラーニング入門集中講義

まず、学ぶことから始めよう!

ITの世界は、この10年で大きく変わったクラウドとモバイルの時代

2004年 Google上場

2006年 Amazon EC2, S3

2007年 Apple iPhone

2008年 Microsoft Azure

2008年 Google Android

2012年 Facebook上場

世界は、この先10年でどう変わるのか?

来たるべきAI新時代に向けて

モバイルとクラウドの時代が始まって10年が経った。次の10年を展望した時、AI技術が、その新しい技術的中核として登場しようとしている。

ただ、モバイルが携帯電話の、クラウドがデータセンターの、ある意味では連続的な発展だったのに対して、ニューラル・ネットワークは、ほとんどの技術者にとって全く新しい技術である。そこには、技術的な「断絶」がある。

問題は明確である。我々は、来たるべきAI新時代に向けて、学ぶことから始めなければならない。同時に、重要なことは、今後の10年を展望すれば、それはすべての技術者にとって必要な課題になるだろうだということである。

CAMEL の Opening Remark のスライド http://goo.gl/JVjGne

人間の学習が重要

まず、学ぶことから始めよう。

人工知能を作るには、人間の知能が必要であり、機械学習を知るためには、人間の学習が必要である。

様々なAI技術

Azure ML統計処理

A. 統計的分析に基づく、数値予測・クラス分け

これは昔から統計学の手法として存在する、回帰分析やクラスター分析と考え方は、基本的に同じものである。

ただ、マシンのパワーが飛躍的に増大して、大量のデータを短時間で処理できるようになり、かつ効果的なビジュアリゼーションが可能になったのが、実践的には新しく、かつ重要な変化である。

現在、クラウドで提供されている、大部分の機械学習のサービスは、このクラスに属する。

同時に、「決定論的なアプローチ」に対する「統計的なアプローチ」の優位という方法論的な自覚は、現在の機械学習技術・AI技術の多くの領域に、大きな影響を与えつつある。

パーソナル・アシスタンス・システム

B. 経験的に構築された知識・推論・対話システム

パーソナル・アシスタント・システムGoogleのGoogle Now, AppleのSiri, MicrosoftのCortana, AmazonのAlexa等々。私たちの身近なところで、もっとも活発に応用が進んでいる分野。完成度の高い 「質問応答システム」として、(かつての)IBMのWatsonがある。

入力(Speech to Text)、出力(Text to Speech)に、ニューラル・ネットワーク技術を利用する。

「パーソナルアシスタント」のプログラムは、Turing Test

的には、「知的」にふるまっているように見えるのだが、その多くの実装は、「知的」なものとは言えない。

Deep Learning

C. ニューラルネットワークに基づく、知覚・運動系へのアプローチ。Deep Learning

現在、活発に研究・応用が進んでいる分野である。文字認識・発話の文字列への変換、静止画・動画からの対象の判別・動きの検出等々で、大きな成功を収めている

基本的なモデルの起源は、生物の知覚・感覚(主要には、視覚・聴覚)を司る神経回路網にある。

生物の知覚・感覚の能力は、運動能力と密接に結びついて、感覚・運動系を構成しているので、ロボットの動作の制御、ドローンの姿勢制御、自動運転等にも、このアプローチは有効で、応用分野を拡大している。

「女性が公園でフリスビーを投げている」 「幼い子がテディベアを持ってベッドに座っている」

「一群の人たちが野外マーケットでショッピングをしている」「フルーツスタンドにはたくさんの野菜がある」

イメージからテキストへ

言語理解

D.人間固有の言語能力の機械による実現

「機械翻訳システム」 本来は、意味理解を含む人間の一般的な言語能力に関わっている。ただ、機械翻訳の場合、質問に答えることが求められているわけではない。それは、ある言語から他の言語への形式的な「書き換え」システムなのかもしれない。

この領域は、最終的には、機械が人間のように、言語の「意味」を理解して、「知識」を活用して「意味」のある活動をするのを目指している。ある意味、人工知能の本丸である。ただ、多くの課題が残されている。

HoTT(Homotopy Type Theory)とUnivalent Theory

論理=数学的には、 a : A には、様々な解釈がある。ここでは、他の解釈と比較して、HoTTでの a : A の解釈を見てみよう。

1. 集合論: Russellの立場Aは集合であり、aはその要素である。

2. 構成主義: Kolmogorovの立場Aは問題であり、aはその解決である

3. PAT: Curry & Howardの立場Aは命題であり、aはその証明である。

4. HoTT: Voevodskyの立場Aは空間であり、aはその点である。

”Propositions as Types” “Proofs as Terms”

数学的認識の理解

E. 人間の数学的・論理的な推論能力に関わるもの

ここでは、経験的な起源からは相対的に独立な、純粋に数学的な定理の証明や、複雑な証明の機械による支援が課題になる。この分野でも、COQ等の「証明支援システム」を中心に、興味ふかい前進がある。 マルレク「「型の理論」と証明支援システム -- Coqの世界」

http://bit.ly/1qbdXVE を参照されたい。

かつての日本の「第五世代」的な、AIに対する「論理的」な(というより「定理証明的」な)アプローチは、現在のAI

研究においては主流ではない。ただ、そのことは、他のすべての領域と同じように、数学的・論理的なアプローチの有効性を否定するものではない。

数学や物理といった知識の体系は、誰もが生得的に持つ言語能力や経験的な知識の体系には、還元されない。

AI技術を構成する複数の流れの中で、なぜ、ニューラル・ネットワークが重要なのか?

A) 既知のデータの統計的分析をもとに、数値予測・クラス分けを行うもの。機械学習技術。

B) 経験的に構築された知識・推論・対話システム。パーソナル・アシスタンス・システム etc。

C) ニューラルネットワークの手法を用いて、生物の感覚・運動系の能力の相同物を機械上で実現しようとするもの。ディープ・ラーニング。

D) 人間固有の言語能力の機械による実現。

E) 人間の数学的・論理的な推論能力に関わるもの。

ニューラル・ネットワークは、新しいAI技術の現在の技術的中核だから

A) 既知のデータの統計的分析をもとに、数値予測・クラス分けを行うもの。機械学習技術。

B) 経験的に構築された知識・推論・対話システム。パーソナル・アシスタンス・システム etc。

C) ニューラルネットワークの手法を用いて、生物の感覚・運動系の能力の相同物を機械上で実現しようとするもの。ディープ・ラーニング。

D) 人間固有の言語能力の機械による実現。

E) 人間の数学的・論理的な推論能力に関わるもの。

NNは、同等の能力を持つ

Speech2TextText2SpeechHumanInterface

CNN+RNN機械翻訳KnowledgeDatabase

未来の、「人工知能」

モデルとしての生物のニューラル・ネットワーク

http://www.tmd.ac.jp/artsci/biol/textlife/neuron.htm

クラゲだって神経はある

「神経系の起源と進化」http://bit.ly/1qR2Dmq

http://goo.gl/0lbzRg

線虫のC. Eleganceは、すべての神経の接続がわかっている唯一の生物である。302の神経と8,000のシナプスがある。

1987年

アノマロカリス

「視覚」の誕生と発展

生物の進化の歴史の中で、「視覚」の能力は、5億年前の「カンブリア紀」に獲得された。それは、長い長い歴史を持っている。当時の食物連鎖の頂点に立っていた「アノマロカリス」は、立派な眼を持っていた。

「眼」の獲得、同じことだが、「視覚」の能力の獲得は、「捕食者」にとっても(獲物を見つける)、「被捕食者」にとっても(捕食者から逃れる)、その「生き残り」に、死活的に重要な意味を持つことになった。人間を含めて、すべての動物で、強い淘汰の圧力のもとで、視覚処理の能力は、高度に発達している。

同時に、この「視覚」の能力は、追いかける、捉える、あるいは、逃げるといった「運動能力」に深く結びついている

多くの生物は目を持っている

https://www.brh.co.jp/seimeishi/journal/012/ss_1.html

ゲーリングによる「目の遺伝子」Pax-6の発見

視覚と運動能力は、強く結びついている

60年代から70年代にかけての、Hubel と Wieselの大脳視覚野の研究は、各方面に大きな影響を与えた。ニューラル・ネットワークの最初の研究も、こうした影響のもとで始まった。

David H. Hubel

Torsten Wiesel

1960年代

脳は、1mm立方に5万個のニューロンを含み、一つのニューロンは6千個のシナプスをもつ。

大脳新皮質には、100億のニューロンと60兆個のシナプスがある!

人間の脳のエネルギー効率は、驚異的に高い。

AIのハードの世界でも大きな変化が進んでいるのだが、留意すべきこと....

「人間と機械」という対比だけでなく、「生物と機械」という対比でも、考えることは面白い。

ニューラル・ネットワークが、今後、大活躍するであろう「感覚-運動系」でも、生物の能力は、驚異的である。

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明脳研究の取り組み

脳研究の取り組み

現在は、それぞれ異なった道を歩いているのだが、ニューラル・ネットワークの研究と脳研究とは、「人間の知能」の解明という共通の目標で結ばれている。ここでは、脳研究のいくつかの取り組みを紹介する。

Blue Brain ProjectHenry Markram

“I wanted to model the brain because we didn’t understand it.”

“The best way to figure out how something works is to try to build it from scratch.”

in vivo

in vitro

in silico

http://seedmagazine.com/content/article/out_of_the_blue/P1/

ネズミの脳

http://seedmagazine.com/content/article/out_of_the_blue/P1/

EU Human Brain Project

2013年10月 10年間で総額約12億ユーロ

EU Human Brain Projectビジョン

人間の脳を理解することは、21世紀の科学が直面している最も偉大な挑戦の一つである。もしも、我々が、それに対して立ちあがることが出来るならば、我々は、我々を人間にしているものが何であるかについて深い洞察を得て、革命的なコンピュータ技術を構築し、脳の異常に対して新しい治療法を開発出来るだろう。今日、初めて、現代のICT技術が、こうした目標を到達可能なものにしている。

EU Human Brain Project批判 ECへの公開質問状

脳研究をめぐる「対立」の構図認知科学 vs 脳科学、トップダウン vs ボトムアップ

発端は、次年度のプロジェクトの予算配分で、認知科学的なアプローチの予算が、ばっさりと切られたことにあるらしい。それに反発した研究者のグループが、150名の連名で、欧州委員会に公開質問状を提出した。

対立の根底にあるのは、脳研究でのアプローチの違い。Henry Markramら主流派は、ニューロンとシナプスの数学的モデルに基づいて脳全体のモデルをボトムアップに作り上げようというアプローチ。 一方、反対派は、脳研究には、認知科学の知見に基づいたトップダウンのリバース・エンジニア的なアプローチが必要だという。

「鳥の羽の全てをシミュレーションしたとしても、鳥が空を飛べることを解明出来ないのと同じことだ」

NIH Human Connectome Project

http://www.nih.gov/news/health/sep2010/nimh-15.htm

2010年10月 40億円の賞金

NIH Human Connectome Project

http://www.humanconnectomeproject.org/

US BRAIN Initiative NIHのもとで、12年間で4,500億円投資する

2014/06/05 http://1.usa.gov/1pIIhvx

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明ニューロンの働き

ニューロンの働き

脳の働きも、最終的には、脳を構成する無数のニューロンの働きに帰着する。

コンピューター上のニューラル・ネットワークを構成する個々の「ニューロン」の動作原理は、生体のニューロンの働きをシミレートしたものである。

脳のニューロンのコンピュータ・グラフィックス

ヘッブの法則Donald O. Hebb

ヘッブの法則(ヘッブのほうそく)は、脳のシナプス可塑性についての法則である。ヘッブ則、ヘブ則とも呼ばれる。心理学者のドナルド・ヘッブによって提唱された。ニューロン間の接合部であるシナプスにおいて、シナプス前ニューロンの繰り返し発火によってシナプス後ニューロンに発火が起こると、そのシナプスの伝達効率が増強される。また逆に、発火が長期間起こらないと、そのシナプスの伝達効率は減退するというものである。

The Organization of Behavior. 1949年

https://goo.gl/2HsDwK

ヘッブの法則Donald O. Hebb

1950年代

http://kitsuon-kaizen.en.que.jp/hori/108.htm

http://blogs.yahoo.co.jp/yuyamichidori/11068629.html

興奮性シナプスと抑制性シナプス

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明ニューラル・ネットワークとその表現

ニューラル・ネットワークとその表現(1)

一つのニューロンの動きを考える

一つのニューロンの内部の状態の表現

複数のニューロンからなる一つの層の内部の状態の表現

式は便利だ! Y = W・X + b が表すもの

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

ニューラル・ネットワークの例

一つ一つの丸が、一個のニューロンを表している。一つのニューロンは、その「出力」を、他のニューロンに、送り出す。

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

入力層 隠れ層 出力層

ニューラル・ネットワークの例

複数のニューロンの集まりが、「層」をなしている。

もう少し複雑なニューラル・ネットワークの例

これでも省略されている784->8

一つのニューロンの動きを考える

以下の文中に現れる「ニューロン」は、コンピューター上でシミレートされた偽の「ニューロン」である。ただし、基本的な動作原理は、本物のニューロンを真似ていることを知っておくことは、役に立つと思う。

ニューロンは、いつ発火するのか?

ニューロンは、いつ発火するのか?

ニューロンの働きは、発火するか発火しないかの

1か0かのディジタル・スタイル

個々のシナプスの性質同じ発火信号を受けても、受け止めるニューロン内でのその信号の「強さ」は、シナプスごとに異なる。

興奮性シナプスからの信号の強さから抑制性シナプスからの信号の強さを引いた値がある閾値を越えると、ニューロンは、「発火」する。

興奮性シナプスからの信号の強さから抑制性シナプスからの信号の強さを引いた値がある閾値を越えると、ニューロンは、「発火」する。

ニューロンの働きは、発火するか発火しないかの

1か0かのディジタル・スタイル

個々のシナプスの性質同じ発火信号を受けても、受け止めるニューロン内でのその信号の「強さ」は、シナプスごとに異なる。

ニューロン発火の条件

あるニューロンが「発火」するかは、次のようにして決まる。

興奮性シナプスから受け取る信号の強さ全体 A から抑制性シナプスから受け取る信号の強さ全体 B を引いて、その値がある閾値 C より大きければ発火する。

A – B > C 発火 ( A – B – C > 0 )A – B < C 発火しない ( A – B – C < 0 )

発火賛成と発火反対の多数決。ただし、賛成票が、ある一定数以上(閾値)、反対票を上回らないといけないというルール。至極、単純である。

賛成票 - 反対票 > 閾値 発火賛成票 - 反対票 < 閾値 発火しない

賛成票:3+3+2=7反対票:2+1+2=5

賛成票 - 反対票 = 2 > 1(閾値)

発火!

ニューロン発火の判断賛成票 - 反対票 > 閾値 発火

閾値=1の場合

個々のシナプスの性質は異なる内部の数字は、シナプスごとに異なる

信号を受けた時に伝えられる、信号の「強さ」

X1=1

X2=1

X3=1

X4=1

X5=1

X6=1

2

3

1

32

2

賛成票:0+0+2=2反対票:2+1+2=5

賛成票 - 反対票 = -3 < 1(閾値)

発火せず!

ニューロン発火の判断賛成票 - 反対票 < 閾値 発火しない

閾値=1の場合X2, X4からの信号なし

X1=1

X2=0

X3=1

X4=0

X5=1

X6=1

2

3

1

32

2

個々のシナプスの性質は異なる内部の数字は、シナプスごとに異なる

信号を受けた時に伝えられる、信号の「強さ」

賛成票:3+3+0=6反対票:2+0+2=4

賛成票 - 反対票 = 2 > 1(閾値)

発火!

ニューロン発火の判断賛成票 - 反対票 > 閾値 発火

閾値=1の場合X3, X5からの信号なし

X1=1

X2=1

X3=0

X4=1

X5=0

X6=1

2

3

1

32

2

個々のシナプスの性質は異なる内部の数字は、シナプスごとに異なる

信号を受けた時に伝えられる、信号の「強さ」

「重み」と「バイアス」

賛成票の数 Aをプラスの値に反対票の数 Bをマイナスの値 B’ にし、閾値 Cの符号を逆にして C’ (バイアス)とすると、発火の条件 A – B > C (すなわち、A – B – C > 0)は、A + B’+ C’ > 0 の形になる。

各シナプスごとに異なる投票権の大きさを「重み」という。興奮性シナプスはプラスの「重み」を持ち、抑圧性シナプスはマイナスの「重み」を持つと考えるということ。

一つの入力Xi(0か1の値をとる)には、それに対応した一つのシナプスが存在する。そのシナプスの重みをWiとすれば、この一つのシナプスの投票数は、入力 Xi に 重みWi をかけたもの。

入力Xiと重みWiとバイアスbで発火の条件を表す

今、6つの入力Xi (i=1,2,...6)があったとしよう。この時、この入力に対応するシナプスの重みをWi (i=1,2,...6)とすれば、各シナプスでの投票数は、入力Xiに対応する重みWiをかけたものだから、一つのニューロン全体の投票数は、このニューロンのすべての6個のシナプスの投票を足し合わせたものになる(符号も込みで考えている)。

この投票数にバイアスを足し合わせたものがプラスの時、このニューロンは発火する。

式で表すと、入力 X1,X2,..X6は、0または1でW1X1+W2X2+W3X3+W4X4+W5X5+W6X6+ b > 0 の時発火ということになる。

X

X1,X2,..X6は、0または1で

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6

+ b > 0

の時発火

重み:Wiシナプスごとの賛成票の投票権をプラスの値に反対票の投票権をマイナスの値にすると、式が簡単になる。

バイアス:bついでに、閾値 Cの符号を逆にすれば、

式はもっと簡単になる。それを「バイアス」という。

X1

X2

X3

X4

X5

X6

W2=3

W3=-1

W4=3W5=2

W6=-2

W1=-2

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6

+ b =(-2)x1+3x0+(-1)x1+

3x0+2x1+(-2)x1-1 =

-2-2+2-2-1= -5<0

発火せず!

重みWi=[-2,3,-1,3,2,-2]バイアス b=-1

入力Xi=[1,0,1,0,1,1]の場合

X1=1

X2=0

X3=1

X4=0

X5=1

X6=1

-2

3

-1

32

-2

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6

+ b =(-2)x1+3x1+(-1)x0+

3x1+2x0+(-2)x1-1 =

-2+3+3-2= 2>0

発火!

X1=1

X2=1

X3=0

X4=1

X5=0

X6=1

-2

3

-1

32

-2

重みWi=[-2,3,-1,3,2,-2]バイアス b=-1

入力Xi=[1,1,0,1,0,1]の場合

一つのニューロンの内部の状態の表現

一つのニューロンの内部の状態は、ニューロンがシナプスを通じて受け取る刺激である「入力」と、シナプスごとの「重み」と、発火の閾値に対応する「バイアス」の三つの量で表現できる。

X1

X2

X3

X4

X5

X6

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6+b > 0 ?

重み W=[W1,W2,W3,W4,W5,W6]バイアス b

入力 X=[X1,X2,X3,X4,X5,X6]の場合の発火の条件

まず、一つのニューロンで考えてみよう

X1

X2

X3

X4

X5

X6

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6+b > 0 ?

重み W=[W1,W2,W3,W4,W5,W6]入力 X= [X1, X2, X3, X4, X5, X6]

バイアス b

重みと入力の対応する項目同士をかけて、すべて足し合わせて、それにバイアス bを足したもの。

X1

X2

X3

X4

X5

X6

W1X1+W2X2+W3X3+W4X4+W5X5+W6X6+b > 0 ?

重み W=[W1,W2,W3,W4,W5,W6]バイアス b

入力 X=[X1,X2,X3,X4,X5,X6]の場合の発火の条件

X1

X2

X3

X4

X5

X6

先の行ベクトルXを列ベクトルに変えたものをXTで表す

XT =

行ベクトルと列ベクトルの積

行ベクトル W=[W1,W2,W3,W4,W5,W6] と行ベクトル X=[X1,X2,X3,X4,X5,X6] を列ベクトルに変えた XTとの積を次のように定義する。

W・XT = [W1,W2,W3,W4,W5,W6] ・

= W1X1+W2X2+W3X3+W4X4+W5X5+W6X6

対応する要素を掛けて、足し合わせたものである。

X1

X2

X3

X4

X5

X6

X1

X2

X3

X4

X5

X6

W・XT + b > 0 ?

この時、重み W=[W1,W2,W3,W4,W5,W6]

バイアス b入力 X=[X1,X2,X3,X4,X5,X6]の場合の発火の条件は、次のように、簡単に書ける。

もしも、Xが最初から行ベクトルの形で与えられていれば、重みWとバイアスbを持つあるニューロンの発火の条件は、W・X+b > 0 で与えられることになる。これは、y = ax + b > 0 と同じくらい、簡単な式の形である。

X1

X2

X3

X4

X5

X6

W・XT + b > 0 ?

この時、重み W=[W1,W2,W3,W4,W5,W6]

バイアス b入力 X=[X1,X2,X3,X4,X5,X6]の場合の発火の条件は、次のように、簡単に書ける。

この式は、ニューラルネットワークで、もっとも重要な式の一つである。

複数のニューロンからなる一つの層の内部の状態の表現

複数のニューロンの集まりが、一つの「層」として、入力を受け取り出力を返すことがある。

この層の内部の状態も、この層が受け取る「入力の全体」と、シナプスごとの「重みの全体」と、層を構成するニューロンの閾値に対応する「バイアスの全体」という三つの量で表現できる。

X1

X2

X3

ニューロン1

ニューロン2

ニューロン3

入力 X=[X1,X2,X3]

例えば、入力 X=[1,0,1] で

ニューロン1の重みが [2,-3,4] バイアスが -4ならニューロン1の出力は、2・1+(-3)・0+4・1-4=2>0で発火。

ニューロン2の重みが [-4,1,-5] バイアスが 5ならニューロン2の出力は、(-4)・1+1・0+(-5)・1+5=-4<0で発火せず。

ニューロン3の重みが [-4,-2,5] バイアスが 2ならニューロン3の出力は、(-4)・1+(-2)・0+5・1+2=3>0で発火。

三つのニューロンで考えてみよう

X1

X2

X3

ニューロン1W1・X

T + b1 > 0

ニューロン2W2・X

T + b2 > 0

ニューロン3W3・X

T + b3 > 0

入力 X=[X1,X2,X3]

重み W1=[W11,W12,W13]バイアス b1

重み W2=[W21,W22,W23]バイアス b2

重み W3=[W31,W32,W33]バイアス b3

ニューロン1の値: W1・XT + b1 = W11X1+W12X2+W13X3+b1

ニューロン2の値: W2・XT + b2 = W21X1+W22X2+W23X3+b2

ニューロン3の値: W3・XT + b3 = W31X1+W32X2+W33X3+b3

一般的には、

X1

X2

X3

ニューロン1W1・X

T + b1 > 0

ニューロン2W2・X

T + b2 > 0

ニューロン3W3・X

T + b3 > 0

入力 X=[X1,X2,X3]

重み W1=[W11,W12,W13]バイアス b1

重み W2=[W21,W22,W23]バイアス b2

重み W3=[W31,W32,W33]バイアス b3

W11X1+W12X2+W13X3+b1

W21X1+W22X2+W23X3+b2

W31X1+W32X2+W33X3+b3

これを、行列の積と和を使うと (あとで少し述べる)

W11,W12,W13 X1 b1

W21,W22,W23 X2 + b2 =

W31,W32,W33 X3 b3

これも、 W・XT + b の形をしている!

X1

X2

X3

X4

X5

X6

ニューロン1

ニューロン2

ニューロン3

ニューロン4

ニューロン5

ニューロン6

入力 X=[X1,X2,X3,X4,X5,X6]

六つのニューロンで考えてみよう。基本的には、同じである。

X1

X2

X3

X4

X5

X6

ニューロン1

W1・XT + b1 > 0

ニューロン2

W2・XT + b2 > 0

ニューロン3

W3・XT + b3 > 0

ニューロン4

W4・XT + b4 > 0

ニューロン5

W5・XT + b5 > 0

ニューロン6

W6・XT + b6 > 0

入力 X=[X1,X2,X3,X4,X5,X6]

重み W1=[W11,W12,W13,W14,W15,W16]バイアス b1

重み W2=[W21,W22,W23,W24,W25,W26]バイアス b2

重み W3=[W31,W32,W33,W34,W35,W36]バイアス b3

重み W4=[W41,W42,W43,W44,W45,W46]バイアス b4

重み W5=[W51,W52,W53,W54,W55,W56]バイアス b5

重み W6=[W61,W62,W63,W64,W65,W66]バイアス b6

X1

X2

X3

X4

X5

X6

ニューロン1

W1・XT + b1 > 0

ニューロン2

W2・XT + b2 > 0

ニューロン3

W3・XT + b3 > 0

ニューロン4

W4・XT + b4 > 0

ニューロン5

W5・XT + b5 > 0

ニューロン6

W6・XT + b6 > 0

入力 X=[X1,X2,X3,X4,X5,X6]

値:W11X1+W12X2+W13X3+W14X4+W15X5+W16X6+b1

値:W21X1+W22X2+W23X3+W24X4+W25X5+W26X6+b2

値:W31X1+W32X2+W33X3+W34X4+W35X5+W36X6+b3

値:W41X1+W42X2+W43X3+W44X4+W45X5+W46X6+b4

値:W51X1+W52X2+W53X3+W54X4+W55X5+W56X6+b5

値:W61X1+W62X2+W63X3+W64X4+W65X5+W66X6+b6

W11, W12, W13, W14, W15, W16 X1 b1

W21, W22, W23, W24, W25, W26 X2 b2

W31, W32, W33, W34, W35, W36 X3 + b3 =W41, W42, W43, W44, W45, W46 X4 b4

W51, W52, W53, W54, W55, W56 X5 b5

W61, W62, W63, W64, W65, W66 X6 b6

W11X1+W12X2+W13X3+W14X4+W15X5+W16X6+b1

W21X1+W22X2+W23X3+W24X4+W25X5+W26X6+b2

W31X1+W32X2+W33X3+W34X4+W35X5+W36X6+b3

W41X1+W42X2+W43X3+W44X4+W45X5+W46X6+b4

W51X1+W52X2+W53X3+W54X4+W55X5+W56X6+b5

W61X1+W62X2+W63X3+W64X4+W65X5+W66X6+b6

行列による表現(六個のニューロンの場合)

これも、 W・XT + b の形をしている!

式は便利だ!Y = W・XT + b が表すもの

数学的な表記を使うと、問題を簡潔に定式化できる。

ここでは、一つのニューロンの状態だけでなく、複数のニューロンからなる層も、一つの式で表現できる背景について述べる。

この節は、読み飛ばしてもらって結構です。

式は便利だ!

Y = W・XT + b が表すもの

ニューラル・ネットワークの本を読んで、最初につまずくのは、行列が出てくるあたりだと思う。ただ、ニューラル・ネットワークの理解で、当面、必要なことは、式 Y = W・XT + b が表現しているものを理解することだ。見慣れていないだけで、難しい数学ではない。

具体的な例で、式 Y = W・XT + b が表しているものを、紹介したいと思う。一見、複雑に見える沢山の関係が、この式一つで表現されていることがわかるはずだ。式は便利だということがわかってもらえると思う。

以下の例では、XもYもbも、最初から列ベクトルだとしよう(このことを、仮に、X=[X1,X2,...Xn]

Tのように表そう)。この時、 Y = W・X + b が、何を表すかを考えよう。

Y = W・X + b が表すもの

Wが数値(スカラー)の時

Y=y, X=x, W=a, b=b なら、この式は、y = ax + b という、式を表す。

Y=y, X=x, W=2, b=3 なら、この式は、y = 2x + 3 という、式を表す。

Y=y, X=x, W=4, b=0 なら、この式は、y = 4x という、式を表す。

Y = W・X + b が表すもの

Wがベクトルの時

Y=y, X=[x1,x2]T W=[w1,w2] b=b0 なら、この式は、

y = w1・x1+w2・x2+b0 という、式を表す。

Y=y, X=[c,d]T W=[m,n] b=b なら、この式は、y = m・c+n・d+b という、式を表す。

Y=y, X=[1,0]T W=[2,3] b=4 なら、この式は、y = 2・1+3・0+4 = 6 という、式を表す。

Y=y, X=[x1,x2,x3]T W=[w1,w2,w3] b=b0 なら、

y = w1・x1+w2・x2+w3・x3+b0

Y=y, X=[x1,x2,x3,x4]T W=[w1,w2,w3,w4] b=b0 な

ら、y = w1・x1+w2・x2+w3・x3+w4・x4+b0

Y = W・X + b が表すもの

Wが行列の時

2x2の行列(2行2列の行列)を、[ [a,b], [c,d] ]と表そう。同様に、3x3 (3行3列の行列)の行列を、[ [d,e,f], [g,h,i], [j,k.l] ] と表そう。 ....

Y=[y1,y2]T, X=[x1,x2]

T、W= [ [2,3], [4,5] ]、b=[1,2]Tのとき、 Y = W・X + b は、次の二つの式を表す。y1 = 2x1+3x2+1、 y2 = 3x1+5x2+2

Y=[y1,y2,y3]T, X=[x1,x2,x3]

T、W= [ [2,3,-1], [4,-5,1], [1,2,3] ]、 b=[1,2,3]Tのとき、 Y = W・X + b は、次の三つの式を表す。y1 = 2x1+3x2-x3+1、 y2 = 4x1+5x2+x3+2、y3 = x1+2x2+3x3+3

Y = W・X + b が表すもの

Wが行列の時

例えば、Wが6x6(6行6列)の行列の時、 Y = W・X + bが表すものの例については、先に見た。もちろんnが100でも10,000でも同じ式で、表現できる。

Wが n行 m列の行列の時、 Y = W・X + bが、n個の式を表していることを示すために、次のように書くこともある。Yn = Wn・X + bn

こうした表記は、数百・数千のノードからなるニューラル・ネットワークが満たす多数の関係式を、一つの式で簡潔にまとめることができるので、プログラミング上も極めて有用である。

Y=W・XT+b と Y=X・W+b という二つの表記

これまで、入力の X=[X1,X2,...,Xn] を行ベクトルとして、Y=W・XT+b という表記を用いてきた。多くのドキュメントもこうした表記を採用している。

X=[X1,X2,...,Xn]T として、 Y=W・X+bと表しても、この

二つの表記は、同じ内容を表し、重みを表す行列Wも、同じものである。 どちらでも XT, b は列ベクトルである。

ただ、 X=[X1,X2,...,Xn] を行ベクトルとした時、Y=X・W+b という表記も可能である。ここでのWは、先のWの行と列を入れ替えたものである。W=WT。bは、行ベクトルとなる。b=bTである。基本的には同じである。

ただ、TensorFlowでは、 Y=X・W+b の方の表記を採用している。TensorFlowに関連する部分に入ったら、この表記に切り替えたいと思う。

ニューラル・ネットワークとその表現(2)

ニューロンを動かす -- 活性化関数 (Activator)

クラス分けのActivator -- SoftMax

ニューロンを動かす-- 活性化関数 (Activator)

活性化関数は、その名前の通りに、一つのニューロンが発火(活性化)する時の条件と出力を関数の形で表したものである。いろいろな種類の活性化関数がある。

活性化関数

先に見たようにように、重みWとバイアスbを用いて、W・X + b という式で、ニューロンの興奮のレベルが計算できるとするなら、 「W・X + b > 0 なら、ニューロンは発火する」という条件は、どのように表現できるだろうか?

W・X + b は、ニューロンの内部の状態を表す量なので、その値を、ニューロンの出力に変える関数 φ をうまく定義して、φ (W・X + b ) がそのニューロンの発火・出力を表現するようにすればいい。こうした関数 φ を、「活性化関数」とよぶ。

例えば、ニューロンの発火の信号の強さが 1で、発火しない時は信号が 0 であるなら、次のような関数 φ を考えればいい。 0 x<=0 の時

1 x> 0 の時φ (x) =

sigmoid 関数 (logistic 関数)

先の φ を、右のグラフでは、赤線で示した。x=0の時に、非連続に変化する。

実際の応用では、こうした飛躍のない、青線のような関数が持ちいられることが多い。

これをsigmoid関数という。(logistic関数)

近似的には、x<0の時 0x>0の時 1 基本的には0と1の間の値をとる。

ReLU (rectified linear unit)

rectifier は、「整流器」。ReLUは、マイナスの値は通さず 0を返すが、プラスの値は、そのまま通す。(青線)

sigmoidは、0と1の間の値を出力するが、ReLUの出力には、そうした制限はない。

断続はないが、x=0のところで折れ曲がっている。それを、スムースに近似した関数も存在する。(Softplus 緑線)

x<0の時 0 x>0の時 x の値をとる。

tanh 関数

sigmoidの仲間だが、ちょうどそれを1/2ほど、下に移動した形である。-1と+1との間の値を出力する。tanh以外にも、同じ性質を持つ、様々な関数が提案されている。

(

W・X + b =(-2)x1+3x0+(-1)x1+3x0+2x1+(-2)x1 -1 =

-2-2+2-2-1= -5

φ(W・X + b ) =sigmoid(-5) ≒ 0

重み W=[-2,3,-1,3,2,-2]、バイアス b=-1入力 X = [1,0,1,0,1,1]T

φ(x) = sigmoid(x) の場合X1=1

X2=0

X3=1

X4=0

X5=1

X6=1

-2

3

-1

32

-2

0

一つのニューロンの出力は、φ( W・X + b )

の形で表せる。

W・X + b =(-2)x1+3x1+(-1)x0+3x1+2x0+(-2)x1 -1 =

-2+3+3-2= 2

φ(W・X + b ) =ReLU(2) =2

X1=1

X2=1

X3=0

X4=1

X5=0

X6=1

-2

3

-1

32

-2

重み W= [-2,3,-1,3,2,-2]、バイアス b=-1入力 X = [1,1,0,1,0,1]T

φ(x) = ReLU(x)の場合

2

一つのニューロンの出力は、φ( W・X + b )

の形で表せる。

X1

X2

X3

ニューロン1φ(W1・X + b1)

ニューロン2φ(W2・X + b2)

ニューロン3φ(W3・X + b3)

入力 X=[X1,X2,X3] T 出力 Yi = φ(Wi・X + bi)

重み W1=[W11,W12,W13]バイアス b1

重み W2=[W21,W22,W23]バイアス b2

重み W3=[W31,W32,W33]バイアス b3

W11,W12,W13 X1 b1

W21,W22,W23 X2 + b2

W31,W32,W33 X3 b3

φ

φ(W11X1+W12X2+W13X3+b1)

φ(W21X1+W22X2+W23X3+b2 =

φ(W31X1+W32X2+W33X3+b3)

複数のニューロンの出力も、 φ( W・X + b ) の形で表せる。

一つのニューロンの出力も、複数のニューロンの出力も、

φ( W・X + b ) の形で表せる。

この式は、ニューラルネットワークで、もっとも重要な式の一つである。

クラス分けのActivatorSoftMax

画像認識等のクラス分けの出力には、Softmaxという活性化関数がよく利用される

クラス分けの場合の出力に利用されるactivator。手書き数字画像の認識だと、提示された画像が0から9までの10個の数字のどれかだと判断しなければいけない。

ニューラル・ネットワークでは、こうした場合、出力層に、 0から9までの10個の数字に対応した10個のノードが並び、それぞれのノードの値が、「提示された画像がその数字である確率」であるようにする。

ノードごとに、確率を計算するのが softmax関数である。最終的には、10個のノードの中で、その確率が最大であるものが選ばれる。

softmax 関数

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 1 0 0 0 0 0 0

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 0 0 1 0 0 0 0

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 0 0 1 0 0 0 0

softmax 関数の性質

softmax関数は、それが適用される層のノードのsoftmac関数の値をすべて足し合わせると1になるという性質を持つ。それは、softmaxの出力が「確率」であることを考えれば、すぐわかる。

例えば、先の例で、ある画像が3である確率が 0.75であったとしよう。そのことは、その画像が3以外の数字である確率は、1 - 0.75 = 0.25 だということである。3以外のノードの確率(softmaxの出力の値)を全部足しても、0.25にしかならないということである。

次のこともわかる。あるノードのsoftmaxの値が上がれば、他のノードの値は下がる。あるノードの値を下げれば、他のノードの値は上がる。全部足して1になるように、値は変化する。

One-Hot-Vector

先のsoftmax関数の出力例の、一番上のノードは、「この画像は数字nである」という、ニューラル・ネットワークの判断を表しているの。もちろん、softmaxの値が一番大きいところが選ばれて、そこに一つだけに1が入っていて、残りはすべて0になっている。

こうした一つだけに1が、残りすべてが0のベクトルを、One-Hot-Vector と呼ぶ。

One-Hot-Vectorは、クタス分けの出力に現れるだけではない。ニューラル・ネットワークを「学習」させるための訓練用データは、画像と一緒に「この画像は数字nである」という「正解」の情報を持っていなければならない。訓練用データは、画像と正解を示すOne-Hot-Vectorの二種類のデータから構成されている。

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明ニューラル・ネットワークをグラフで表現する

複数のニューロンからなる一つの層を、グラフで表す

ここから、TensorFlowを使った、ニューラル・ネットワークの実装のスタイルを紹介する。

「グラフ」「演算ノード」「テンソル」というのが、基本的なコンセプトとなる。

複数のニューロンからなる一つの層の出力の計算、φ( W・X + b ) を、次のような図形で表わすことにしよう。

行列の積X

W

行列の和

b

φの適用

先の例で言うと、Xは、[X1,X2,X3]

T の列ベクトルで、Wは 3x3の行列、bは、[b1,b2,b3]

T の列ベクトルである。

複数のニューロンからなる一つの層の出力の計算、φ( X・W + b ) を、次のような図形で表わすことにしよう。

行列の積X

W

行列の和

b

φの適用

先の例で言うと、Xは、[X1,X2,X3] の行ベクトルで、Wは 3x3の行列、bは、[b1,b2,b3] の行ベクトルである。

TensorFlowのスタイルに準じて、表記を切り替えていることに注意!φ( X・W + b )

TensorFlowでは、こうした図形を「グラフ」と呼んでいる。グラフは、「ノード」とノード同士を結ぶ「辺」からできている。

行列の積X

W

行列の和

b

φの適用

TensorFlowのグラフのノードは、基本的には、演算を行う「演算ノード」である。様々な演算が用意されている。演算を行わない「変数ノード」「プレースゴルダー・ノード」も存在する。

変数ノード 変数ノード

プレースホルダー 演算ノード 演算ノード 演算ノード

TensorFlowのグラフが有用なのは、一つの同じグラフで、様々な複雑なニューラル・ネットワークを表現できるからである。(もちろん、X,W,bのタイプはことなるのだが)

行列の積X

W

行列の和

b

φの適用

もっとも、そのことは、基本的には、このグラフの場合には、すでに見た φ( X・W + b ) という数学的な抽象化に負っている。ただ、グラフの方が具体的に処理をイメージしやすい。

TensorFlowのスタイルに準じて、表記を切り替えていることに注意!φ( X・W + b )

いくつかの例で考えてみよう。4つの入力を受け取り、3つの出力を返す、3つのニューロンからなる「層」を考えてみよう。これも、このグラフで表現できる。

行列の積X

W

行列の和

b

φの適用

[X1,X2,X3 ,X4]

4行3列の行列 [b1,b2,b3]

ある「層」の出力の数は、その層に含まれるニューロンの数に等しいのは、当然である。

2つの入力を受け取り、5つの出力を返す、5つのニューロンからなる「層」を考えてみよう。これも、このグラフで表現できる。

行列の積X

W

行列の和

b

φの適用

[X1,X2]

2行5列の行列 [b1,b2,b3,b4,b5]

一般に、n個の入力を受け取り、m個の出力を返すニューロンの「層」では、Xはn次元の行ベクトル、Wはn行m列の行列、bはm次元の行ベクトルである。

複数の層からなるニューラル・ネットワークを、グラフで表す

もちろん、通常の表現でも、ニューラル・ネットワークはグラフとして表現される。ただ、TensorFlowのグラフは、それをさらに単純化する。

そうした単純化されたグラフ表現は、TensorFlowの大きな能力である。そのことと、グラフを流れる「テンソル」というデータの捉え方とは、結びついている。

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

Full Connectなニューラル・ネットワークの旧来のグラフでの表現

Full Connectというのは、向かい合ったノードがすべて接続されているということ

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

入力層・隠れ層・出力層旧来のグラフでの表現

入力層 隠れ層 出力層

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

X層 H層 M層 Y層

H層の重み WH

バイアス bH

活性化 φH

M層の重み WM

バイアス bM

活性化 φM

Y層の重み WY

バイアス bY

活性化 φY

旧来のグラフ

一つの「層」のグラフでの表現

行列の積X

W

行列の和

b

φの適用

W

b

φ

X1

X2

X3

X4

H1

H2

H3

M1

M2

M3

M4

Y1

Y2

X層 H層 M層 Y層

H層の重み WH

バイアス bH

活性化 φH

M層の重み WM

バイアス bM

活性化 φM

Y層の重み WY

バイアス bY

活性化 φY

旧来のグラフ

積X

W

b

φ 積

W和

bφ 積

W和

H層のニューロン数:3重み W:4x3次元バイアス b:3次元

M層のニューロン数:4重み W:3x4次元バイアス b:4次元

Y層のニューロン数:2重み W:4x2次元バイアス b:2次元

X層 H層 M層 Y層

こっちのグラフの方が、ずっとわかりやすい!

X層の入力:44次元

TensorFlowのグラフ

ニューラル・ネットワークの例

これでも省略されている784->8

旧来のグラフ

積X

W

b

φ 積

W

b

φ

隠れ層のニューロン数:15重み WH:784x15次元バイアス bH:15次元

出力層のニューロン数:10重み WO:15x10次元バイアス bO:10次元

入力層 隠れ層 出力層

こっちのグラフの方が、ずっとわかりやすい!

隠れ層の入力:784784次元

TensorFlowのグラフ

Sigmoid SoftMax

グラフの例(学習用)

https://www.tensorflow.org/

Logit Layer, ReLu Layerを見れば、先に見た「層」のパターンが現れているのがわかる。

演算ノードの、MatMulは行列の積、BiassAddはバイアスの加算である。

Logit LayerのActivatorは、Softmaxで、ReLu LayerのActivatorは、ReLuである。

(このグラフ、GitHubで提供されているコードのグラフとは、少し、違っている。)

グラフの例(学習済み)

ニューラル・ネットワークでは、学習の過程と、学習済みの結果を利用する過程では、計算量には、大きな差がある。

学習に持ちいたグラフの一部を再利用して、学習済みのデータ(基本的には、学習された各レーヤーの重みとバイアスである)を利用すれば、スマホでも機械学習の成果を利用できる。TensorFlowは、それを可能にする

少し複雑なグラフの例(これは、LSTMのセル)σ(sigmoidのこと), tanh は、活性化関数

次の式をグラフで追ってみるといい。

Chris Olah "Understanding LSTM Networks"http://colah.github.io/posts/2015-08-Understanding-LSTMs/

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明ニューラル・ネットワークのグラフ表現とモジュール構造

ニューラル・ネットワークのグラフ表現とモジュール構造

それぞれのフレームワークごとに表現のスタイルには違いがあるものの、重要なことは、それが表現しているニューラル・ネットワークの「グラフ」は、同一のものであるということである。それは、基本的なモジュールの組み合わせでできている。

フルコネクトDNNのグラフ表現とモジュール構造

まずは、基本的な フルコネクトDNN (Deep Neural Network)のグラフ表現とモジュール構造を見ていこう

ニューラル・ネットワークの例

これでも省略されている784->8

DNNのグラフ

TensorFlowでは、複数のニューロンからなる一つの層は、次のようなグラフで表現される。

行列の積X

W

行列の和

b

φの適用

5つのノードがあるが、Wとbには、重みとバイアスの値が入り、残りの3つのノードは、演算を行うノードである。この層の働きは、φ(X・W+b) で表現される。

一つの層

積X

W

b

φ 積

W

b

φ

隠れ層のニューロン数:15重み WH:784x15次元バイアス bH:15次元

出力層のニューロン数:10重み WO:15x10次元バイアス bO:10次元

入力層 隠れ層 出力層

こっちのグラフの方が、ずっとわかりやすい!

隠れ層の入力:784784次元

TensorFlowのグラフ

TensorFlowCNTK

これらのグラフは、同じものである

TensorFlowCNTK

これらのグラフは、同じものである

TensorFlow

Torch7

これらのグラフは、ほぼ、同じものである

Torch7でのDNNモジュールの記述例

DNN

# Hidden 1with tf.name_scope('hidden1'):

weights = tf.Variable(tf.truncated_normal([IMAGE_PIXELS, hidden1_units],

stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),name='weights')

biases = tf.Variable(tf.zeros([hidden1_units]),name='biases')

hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)# Hidden 2with tf.name_scope('hidden2'):

weights = tf.Variable(tf.truncated_normal([hidden1_units, hidden2_units],

stddev=1.0 / math.sqrt(float(hidden1_units))),name='weights')

biases = tf.Variable( tf.zeros([hidden2_units]),name='biases')

hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)# Linear

....

....

TensorFlowでのDNNモジュールの記述例

DNNモジュールが、φ(X・W+b)の形をしていることは、簡単に確認できる。

DNN = [hiddenDim = 200

# DNNSigmoidLayer and DNNLayer are defined in Macros.ndlh1 = DNNSigmoidLayer(featDim, hiddenDim, featScaled, 1)ol = DNNLayer(hiddenDim, labelDim, h1, 1)

ce = CrossEntropyWithSoftmax(labels, ol)err = ErrorPrediction(labels, ol)

# Special NodesFeatureNodes = (features)LabelNodes = (labels)CriterionNodes = (ce)EvalNodes = (err)OutputNodes = (ol)

]

CNTKでのDNNモジュールの記述例

DNNSigmoidLayer, DNNLayerの定義は、Macro.ndlの中にある。

DNNLayer(inDim, outDim, x, parmScale) = [W = LearnableParameter(outDim, inDim,

init="uniform", initValueScale=parmScale)b = LearnableParameter(outDim, 1,

init="uniform",initValueScale=parmScale)t = Times(W, x)z = Plus(t, b)

]

DNNSigmoidLayer(inDim, outDim, x, parmScale) = [W = LearnableParameter(outDim, inDim,

init="uniform", initValueScale=parmScale)b = LearnableParameter(outDim, 1,

init="uniform",initValueScale=parmScale)t = Times(W, x)z = Plus(t, b)y = Sigmoid(z)

]

CNTKマクロでのDNNモジュールの記述例

DNNモジュールが、φ(X・W+b)の形をしていることは、簡単に確認できる。

例1A -> (A->B) ->B の証明

Coq < Lemma S1 : forall A B :Prop, A ->(A->B) ->B.1 subgoal

============================forall A B : Prop, A -> (A -> B) -> B

S1 < intros.1 subgoal

A : PropB : PropH : AH0 : A -> B============================B

Goalから、forallを消す。→の前提部分を仮説に移す。introsは、複数のintroを同時に適用する。

Γ1 新しい仮定

新しいゴール

機械証明グラフを流れる量 -- テンソル

グラフを流れる量 -- テンソル

旧来のグラフの沢山の線は、どこへ行ったのか?

TensorFlowのグラフでは、グラフを流れるデータは、すべて「テンソル」にまとめられている。

4つの入力を受け取り、3つの出力を返す、3つのニューロンからなる「層」を考えてみよう。

行列の積X

W

行列の和

b

φの適用

[X1,X2,X3 ,X4]

4行3列の行列 [b1,b2,b3]

ただ、ここでは、ノードではなく辺の方に注目してみよう。どのようなタイプのデータが、辺の上を流れるかを考えよう。

4つの入力を受け取り、3つの出力を返す、3つのニューロンの「層」

行列の積X

W

行列の和

b

φの適用

[X1,X2,X3 ,X4]

4行3列の行列 [b1,b2,b3]

TensorFlowでは、こうしたデータをすべてテンソルと呼んでいる。どのような、タイプのデータか見てみよう。

4つの入力を受け取り、3つの出力を返す、3つのニューロンの「層」

行列の積X

W

行列の和

b

φの適用

[X1,X2,X3 ,X4]

4行3列の行列 [b1,b2,b3]

テンソルには、いろいろなタイプがある。

3次元の 3次元の 3次元の行ベクトル 行ベクトル 行ベクトル

2つの入力を受け取り、5つの出力を返す、5つのニューロンの「層」

行列の積X

W

行列の和

b

φの適用

[X1,X2]

2行5列の行列 [b1,b2,b3,b4,b5]

テンソルには、いろいろなタイプがある。

5次元の 5次元の 5次元の行ベクトル 行ベクトル 行ベクトル

TensorFlowとテンソル

TensorFlowのプログラムは、すべてのデータを表現するものとしてテンソル・データ構造を利用する。

TensorFlowのテンソルは、n次元の配列あるいはリストだと考えることができる。

テンソルは、静的な型と動的な次元を持っている。

計算グラフのノード間を移動するのは、テンソルだけである。

テンソルのランク(階数)

TensorFlowのシステムでは、テンソルは「ランク」と呼ばれる次元の単位で記述される。

テンソルのランクは、行列のランクとは異なるものである。

テンソルのランクは、(時には、位数(order)とか度数(degree)とかn次元とも呼ばれることがあるのだが)、テンソルの次元の数である。

例えば、Pythonのリストで定義された次のテンソルのランクは 2である。

t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

テンソルのランク(階数)

ランク2のテンソルで、われわれが典型的に考えるのは「行列」である。

ランク1のテンソルは、「ベクトル」である。

ランク2のテンソルに対しては、t[i,j] という構文で、任意の要素にアクセスできる。

ランク3のテンソルには、t[i,j,k]でアクセスする必要がある。

ランク 数学的実体 Pythonでの表記

0 スカラー(大きさのみ) s = 483

1 ベクトル(大きさと向き) v = [1.1, 2.2, 3.3]

2 行列 (数字のテーブル) m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

3 3-テンソルt = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]]

n n-Tensor ....

テンソルのランク(階数)

テンソルの形

TensorFlowのドキュメントでは、テンソルの次元を記述するのに、ランク、形、次元数の三つを用いる。

Rank Shape

Dimension number

Example

0 [] 0-D A 0-D tensor. A scalar.

1 [D0] 1-D A 1-D tensor with shape [5].

2 [D0, D1] 2-D A 2-D tensor with shape [3, 4].

3 [D0, D1, D2] 3-D A 3-D tensor with shape [1, 4, 3].

n [D0, D1, ... Dn] n-D A tensor with shape [D0, D1, ... Dn].

9/27 マルレク

「パーソナル・アシスタント・システムとAI」

Part II

ニューラルネットワークはどう「学習」するのか?

ディープラーニング入門集中講義

ニューラル・ネットワークの「学習」と技術の特徴

データ依存:大量のデータの「学習」で、必要な能力をマシンに伝える。データを与えるのは、当面は、人間の仕事。

非言語的コントロール:プログラム言語によらず、マシンをコントロールする。

確率論的:ふるまいは、非決定論的で確率論的である。

学習・実行の非対称性:「学習」には、大規模・高機能なシステム(GPU・クラウド等)が必要だが、学習された能力は、小規模なモバイルでも、「実行」できる。

ハードウェア依存:学習・実行環境は、ともに、ハードウェアの進化に強く依存する。OSの進化にも大きな影響が及ぶだろう。

Faceno Face

これが、一千万個の画像データから、16,000コアのマシンが三日間かけて抽出した「人間の顔」のイメージらしい。子供の絵に似ているのが面白い。

大量のデータ

Team MIT: Atlas Robot Push Recovery

https://www.youtube.com/watch?t=193&v=2mhIYetkNIg

非言語的

確率論的

https://goo.gl/b5Pe5j

MS ResearchのDeep Learning “Project Adam”1,400万枚の画像を学習して、22,000のカテゴリーに分類できる。イヌとネコを区別できるだけでなく、イヌの犬種も正しく判別する。

http://goo.gl/2EMIkJ

非対称的

NVIDIA M40

FPGA Stratix V 新しいハードウェア

ニューラル・ネットワークの「学習」と技術の特徴

データ依存:大量のデータの「学習」で、必要な能力をマシンに伝える。データを与えるのは、当面は、人間の仕事。

非言語的コントロール:プログラム言語によらず、マシンをコントロールする。

確率論的:ふるまいは、非決定論的で確率論的である。

学習・実行の非対称性:「学習」には、大規模・高機能なシステム(GPU・クラウド等)が必要だが、学習された能力は、小規模なモバイルでも、「実行」できる。

ハードウェア依存:学習・実行環境は、ともに、ハードウェアの進化に強く依存する。OSの進化にも大きな影響が及ぶだろう。

ニューラル・ネットワークは、どのようなデータで学習するのか?

機械学習の基本は、人間の知識を機械に移転すること

機械学習の基本を確認しよう。ただ、人間の知識を機械に移転するためには、単にマシンと大量のデータがあればいいというわけではない。正確にラベル付けられたデータの「作成」と「蓄積」が不可欠。それには、人間の根気強い、組織的な取り組みが必要。

「人間には容易でも機械には難しいこと」「機械には容易でも人間には難しいこと」

その境界は、動的に変化するのだが、いつの時点でも、機械に提供する学習データ作りは、前者。その段階を経なければ、機械は賢くならない。現実的には、それぞれに要する経済的なコストが、現実を動かす。その費用を、誰がどう負担するのか? 以下で、基本的な学習用データセットを見てみよう。

http://yann.lecun.com/exdb/mnist/

MNIST 手書き数字のデータベース

60,000サンプル

CIFAR-10 10のカテゴリーの画像データ

一つのカテゴリーに6,000枚。計60,000サンプル

https://www.cs.toronto.edu/~kriz/cifar.html

Tront大学

ImageNet

http://www.image-net.org

WordNetの名詞(80,000+)に対応した画像データベース

Stanford大学

http://image-net.org/synset?wnid=n02084071

https://wordnet.princeton.edu/

類義語

imagenet_fall11_urls.tgz http://goo.gl/BldrSR

WordNet ID n02084071 Dog, domestic dog, Canis familiaris

画像のURL

The Penn Treebank Project

https://www.cis.upenn.edu/~treebank/

Pennsylvania大学

https://www.ldc.upenn.edu/

The Penn Treebank Project

MS COCO Data set

http://mscoco.org/

http://arxiv.org/pdf/1405.0312v3.pdf

MS COCO Data setMicrosoft COCO: Common Objects in Context

MS COCO Data set

instanceの切り出し

keypoint

画像へのCaption 5つ

http://goo.gl/qIadT1

基本的な性格をもつオープンなデータの共有が、機械学習のイノベーションをドライブしている

先の「データ作成のコスト」の問題に対する最も有力な回答は、オープンなコミュニティ(大学・学会を含む)が、基本的な性格をもつ学習用データを公開し、それを皆が共有すること。

(日本は、どうだろう? 少なくとも日本語は、日本がやるしかない。)

Human Computing

「人間には容易でも機械には難しいこと」

Captcha

画像のラベル付け (with Google)

Duolingo

ゲミフィケーションとクラウド・ソーシング

人間の自由時間の利用

2003 年に、ソリティアを遊んだ、人間の総時間は、90億時間。

ある 人たちは、コンピュータの無駄な計算サイクルについて話をしているが、人間の無駄なサイクルについては、どうなんだろう?

エンパイア・ステートビルを 作るために、人間が使った時間は、700万時間。

パナマ 運河を作るために、人間が使った時間は、2000万時間。(ソリティアの一日分以下)

Carnegy Melon Univ. Luis von Ahn

Most human can pass, but current computer can not pass.

http://elie.im/blog/security/five-surprising-captcha-schemes/#.UjUKt7zqH9I

http://www.youtube.com/watch?v=tx082gDwGcM

Human Computing / Crowd Sourcing2012年 Google TechTalk

学習用データの作成ツールとクラウド・ソーシング

MS COCO Data Set

Scene Graph

MS COCO Data Set作成の作業用アイコン

80 object categories

http://mscoco.org/explore/

オブジェクト

オブジェクト間の位置関係。状態。

オブェクトの属性

画像と、それから作られるscene graphの例

画像と、それから作られるscene graphの例

我々が、それぞれのドメインで持つ知識を、きちんとデータ化すること

それを機械に学習させる。量優先で質的規定が曖昧なBig Dataではなく、優れた質をもった、それぞれのドメインに固有のGood Data

を持つことが、より重要。ニッチでもいい。チャンスは、AIの応用領域の数ほど、たくさん存在している。もちろん、その前提は、基本的なオープンなデータの存在と共有なのだが。

ニューラルネットワークはどう「学習」するのか?

ニューラル・ネットワークの学習 =「パラメーターを最適なものに修正すること」

ニューラル・ネットワークの学習というのは、大量の訓練用データを読み込んで、その出力が予想されるものに近い値を返すように、ネットワークのパラメーターの値を修正することである。

パラメーター修正の基本的な道具たち

ニューラル・ネットワークでのパラメーター修正を行うのに必要な道具立てを、あらかじめ、簡単に紹介しよう。その詳細については、その後に述べることにする。

Backpropagation

Loss Function

Gradient Descent

出力結果を見て、パラメーターを修正する

Backpropagation

ニューラルネットワークには 、膨大な数のパラメーターが存在する。望ましい結果を得るために、手動の試行錯誤で、パラメーターの修正を行っていては、ラチがあかない。

Rumelhart らが開発した(1986年) Backpropagation

は、こうしたパラメーターの修正を、システマチックに行う方法を提供する。

出力結果 が、予期していたものと異なっていたら、まず、その出力を行った一つ前の層にさかのぼって、パラメーター(重みWとバイアスb)を修正すればいい。

ニューラルネットワークが 、多段の層からなるならば、出力層の一つ前の層から始めて、順次、層をさかのぼってパラメーターの変更を行う。

出力結果と「正解」とのずれLoss Function (損失関数)

その為に、出力結果と予期していた「正解」とのズレを、何らかの方法で定式化する必要がある。そのズレを関数の形で表したものを Loss Function (損失関数)という。Cost Function (コスト関数)ということもある。

出力が「正解」と一致した時、 Loss Functionの値が最小値を取るようにする。この時、パラメーター修正の目的を、Loss Functionの値をできるだけ小さくすることだと言い換えることができる。

ある問題に対して、Loss Functionは一つとは限らない。どのようなLoss Functionを選ぶかで、パラメーター修正の効率は変化する。

Gradient Descent (勾配降下法)

パラメーター修正で、最もよく使われる方法が、このGradient Descent (勾配降下法)である。

Loss Functionを Jだとしよう。パラメーターのWとbの値が、それぞれ少し変化した時に、Jの値がどう変化するかを調べる。このJの変化が「勾配」である。「勾配」にそって、Jの値が下がるように、Wとbを変化させればいい。それが、Gradient Descent である。

数学的には、∂J/∂W と ∂J/∂b をチェックすることになる。Jは、ニューラル・ネットワークの出力と「正解」とのズレなので、φ(WX+b)という形の項を含んでいる。アクティベーターφとして、微分可能なものが好まれるのは、このGradient Descentに関係している。

一つのニューロンで数値予測する(線形回帰)

ここでは、ただ一つのニューロンでも、それが線形回帰の数値予測の能力を持つことを述べる。

単純なニューロンの集まりでも、パラメーター最適化のメカニズムと組み合わせれば、強力な機能を持ちうる。

ここでは、もっとも単純な一つのニューロンのパラメーター最適化が、線形回帰の数値予測の能力を持ちうることを示す。

一つのニューロンのパラメーターを動かす

ニューロン 一つの働きは、先に見たようにφ(W・X+b) と表現できる。φは活性化関数、W, X, b

はベクトルである。ここではさらに単純化して、入力を数字一つにする。この時、Wもただの数字になる。さらに、Activator φも取り除く。

このニューロン 一つの「ニューラル・ネットワーク」は、一つの数字の入力xに対して、内部のパラメーター(単なる実数である) a, b に応じて、ax+bを返すのである。この値をyとしよう。

y= ax+bは、直線を表す式である。この単純なニューラル・ネットワークでパラメーターを様々に変更するというのは、様々な直線を考えることに等しい。

入力が6つの場合シナプスが6つで重みも6つ

入力が1つの場合シナプスが1つで重みも1つ

これが、このニューロンの出力

入力X1=x

重みW1 = a

重みを a, バイアスを b とすると、ax+b が、このニューロンの出力になる

一つの入力と出力を持ち、一つだけのニューロンからなるネットワークは、y=ax+bという直線に対応している。このニューロンのパラメーターを動かすということは、下の図のようにこの直線を、いろいろに動かすということである。

a, b の値を変えれば、y=ax+bの形は変化する(傾きがaで、切片がbの直線である)

この図は、あるデータ(赤点)の分布を直線で近似しようというもの。統計学では「線形回帰」と飛ばれているものだ。(左の直線より、右の直線の方が「いい近似」を与えている。)

それでは、ある直線が、データの分布の「いい近似」であるとは、どういうことをいうのだろう。

データ群に一番「近い」直線?

ここでは、データ群と直線の「近さ」を、幾つかの図で、直感的に表してみよう。

実際的な応用では、一番「いい近似」の、直線が見つかれば、それに基づいて、数値予測が可能になる。もちろん、それはデータが線形に分布していると想定してのことなのだが。

入力X=x1

重みW = a

重みを a, バイアスを b とすると、ax+b が、このニューロンの出力になる

予測値 ax1+b 実際の値 y1

実際のyの値y1

実際のデータの値 x1から、ニューロンの出力で、Yの値を予測することを考える

入力X=x1

重みW = a

重みを a, バイアスを b とすると、ax+b が、このニューロンの出力になる

予測値 ax1+b 実際の値 y1

実際のyの値y1

予測値と実測値の誤差を、すべてのデータに対して最小にするような、a と b の値を求める。

ここでの「すべてのデータに対して」という条件に注意すること。

この枠内だけのデータであれば、この直線でも、線形予測は可能。ただ、全体のデータに対しては、この直線では誤差が大きい。

この枠内だけのデータであれば、この直線でも、線形予測は可能。ただ、全体のデータに対しては、この直線では誤差が大きい。

だんだん、予測可能なデータが増えてくる。最適なものを探す。

損失関数

どのように、データ群に一番「近い」直線を求めるか?その為に、「損失関数」という考え方を導入する。

損失関数(コスト関数ともいう)は、ニューラル・ネットワークで、重要な役割を果たす。ニューラル・ネットワークでの「学習」は、すべて「損失関数を最小のものにせよ」という指示に従ったパラメーター変更に帰着する。

誤差

誤差

誤差誤差

データの各点と、y=ax+b との誤差が、もっとも小さくなるように、a,b の値を修正する。

(x(i), y(i))

(ax(i)+b) – y(i)

( ax(i)+b), y(i) )

損失関数を定めて、誤差を最小にする a,bを求める

サンプル中のi 番目の点を (x(i), y(i))とすれば、y=ax+b上の点と点 (x(i), y(i)) との垂直方向の誤差は、(ax(i)+b) – y(i) となる。

誤差は、正負の値をとるので、単純に、誤差の平均を取っても、打ち消しあって、全体としての誤差の大きさはわからなくなる。

そこで、誤差の二乗をとって、その平均を最小にすることを考える。

a, b の関数である、この誤差の二乗の平均を、損失関数とすればいい。

誤差

誤差

誤差誤差

(x(i), y(i))

(ax(i)+b) – y(i)

( ax(i)+b), y(i) )

誤差の二乗の和を損失関数にする

こうした形の損失関数を、 “quadratic cost” という

係数1/2は計算上の便宜のためのもの

入力X=x1

重みW = a

重みを a, バイアスを b とすると、ax+b が、このニューロンの出力になる

予測値 ax1+b 実際の値 y1

実際のyの値y1

一つのデータについての垂直方向の誤差

(ax1+b) – y1

誤差が打ち消しあうのを避けるために二乗する((ax1+b) – y1)^2

すべてのデータについて、上の値を足し合わせる。

Σ ((axi+b) – yi)^2

損失関数

誤差

誤差

誤差誤差

(x(i), y(i))

(ax(i)+b) – y(i)

( ax(i)+b), y(i) )

あるa,b に対して、すべてのデータについての誤差の二乗の和が、損失関数の値になる

誤差

誤差

誤差誤差

(x(i), y(i))

(ax(i)+b) – y(i)

( ax(i)+b), y(i) )

あるa,b に対して、すべてのデータについての誤差の二乗の和が、損失関数の値になる

誤差

誤差

誤差誤差

あるa,b に対して、すべてのデータについての誤差の二乗の和が、損失関数の値になる

誤差

誤差

誤差誤差

あるa,b に対して、すべてのデータについての誤差の二乗の和が、損失関数の値になる

誤差

誤差

誤差誤差

損失関数が最小になるような直線が、データ群に一番「近い」直線になる。

あるa,b に対して、すべてのデータについての誤差の二乗の和が、損失関数の値になる

損失関数の値の計算

・・・・・全てのデータ

すべてのデータについて、与えられた a, b に基づいて予測値を計算し、実際の値との誤差を求める(赤い矢印)、その後、これらの誤差の二乗の和(あるいは、その平均)を、損失関数の値とする(緑の矢印)。

損失関数

クラス分けの場合の損失関数

出力が数値一つだけだったら、正解の数字との「誤差」を定義するのは容易である。それを損失関数にすればいい。

ただ、出力が、画像認識のようなクラス分けだったら、誤差の定義は簡単ではない。

クロス・エントロピー

クラス分けによく使われるSoftmaxの出力の場合で考えてみよう。例えば、数字の画像認識なら0から9までの数字に対応した10個のノードそれぞれに、その画像がそのノードに対応した数字である確率が入ってくる。こうした場合の損失関数に利用されるのが、クロス・エントロピーである。

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 1 0 0 0 0 0 0

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 0 0 1 0 0 0 0

softmax 関数の出力例

ノード0 ノード1 ノード2 ノード3 ノード4 ノード5 ノード6 ノード7 ノード8 ノード9

0 0 0 0 0 1 0 0 0 0

クロス・エントロピー H(p,q) の定義

ΣΣ p(x)log(q(x))N x

サンプルの数 分類の数

目標の確率 データの確率

マイナス

クロス・エントロピー H(p,q) の定義

ΣΣ p(x)log(q(x))N x

サンプルの数 分類の数

目標の確率 データの確率

マイナス

まず、この部分の計算のサンプルを見ておこう。

p(x) q(x)

P(1)=2/3,p(2)=1/4,p(3)=5/24,p(4)=5/24 q(1)=1/8,q(2)=1/8, q(3)=5/8,q(4)=1/8

x=1の時 2/3log(1/8) = -2/3log8 = -2log2x=2の時 1/4log(1/8) = -1/4log(8) = -3/4log2x=3の時 5/24log(5/8)= 5/24log(5) - 15/24log2x=4の時 5/24log(1/8)= -5/24log(8) = -15/24log2全部足し合わせると

-(48log2+18log2-5log5+15log2+15log2)/24=-(96log2-5log5)/24

H(p,q) = (96log2-5log5)/24

Σ p(x)log(q(x))x

の計算

期待される目標の分布

実際のデータの分布

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=2/3,q(2)=1/4,q(3)=5/24,q(4)=5/24

x=1の時 0log2/3x=2の時 1log1/4x=3の時 0log5/24x=4の時 0log5/24全部足して

log1/4 = -log4 = -2log2H1(p,q) = 2log2

H1

Σ p(x)log(q(x))x

の計算

p(2) = 1 の場合の

「目標」のpの分布は、こういう形になる。

期待される目標の分布

実際のデータの分布

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=1/4,q(2)=2/3,q(3)=5/24,q(4)=5/24

x=1の時 0log1/4x=2の時 1log2/3x=3の時 0log5/24x=4の時 0log5/24全部で

log2/3 = log2 – log3

H2(p,q) = log3-log2

H2

Σ p(x)log(q(x))x

の計算

p(2) = 1 の場合の

「目標」のpの分布は、こういう形になる。

期待される目標の分布

実際のデータの分布

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=5/24,q(2)=2/3,q(3)=1/4,q(4)=5/24

x=1の時 0log5/24x=2の時 1log2/3x=3の時 0log1/4x=4の時 0log5/24全部足し合わせるとlog2/3

H3(p,q) = log3-log2

H3

Σ p(x)log(q(x))x

の計算

p(2) = 1 の場合の

「目標」のpの分布は、こういう形になる。

期待される目標の分布

実際のデータの分布

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=0,q(2)=1,q(3)=0,q(4)=0

x=1の時 0log0 = 0x=2の時 1log1 = 0x=3の時 0log0 = 0x=4の時 0log0 = 0

H5(p,q) = 0

H4

Σ p(x)log(q(x))x

の計算

p(2) = 1 の場合の

「目標」のpの分布は、こういう形になる。

期待される目標の分布

実際のデータの分布

p(x)が one-hot-value の時

ΣΣ p(x)log(q(x))N x

= - { サンプル中の正解値をとった i についての log(q(i))の和 }

H(p,q) =

0 ≦ q(i) ≦ 1 で、 log(q(i)) ≦ 0 だが、q(i) 0 の時 log(q(i)) - ∞q(i) 1 の時 log(q(i)) 0

だから、q(i)が正解に近いほど、H(p,q)は小さくなる。

Σ log(q(i))N

ー=

クロス・エントロピー H(p,q) の定義

ΣΣ p(x)log(q(x))N x

サンプルの数 分類の数

目標の確率 データの確率

マイナス

この部分は、どうなるか?

クロス・エントロピーの値の計算

・・・・・全てのデータ

すべてのサンプル・データ x について、Σ p(x)log(q(x)) を計算し、(赤い矢印)、その後、これらをすべて足し合わせる。(緑の矢印)。

クロス・エントロピー損失関数

p(x)log(q(x)Σ

Σ

バイナリー・クロス・エントロピー

先に見たクロス・エントロピーは、二つの分布pとqが「似ているか?」については、あまり有効な情報を与えない。なぜなら、p(x)=1 以外のxの値でのqの値は、すべて無視するので。

ただ、次のように定義を変更すると、二つの分布の「近さ」を数値化できる。(計算が増えるので、必要ないかもしれないのだが)

この節は、読み飛ばしてもらって結構です。

これは、統計学での二項分類のLogistic回帰にあたる。

二つのデータ群を分離する直線を求める。

H(p, q) = - { p(x)log(q(x)) + (1-p(x))log(1-q(x)) }Σx

P(x),q(x)は、確率を表しているので0 ≦ p(x) ≦ 1、 0 ≦ q(x) ≦ 10 ≦ 1-p(x) ≦ 1、 0 ≦ 1-q(x) ≦ 1

P(x) ≧ 0 で、log(q(x)) ≦ 0 だからp(x)log(q(x)) ≦ 0

(1−p(x)) ≧ 0 で、log(1-q(x)) ≦ 0 だから(1-p(x))log(1-q(x)) ≦ 0

よって、Σの中のp(x)log(q(x)) + (1-p(x))log(1-q(x)) ≦ 0 となる

Σの前に マイナス符号が付いているので、H(p, q) ≧ 0

H(p, q) = - { p(x)log(q(x)) + (1-p(x))log(1-q(x)) }Σx

マイナスが付いている

p(x)が成り立つ確率 p(x)が成り立たない確率

目標とする確率

データの確率

H(p, q) = - { p(x)log(q(x)) + (1-p(x))log(1-q(x)) }Σx

p(x)=0の時は、この項が消える

p(x)=1の時は、この項が消える

H(p) = - p(x)log(p(x))Σx

ShannonのEntoropy

Binary Entoropyの式の特徴

p(x) q(x)

P(1)=2/3,p(2)=1/4,p(3)=5/24,p(4)=5/24 q(1)=1/8,q(2)=1/8, q(3)=5/8,q(4)=1/8

x=1の時 2/3log(1/8)+(1-2/3)log(1-1/8) = 2/3log(1/8)+1/3log(7/8)x=2の時 1/4log(1/8)+(1-1/4)log(1-1/8) = 1/4log(1/8)+3/4log(7/8)x=3の時 5/24log(5/8)+(1-5/24)log(1-5/8) = 5/24log(5/6)+19/24log(3/8)x=4の時 5/24log(1/8)+(1-5/24)log(1-1/8) = 5/24log(1/8)+19/24log(7/8)全部足し合わせると

(-2/3log8+1/3(log7-log8)) + (-1/4log8+3/4(log7-log8)) +(5/24(log5-log6)+19/24(log3-log8) + (-5/24log8+19/24(log7-log8))

= ( -16log8+8log7-8log8-6log8+18log7-18log8 +5log5-5log6+19log3-19log8-5log8+19log7-19log8)/24

= ( -(16+8+6+18+19+5+19)log8+(8+18+19)log7-5log6+19log3)/24H(p,q) = - ( -91log8 + 45log7 – 5(log2+log3) +19log3)/24

= (278log2-45log7+14log3)/24

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=2/3,q(2)=1/4,q(3)=5/24,q(4)=5/24

x=1の時 0log2/3+1log(1-2/3) = log(1/3) = -log3x=2の時 1log1/4+0log(1-1/4) = log(1/4) = -2log2x=3の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24x=4の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24全部足し合わせると

-log3-2log2+log19-log24+log19-log24= -log3-2log2+2log19-2(log3+log8)= -3log3+2log19 – 8log2

H1(p,q) = 3log3+8log2-2log19

H1

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=2/3,q(2)=1/4,q(3)=5/24,q(4)=5/24

H’1

H(p, q) = - { p(x)log(q(x)) + (1-p(x))log(1-q(x)) }Σx

p(x)が、One Hot Valueの分布の場合でも、q(x)の分布の情報を拾っている。

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=1/4,q(2)=2/3,q(3)=5/24,q(4)=5/24

x=1の時 0log1/4+1log(1-1/4) = log(3/4) = log3 – log4x=2の時 1log2/3+0log(1-2/3) = log2/3 = log2 –log3x=3の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24x=4の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24全部足し合わせると

log3–log4+log2-log3+log19-log24+log19-log24= log4+2log19-2(log3+log8)= -log3-8log4+2log19

H2(p,q) = log3+8log2-2log19

H1-H2 = (3log3+8log2-2log19) –(log3+8log2-2log19)= 2log3 > 0

H2

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=5/24,q(2)=2/3,q(3)=1/4,q(4)=5/24

x=1の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24x=2の時 1log2/3+0log(1-2/3) = log(2/3) = log2 – log3x=3の時 0log1/4+1log(1-1/4) = log(3/4) = log3 – log4x=4の時 0log5/24+1log(1-5/24) = log(19/24) = log19 –log24全部足し合わせると先のH2と同じになる

H3(p,q) = H2(p,q) =log3+8log2-2log19

H3

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=0,q(2)=3/4,q(3)=1/8,q(4)=1/8

x=1の時 0log0+1log(1- 0) = 0x=2の時 1log3/4+0log(1-3/4) = log(3/4) = log3 – log4x=3の時 0log1/8+1log(1-1/8) = log(7/8) = log7 –log8x=4の時 0log1/8+1log(1-1/8) = log(7/8) = log7 –log8全部足し合わせると

log3-log4+log7-log8+log7-log8= log3+2log7-8log2

H4(p,q) = 8log2-2log7-log3

H3-H4 = (log3+8log2-2log19) – (8log2-2log7-log3)= 2log3+ 2log7 -2log19 > 0

9x49 > 19x19

H4

p(x) q(x)

P(1)=0,p(2)=1,p(3)=0,p(4)=0 q(1)=0,q(2)=1,q(3)=0,q(4)=0

x=1の時 0log0+1log(1-0) = 0x=2の時 1log1+0log(1-1) = 0x=3の時 0log0+1log(1-0) = 0x=4の時 0log0+1log(1-0) = 0

H5(p,q) = 0

H5

Gradient descent勾配降下法

Gradient descent 勾配降下法は、ニューラル・ネットワークのパラメーター更新の基本的な手段である。多くのフレームワークでは、 Gradient descent が、標準的な関数として、あらかじめ組み込まれている。

仮説:

パラメーター: a, b

損失関数:

目標:

問題の整理

y(x) = ax + b

a, b y

a, ba, b

a, b の値を動かして、損失関数 J( a, b ) を最小のものにする

損失関数 J(a, b)は、a,b についての関数で、この例では、次のような形をしている

a b

1

0

J(0,1)

損失関数 J(θ0 , θ1)の別の例

ある関数があって

その値を最小にしたい

基本的な考え方:

• ある からはじめる。

• の値を、 が減少するように

変化させる。

• 最小値になるまで、繰り返す。

Gradient descent(勾配降下法)

簡単にするために、二次元のグラフで考えよう。ある点から始めて、その点から極小点に近ずくためには、どうすればいいか?

二つの場合がある。その点が極小点の右側にある場合には、その点のx座標を少し減らせばいい。その点が極小点の左側にある場合には、その点のx座標を少し増やせばいい。

その点が、極小点の右にあるか左にあるかは、その点での接戦の傾きが、正であるか負であるかでわかる。

よって、α を正の数値とすれば、次の式が、より近づいた点の位置を与える。

直感的な説明

損失関数を、パラメーターで微分している

If α is too small, gradient descent can be slow.

If α is too large, gradient descent can overshoot the minimum. It may fail to converge, or even diverge.

アルファが、あまりに小さいと、Gradient descentは、ゆっくりにしか進まない。

アルファが、あまりに大きいと、Gradient descentは、最小値を通り越してしまう。場合によっては、振動したり、収束しない場合もある。

このアルファを学習率(Learning Rate)という。

Gradient descentは、アルファが固定されていても、極小値に収束できる。

局所的な最小値に近づくにつれ、gradient descent

は、自動的に小さなステップを取るようになるので、繰り返しアルファを小さくしてゆく必要はない。

1

0

J(0,1)

0

1

J(0,1)

ある場合には、最小値ではなく、局所的な極小値に、入り込むことがある。

http://arxiv.org/pdf/1210.0811v2.pdf

gradient descent method

先の例で、パラメーターの修正を考える

入力X=xi

予測値 axi+b 実際の値 yi

実際のyの値yi

損失関数J(a,b)=

Σ ((axi+b) – yi)^2

重み= a, バイアス

= b

損失関数は、前向きの推論で生み出されるデータを持ちいて、計算される。

重み= a, バイアス

= b

予測値 axi+b 実際の値 yi

損失関数J(a,b)=

Σ ((axi+b) – yi)^2

パラメーターの変更

a’ = a - α∂/∂a(J(a,b))

b’ = b - α∂/∂b(J(a,b))

損失関数の微分を使って、今度は、後ろ向きに、損失関数を計算した層のパラメーターを、変更する

入力X=xi

予測値 a’xi+b’ 実際の値 yi

実際のyの値yi

損失関数J(a’,b’)=

Σ ((a’xi+b’) – yi)^2

重み= a’, バイアス

= b’

損失関数は、前向きの推論で生み出されるデータを持ちいて、計算される。

重み= a’, バイアス

= b’

予測値 a’xi+b’ 実際の値 yi

損失関数J(a’,b’)=

Σ ((a’xi+b’) – yi)^2

パラメーターの変更

a’’ = a’ - α∂/∂a’(J(a’,b’))

b’’ = b’ - α∂/∂b’(J(a’,b’))

損失関数の微分を使って、今度は、後ろ向きに、損失関数を計算した層のパラメーターを、変更する

損失関数の計算

パラメーターの変更

損失関数の計算

パラメーターの変更

⚫️ ⚫️ ⚫️ ⚫️

こうした過程を繰り返して、パラメーターは、少しづつ、変更されていく。繰り返しの結果、パラメーターの値が、一定の値に収束すれば、学習は成功したとみなされ、繰り返しは、中止される。

どう、重みとバイアスを修正するのか?

もう少し、一般的に、Gradient Descent をまとめてみよう。損失関数をCとするとき、次の式に従って、重みWkとバイアスbl を変更すればいい。

ηは学習率

損失関数が、 ここで見た、quadratic costの形をしていない場合(例えば、 Cross Entropyの場合)でも、この考え方は、変わらない。

コスト関数がQuadratic Costの時の勾配を求めてみる (線形回帰)

だとして、1項だけの場合の微分を考える

hθ(x) = ax+bθ1 = aθ2 = bと考えればいい

j jj

この式を、そのまま用いると、パラメータ更新の、基本的なアルゴリズムは、次のようになる。この操作を、値が収束するまで何度も繰り返す。mは、全データの数である。

二項分類のLogistic回帰の場合

コスト関数 (Log Likelihood)

Logitic回帰の微分も、線形回帰の場合のQuadratic Costの微分と同じ形になる!計算は省略したが、次の文献を参照されたい。“CS229 Lecture notes”http://cs229.stanford.edu/notes/cs229-notes1.pdf

Back Propagation

前向きの推論に対して、パラメータの変更は、勾配(Gradient)を用いて、後ろ向きに行われる。

先に見たのは、一つのニューロンの場合だったが、多段の層からなるニューロンの場合でも、ある層から一つ前の層に対して、後ろ向きに、同じような処理が行われる。そのプロセスをまとめてみよう。

F1(X0 , W1)

Fi(Xi-1 , Wi)

Fn(Xn-1 , Wn)Wn

Wi

W1

X0 (入力)

n層のネットワークの前向きの推論。推論の結果を X としよう。

簡単にするために、バイアスの項 bi は省略している。

Xi-1

Xi

X

省略

前向きの推論

F1(X0 , W1)

Fi(Xi-1 , Wi)

Fn(Xn-1 , Wn)Wn

Wi

W1

X0 (入力) Y (期待される出力)

Cost

C(X,Y, ...)

前向きの推論の結果Xは、Cost関数(Loss関数・損失関数)で、期待される出力Yと比較される。

その結果をCとしよう。

X

Xi

Xi-1

省略

Cost関数

F1(X0 , W1)

Fi(Xi-1 , Wi)

Fn(Xn-1 , Wn)dC/dWn

Cost

C(X,Y, ...)

各層の出力Xi について、Cに対する勾配dC/dXiが計算される。

同様に、各層の重みWi について、Cに対する勾配dC/dWiが計算される。この値に基づいて重みは更新される。

dC/dWi

dC/dW1

dC/dX

dC/dXi

dC/dXi-1

X

Xi

Xi-1

省略

Backpropagation/Gradient

F1(X0 , W1)

Fi(Xi-1 , Wi)

Fn(Xn-1 , Wn)dC/dWn

Cost

C(X,Y, ...)

Xi = Fi(Xi-1,Wi) なので、

dC/dXi-1

= dC/dXi ・ dXi/dXi-1

= dC/dXi ・ dFi(Xi-1,Wi)/dXi-1

dC/dWi

= dC/dXi ・ dXi/dWi

= dC/dXi ・ dFi(Xi-1,Wi)/dWi

dC/dWi

dC/dW1

dC/dX

dC/dXi

dC/dXi-1

省略

Chain Rule

Stochastic Gradient Descent

ここでは、まず、訓練実行の三つのスタイル、Batch, SDG, mini-Batch の違いを見る。実際の応用では、mini-Batchを用いるのが一般的である。最後に、mini-Batchも、その確率論的性格から、SDGと呼ばれることを述べる。

変数の修正にどのくらいの時間がかかるか?前向きの推論と比べて、約3倍の時間がかかる。

Batch

・・・・・全てのデータ

先のパラメータ更新のアルゴリズムを、そのまま実装したもの。すべてのデータについて前向き推論した後で、一つの更新が行われる

データの数が大きくなると、計算量とメモリー消費が巨大になり、現実的でない。

Stochastic Gradient Descent(SDG)

・・・・・

こういうやり方もある。ひとつのデータについて前向き推論した後で、一つのパラメータ更新を行う。これを、SDGという。

一つのデータのみで全てのパラメータをいじるので、収束性にやや問題がある。

Mini-Batch

・・・・・

先に見たBatchとSDGを組み合わせたスタイル。一定数のかたまりのデータで推論を行った後、それに基づいてパラメータを変更する。今の訓練の基本的スタイルである。

ミニバッチ ミニバッチ ミニバッチ ミニバッチ

Batch

キレイに収束しているが、計算量が巨大

一回のパラメータ変更のために全データを読み込む。推論の結果を蓄えるための領域も巨大になる

Stochastic Gradient Descent

迷走気味

一回のパラメータ変更のために、一個だけデータを読み込む。

Mini-Batch

10個のデータを読み込んで、その結果で、パラメータを変更することを繰り返すプログラム

SDGの現在の用法

現在のMLの文脈では、SDGは、一個のデータにつき一回全データの更新を行う前述のSDGではなく、mini-batchの処理を行う訓練のスタイルをSDGと呼ぶことがある。下のCNTKでのSDGの定義を見て欲しい。この時は、SDGとはmini-batchのことである。

SDGのStochasticというのは、全体のデータから少数のデータをサンプリングして、確率的に推定をおこなうということ。モンテカルロ法と同様のアプローチである。

訓練の定義と実行

訓練の実行 -- TensorFlowとCNTK

訓練の定義 -- TensorFlowとCNTK

訓練の定義と実行

ニューラル・ネットワークの学習は、基本的には、次のようなステップからなる。

訓練の定義 推論を行うネットワーク・グラフの定義

学習、すなわち、ネットワークのパラメーターの変更を行うアルゴリズムの定義

訓練、すなわち、データでの繰り返し学習を行う、繰り返しの定義

...

訓練の実行

訓練の実行-- TensorFlowとCNTK

訓練の実行での、TensorFlowとCNTKのコマンド・シーケンスを見てみよう。ここでは、まだ、違いしか見えてこない。

訓練の実行例 TensorFlow

$ python –m モデル

$ python -m

tensorflow.models.image.mnist.convolutional

tensorflor-master/tensorflow/ 以下

訓練の実行例 CNTK

$ cntk configFile=cntk ファイル

$ cntk configFile=../Config/02_Convolution.cntk

CNTK/Examples/ 以下

訓練の定義-- TensorFlowとCNTK

TensorFlowとCNTKの訓練の定義を比較してみよう。TensorFlowはPythonで手続きをベタに記述し、CNTKは宣言的なDomain Specific Languageを使う。違いが目立つが、グラフの定義・最適化のアルゴリズムの指定・訓練の繰り返しの指定等で、基本的な対応が見え始める。

# Create the modelx = tf.placeholder("float", [None, 784])W = tf.Variable(tf.zeros([784, 10]))b = tf.Variable(tf.zeros([10]))y = tf.nn.softmax(tf.matmul(x, W) + b)

# Define loss and optimizery_ = tf.placeholder("float", [None, 10])cross_entropy = -tf.reduce_sum(y_ * tf.log(y))train_step = tf.train.GradientDescentOptimizer(0.01)¥

.minimize(cross_entropy)

# Traintf.initialize_all_variables().run()for i in range(1000):

batch_xs, batch_ys = mnist.train.next_batch(100) train_step.run({x: batch_xs, y_: batch_ys})

グラフの定義

最適化のアルゴリズム

グラフで訓練繰り返し

https://goo.gl/MwscZO

訓練の定義例 TensorFlow

ndlMacros = "$ConfigDir$/Macros.ndl”

train = [

action = "train”

NDLNetworkBuilder = [

networkDescription = "$ConfigDir$/02_Convolution.ndl”

] < ndlは、Net Definition Language 次にリストを示す>

SGD = [

epochSize = 60000

minibatchSize = 32

learningRatesPerMB = 0.5

momentumPerMB = 0*10:0.7

maxEpochs = 15

]

reader = [

...

]

]

訓練の定義例 CNTK

グラフの定義

繰り返しの指定

....run = DNN // 実際に DNNという名前のグラフを構成する

ndlMnistMacros = [ .... ]

DNN = [....

<省略: グラフの定義の一部を次ページに示す >....ce = CrossEntropyWithSoftmax(labels, ol ) err = ErrorPrediction(labels, ol)

# Special NodesFeatureNodes = (features)LabelNodes = (labels)CriterionNodes = (ce)EvalNodes = (err) OutputNodes = (ol)

]

最適化のアルゴリズム

02_Convolution.ndl

最適化の定義 CNTK

DNN = [....# conv1kW1 = 5; kH1 = 5; cMap1 = 16hStride1 = 1; vStride1 = 1# weight[cMap1, kW1 * kH1 * inputChannels]# ConvReLULayer is defined in Macros.ndlconv1_act = ConvReLULayer(featScaled, cMap1, 25,

kW1, kH1, hStride1, vStride1, 10, 1)# pool1 ...# conv2 ...# pool2 ...# DNNImageSigmoidLayer and DNNLayer are defined in Macros.ndlh1 = DNNImageSigmoidLayer(4, 4, cMap2, h1Dim, pool2, 1)ol = DNNLayer(h1Dim, labelDim, h1, 1)

ce = CrossEntropyWithSoftmax(labels, ol)...

]

02_Convolution.ndl

グラフの定義 CNTK

Macros.ndlを参照している

ConvReLULayer(inp, outMap, inWCount, kW, kH, hStride, vStride, wScale, bValue) = [

convW = LearnableParameter(outMap, inWCount, init="uniform",initValueScale=wScale)

convB = ImageParameter(1, 1, outMap, init="fixedValue", value=bValue, imageLayout=$imageLayout$)

conv = Convolution(convW, inp, kW, kH, outMap, hStride, vStride, zeroPadding=false, imageLayout=$imageLayout$)

convPlusB = Plus(conv, convB);act = RectifiedLinear(convPlusB);

]DNNImageSigmoidLayer(inW, inH, inC, outDim, x, parmScale) = [ ... ]DNNLayer(inDim, outDim, x, parmScale) = [

W = LearnableParameter(outDim, inDim, init="uniform",initValueScale=parmScale)

b = LearnableParameter(outDim, 1,init="uniform", initValueScale=parmScale)

t = Times(W, x)z = Plus(t, b)

]

Macro.ndl

グラフの定義 CNTK

マクロを見るとネットワークの見慣れた形が見えてくる

TensorFlowプログラミング

TensorFlowでグラフを定義する

TensorFlowの変数定義

訓練: パラメーターを最適化をする

TensorFlowプログラムサンプル

TensorFlowでグラフを定義する

TensorFlowのプログラムは、まず、グラフを定義することから始まる。

表現は単純化されているが、多数のノードからなる、多層のグラフも、簡単に定義できる。

TensorFlowでは、複数のニューロンからなる一つの層は、次のようなグラフで表現されることを、思い出して欲しい。

行列の積X

W

行列の和

b

φの適用

5つのノードがあるが、Wとbには、重みとバイアスの値が入り、残りの3つのノードは、演算を行うノードである。この層の働きは、φ(X・W+b) で表現される。

一つの層

Wとbの値は、この層の中での計算に利用されるだけでなく、その次の段階では、Back Propagationで修正を受ける。それは、変数Variableである。

行列の積X

W

行列の和

b

φの適用

PythonのTensorFlowプログラムでは、固有の役割をもったそれぞれのノードは、固有の名前が割り当てられている。先頭の tf はTensorFlow、nnはNeural Netの略だと思えばいい。

tf.Variable tf.Variable

tf.matmul + tf.nn.relu

φ(X・W+b)

グラフ定義は、次のようなわずか3行のプログラムになる。

weights = tf.Variable( ... ) # weight を入れる変数の定義bias = tf.Variable( ... ) # biasを入れる変数の定義# 層の働きを φ(X・W+b) で定義する。# ここではφにreluを使っている# imagesは、この層が受ける入力# hidden1は、この層の出力であるhidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)

φ(X・W+b)

このプログラムに出てくる、 images, weights, bias, hidden1は、いずれもテンソルである。それがどのような形をしているかは、ここでは省略したVariableの定義を述べる際に詳しく述べる。Variableの定義によってテンソルの形は決まる。

二層からなるグラフのプログラムを見てみよう。

# 第一層weights1 = tf.Variable( ... ) bias1 = tf.Variable( ... )hidden1 = tf.nn.relu(tf.matmul(images, weights1) + biases1)

# 第二層weights2 = tf.Variable( ... ) bias2 = tf.Variable( ... )hidden2 = tf.nn.relu(tf.matmul( hidden1, weights2) + biases2)

第一層の出力のhidden1テンソルが、第二層の入力に、そのまま利用されているのがわかる。

W

images 和

b

φ 積

W

b

φ

weight1 bias1 weight2 bias2

relu relu

images hidden1 hidden2

# 第一層weights1 = tf.Variable( ... ) bias1 = tf.Variable( ... )hidden1 = tf.nn.relu(tf.matmul(images, weights1) + biases1)

# 第二層weights2 = tf.Variable( ... ) bias2 = tf.Variable( ... )hidden2 = tf.nn.relu(tf.matmul( hidden1, weights2) + biases2)

TensorFlowプログラムと対応するグラフ

三層からなるグラフのプログラムも簡単に書ける。

# 第一層weights1 = tf.Variable( ... ) bias1 = tf.Variable( ... )hidden1 = tf.nn.relu(tf.matmul(images, weights1) + biases1)

# 第二層weights2 = tf.Variable( ... ) bias2 = tf.Variable( ... )hidden2 = tf.nn.relu(tf.matmul( hidden1, weights2) + biases2)

# 第三層weights3 = tf.Variable( ... ) bias3 = tf.Variable( ... )logit = tf.matmul( hidden2, weights3) + biases3)

この例では、第三層は、Activatorを呼んでいない。

TensorFlowの変数定義

TensorFlowの変数(Variable)は、データの格納場所として、他のプログラミング言語の変数と同じ役割を果たす。ただ、TensorFlowの変数は、テンソルの格納場所である。変数の定義では、それがどのような「形」のテンソルの格納場所であるかを定義することが、重要な意味を持つ。

TensorFlowの変数

他のプログラミング言語での変数と同じように、TensorFlowの変数も、プログラムの中で、その値を読みだしたり、値を変更したりできる。

ただ、TensorFlowの変数は、一つの値を持つのではなく、多次元の行列であるテンソルを格納している。実装としては、それは、大きなメモリー・バッファーである。

TensorFlowの変数は、どのようなテンソルを格納するのかの情報をはじめとして、利用前に明示的に初期化されなければならない。

TensorFlowの変数は、その値を直接ディスクにSaveでき、また、プログラムの中で、それをディスクからRestoreできる。

TensorFlowの変数の生成

変数を生成するためには、そのコンストラクターに初期値としてテンソルを渡す必要がある。そのための幾つかのHelper関数が用意されている。

この例では、 tf.random_normal と tf.zeros という Helperを使っている。前者は乱数で、後者はゼロで変数を初期化する。

重要なことは、このHelperの第一引数が、この変数の初期化に使われたテンソルの形(shape)を示しているということである。

# Create two variables. weights = tf.Variable(

tf.random_normal([784,200], stddev=0.35), name="weights") biases = tf.Variable(tf.zeros([200]), name="biases")

変数の初期化

# 二つの変数を生成するweights = tf.Variable(tf.random_normal([784, 200],

stddev=0.35), name=“weights”)biases = tf.Variable(tf.zeros([200]), name="biases") ... # この変数を初期化する演算を追加しておくinit_op = tf.initialize_all_variables()

# モデルを起動した後で、この初期化を呼び出す。with tf.Session() as sess:

# Run the init operation. sess.run(init_op)

... # モデルを使う...

ここではまだ実行されないノードが追加されただけ

ノードで構成されたモデルはSessionで初めて動き出す呼出には、runを使う

[784,200]あるいは[200]の形をしたテンソルが用意されている。

変数の初期化(他の変数から)

# 乱数からなる変数を作る。784x200の行列。weights = tf.Variable(tf.random_normal([784, 200],

stddev=0.35), name="weights")

# 先のweightsの初期値と同じ値を持つ変数w2を作るw2 = tf.Variable(weights.initialized_value(), name="w2")

# weightsの初期値を二倍した値を持つ変数 twice を作るtwice = tf.Variable(weights.initialized_value() * 2.0,

name="w_twice")

変数のsave

# 変数を作るv1 = tf.Variable(..., name="v1") v2 = tf.Variable(..., name="v2") ...

# 変数を初期化する init_opノードを追加init_op = tf.initialize_all_variables() # すべての変数をsave,restoreするsaveノードを追加saver = tf.train.Saver()

# モデルを起動し、変数を初期化し、何かの仕事をした後で# 変数をディスクにsaveするwith tf.Session() as sess:

sess.run(init_op) # モデルで何かの仕事をする...# 変数をディスクにsaveするsave_path = saver.save(sess, "/tmp/model.ckpt") print("Model saved in file: %s" % save_path)

変数のrestore

# 変数を作るv1 = tf.Variable(..., name="v1") v2 = tf.Variable(..., name="v2") ... ...# すべての変数をsave,restoreするsaveノードを追加saver = tf.train.Saver()

# モデルを起動し、 変数をディスクからrestoreして# 何かの仕事をするwith tf.Session() as sess: # 変数をディスクにsaveする

saver.restore(sess, "/tmp/model.ckpt") print("Model restored" )

# モデルで何かの仕事をする...

訓練: ニューラル・ネットワークのパラメーター(重みとバイアス)を最適化をする

ニューラル・ネットワークの「訓練」は、プログラム上では簡単に記述されているが、計算時間の大部分は、この「訓練」に費やされる。

パラメーター(重みとバイアス)の最適化

パラメーター(重みとバイアス)の最適化は、次のような繰り返しのステップで行われる。(幾つかのバリエーションあり)

1. グラフが組みあがったら、そのグラフで入力データに対して出力を計算する。

2. その出力結果を、正しい答えと比較する。比較には、あらかじめ定義していた損失関数を用いる。

3. Gradient Descent(勾配降下法)を使って、損失関数の値が小さくなるようにパラメーター(重みとバイアス)を修正する。

4. 新しいパラメーターのもとで、入力データに対して出力を計算し、2.に戻る。損失関数が十分小さくなるまでこの処理を繰り返す。

GradientDescentOptimizer

TensorFlowでは、GradientDescentを使ったパラメーターの最適化のための最適化演算GradientDescentOptimizerがあらかじめ用意されている。

このOptimizerを使って、損失関数を最小化せよという指示を出せば、ニューラル・ネットワークのパラメーターは、自動的に更新される。

TensorFlowでは、こうして、パラメーター最適化のアルゴリズムが極めて簡単に書ける。

最適化のアルゴリズムの例1(数値予測の場合)

loss = tf.reduce_mean(tf.square(y - y_data)) optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss)

(y-y_data)2Σ1/2m損失関数 C =

学習率

最適化のアルゴリズムの例(クラス分けの場合)

y_ = tf.placeholder("float", [None, 10])cross_entropy = -tf.reduce_sum(y_ * tf.log(y))optimizer = tf.train.GradientDescentOptimizer(0.01)train = optimizer.minimize(cross_entropy)

(y_*log(y))Σ損失関数 C =

学習率

TensorFlowプログラムサンプル

数値予測とクラス分けは、ニューラル・ネットワークの二大機能である。ここでは、この二つのタイプの簡単なプログラム・サンプルを示す。

数値予測(線形回帰)の例

....W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) b = tf.Variable(tf.zeros([1]))y = W * x_data + b

# Minimize the mean squared errors. loss = tf.reduce_mean(tf.square(y - y_data)) optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss)

# Before starting, initialize the variables. We will 'run' this first. init = tf.initialize_all_variables()

# Launch the graph. sess = tf.Session() sess.run(init)

# Fit the line. for step in xrange(201):

sess.run(train) if step % 20 == 0:

print(step, sess.run(W), sess.run(b))

....W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) b = tf.Variable(tf.zeros([1]))y = W * x_data + b

# Minimize the mean squared errors. loss = tf.reduce_mean(tf.square(y - y_data)) optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss)

# Before starting, initialize the variables. We will 'run' this first. init = tf.initialize_all_variables()

# Launch the graph. sess = tf.Session() sess.run(init)

# Fit the line. for step in xrange(201):

sess.run(train) if step % 20 == 0:

print(step, sess.run(W), sess.run(b))

グラフの定義

最適化のアルゴリズム

グラフの起動

グラフで訓練繰り返し

クラス分け(手書き文字の認識)の例

....# Create the modelx = tf.placeholder("float", [None, 784])W = tf.Variable(tf.zeros([784, 10]))b = tf.Variable(tf.zeros([10]))y = tf.nn.softmax(tf.matmul(x, W) + b)

# Define loss and optimizery_ = tf.placeholder("float", [None, 10])cross_entropy = -tf.reduce_sum(y_ * tf.log(y))train_step = tf.train.GradientDescentOptimizer(0.01)

.minimize(cross_entropy)

# Traintf.initialize_all_variables().run()for i in range(1000):

batch_xs, batch_ys = mnist.train.next_batch(100) train_step.run({x: batch_xs, y_: batch_ys})

ソースの全体は、こちらにある。https://goo.gl/MwscZO

....# Create the modelx = tf.placeholder("float", [None, 784])W = tf.Variable(tf.zeros([784, 10]))b = tf.Variable(tf.zeros([10]))y = tf.nn.softmax(tf.matmul(x, W) + b)

# Define loss and optimizery_ = tf.placeholder("float", [None, 10])cross_entropy = -tf.reduce_sum(y_ * tf.log(y))train_step = tf.train.GradientDescentOptimizer(0.01)¥

.minimize(cross_entropy)

# Traintf.initialize_all_variables().run()for i in range(1000):

batch_xs, batch_ys = mnist.train.next_batch(100) train_step.run({x: batch_xs, y_: batch_ys})

グラフの定義

最適化のアルゴリズム

グラフで訓練繰り返し

ソースの全体は、こちらにある。https://goo.gl/MwscZO