HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学、量子計算などをテーマに扱っていきます

【陰関数微分】一入力一出力から多入力多出力まで

 

 

follow us in feedly

はじめに

なんだかディープラーニングには陰関数微分が使われるということで、まとめて書いておきます(ディープラーニングはこれに加えて合成関数の式が入り込むので、もう少し作業的に面倒だと思われるが)。 ここでも、私の信念である、微分は線形近似である、というようなことを強調しつつ書いています。まあ、それは好みなのであまり気にせず、ディープラーニングの勉強の一環として、あるいは多変数関数の微分やベクトル解析の勉強の一環としても読めると思います。

ちなみに陰関数かどうかはともかくとして、この程度の話が分かると、

www.hellocybernetics.tech

www.hellocybernetics.tech

など、機械学習と関係なさそうな分野の話も見えるようになってきます。

微分

微分係数

微分を説明するために変数 $y$ と $x$ というものがあるとします。ここで変数 $y$ は $x$ の値が定まれば、何らかの値に定まるものとして $y = y(x)$ と明示することとしましょう。 そこで、 $x$ という値に対して $y = y(x)$ と値が定まるとして、では $x \rightarrow x + \epsilon _ x$ とちょっとだけ固定した値$\epsilon _ x$で入力を変えた場合に $y + \epsilon _ y$ と変化すると考えられます。

この入力側の変化 $\epsilon _ x$ に対して出力側の変化 $\epsilon _ y$ のことを微分と言います。ここで適当な係数 $a$ を使って

$$ \epsilon _ y \simeq a \epsilon _ x $$

と近似できたとしたらどうでしょう。もともと $y = y(x)$ という値の決まり方が複雑だったとしても、もしも上記の関係で微分を計算できたとしたならば、入力の変化に応じた出力の変化を計算するのがとても楽になるはずです。

今、固定した定まった値 $x _ i$ に対して $y _ i = y(x _ i)$ であるとすれば、微分は

$$ \epsilon _ y \simeq a _ i \epsilon _ x $$

と書き表されます。ここで $a _ i$ という書き方をしたのは固定した $x _ i$ の、固定されている場所 $i$ に応じて、微分が変わっていると考えているからです。 $\epsilon _ x$ の方は小さな固定の大きさだとして考えているので、場所 $i$ 毎に微分値が変わるとすれば、その効果を係数 $a _ i$ 側に担ってもらうしかありません(ご存知の通り、 $\epsilon _ x$ は後に無限小に飛ばしてしまう)。

このとき、$a _ i$ を(場所$x _ i$における)微分係数と呼びます。

導関数

それでは一般の話をすると、そもそも係数 $a$ は$x$ に応じて変わるのですから、

$$ \epsilon _ y = a(x) \epsilon _ x $$

と書いておいた方が楽そうです。このとき $x$ は固定していませんが、 $a(x)$ の方は微分の世界に入るときに初めて $x$ の値を固定し、それにより微分係数という形で値が定まります。このような形式において $a(x) $ のことを導関数と呼ぶわけです。

線形近似

さて、もともと $\epsilon _ y$ というのは $y=y(x)$ の関係において $x \rightarrow x + \epsilon _ x$ と変化させた時に $y \rightarrow y + \epsilon _ y$ と表せると考えたのが出発点でした。今、微分の世界から元の関数の世界に戻って、真面目にこの関係をみてみることにすれば

$$ y(x + \epsilon _ x) \simeq y(x) + \epsilon _ y = y(x) + a(x) \epsilon _ x $$

と勝手にしていたところを

$$ y(x + \epsilon _ x) = y(x) + ... $$

と正確に表現してやらなければなりません。もしも $\epsilon _ y = a(x) \epsilon _ x$ で $...$ の部分を完全に表現できると信ずるならば、これは入力の変化に対して、係数 $a(x)$ に比例した変化量を出力側が持つということになります。しかし実際にそうなっていないとしたならば

$$ y(x + \epsilon _ x) = y(x) + a(x)\epsilon _ x + O(\epsilon _ x ^ 2) $$

と、二次以降の項を考慮しなければなりません。そうであっても、$\epsilon _ x$ を無限小に飛ばしてしまえば、線形の項に比べて二次以上の項は急激に値が小さくなってしまうので、無視しても良さそうです。 本当は無視していいかは場合によるのですが、無限小に飛ばすことで無視できるようなケースを「微分可能」であると言います。俗に「なめらか」と表現するものがこれに相当します。

