茶国 Rev3

2016-10-14

[]ゼロから作るDeep Learningを購入

DeepLearningがいろんなところで取り上げられていて、よく講習会等にも参加した。DeepLearningのフレームワークとして、Caffe、TensorFlow、Chainer等があって、それぞれの使い方もいろんなサイトで紹介されているし、情報処理学会のセミナーでも、あれをこう使ってどうやってたらこうなったという話を聞いた。いろんなセミナーで説明を聞いても、半分ぐらいしかわからなかった。どうやったらできましたというネットワークの実装結果は聞くとまぁそれとなくわかるけど、もし自分で実装するならどうする?と考えると、なぜそれを選ぶべきなのか?が分からなかった。何層にするのか、プーリング層をどうやって選択するのかとか、どんなアルゴリズムを使うのかとか、、

分からない理由を考えると、理由の一つは、最適なネットワーク構成を決めるのは試行錯誤の結果であって、設計で決まるものではなさそうだという点。もう一つの理由は、それぞれの理論が自分はいまいち分かっていなくて、根本原理が分からないからどうやって使い分けるのがいいのかも分からないということ。そんな中、フルスクラッチでDeepLearningを作りましょうという本が出て、結構評判が良いので買ってみた。

パラパラっと読んだだけですが、、この本の構成とポイントは以下

少しずつ読んでいますが、この本で偏微分というのがやっと理解できました。偏微分は2変数微分で、1変数を固定するということまでは分かっていましたが、Matplotlibでの立体グラフが掲載され、XYZ空間での傾きなのだということが分かりました(50になってやっと理解)。

一方、計算グラフも正方向は分かるけど、逆方向はなぜ微分なのかが分からず。。逆方向は逆関数ではないのか!?(逆方向は本質的に微分と等しいのか、それとも、逆方向は微分と定義しているのか、どっちなのか分からない)。。今悩み中

とにかくこの本を全部読んで全部実装すれば俺ディープラーニングが作れると信じてもうちょっと勉強を続ける予定でございます。

■追記(161015)

下記の計算グラフの微積分をちょっと読んで理解したのは、、「ゼロから作る」で言及している、計算グラフの微分(5.2.1計算グラフの逆伝播(P129))とは、計算グラフの計算式に微分を適用したらどういう事実が得られるか、もしくは、どういう使い道があるか?という説明であって、計算グラフを逆向きに辿ること自体が偏微分に一致するというわけではないということ。分かってみれば当たり前と言えば当たり前で、、関数を逆に辿って得られるのは逆関数であって、偏微分ではない。。

■ご参考URL

計算グラフについて詳細に説明しているサイト

計算グラフの微積分:バックプロパゲーションを理解する(postd様)

http://postd.cc/2015-08-backprop/

これをしっかり読めば、逆方向は偏微分というのが理解できるかも!?

金沢工業大学の偏微分のページ

http://w3e.kanazawa-it.ac.jp/math/category/bibun/henbibun/henkan-tex.cgi?target=/math/category/bibun/henbibun/index.html

■TT(仮)氏からのコメント追加(2016/10/22)

知人のTT(仮)氏から本文へのコメント(補足説明)をもらったので参考になるようこちらに転記します。

〜〜ここから〜〜

(その1)

> 偏微分は2変数微分で、1変数を固定するということまでは分かっていましたが、

・「2変数微分」というのは正確では無くて、多変数ですね。極端に言えば10000変数でも可能ですよ。

・「1変数を固定する」というよりは、「着目している1変数以外の全変数を固定する」という訳で。

着目している変数1個のみが変化した場合の微分係数ということで。

(その2)

> XYZ空間での傾きなのだということが分かりました

w = f(x,y,z) という3変数のスカラー関数があったとして、 (x,y,z,w) の4次元空間に存在する wという曲面上で、(図に描けませんが)

∂f/∂x は、xのみが変化した場合、xの変化する方向に沿った方向の微分係数(傾き)

∂f/∂y は、yのみが変化した場合、yの変化する方向に沿った方向の微分係数(傾き)

∂f/∂z は、zのみが変化した場合、zの変化する方向に沿った方向の微分係数(傾き)

で、普通は(?)、それぞれの傾き具合は相互に独立で異なっています。

そのため、曲面wのある点(x,y,z)での傾きとしては

∇f = [∂f/∂x, ∂f/∂y, ∂f/∂z]

というベクトルで表されます。これが勾配ベクトルですね。

