対象者
深層学習について勉強始めたいな〜って考えている人向け。
いきなりライブラリを利用して何か作るのも手ですが、やっぱりちゃんと理解するには「車輪の再発明」しないといけませんね〜
本記事は深層学習の基礎理論メインですが、できるだけ数式を少なくして図メインでざっくり説明します。
実装などは次回以降順番にやっていこうと思います。
次回の記事はこちらです。
目次
深層学習とは
深層学習はもう半世紀以上も前に提案されたニューラルネットワークを起源に持つ、機械学習の一手法です。
例えば上のグラフでは$x_1, x_2, x_3$が関数$f$に入力されて$y_1, y_2$が出力されていますね。
これはニューロン(神経細胞)のモデルの一つです。式で書くと
f(x_1, x_2, x_3) = \left(
\begin{array}{c}
y_1 \\
y_2
\end{array}
\right)
という感じです。これだとちょっと抽象的&複雑なので、別のモデルを紹介します。
ニューロンモデル
まずは基本のニューロンモデルを紹介します。
はい、1入力1出力の最もシンプルなモデルですね。数式では
f(x) = y
となります。ここではこの関数$f$の実際について掘り下げ、ニューロンの最もシンプルなモデルを作ります。
まず、実際のニューロンの動作について説明します。
ニューロンは電気信号$x$を入力され刺激されることで、それに対応した電気信号$y$を発して次のニューロンに情報を伝達していきます。
このとき、ある一定値以下の刺激の時は電気信号$y$を発しません。この値のことを閾値(しきいち)といいます。
ちなみに電気信号を発することを(ニューロンが)発火するなどと表現することが多いです。
また、ニューロン同士の結合はシナプスと呼ばれるのですが、このシナプスによる結合の強さというのは、前のニューロンからの情報伝達回数などに依存して強くなったり弱くなったりします。
つまり、前のニューロンからよく情報が伝達される(必要/重要な情報が多く伝達される)とシナプス結合が強くなり、逆にあまり情報が伝達されない(必要/重要な情報があまり伝達されない)とシナプス結合が弱くなるということです。
これを簡単に定式化すると
y = f(x) = wx + b = \left\{
\begin{array}{cc}
\textrm{ニューロンが発火した} & (wx + b \gt 0) \\
\textrm{ニューロンが発火しなかった} & (wx + b \le 0)
\end{array}
\right.
のようになります。記号についてざっくりまとめると
- $x \cdots$入力された電気信号
- $y \cdots$出力された電気信号
- $w \cdots$シナプス結合の強さ
- $b \cdots$閾値
という感じです。
これで最もシンプルなニューロンのモデルが完成です。
レイヤーモデルとニューラルネットワークモデル
さて、ニューロンモデルで解説したモデルではほとんど何もできません。ただの1次関数ですしね〜
そこでこのニューロンをたくさん用意し、つなぎ合わせることでできることを増やしていきます。
それぞれ
- $x_i \cdots$前のニューロンから発せられた電気信号
- $f_i \cdots$それぞれのニューロンの発火する/しないを決定する関数
- $y_i \cdots$このニューロンの出力
となっています。
関数$f_i$の中身は
f_i(x_1, x_2, x_3) = \sum_{j=1}^{3}{w_{ij}x_j} + b_i
のようになります。このレイヤーモデルを積み重ねるとニューラルネットワークのモデルとなります。
(積み重ねる際はもちろんこのレイヤーモデルでの出力$y_i$を入力$x_i$に読み替えていきます)。
紛らわしいかもしれませんが、図中の$f'$などは微分を意味する訳ではありませんので注意しましょう。
活性化関数
さて、モデルの紹介は以上で終了です。
ニューラルネットワークモデルではレイヤーモデルを積み重ねるわけですが、ここでは以下の画像についてまず考察します。
これを数式で追いかけてみましょう。
\begin{align}
y' &= f'(x') = f'(y) = f'(f(x))\\
&= w'y + b' \\
&= w'(wx + b) + b' \\
&= w'wx + w'b + b' \\
&= \hat{w}x + \hat{b} \\
&= \hat{f}(x)
\end{align}
この式変形が意味することとは、$\hat{w} = w'w$および$\hat{b} = w'b + b'$とおくと、1層のネットワークでも表現できてしまうということです。つまり重ねる意味がありません。
この原因はニューロンモデルの関数$f$が線形であるためです。
線形関数1は複数回重ねても、うまくすると1回の処理にまとめることができます。ということで非線形化しましょう。
非線形化2するため(だけではないですが)に用いる関数を活性化関数と言います。
記号はよく$\sigma(•)$を用いますね。
これを用いて関数$f$を
f(x) = \sigma(wx + b)
とすることで1層のネットワークでは表現できない出力を生成することが可能となります。
では、この活性化関数には一体どのような物があるか、代表的な物をご紹介します。
他にどんなものがあるか気になる方はこちらをご覧ください。
シグモイド関数(sigmoid)
sigmoid関数はどの入門書でも(多分)最初に紹介される活性化関数でしょう。
\sigma_{sigmoid}(x) = \cfrac{1}{1 + e^{-x}}
- 値域が$0 \le y \le 1$
- 微分が$x \rightarrow \pm \infty$で$0$になる
- 有限の$x$では微分が$0$にならない(ただし、コンピュータで扱う以上0と見なすべき値にはなります)
といったところでしょうか。
値域の性質から2値分類問題の最後の活性化関数に用いられることがあります。
ロジスティック関数の特殊例ですね。
tanh関数
sigmoid関数と形がよく似た関数ですね。
\sigma_{tanh}(x) = \tanh(x) = \cfrac{e^x - e^{-x}}{e^x + e^{-x}}
sigmoid関数との最大の違いは値域が$-1 \le y \le 1$であることですね。ただし、sigmoid関数とは違って2値分類問題の最後の活性化関数に用いられることはありません(ぼくの知る限り)。
sigmoid関数の線形変換関数ですね。
どうやら最近注目度が増しているようです。
ReLU関数
ReLU関数は実装・計算の簡単さと速度の観点から非常によく使われる活性化関数です。
\sigma_{ReLU}(x) = \left\{
\begin{array}{cc}
x & (x \gt 0) \\
0 & (x \le 0)
\end{array}
\right.
\cfrac{dy}{dx} = \left\{
\begin{array}{cc}
1 & (x \gt 0) \\
0 & (x \le 0)
\end{array}
\right.
のように、非常にシンプルなステップ関数になること、かつその微分値が$1$であることですね。
微分値が$1$であるメリットはいつか別の記事で詳しく説明すると思いますが、勾配消失問題3が軽減されることですね。
ソフトマックス関数(softmax)
最後にソフトマックス関数です。こちらは多値分類問題の出力層の活性化関数に用いられます。
その最大の特徴といえば、出力の総和が$1$になるため出力を確率とみなせることでしょう。
\sigma_{softmax}(x_i) = \cfrac{e^{x_i}}{\displaystyle\sum_{k=1}^{n}{e^{x_k}}} \quad (i = 1, 2, \ldots, n)
微分に関しては、いずれ紹介する損失関数の誤差関数に交差エントロピー誤差というものを用いることで、出力層から伝播する勾配が
Errors = y - t
のように非常に単純な値となります。
計算グラフ
さて、モデルの紹介と活性化関数の紹介が一通り済んだところで、今後の理解を深めやすくするために計算グラフを紹介します。
計算グラフとは文字通り計算をグラフ化したもので、これを用いると誤差逆伝播における伝播の様子などがより理解できます。
とりあえず模式図は
こんな感じです。
真ん中の丸に書かれている$f$は計算ノードと呼ばれるものです。ここを左から右に通ることを順伝播、逆に右から左に通ることを逆伝播といいます。
黒字は順伝播、赤字は逆伝播を表しています。
順伝播で入力される変数の数は可変ですが、出力は大抵1つですね(分岐して複数箇所に流れることはあります)。
そして逆伝播についてですが、計算ノードを通る時にその計算ノードの各入力変数に対して偏微分を乗算した値がそれぞれのルートへと流れます。
偏微分がよくわからない方はこちらでざっくり解説しています(数学的な厳密さは全くありません)。
足し算の計算グラフ
まずは簡単に足し算の計算グラフです。
順伝播は見ればわかると思うのでカット、逆伝播を数式で追いかけてみましょう。
\cfrac{\partial z}{\partial x} = 1, \quad
\cfrac{\partial z}{\partial y} = 1 \\
\Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = E, \quad
E \cfrac{\partial z}{\partial y} = E
掛け算の計算グラフ
続いて掛け算の計算グラフです。
逆伝播は偏微分の知識が必要ですね。
\cfrac{\partial z}{\partial x} = y, \quad
\cfrac{\partial z}{\partial y} = x \\
\Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = Ey, \quad
E \cfrac{\partial z}{\partial y} = Ex
割り算の計算グラフ
割り算は逆数の掛け算で表されますが、計算グラフでも書いておきます。
こちらは数3微分の知識が必要になります。
\cfrac{\partial z}{\partial x} = \cfrac{1}{y}, \quad
\cfrac{\partial z}{\partial y} = -\cfrac{x}{y^2} \\
\Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = \cfrac{E}{y}, \quad
E \cfrac{\partial z}{\partial y} = -E \cfrac{x}{y^2}
指数関数の計算グラフ
指数関数の計算グラフはこんな感じですね。
まあ滅多に使うことはないでしょう。
逆伝播には偏微分の知識以前に数3微分の知識が必要ですね。
\cfrac{\partial z}{\partial x} = yx^{y-1}, \quad
\cfrac{\partial z}{\partial y} = x^y \log x \\
\Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = Eyx^{y-1}, \quad
E \cfrac{\partial z}{\partial y} = Ex^y \log x
底がネイピア数の指数関数の計算グラフ
底がネイピア数の場合は指数関数よりも簡単になります。
逆伝播についてはやっぱり数3微分の知識が必要ですが、なくても出力をそのまま乗算すると覚えておけばいいですね。
\cfrac{\partial z}{\partial x} = e^x
\quad \Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = Ee^x
対数関数の計算グラフ
一応紹介しますがまず使わないでしょう。基本的に底はネイピア数$e$を用いるので。
対数の微分はなかなか複雑です。数3微分も併せてご覧ください。
\cfrac{\partial z}{\partial x} = -\cfrac{\log y}{x \log^2 x}, \quad
\cfrac{\partial z}{\partial y} = \cfrac{1}{y \log x} \\
\Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = -E \cfrac{\log y}{x \log^2 x}, \quad
E \cfrac{\partial z}{\partial y} = \cfrac{1}{y \log x}
底がネイピア数の対数関数の計算グラフ
底がネイピア数の対数関数の計算グラフを紹介します。こちらは使われることがあるかも?
対数関数の計算グラフよりも随分とすっきりしています。
\cfrac{\partial z}{\partial x} = \cfrac{1}{x}
\quad \Leftrightarrow \quad
E \cfrac{\partial z}{\partial x} = \cfrac{E}{x}
sigmoid関数の計算グラフ
最後にsigmoid関数の計算グラフ(の一例)を紹介します。
逆伝播を考える時、$-1$は定数ですので無視して、変数$x$に関連する物のみを書いています。
ちょっと複雑ですが、順を追って見てみるとこれまでに紹介した計算グラフの計算にそのまま当てはめているだけですね。
ちなみに、計算グラフを辿る練習として無視している$-1$のルートへ流れる逆伝播も考えてみてください。解答はsigmoid関数の逆伝播で紹介します。
sigmoid関数の順伝播
順伝播を追いかけてみましょう。
一番最初の部分は$-1$と$x$を掛け算しています。黒丸(●)は分岐点を表しています。
次に上段では$-1$を二乗して$1$に、下段では$e$の$-x$乗を計算していますね。
その次は$1$と$e^{-x}$を足し算します。これで分母ができましたね。
最後に$1$と$1+e^{-x}$とを割り算するとsigmoid関数の計算グラフの順伝播が完成です!
sigmoid関数の逆伝播
続いて逆伝播を追いかけましょう。
最初は割り算の逆伝播ですね。$x=1$および$y=1+e^{-x}$に相当します。
合成関数の微分などを一切考えなくて済むのが計算グラフの強みです。
次は足し算の逆伝播ですね。足し算は流れてきた逆伝播をそのままそれぞれのルートに流します。
また、分岐(●)を通る際は逆伝播の値が足し算されます。
\cfrac{E}{1+e^{-x}} + \left\{ -\cfrac{E}{(1+e^{-x})^2} \right\} = E \cfrac{(1+e^{-x}) - 1}{(1+e^{-x})^2} = E \cfrac{e^{-x}}{(1 + e^{-x})^2}
\cfrac{\partial}{\partial a}a^2 = 2a \\
\Leftrightarrow
E \cfrac{e^{-x}}{(1 + e^{-x})^2} \cfrac{\partial}{\partial a}a^2 = 2aE\cfrac{e^{-x}}{(1 + e^{-x})^2} \\
\xrightarrow{a = -1}
-2E\cfrac{e^{-x}}{(1 + e^{-x})^2}
-2E \cfrac{e^{-x}}{(1 + e^{-x})^2} + \left\{ -xE \cfrac{e^{-x}}{(1 + e^{-x})^2} \right\} = -E \cfrac{(x + 2)e^{-x}}{(1 + e^{-x})^2} = -E(x + 2)z(1 - z)
sigmoid関数の微分
計算グラフで計算したところ、$E = 1$の時の値(sigmoid関数を微分しただけの値)は$z(1 - z)$となりますが、実際に微分計算してみるとどうでしょう?
z = \cfrac{1}{1 + e^{-x}}
\Rightarrow
\begin{align}
\cfrac{\partial z}{\partial x} &= \cfrac{-(-e^{-x})}{(1 + e^{-x})^2} = \cfrac{e^{-x}}{(1 + e^{-x})^2} \\
&= \cfrac{1}{1 + e^{-x}} \cfrac{e^{-x}}{1 + e^{-x}} \\
&= \cfrac{1}{1 + e^{-x}} \left\{ 1 - \cfrac{1}{1 + e^{-x}} \right\} \\
&= z(1 - z)
\end{align}
ご覧の通り、しっかり一致しますね!sigmoid関数の最大の利点は逆伝播の計算が出力のみから単純に求まることですね。
以上までで深層学習の一通りの基礎知識は紹介し終わったと思います。
次回以降は実装も交えて色々と詳細に説明していくつもりです。
数3微分
数3微分覚えてない...という方向けの数3微分一覧です。
全く知らない人はそういうもんなんか〜くらいで納得してください。
関数 | $\cfrac{d}{dx}$ |
---|---|
$a^x$ | $a^x \log a$ |
$e^x$ | $e^x$ |
$\log_a x$ | $\cfrac{1}{x \log a}$ |
$\log x$ | $\cfrac{1}{x}$ |
$\sin x$ | $\cos x$ |
$\cos x$ | $-\sin x$ |
$\tan x$ | $-\cfrac{1}{\cos^2 x}$ |
$f(x)g(x)$ | $f'(x)g(x) + f(x)g'(x)$ |
$\cfrac{f(x)}{g(x)}$ | $\cfrac{f'(x)g(x) - f(x)g'(x)}{g^2(x)}$ |
$\cfrac{1}{g(x)}$ | $- \cfrac{g'(x)}{g^2(x)}$ |
$f(g(x))$ | $g'(x)f(g(x))$ |
全部微分の定義式である
\lim_{h \to 0}{\cfrac{f(x+h) - f(h)}{h}}
に代入して計算すれば導出できますね。
ただしそれぞれ必要な知識が数2とかで出てきているので復習をお忘れずに。
偏微分と連鎖律
ここではウルトラ簡単に偏微分について説明します。数学的な厳密さは0です。あくまで深層学習の理解メインですので、深層学習を理解する上で必要な理解の仕方だけ説明します。
偏微分
偏微分とは多変数関数においてある一つの変数だけを変数であるとみなして、他の変数を全て定数だとして微分することです。
以下で例を挙げて説明します。
f(x, y, z) = x^2y + \cfrac{y}{z + x} + z^x
3変数関数ですね。偏微分してみましょう。
\cfrac{\partial f}{\partial x} = f_x
などと書くことにすると、
\begin{align}
f_x &= 2xy - \cfrac{y}{(z + x)^2} + z^x \log z \\
f_y &= x^2 + \cfrac{1}{z + x} \\
f_z &= - \cfrac{y}{(z + x)^2} + xz^{x - 1}
\end{align}
のようになります。
以下では$f_x$に注目して説明します。
そもそも$f_x$の意味は「関数$f$を$x$だけ変数とみなし、$y, z$を定数とみなして微分する」ということです。ということで極端に
y = 1, \quad z = 2
とおいてしまいましょう。すると
f(x, 1, 2) \rightarrow f(x) = x^2 \times 1 + \cfrac{1}{2 + x} + 2^x
のようになります。これなら数3微分を用いれば計算できますね。
f_x = 2x \times 1 - \cfrac{1}{(2 + x)^2} + 2^x \log 2
あとはこの式のもともと$y, z$だったところを書き戻してやると
f_x = 2xy - \cfrac{y}{(z + x)^2} + z^x \log z
となり、$x$についての偏微分の計算ができました!
他の変数についても同様に考えればできるでしょう。ぜひやってみてください。
連鎖律
連鎖律は、実際は小難しい証明があったはずですが、めんどくさいので雑な説明をします。
微分って
\cfrac{\partial f}{\partial x}
とかって書けますよね?
どこからどう見ても分数ですよね?(違うけど)
ということは約分(みたいなことが)できるわけです。
\cfrac{\partial f}{\partial x} = \cfrac{\partial f}{\partial y} \cfrac{\partial y}{\partial x} = \cfrac{\partial f}{\partial z} \cfrac{\partial z}{\partial y} \cfrac{\partial y}{\partial x} = \ldots
こんな感じで鎖のように増やしていけるので連鎖律と呼ばれています。
これが誤差逆伝播法の肝となる定理です。
詳しくはまた別の記事で逆伝播に触れた時に紹介します。
#おわりに
今回で大体必要な事前知識は説明できたかな〜と思います。
足りなければ今後補足していくかもしれません。
P.S. 結局数式ばっかり...
参考
深層学習シリーズ
- 深層学習入門 ~基礎編~
- 深層学習入門 ~コーディング準備編~
- 深層学習入門 ~順伝播編~
- 深層学習入門 ~逆伝播編~
- 深層学習入門 ~学習則編~
- 深層学習入門 ~ローカライズと損失関数編~
- 深層学習入門 ~関数近似編~
- 深層学習入門 ~畳み込みとプーリング編~
- 深層学習入門 ~CNN実験編~
- 深層学習外伝 ~GPUプログラミング編~
- 深層学習入門 ~ドロップアウト編~
- 活性化関数一覧 (2020)
- 勾配降下法一覧 (2020)
- 見てわかる!最適化手法の比較 (2020)
- im2col徹底理解
- col2im徹底理解
- numpy.pad関数完全理解