微分可能な関数 $y(x) $を、適当な $x$ の周囲で $y(x + \epsilon _ x) \simeq y(x) + a(x) \epsilon _ x$ を近似しているのだと思い返せば、微分とは線形近似であると思えるわけです。

多変数関数の微分

ここで多変数関数 $y = y (x _ 1, ..., x _ d)$ を考えると同様にして線形近似

$$ y (x _ 1 + \epsilon _ {x _ 1}, ... , x _ d + \epsilon _ {x _ d}) \simeq y(x _ 1, ..., x _ d) + \sum _ {i=1} ^ d a(x _ i) \epsilon _ {x _ i} $$

と表せます。ここで $a (x _ i)$ というのは $x _ i \rightarrow x _ i + \epsilon _ {x _ i}$ と値を個別に変化させたときに $y \rightarrow y + \epsilon _ {y _ i}$ と変化したとしたならば

$$ \epsilon _ {y _ i} \simeq a(x _ i) \epsilon _ {x _ i} $$

と線形できるだろうと思ってしまった場合の係数になります。それらを全ての変数に対して都合よく「いける」と思ったのが多変数関数に対する(全)微分です。 都合よくそれぞれの入力の変化が、出力の変化に線形に効いてくると考えているので、全体の変化は単に和をとって

$$ \epsilon _ {y} = \sum _ i\epsilon _ {y _ i} \simeq \sum _ i a(x _ i) \epsilon _ {x _ i} $$

と書いてしまいます。これが全微分(全ての入力変数が少しずつ変化した時の出力の変化)です。

ところで比例係数 $a (x _ i)$ の方は、それぞれ個々の変数に関する係数となっています。こいつらが、全微分を構成するための要素となっているわけです。 一変数のときにはこれを微分係数と呼んでいたことに対して、多変数の話では"偏"微分係数 と呼びます。また導関数という言葉に対しては偏導関数という言葉を使います。

微分の通常の表記

さて、ここで微分の通常の表記は $\epsilon _ x $ などとは書かずに ${\rm d} x$ などと書かれることを伝えておきましょう。すると一変数の微分は

$$ {\rm d} y = a(x){\rm d} x $$

などと表記され、多変数の場合は

$$ {\rm d} y = \sum _ i a(x _ i){\rm d} x _ i $$

と表されます。微分という計算は、いわば一般の $y = y(x _ 1, x _ 2, ...)$ という非線形関数の世界から${\rm d} y = \sum _ i a(x _ i){\rm d} x _ i$ という計算しやすい線形の世界への変換操作なのです。 この変換を行うことで「小さな値しか取らない前提であれば、元の非線形関数と遜色ない」新たな空間で議論ができるというわけです。

そして、その時に重要になってくるのは「(偏)微分係数」あるいは「(偏)導関数」になります。こいつらが新たな空間の作り方を教えてくれるわけですから大変重要です。通常は、これらは元々の関係 $y=y(x)$ のことをちゃんと覚えておくために、$a(x)$ という雑な表記をせずに

$$ \frac{{\rm d}y}{{\rm d}x} $$

あるいは

$$ \frac{\partial y}{\partial x _ i} $$

と表記されます。後者の表現は多変数関数に対して、他にも色々変数があるから、これは $x _ i$ に関することしか考えていませんよ、ということを強調している表現です。噂には $d$ という書き方を崩したら $\partial$ という形になったという程度の話らしいですが、この書かれ方をしていたときには $y$ の値を定めるには他の引数も存在しているということを意識しましょう。

また、普通は関数を $y = y(x)$ という書き方はせず、どんな変換がされているのかを表す $f$ というものを考え $y = f(x)$ と表記するのが一般的です。上記ではその変換の仕方がどんなものかを議論せず、単に入力と出力の値にだけ興味を持っていたため $y$ が $x$ の値によって定まるということが明示できればよく $y = y(x)$ という横着をしたのです。これは表記の濫用なので特別事情が無い限りはおすすめしないです。

陰関数

陰関数

さて、上記の議論では入力側 $x$ と出力側 $y$ という関係性を考えていました。 $y = y(x)$ という関数は 「$x$ "から" $y$ への関係」を示しているものです。 では下記のような式はどうでしょうか。

$$ ax + by = 0 $$

この式は言わずもがな $b \neq 0$ において

$$ y = -\frac{a}{b}x $$

と表せるので、このような形式で見てしまえば $y = y(x)$ すなわち、$x$ から $y$ への関数だと見ることができます(その逆もできますね)。 そういった意味で、明示的には $y = y(x)$ の関係にはなっていないのだが、整理すればそのような形式できる場合に

$$ f(x, y) = 0 $$