ーーーーーーーー

変数を3個にしてしまったために、4次元空間になって 図で描けない例ですみません。

f:id:chakoku:20161022003436p:image:w250:leftんで、maximaを使ってグラフを描いてみました。

z = x^2-y^2

の2変数のスカラー関数ですが、この曲面上で黄色と赤色の線が クロスしている点(の近傍)で考えると

xのみ変化した場合:zの値は黄色線に沿って変化する

yのみ変化した場合:zの値は赤色線に沿って変化する

という訳で、クロスしている点における各偏微分(偏微分係数)の値は

∂z/∂x :黄色線の方向に一致した接線の傾き

∂z/∂y :赤色線の方向に一致した接線の傾き

となります。図から明らかなように、それぞれの接線の傾きの大きさは異なっていて 1個(1種類)の傾きの値としては表現できません。 なので、通常は

∇z = [∂z/∂x, ∂z/∂y]

のように、2種類(2方向)の傾きを表している偏導関数の組み(ベクトル)として表現しています。これを勾配ベクトルと呼びます。 (超いいかげんな説明ですみません)

〜〜ここまで〜〜

詳細な説明ありがとうございます。染み込むのに時間かかりますが、概念的には理解しました。

で、、普通に学ぶ、dy/dxという微分は、変数が一つの偏微分と解釈してもいいのでしょうか??

dx と∂xは、本質的に違うものなのかどうか。。dxからみて、∂xは上位概念と理解してOK??

日本語で喋らず、定理で証明して確認しろよ。。とか!?

TT(仮)TT(仮) 2016/10/22 00:29 本文へのコメント

(その1)
> 偏微分は2変数の微分で、1変数を固定するということまでは分かっていましたが、

・「2変数の微分」というのは正確では無くて、多変数ですね。極端に言えば10000変数でも可能ですよ。
・「1変数を固定する」というよりは、「着目している1変数以外の全変数を固定する」という訳で。
着目している変数1個のみが変化した場合の微分係数ということで。

(その2)
> XYZ空間での傾きなのだということが分かりました

w = f(x,y,z) という3変数のスカラー関数があったとして、
(x,y,z,w) の4次元空間に存在する wという曲面上で、(図に描けませんが)
∂f/∂x は、xのみが変化した場合、xの変化する方向に沿った方向の微分係数(傾き)
∂f/∂y は、yのみが変化した場合、yの変化する方向に沿った方向の微分係数(傾き)
∂f/∂z は、zのみが変化した場合、zの変化する方向に沿った方向の微分係数(傾き)

で、普通は(?)、それぞれの傾き具合は相互に独立で異なっています。
そのため、曲面wのある点(x,y,z)での傾きとしては
∇f = [∂f/∂x, ∂f/∂y, ∂f/∂z]
というベクトルで表されます。これが勾配ベクトルですね。

TT(仮)TT(仮) 2016/10/23 11:01 さらに、しつこいようですが、こちらに記載しますね。

> 普通に学ぶ、dy/dxという微分は、変数が一つの偏微分と解釈してもいいのでしょうか?

と言うより、普通に1変数のスカラー関数は、そもそも1変数しか無いので、その変数でしか微分できないわけです。
んで、多変数のスカラー関数を考えたとき、全部の変数が勝手に(独立に)一斉に変化すると、訳がわからんことになるので、
「着目している1変数だけが変化したときの導関数(微分)を考えてみよう」-> その他の変数は、一応、固定したものとして扱う。
そんな感じで、「着目している1変数」に偏った(かたよった)観点で微分しているので「偏微分」と思えば良いのでは?
と思いますけど。

こんな感じで、「偏微分」という考え方が生まれたので、これに対応して、そもそもの微分の方は「常微分」というのだったと思った。
常微分方程式とかありましたよね。もちろん、偏微分方程式もありますけど。(違ってたらすみません)

> dx と∂xは、本質的に違うものなのかどうか。dxからみて、∂xは上位概念と理解してOK??

本質的には同じものでしょうけど、、、
上記のように、スカラー関数を1変数から多変数に拡張したので、各変数一個一個ごとに、(偏)導関数/(偏)微分を考えることに
したということで、上位概念(スーパークラスみたいな意味で使ってますか?)ではない感じ。

★あと、前回の説明で勾配ベクトルの超重要な性質を説明していません。
(うまい説明図が欠けなかった && 一度に全部言ってしまうと混乱するかも?だったので)

