HELLO CYBERNETICS

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

変分と機械学習

 

 

follow us in feedly

はじめに

変分法

変分

変分の概念は下記の通りです。

引数 $x$ を受け取る関数 $F[x]$ に関して、引数を $x + h$ へ変えることを考えましょう。すると、引数を変えたことによる $F$ の変化量は

$$ \delta F[x] = F[x + h] - F[x] $$

と表すことができます。この $\delta F[x]$ を変分と呼びます。

微分との差異

さて、上記までの議論を見てみると、これは普通にいつも考える微分と何も違いが無いように見えるでしょう。 実際、微分とは、関数 $f(x)$ の引数 $x$ を $x + h$ と変化させた時の $f$ の変化量

$$ {\rm d} f = f(x + h) - f(x) $$

のことを指すのでした。何やら文字の書き方がちょっと違うだけで、意味は何も変わらないんじゃないか?と思えます。実際、その認識は間違ってはいません。 この形式で見ている限り、両者は同じことなのです。

微分可能

さて、微分の話を続けましょう。 微分可能であるというのは、下記のように ${\rm d} f$が

$$ {\rm d} f = f(x + h) - f(x) = a(x)h + O(h ^ 2) \simeq a(x)h $$

と見積もれる場合のことを指します。これは$x$ を出発点として $h$ だけ値を増やした場合に $f$ の変動の2次の項が1次の項に比べてほぼ無視できるような状況を指しています。 言い方を変えれば、$x$ を変化させた時の $f(x)$ の変化量が線形近似できる場合のことを指しているのです。

この時、変化量 $h$ に対して、線形近似の係数 $a(x)$ は、当然出発点 $x$ に依存しているということで $x$ の関数として表されています。この線形近似をした際の係数関数 $a(x)$ のことを導関数と呼ぶわけです。

通常は $x$ を変化させたのだということを明示するために $h$ の代わりに ${\rm d} x$ を使うのが通例であり、 $f(x)$ の導関数 $a(x)$ を $f'(x)$ のと表すのも通例となっています。従ってよく見る表記は下記のようになっているでしょう。

$$ {\rm d}f = f'(x) {\rm d}x $$

また、ある出発点 $x$ を固定 $x=x _ 0$してしまったとすれば、上記の式は ${\rm d}f = f'(x _ 0) {\rm d}x$ と書かれ、この $f'(x _ 0)$ のことを $x _ 0$ での微分係数と呼びます(ある意味、線形近似の係数であったことを思い起こせば、こっちのほうが馴染みやすい?)。そして、実際にはある固定された $x$ での微分係数を考えれば $f'(x)$ を微分係数と呼ぶこともできるので、議論の上で問題が生じない場合、導関数と微分係数はあまり区別されずに用いられます。

意識としては、導関数よりも微分係数のほうが具体的な何かの値なのですが、 固定された $x$ という文字で置かれている以上は、問題はそんな生じないというわけです。

ここで変分の話に戻ると、上記と同様にして

$$ \delta F[x] = F[x + h] - F[x] = a[x] h + O(h ^ 2) \simeq a[x] h $$

みたいな書き方ができそうですね。

変分と汎関数

ここで、区別の付かない上記の話をちゃんと見ることにすると、実は $F[x]$ を汎関数と呼びます。そして、この引数になっている $x$ は、何らかの「値」ではなく「関数」なのです。 つまり、

$$ \delta F[x] = F[x + h] - F[x] $$

という変化の度合いを図るときに、もしも $x$ が何らかの値であるとするならば $x=3$ を出発点に $h = 0.01 $ だけ増やしたらどうなるだろうか?なんてことが議論できるのです。ところが、変分での $x$ は実際には関数なのです。例えば何らかの時間波形(時間関数) $x(t)$ を思い浮かべてください。これを $x(t) + h(t)$ へと変化させるとは一体どういうことでしょうか?きっと、$h(t)$ という変化の与え方は無数にありそうだと思うはずです。

なので、 $h(t)$ の与え方で、随分と $\delta F[x] = F[x + h] - F[x]$ も変わってしまうことが想定できるのではないでしょうか。値ならば、どれくらいの大きさの $h$ を与えるが重要で。結局それは無限小に飛ばすのであったのです。 $h(t)$ という関数を無限小に飛ばす $h(t) \rightarrow 0$ とは、どのように飛ばすのでしょうか・・・?最終的には至る $t$ の地点 $h(t) $ が $0$ に近づくようにするのですが、その近づけ方もよく分かりません。