という関係式を「陰関数」と呼びます。言い方を変えるならば、陰関数であれば、それは整理しさえすれば関数の形に書き換えられるということです。

陰関数の微分

ところで、明示的に関数の形になっていない場合に(例えば式を整理するのが面倒な場合に)、兎にも角にも微分を知りたいということが起こった場合はどうすればよいでしょう。 1つは面倒な式の整理を行ってから、普通に微分を求めることです。そしてもう1つが 陰関数微分 というテクニックを用いることです。

$$ f(x, y) = 0 $$

という陰関数に対して、今、恒等的に $0$ という値を持っているコンスタントな値 $z$ を準備します。そうすると

$$ z = f(x, y) $$

とあたかもこれが多変数関数の如く扱うことができます。これに対して、既に述べたとおり多変数関数の微分を計算すれば

$$ {\rm d} z = \frac{\partial f}{\partial x} {\rm d}x + \frac{\partial f}{\partial y} {\rm d}y $$

と線形の世界へ持ち込むことが可能です。さて、ここで $z = 0$ というコンスタントな値であることを思い出せば ${\rm d}z = 0$ であるはずなので、早々にお役御免していただき

$$ 0 = \frac{\partial f}{\partial x} {\rm d}x + \frac{\partial f}{\partial y} {\rm d}y $$

としてしまいましょう。すると、微分 ${\rm d} y$ が欲しい場合には

$$ {\rm d}y = - \frac {\frac{\partial f}{\partial x} } {\frac{\partial f}{\partial y} } {\rm d} x $$

と書けることになります。これは一次関数の陰関数 $ax + by = 0$ を考えた時の式の整理の仕方を模倣したに過ぎません。一般の陰関数 $f(x, y) = 0$ を微分によって局所線形近似することで、あたかも一次関数の如く変形してしまったというわけです。もちろん、上記に出ている偏微分係数が一次関数における $a, b$ の役割を担っているわけですから、一次陰関数を関数の形に整理するために $ b \neq 0$ という条件が必要であったように、この陰関数微分によって、微分を求めるためには

$$ \frac{\partial f}{\partial y} \neq 0 $$

が条件になることを忘れてはなりません(まあ、単に 0 割に注意せよということにすぎませんが)。

多変数入力の陰関数微分

さて、多変数の一次陰関数でも

$$ a _ 1 x _ 1 + ... + a _ d x _ d + b y = 0 $$

という式に対しては、単に

$$ y = - b ^ {(-1)} (a _ 1 x _ 1 + ... + a _ d + x _ d) $$

と整理することができます。これをベクトルで表記すれば

$$ y = - b ^ {(-1)} \bf a \cdot x $$

と表せます。ここで ${\bf a }$ は $i$ 番目に $a _ i$ の要素を持つベクトルです。$\bf x$ も同様で、これは内積を使って表記を簡略化しただけの話です。

さて、多変数の陰関数でも、局所線形近似を介することで、上記の議論を真似して上手に微分を得られそうです。まず

$$ f(x _ 1, ..., x _ d, y) = 0 $$

なる陰関数があったとすれば、

$$ \frac{\partial f}{\partial x _ 1} {\rm d}x _ 1 + ... + \frac{\partial f}{\partial x _ d } {\rm d}x _ d + \frac{\partial f}{\partial y} {\rm d} y = 0 $$

とできるのでした( $z = 0$ というコンスタントな変数を介して $z = f(x _ 1, ..., x _ d , y)$ を微分して $dz = 0$ を代入してやるだけです)。 さて、見た目が仰々しいですが、所詮、係数×変数の足し算が続いているだけです。一次関数がそうであったように、

$$ \frac {\partial f}{\partial {\bf x}} = \left ( \frac{\partial f}{\partial x _ 1}, ..., \frac{\partial f}{\partial x _ d} \right) $$

というベクトルと、

$$ {\bf x} = (x _ 1, ..., x _ d) $$ $$ {\rm d} {\bf x} = ({\rm d}x _ 1, ..., {\rm d}x _ d) $$

というベクトルを考えてあげることにすれば、

$$ \frac{\partial f}{\partial {\bf x}} {\rm d}{\bf x} + \frac{\partial f}{\partial y} {\rm d} y = 0 $$

と表せてしまいます。結局陰関数から微分を得ることは $\frac{\partial f}{\partial y} \neq 0$ に注意しておけば

$$ {\rm d} y = -\left( \frac{\partial f}{\partial y} \right) ^ {-1} \frac{\partial f}{\partial {\bf x}} {\rm d}{\bf x} $$