ちょっと時間がないので、言葉で記しますけど
「ある点(p,q)にて、勾配ベクトル ∇f を評価する(各偏導関数に(p,q)を代入して計算して値が決まる)と
そのベクトルは(p,q)を含む等高線(本当は、等ポテンシャル面?)に、当の(p,q)の点にて直交します」
つまり、法線ベクトルの方向となり、(p,q)にて、この方向に沿って(x,y)が変化すると
スカラー関数 f は、最も急峻に増加(減少)します。
ここから、最急降下法の考え方につながっていくと思われ。

おしまい → 次回はいつになるか、わかりません(すみません)
また、「ウザいので、もう来んな」というのもOK

chakokuchakoku 2016/10/23 14:27 >また、「ウザいので、もう来んな」というのもOK

いやいや、、ゼロから作るDeepLearningは全ページ読破して、
全部実装するつもりなのでフォローよろしくお願いします。
(人生最後のプログラム開発ぐらいのノリです。
 これが最後!!のパターンが最近多いけど。。)

TT(仮)TT(仮) 2016/11/30 22:25 何度もすみません。しつこいようですが。

前回の説明の訂正と補足を以下に。
<訂正>
・勾配ベクトル ∇f は、f が最も急峻に増加する方向を指しています。
<補足>
・その逆方向のベクトル -∇f が最も急峻に減少する方向を指しています。
-> 最急降下方向(steepest descent direction)になっています。

これらについては、適当なベクトル解析の本に説明がある筈なので、
参照してみて下さい。(誰かに本を借りる or 大学の講義用資料のpdfでも良いかも)
∇f が等ポテンシャル面(等位面)に直交する(法線ベクトルの方向になる)件も
説明されている筈です。->逆に、これらが説明されてない本はクソ。
「そんなん、興味ない。いらん。」でも別に良いと思いますが。

あと、どなたかのブログで見ましたが、共役勾配法を使うと
最急降下法よりも少ないイテレーションで極小点に到達できたとかありましたが、
まあ、あまり深入りしない方向で。
----------------------------------------------------------------------
あと、計算グラフの逆伝搬については、何となく分かってきましたよ。

> 計算グラフの微分(5.2.1計算グラフの逆伝播(P129))とは、計算グラフの計算式に微分を適用したらどういう事実が得られるか、
> もしくは、どういう使い道があるか?という説明であって、計算グラフを逆向きに辿ること自体が偏微分に一致するというわけでは
> ないということ。分かってみれば当たり前と言えば当たり前で、、関数を逆に辿って得られるのは逆関数であって、偏微分ではない。。

この表現だけでは、chakoku氏がどのように考えているのか、よく分からないのですが、

> 関数を逆に辿って得られるのは逆関数であって、偏微分ではない。。

この断定は、ちょっと言いすぎでしょう。

「ゼロから作る〜」のp.131 図5-7 が最も分かりやすく説明されていると思います。(少なくとも、私にとっては)
右側から順に辿っていくと、、、
(1)一応、∂z/∂zを最初の入力と考えています。∂z/∂z=1 なので、要らないといえば要らないのですが、形式的な入力として存在しているのでしょう。
この地点では、zがtの関数だということしか見えないので、zをtで偏微分したものを、(形式的な入力の)∂z/∂zに掛けます。
で、得られるのが (∂z/∂z)(∂z/∂t)です。これが次のノードへの入力になります。

(2)次のノードに到達した地点で、実はtがxとyの関数だということが見えます。んで、xの方向に進む際に、tをxで偏微分したものを、入力に掛けます。
で、得られるのが (∂z/∂z)(∂z/∂t)(∂t/∂x)です。これが、xの方向の次のノード(もしあるとすれば)への入力になります。

また、yの方向に進む際には、tをyで偏微分したものを、入力に掛けます。
で、得られるのが (∂z/∂z)(∂z/∂t)(∂t/∂y)です。これが、yの方向の次のノード(もしあるとすれば)への入力になります。

(3)上記の手続きを最終段まで繰り返し適用して行く際に、
・変数αだと思っていたものが実は変数βの関数だった。
・変数βだと思っていたものが実は変数γの関数だった。
・(以下、同様のことの有限回の繰り返し)
が連続して起こるので、微分の連鎖律を次々と適用して行ける訳ですね。
仮に、ノード(ブランチ?)の列が z->t->x->.....->q->pだったとすれば、最終的に
(∂z/∂z)(∂z/∂t)(∂t/∂x).....(∂q/∂p) が得られます。
これが、『今、辿ってきたノードのパスでの ∂z/∂p の値(変微分係数?)』となりますね。

