Understanding Deep LearningのノートブックをJuliaで確認する。
4.2 Clipping functions
JuliaでDeep Learningを理解する: 4.1 Composing networksでは簡単のために特殊な形の2層ニューラルネットワークを確認した。
(画像はudlbookより引用)
一般には2層ニューラルネットワークは以下のようになる。
(画像はudlbookより引用)
式で表すと
\begin{align}
y' = &\phi'_0 + \phi'_1a\left[\psi_{10} + \psi_{11}a\left[\theta_{10} + \theta_{11}x\right] + \psi_{12}a\left[\theta_{20} + \theta_{21}x\right] + \psi_{13}a\left[\theta_{30} + \theta_{31}x\right]\right] \\
&+ \phi'_2a\left[\psi_{20} + \psi_{21}a\left[\theta_{10} + \theta_{11}x\right] + \psi_{22}a\left[\theta_{20} + \theta_{21}x\right] + \psi_{23}a\left[\theta_{30} + \theta_{31}x\right]\right] \\
&+ \phi'_3a\left[\psi_{30} + \psi_{31}a\left[\theta_{10} + \theta_{11}x\right] + \psi_{32}a\left[\theta_{20} + \theta_{21}x\right] + \psi_{33}a\left[\theta_{30} + \theta_{31}x\right]\right]
\end{align}
となる。
これをJuliaで実装する。
function shallow(x, activation_fn, phi, psi, theta)
pre1 = theta * [1; x]
h1 = activation_fn.(pre1)
w_h1 = psi' .* [1; h1]
pre2 = sum(w_h1, dims=1)'
h2 = activation_fn.(pre2)
w_h2 = phi' .* [1; h2]
y = sum(w_h2, dims=1)'
y, pre1, h1, pre2, h2
end
具体的に値を入れて関数の形を確認する。
theta = [
0.3 -1.0
-1.0 2.0
-0.5 0.65
]
psi = [
0.3 2.0 -1.0 7.0
-0.2 2.0 1.2 -8.0
0.3 -2.3 -0.8 2.0
]
phi = [
0.0 0.5 -1.5 2.2
]
x = 0:0.01:1
results = shallow.(x, ReLU, phi |> Ref, psi |> Ref, theta |> Ref)
y = first.(getindex.(results, 1))
lines(x, y)
JuliaでDeep Learningを理解する: 4.1 Composing networksでは周期的な性質が見て取れたが、一般的な形では隠れユニット数6の2層ニューラルネットワークでも周期性はわからない程度になる。多層で各層の隠れユニット数を増やせば非常に柔軟に関数が作れることが想像に難くない。
大事なのはこのような柔軟な関数が線形関数の組み合わせでできるということである。線形関数は特に勾配計算が高速に実行でき、高速に実行できるからこそ、層を重ねて関数を複雑にして、本質的に複雑な現象の予測ができるようになるのである。