こうなってくると、変分においては、$x(t)$ を出発点とした変化のさせ方 $h(t)$ が重要な役割を担っていそうです。なので下記のように微分とのアナロジーで乱暴に書いていた式を修正します。

$$ \delta F[x, h] = F[x + h] - F[x] = a[x] h + O(h ^ 2) = a[x, h] + \epsilon ||h|| $$

これは何を言っているのかというと、$h$ のとり方で変分 $\delta F$ の具合は変わりそうなのであるから、$\delta F [x, h]$ と一応依存性があるということを明記しておき、更に $a[x] h$ と乱暴に書く前に、 $a[x, h]$ という少し抽象度の高い形式で書いておこうということです。もしも運良く

$$ a[x, h] = a _ 1[x] a _ 2 [h] = a _ 1[x] h $$

などと都合よく分解していけたら、元の式になってくれるのですが、 $h$ の与え方によってはそうなってくれないかもしれないので、一般性の高い形式をひとまずは選んだという話です。 また、 $\epsilon ||h ||$ の部分に関しては $h$ が実は関数であったことを思い返して、一先ずノルムの形式で表しておいたということになります。$L _ 2$ ノルムを頭の中で思い浮かべておけば、微分とのアナロジーからそれほど遠くはないでしょう。ここで $\epsilon$ は $||h|| \rightarrow 0$ となるときに $\epsilon \rightarrow 0$ となるような何かです。仮にそんな都合の良い $\epsilon$ が無いのだとすれば、それは微分不可能なのであった…ということになります。

ところで、ある出発点 $x$ を一先ず固定することを考えてしまえば $h$ の与え方というものに注力することができます。こっちが厄介そうなので、そういう方針で行くこととしましょう。すると

$$ \delta F[h] = a[h] + \epsilon ||h|| $$

と一先ず書いておくことができます。この形式を持って $F[x]$ の $h$ による変分 $h$ を議論することにするのです($x$ は書かれていないが、固定された何らかの関数を出発点として $h$ を加えるという操作をしていることは忘れてはならない)。

補足

微分の方も、例えば多次元関数 $f({\bf x})$ のことを考えると面白い。 $f $ はベクトルを受け取ってスカラーを返す関数である。さて、 $f({\bf x})$ の微分とはなんだろうか。ひとまず全微分を考えることにする。全微分とは ${\bf x} = (x _ 1, x _ 2, ...)$ だとした時に

$$ {\rm d}{\bf f} = \sum _ i f'_ {x _ i}({\bf x}) {\rm d}x _ i $$

であった。 $f' _ {x _ i}$ とは多変数関数 $f(x _ 1, x _ 2, ...)$ の $x _ i$ による偏微分係数(偏導関数)である。要するに多次元ベクトルを受け取る関数を、ベクトルの1つ1つの要素を変数とした多変数関数と見ているのである。そうすれば、各成分の偏微分係数☓変化量を足しあわせて全微分を構成できるという話だ。つまり、多次元ベクトルを引数に取る関数 $f({\bf x})$ の変化量というのは、各成分を個別に少しずつ動かしてみる、というのを全成分でやってみて、それらを足しあわせているというだけのことだ。

さて、汎関数に対する変分問題を考えてみよう。$f({\bf x})$ で $\bf x$ の成分の数が無限大になったとしよう。つまり ${\bf x} = (x _ 1, x _ 2, x _ 3, ..., x _ i, ...)$ が本当に永遠に続いているのだ。しかも $i$ は数えたりできないとしたらどうだろう。普通に思い浮かべるベクトルとは成分を数えられる。しかし今考えている $\bf {x}$ の成分の数は多すぎて、そしてミッチリと詰まりすぎて数えられない。そうすると、成分ごとの変化を考えるなんて悠長なことは言えない。

今までの変分の話は、成分ごとの変化を考える代わりに、変化のさせ方を波形 $h$ で描いて全部一気に考えてきたのである。インデックス $i$ はもはや数えられないので、なんとなく連続的に値をとっていそうな $t$ を使って $x(t) $ と書いてあげてしまおうとか考えるわけである。こうして、なんだかよくわからぬ無限個の成分を持つベクトル $x(t)$ のことをインデックスもどき $t$ を与えたら値が定まる "関数" と呼んできたのである。

この立場に経つと、スカラーなりベクトルなりを受け取る関数と、関数を受け取る汎関数、さほど差はないのではないだろうか?実際、抽象的にはそんなに差はないかもしれない。ただ、やはり「無限個の」という話になってくると数学というのは急に勝手が変わってくるものなので、それを具体的に操作しようというときにどうも具合が違う。だから、一層のこと固有名詞を添えて上げたほうが変な操作ミスをしなくて済むというわけだ。