と書けてしまうのですね。ここでも

$$ y = - b ^ {(-1)} \bf a \cdot x $$

と見比べれば、単に局所線形の世界でいつもどおりの式変形をしているに過ぎないのです。

多変数出力の陰関数

ここで、今、出力側に相当する $y$ という変数が1個しかない場合を考えて来たことに注意しましょう。次は入力 $x$ は1つだが、出力 $y$ が複数あるような場合の陰関数を考えていきます。

同じように一次関数から考えていきます。これは$y$ と $x$ が入れ替わっているだけだと考えれば上記と同じだと思えなくもないのですが、私達が知りたいのは $x$ から $y$ への関数です。今、最終的には $y _ i = f _ i (x)$ のように、出力1つ1つについて $x$ から $y$ への関数を求めなければならないという状況です。この場合は、下記のように連立一次方程式を考えなければ $y$ について整理することができません。

$$ \begin {align} a _ 1 x + b _ {11} y _ 1 + ... + b _ {1D} y _ D &= 0 \\ a _ 2 x + b _ {21} y _ 1 + ... + b _ {2D} y _ D &= 0 \\ & \vdots \\ a _ D x + b _ {D1} y _ 1 + ... + b _ {DD} y _ D &= 0 \\ \end{align} $$

なかなか解くのはめんどくさそうですが、$b _ {ij}$ を $i$ 行 $j$ 番目の要素とする行列 $\bf B$ を考えてやることにして、ベクトル化できるところはベクトル化してしまえば

$$ {\bf a}x + {\bf B} {\bf y} = 0 $$

というのが簡略された表記になります。これは $\bf B$ が正則であれば

$$ {\bf y} = - {\bf B} ^ {-1} {\bf a}x $$

と求めることができ、各 $y _ i$ に対して $x$ を定めることで値を決めることができるようになりました。

さて、一般の非線形な陰関数に関しても同様に連立方程式から出発する必要があります。

$$ \begin {align} f _ 1(x, y _ 1, ..., y _ D)& = 0\\ f _ 2(x, y _ 1, ..., y _ D)& = 0\\ & \vdots \\ f _ D(x, y _ 1, ..., y _ D)& = 0 \end{align} $$

が出発点です。それぞれ、微分をしてやれば、$i$ 番目の方程式に関して

$$ \frac{\partial f _ i}{\partial x } {\rm d}x + \frac{\partial f _ i}{\partial y _ 1 } {\rm d}y _ 1 +...+ \frac{\partial f _ i}{\partial y _ D} {\rm d} y _ D = 0 $$

と線形方程式に変換してやることができます。こうなってしまえば、先ほど同様で、$\frac{\partial f _ i}{\partial y _ j}$ を $i$ 行 $j$ 番目の要素とする行列 $\frac{\partial \bf f}{\partial \bf y}$ を使って、$i = 1, ..., D$ と並んでいる連立線形方程式を

$$ \frac{\partial {\bf f}}{\partial x} {\rm d} x + \frac{\partial \bf f}{\partial \bf y}{\rm d} {\bf y} = \bf 0 $$

と表してやることができます。そうすると、$\frac{\partial \bf f}{\partial \bf y}$が正則である時、

$$ {\rm d}{\bf y} = - \left( \frac{\partial \bf f}{\partial \bf y} \right) ^ {-1} \frac{\partial {\bf f}}{\partial x} {\rm d} x $$

と整理ができて、見事に微分が求まるということになりました。

多入力多出力の陰関数

さて、このまま $x$ もたくさんあるし $y$ もたくさんあるというケースを考えていけば、かなり一般的な関数の議論ができるようになったということになります。上記までを理解していれば話は簡単で、連立方程式

$$ \begin {align} f _ 1(x _ 1, ... ,x _ d , y _ 1, ..., y _ D)& = 0\\ f _ 2(x _ 1,... ,x _ d , y _ 1, ..., y _ D)& = 0\\ & \vdots \\ f _ D(x _ 1 ,... ,x _ d , y _ 1, ..., y _ D)& = 0 \end{align} $$

を考えてやれば良いことになります。もちろん、まだ不慣れな場合は連立一次方程式から始めればいいでしょう。

陰関数微分の結果は、$\frac{\partial \bf f}{\partial \bf y}$が正則である時に

$$ {\rm d}{\bf y} = - \left( \frac{\partial \bf f}{\partial \bf y} \right) ^ {-1} \frac{\partial {\bf f}}{\partial \bf x} {\rm d} \bf x $$

なるのであって、$x$ がたくさんあるということに注意して行列化しただけに過ぎません。