もちろん、zからpに到達するパスが他にも複数存在することもあり得るので、それらの別のパスを経由して得られた複数の∂z/∂pの値を合計したものが、
勾配ベクトルの一つの成分としての ∂z/∂p になるものと思われます。

★この本では、微分の「連鎖率」となっていますが、正しくは「連鎖律」ですね。p.129 に (chain rule) と自分で書いてあるでしょう?
誤変換+思い込みが延々と続いているものと思われます。

「もう、そんなこと、分かってるよ」とか「間違っているのでは?」とかかも知れませんが。

長くなって、すみません。
では、また。→ 次回はあるのか、無いのか???

chakokuchakoku 2016/12/10 00:50 TT(仮)様

コメントありがとうございます。
ひとまず、もういちど微分積分からやり直そうとしているので、質疑は
もう少しお時間ください。
連鎖律が微分を掛け合わせたものであり、計算グラフのノードの
微分を掛けていけば全体の微分が得られるというのは大まかには
理解できるのですが、、

DLfS本での説明で、P128の図5-5等にあるように、逆向きに
計算ノードを辿れば微分になるってのが良くわかりません。
単純に逆向きに計算するだけで何が得られるのか???

個人的には、P128の説明は自分を混乱させるだけなので、
入門ページは飛ばして、P129の連鎖律や自動微分の勉強を
する方がいいのではとも思えます。

TT(仮)TT(仮) 2016/12/10 22:58 さらに、粘着するように、しつこいですが、すみません。
★「長いんで、一々、読んでられないよ」and/or「自分のblogを立ち上げて、そっちに書けよ」と
思われていると拝察しておりますが。。。

> 逆向きに計算ノードを辿れば微分になるってのが良くわかりません。

逆向きの際、
×「計算ノードを辿ると微分になる」
○「計算ノードを辿る際に、当該ノードでの偏微分係数を計算するメソッドを呼ぶ」
ということなのです。

計算ノードがオブジェクトだと考えて下さい。
※以下、Java的な表現を使いますけど。

p.128の図5-5での掛算の計算ノードでは、下記の3メソッドを用意することができます。

(1)掛算:forward(BottomUp)方向に辿る際に使用するメソッド。
double operation(double x, double y) {
return x * y;
}

(2)掛算でのxの偏導関数:backward(TopDown)方向に辿る際にxについての偏微分係数を計算するメソッド。
double partial_derivative_x(double x, double y) {
return y;
}

(3)掛算でのyの偏導関数:backward(TopDown)方向に辿る際にyについての偏微分係数を計算するメソッド。
double partial_derivative_y(double x, double y) {
return x;
}

また、この計算ノードのオブジェクトには、自身への入力値(x, y)を保持するフィールドを持たせておきます。
★★★これが重要なんですよ。(と思っています)
<注意>
オブジェクト内のフィールドに入力値(x, y)を保持できるので、(1)〜(3)のメソッドは
引数無しで定義できるのですが、一応、2個の引数から値を計算している旨を明示的に表すために
上記のようにしています。
また、(2)と(3)を一度に計算して、それぞれの偏微分係数を、別途用意したフィールドに保持させとくと
もっといいことがある筈...

さて、、、
図5-5での順方向の計算の際には、この計算ノードの(1)のメソッドを呼んで、計算させます。

逆方向の計算の際には、(2)or(3)のメソッドを呼んで、偏微分係数を計算させます。
この偏微分係数の計算に、上記の「重要なんですよ」の(x, y)を使うわけです。


DLfS本のあとの方に記載されているPython Scriptを見れば、
上記の内容は分かってもらえると思っています。。。

以下、参考サイト。
<《高速微分法》 - ORWiki>
http://www.orsj.or.jp/~wiki/wiki/index.php/%E3%80%8A%E9%AB%98%E9%80%9F%E5%BE%AE%E5%88%86%E6%B3%95%E3%80%8B
ここには、図がないので、わかりにくいと思いますが、
もともとのヤヤコシい関数 f(x,y) を、中間変数 v_i を使って、単純な演算に分解しているところのみ
参照すれば良いのでは?と思います。

ここで説明されている中間変数 v_i が、1つの計算ノードに対応しているものと考えれば如何でしょうか?

では、また。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/chakoku/20161014/1476441092