はじめに
今回は、機械学習によく使われるアルゴリズムの1つである、勾配降下法について解説していきます。
今回の記事の流れは以下のようになります。
今回の記事の流れ
- そもそも勾配降下法とは何か
- 勾配降下法を使う理由
- 勾配降下法を使う場面
上に書いてあるように、勾配降下法とは何か、という点から説明していくため、是非最後まで読んでみてください。
勾配降下法とは
そもそも勾配降下法とは何なのでしょうか。
このような疑問から解消していきましょう。
(勾配降下法をご存じの方は読み飛ばしてもらっても構いません。)
簡単に言うと、勾配降下法とは、ある関数が最小となる点を求めるためのアルゴリズムです。
と言われても、ピンとこない方もいるかと思いますので、図を用いながら解説します。
では、例として
$$f(x) = x^2$$
という関数が最小となる点を求めてみることにします。
縦軸に\(y\)、横軸に\(x\)を取り、図示するとこんな感じのグラフになりますよね。
グラフを見てわかるように、この関数は\(x = 0\)の時に最小値を取ります。
では、グラフを見ずに、この関数が最小となる点を求めるにはどうすればよいでしょうか。
ここで登場するのが勾配降下法と言われる手法です。
勾配降下法は、以下に示すステップで動いています。
- 初期値をランダムに決める
- 勾配を下る向きと大きさを決める
- ②で決めた向きにちょっとだけ動かす
- ほとんど動かなくなるまで②と③を繰り返す
では、図を見ながら実際の勾配降下法の動きを見てみましょう。
今回は、初期値をこのようにします。
この場合、勾配を下る向きはこうなりますよね。
ということなので、この向きに少しだけ動かしましょう。
まだ、最小値に到達していないので、同様にして勾配を下る向きを決めます。
向きを決めたら、再び少しだけ動かします。
一連の流れを繰り返すことで、最終的には変化がほとんどなくなり、ある1点に落ち着きます。
ここまでが、勾配降下法の基本的な考え方になります。
では、次の章では、この流れを数式に落とし込んでいきます。
勾配降下法の数式化
では、この動きを式として記述するにはどうすればいいのか考えていきましょう。
初期値を決めた後は、勾配を下る向きとその大きさを求める必要がありますよね。
これには、今いる点での傾きを利用します。
傾きが右肩上がりの時は左に動かし、右肩下がりの時は右に動かすと勾配を下ってくれますよね。
このことから、向きに関しては、傾きとは異符号の向きに動かせばよい、ということがわかりました。
では次に、先ほどの向きにどれだけの大きさ動かすのかを考えていきます。
移動する大きさに関しては、最小値となる点から遠いほど大きく動き、逆に近いほど小さく動いてほしいですよね。
では、それを実現する方法を考えていきます。
関数が最小となる点での傾きは0になる、ということから、関数を最小にする\(x\)に近づくにつれて、傾きの値は0に近づいていくことがわかります。
また、最小値とは遠い点での傾きの値は大きくなっていきます。
つまり、点を動かす大きさは、傾きの絶対値に比例しているということがわかりました。
では、これを数式に落とし込んでいきましょう。
まず、適当に決めた\(x\)の初期値を\(x^{(1)}\)として、少し動かした後の\(x\)を\(x^{(2)}\)とします。
すると、このような式がよさそうです。
$$x^{(2)} = x^{(1)} – \frac{df(x^{(1)})}{dx}$$
こうすることで、\(x^{(1)}\)での傾きが正だった場合は負の向きに動き、傾きが負だった場合は正の向きに動くようになります。
これを一般化した式は以下のようになります。
$$x^{(i+1)} = x^{(i)} – \frac{d f({x^{(i)}})}{d x}$$
ただし、機械学習を行う際は、更新する大きさに、学習率と呼ばれる0 ~ 1の任意の値を掛け算します。
これは、最小値に向かって動かしていく際に、傾きの値だと値が大きすぎて、なかなか収束しなくなることがあるので、それを防ぐためです。
ということなので、実際の勾配降下法は学習率\(\eta\)を掛け算して、このように表します。
$$x^{(i+1)} = x^{(i)} – \eta\frac{d f({x})}{d x}$$
さて、ここまで見てきて、ある疑問を抱いた方がいるかもしれません。
僕自身も、最初に勾配降下法を見たときにこのように思っていました。
勾配降下法を使う理由
まず、大前提として、機械学習は手計算ではなくコンピュータを使って行います。
つまり、そもそも一般的な方法で導関数を求める手段は無いし、方程式を解くことさえもできないというわけです。
コンピュータにそこまで便利な機能はありません。
また、仮に導関数を求めることができたとしても、複雑な関数に対応できるのかと言われれば怪しいところです。
今回、例として扱った関数は、ただの1変数の二次関数だったため、かなり単純な関数だったと言えます。
これが複雑な関数になったとき、もはや手計算でも導関数を求めることが厳しくなってきます。
ということなので、導関数=0 を求める、という選択肢は消えます。
しかし、勘の鋭い方なら気づいたかもしれませんが、勾配降下法の式中にも傾きの値を使用しています。
これはどういうことなのでしょうか。
実は、単純なことなのですが、コンピュータは一般的な導関数を求めることは不可能ですが、ある点での微分係数だけであれば普通に求めることができます。
ずばり、定義に従って微分すればいいわけです。
微分の定義に従って計算することで、単純な計算だけで、導関数を求めずとも微分係数の近似値を求めることができます。
求めたいものは、傾きの符号と大体の大きさだけなので、近似値でも全く問題ありません。
ちなみに微分の定義はこうでしたね。
$$\frac{df(x)}{dx} = \lim_{h \to 0}\frac{f(x + h)-f(x)}{h}$$
ある点での\(f(x)\)の値さえわかってしまえば、hを微小量に設定して、コンピュータ内でも普通に微分係数の計算ができるわけですね。
実際に、勾配降下法の式中で使っているものも、傾きの大きさ、つまり微分係数のみです。
このように、勾配降下法を用いると、難しい計算をしないでも汎用性の高いプログラムが書けます。
これがまさに、勾配降下法がよく使われている理由になります。
しかし、当然のことですが、勾配降下法は万能ではありません。
次の章では、どういった関数の場合に勾配降下法が有効なのかを見ていきます。
勾配降下法を使う場面
勾配降下法を使う場面を考える前に、逆に、どういった関数に使うことができないのかを考えてみます。
まず、勾配降下法は、勾配を下る方向に少しずつ動かしていくものでしたよね。
もし、勾配を下る向きにへこんでいる箇所があった場合はどうなるのでしょうか。
そうです。
へこんでいるところにハマって動かなくなってしまいます。
4次関数などがこういった形になりますね。
この関数の最小値は右側のへこんでいるところだとわかるのですが、勾配降下法を使った場合、初期値次第では左側のへこんでいるところで止まってしまいます。
例えば、初期値がここだったとします。
この場合、勾配を下る向きに動いていくと、ちょうどへこんでいる部分にハマってしまう可能性があります。
この場所にはまってしまうと、もう動くことはないので、この点で関数が最小になる、という間違った結果になってしまいます。
これを、局所解にはまる、と言ったりもします。
このことからわかるように、関数内に、最小値以外にへこんでいる箇所があるような関数には、勾配降下法は不向きです。
もうお分かりだと思いますが、勾配降下法が使える関数というのは、下に凸の関数、あるいは上に凸の関数のみです。
汎用性低いじゃん、と感じた方もいるかもしれませんが、実際の機械学習で扱う誤差関数は、この型に当てはまるものが結構あります。
以前の記事で取り上げた、「線形回帰」で登場した誤差関数もパラメータに関しての二次関数となっていました。
線形回帰の記事はこちらになります。
はじめに 今回は、前回までに取り上げた、「単回帰分析」と「重回帰分析」をより一般的にした「線形回帰」について解説していきます。 >>【機械学習】よくわかる単回帰分析 >>【機械学習】よくわかる重回帰分析[…]
また、当ブログではまだ扱っていないのですが、ロジスティック回帰と呼ばれる機械学習の手法でも、尤度関数が上に凸の関数ということから、勾配降下法を用いた演算を行います。
勾配降下法は、意外にも汎用性が高いものなんです。
最後にまとめると、勾配降下法が有効な関数は、「下に凸の関数」、「上に凸の関数」となります。
おわりに
今回は、勾配降下法について解説してみました。
僕自身、導関数=0 が使えない理由がわからなくて、1週間ぐらい、いろんな教材をあさったりしていたぐらいなので、もしも同じようなことを疑問に感じている人がいれば、その疑問も解消されたかと思います。
ちなみに、最後の方で書いた、上に凸や下に凸の関数というのは、対象となる関数の2階微分を求めることでわかります。
これは、手計算でちゃちゃっとやってしまえば、勾配降下法が使えるかどうかの判断ができるものなので、頭の片隅にでも入れておいてください。
では、今回はここまでとします。
お疲れさまでした。