자동미분과 이원수
概要
二元数とは、二つの実数 $a, b \in \mathbb{R}$ に対して次のような形で表現される数を指す。
$$ a + b\epsilon, \quad (\epsilon^{2} = 0,\ \epsilon \neq 0) $$
二元数の加算と乗算の体系は、自動微分の前進モードforward modeを実装するのに有用に使われる。
説明1
自動微分、特に前進モードでは、関数 $f$ の関数値を計算する際に微分係数を同時に計算する。例えば $y(x) = \ln (x^{2} + \sin x)$ の微分係数を計算したい場合、次のように計算する。 $\dot{w} = \dfrac{dw}{dx}$ としよう。
$$ \begin{array}{|l|l|} \hline \textbf{Forward calulations} & \textbf{Derivatives} \\ \hline w_{1} = x & \dot{w}_{1} = 1 \\[0.5em] w_{2} = w_{1}^{2} & \dot{w}_{2} = 2w_{1} = 2x \\[0.5em] w_{3} = \sin w_{1} & \dot{w}_{3} = \cos w_{1} = \cos x \\[0.5em] w_{4} = w_{2} + w_{3} & \dot{w}_{4} = \dot{w}_{2} + \dot{w}_{3} = 2x + \cos x \\[0.5em] w_{5} = \ln (w_{4}) & \dot{w}_{5} = \dfrac{\dot{w}_{4}}{w_{4}} = \dfrac{2x + \cos x}{x^{2} + \sin x} \\[1em] \hline \end{array} $$
このとき二元数の演算を利用すれば、関数値と微分係数を自然に同時に計算することが可能だ。二元数 $a + b\epsilon$ を $(a, b)$ として順序対で表そう。
$$ (a, b) + (c, d) = (a + c, b + d) $$
$$ (a, b)(c, d) = (ac, ab+bc) $$
微分可能な関数 $f : \mathbb{R} \to \mathbb{R}$に対して、 $$ f(a + b\epsilon) := f(a) + f^{\prime}(a)b\epsilon = \big( f(a), b f^{\prime}(a) \big) $$
$f, g : \mathbb{R} \to \mathbb{R}$に対して、 $$ (f \circ g)(a + b\epsilon) := f(g(a)) + f^{\prime}(g(a))g^{\prime}(a)b\epsilon = \big( f(g(a)), bf^{\prime}(g(a))g^{\prime}(a) \big) $$
微分
微分する変数 $x$を二元数 $(x, 1)$として、定数 $\alpha$を $(\alpha, 0)$として表そう。すると二元数の加算はそれ自体で第一成分は関数値、第二成分は微分係数を表す。例えば $x \mapsto x + \alpha$という関数(つまり定数加算)を考えてみよう。 $x = x_{0}$においてこの関数の関数値は $x_{0} + \alpha$であり、微分係数は $\left. \dfrac{d(x + \alpha)}{dx}\right|_{x = x_{0}} = 1$である。これを二元数で表すと次のようになる。
$$ (x, 1) + (\alpha, 0) = (x + \alpha, 1) $$
第一成分は関数値 $x + \alpha$、第二成分は微分係数 $1$だ。当然 $x + x$に対しても成り立つ。
$$ \dfrac{d(x+x)}{dx} = 2x, \qquad (x, 1) + (x, 1) = (2x, 2) $$
次に関数 $x \mapsto \alpha x$ (乗算)を考えてみよう。 $x = x_{0}$においてこの関数の関数値は $\alpha x_{0}$、微分係数は $\left. \dfrac{d(\alpha x)}{dx} \right|_{x = x_{0}} = \alpha$である。これを二元数で表すと次のようになる。
$$ (x, 1)(\alpha, 0) = (\alpha x, x\cdot0 + 1\cdot\alpha) = (\alpha x, \alpha) $$
同様に、第一成分は関数値、第二成分は微分係数になることがわかる。冪 $x \mapsto x^{2}$に対しても成り立つ。
$$ (x, 1)(x, 1) = (x^{2}, 2x) $$
微分可能な関数 $f$と合成関数 $f \circ g$に代入しても微分係数は保存される。
$$ f(x, 1) = \big( f(x), f^{\prime}(x) \big), \qquad (f \circ g)(x, 1) = \big( f(g(x)), f^{\prime}(g(x))g^{\prime}(x) \big) $$
さて、上で見た例 $y(x) = \ln (x^{2} + \sin x)$を再び見てみよう。実数 $x$ではなく二元数 $(x, 1)$を代入して計算すると次のようになる。
$$ \begin{align*} (x, 1)^{2} &= (x^{2}, 2x) \\ \sin(x, 1) &= (\sin x, \cos x) \\ (x, 1)^{2} + \sin(x, 1) &= (x^{2} + \sin x, 2x + \cos x) \\ \ln( (x, 1)^{2} + \sin(x, 1) ) &= \ln(x^{2} + \sin x, 2x + \cos x) \\ &= \Big( \ln(x^{2} + \sin x), (2x + \cos x) \dfrac{1}{x^{2} + \sin x} \Big) \\ &= \Big( \ln(x^{2} + \sin x), \dfrac{2x + \cos x}{x^{2} + \sin x} \Big) \\ \end{align*} $$
実際に $y$の導関数を求めてみると以下のようになるので、二元数の第二成分と一致することを確認できる。
$$ \dfrac{dy}{dx} = \dfrac{d}{dx} \ln (x^{2} + \sin x) = \dfrac{2x + \cos x}{x^{2} + \sin x} $$
ジュリアで自動微分を実装する方法は下の関連リンクを参照しよう。
関連リンク
Mykel J. Kochenderfer, Algorithms for Optimization (2019), p27-32 ↩︎