さて、こうなるとベクトルだとか関数だとかって、成分の数の違いなのかい?とか思えてきてしまう。確かに有限個と無限個は勝手が違うわけだけど、数だけの違いだとすればこの辺をどうにか見通しよくできないのか?ってなってくる。気になってきたら線形代数をもう一度学び直そう。「ベクトル」って一体何だったのかがそこに書かれている。

機械学習

関数近似

さて、機械学習の多くの手法は関数近似という考え方で記述できます。例えば

$$ y = f(x) $$

という関数を考えて、 入力と出力のタプル $(x _ i, y _ i)$ がいっぱいあるときに、それに上手く合致するような $f$ を求めようと考えるのです。具体的には、もしも理想的な関数があれば

$$ y _ i = f(x _ i) $$

が全ての $i$ で成り立っているはずです。しかし、それが難しいであろうという場合には、例えば

$$ L = \sum _ i |y _ i - f(x _ i)|^2 $$

を最小化しようということを考えます。この時 $L$ を損失関数などと呼びます。上記は単に、 $f$ の出力が理想的な関係に絶対値の二乗の意味で近くあれ、と書いていることになります

さて、$x _ i, y _ i $ は、個々では手元にあるデータであり、確定値です。。この時、我々が操作できるのは関数 $f$ であることを思い出しましょう。 なのでそういう意味を込めて、損失関数を

$$ L[f] = \sum _ i |y _ i - f(x _ i)|^2 $$

と書くことにしましょう。出てきました。 $f$ は関数ですから、それを引数に取る損失関数 $L$ は実は汎関数 $L [f] $なのです。 さて、 $L[f]$ の最小値においては、変分 $\delta L = 0$ というふうになっているはずです。

なので、適当に $f$ を変えて行く操作、すなわち $f \leftarrow f + h$ で関数を変更することを繰り返していき、変化しなくなったところを解とする作戦です。しかし、どのように $h$ を与えるのが良いのでしょうか…?そういえば我々はその上手い方法を知らないのでした。損失関数が小さくなる $h$ の与え方とは一体…。

ここで、 $f$ の関数を適当にパラメタライズすることにします。パラメータ $w$ を使って $f (w, x)$ としてしまうのです。典型的には $f (w, x) = wx$ のような関数が考えられます。さて、こうすると損失汎関数が

$$ L[f] = L[f(w, x)] = L [f(w)] = L(w) = \sum _ i |y _ i - wx _ i|^2 $$

となります(損失関数の立場からは、$x$は定数であることに注意。また $w$ は関数ではなく何らかの値であることに注意)。汎関数とかいう扱いにくそうな相手が、ただの関数になってしまいました。多くの機械学習手法では、このように、$f$ を操作しやすいもので書き表しておくことで、損失関数の変化のさせ方を簡単に決定できるようにしているのです。

変分ベイズ法

変分ベイズ法では、事後分布関数 $p(z \mid D)$ を $q(z)$ で近似するために、汎関数

$$ L[q(z), p(z \mid D)] = KL[q : p] = \int q(z) \frac{q(z)}{p(z \mid D)} {\rm d} z $$

の最小化を試みます。これはかなり厳しい問題です。 $q(z)$ をどのように変化させると $p(z \mid D)$ に近づくのでしょうか?という話なわけです。

ただ、一般の関数を引数に取る汎関数を考えているわけではなく、汎関数 $L$ はここでは確率分布しか取りません。すなわち関数 $q$ は積分すれば $1$ になるような関数であることが分かっていますし、ここでは $p(z \mid D)$ は 難しいながらも固定された確率分布です。では、それに近づけられるような $q$ の変化のさせ方を見つける手がかりもそれなりにありそうというわけです(なぜなら $p$ に形が似てれば良さそうというふうに分かっているのだから)。

それでもそのままでは難しいので、変分ベイズ法では平均場近似と呼ばれる、$q(z)$ を分解する手法が用いられます。その場合、近似精度は落ちることに注意が必要です。

一方で、通常の機械学習同様 $q(z)$ という関数自体をパラメタライズすることも考えられます。具体的には $q(z; \eta)$ などと書いて、

$$ L[q(z), p(z \mid D)] = KL[q(z; \eta) : p(z\mid D)] = \int q(z; \eta) \frac{q(z; \eta)}{p(z \mid D)} {\rm d} z $$

としてしまい、$q(z)$ の動かし方を $\eta$ に委ねるのです。このとき $\eta$ を変分パラメータと呼ぶわけです。