はじめに
以前、以下の単体法の記事を書いた。
今回はこのシリーズ第2弾で、以下の制約なし非線形計画問題を準ニュートン法で解くプログラムを実装する。
手法
制約なし非線形計画問題の解き方
非線形計画問題を解く際よく行われるのは、最適性の1次の必要条件であるを満たす(に十分に近い点)を以下の反復計算で見つける方法である。
ここでは探索方向で、が減少する方向に探索方向を選ぶ。探索方向の選び方には様々なバリエーションがあり、その1つが今回実装した準ニュートン法。なおはステップ幅で、これについても目的関数が減少するよう適切に選ぶ必要があるが、こちらの選び方の説明は今回省略する*1。
ニュートン法とその問題点
準ニュートン法の前にニュートン法について書く。のヘッセ行列をとするとニュートン法では探索方向を
とする。これは、目的関数をまわりでの2次近似した関数
のに関する停留点に当たり、ヘッセ行列が正定値なら2次近似の最小解となる。従って、ニュートン法は目的関数を2次近似してその停留点を求めるという操作を収束するまで繰り返すアルゴリズムだといえる。ニュートン法は2次収束するため収束性はよい。
一方問題点としては、目的関数が狭義凸関数でない場合ヘッセ行列が正定値にならないケースがある*2。そのため、が下降方向になることは保証されない。そもそもヘッセ行列が逆行列を持たない可能性もある。更にはヘッセ行列を計算すること自体が難しい場合もある。
準ニュートン法のアルゴリズム
ニュートン法の上記の問題を解消するため、ヘッセ行列そのものではなくヘッセ行列を近似する正定値対称行列を使って探索方向を
とするのが準ニュートン法。が正定値なので探索方向は常に下降方向であり逆行列も存在する。
ヘッセ行列の近似
直前の反復でヘッセ行列を近似した正定値対称行列が得られているとして、これを用いて次の近似行列を求めることを考える。まず、 の1次近似として、
が得られる。式(6)の関係よりヘッセ行列の近似行列としては以下の条件を満たすのが適切だといえる。
この式(7)はセカント条件と呼ばれる。これに加えては正定値対称行列でなければならない。これらの条件を満たす行列はいくつか提案されているが、中でもよく知られているのはBFGS公式と呼ばれるもので、これは直前の反復で得られた正定値対称行列およびを用いて
と計算できる。詳細は省くが式(8)の両辺に右からをかければとなりセカント条件を満たすことを示せる。また、ステップ幅を適切に決めれば正定値性は満たされる*3。
逆行列の更新
式(5)にあるように探索方向を求めるためにの逆行列が必要になるが、次元が大きくなると更新毎に式(8)でを計算してその逆行列を計算する、なんてやってると計算量的に厳しい。そこで式(8)の右辺第2項、第3項が共にランク1の行列であることを考えると、Sherman-Morrisonの公式*4を2回適用することで逆行列そのものの更新式を導くことができる。具体的な式展開などは以下の記事が参考になる。
結果としては、
という更新式が得られる。
BFGS公式について
式(8)でやや唐突にBFGS公式を書いたが、ここではBFGS公式の考え方を示す。まずBFGS公式含めて提案されている多くの更新式は、正定値対称性とセカント条件を満たす行列のうち、直前の行列にもっとも近い行列をとしている。これはヘッセ行列は急激に変化しないという事前知識を基づく。これを式で書くと適当な行列間の非類似度を測る関数を導入して、
という最適化問題の解をとしている。
BFGS公式は非類似度としてKLダイバージェンスを採用して式(10)を解くことに相当する。KLダイバージェンスは確率分布間の非類似度を測る尺度であるが、ここでは平均は共通で共分散行列としてとを用いた多次元正規分布同士のKLダイバージェンスをとする。多次元正規分布のKLダイバージェンスについては以下が参考になる。
これを踏まえてを式で表すと、
となり、この式(11)を式(10)に当てはめて最適化問題を解くと式(8)が得られる*5。
ちなみに、KLダイバージェンスは対称性がないため、式(11)のと を入れ替えたKLダイバージェンスを使うと別の更新式が得られ、こちらはDFP公式と呼ばれている。実はKLダイバージェンスに基づく非類似度にはという性質があり、式(10)のに関する最適化問題を解くことと等価になるため、その最適解である式(9)のをに置き換えたものがDFP公式の更新式となる(従って、その逆行列の更新式は式(8)のをに置き換えたものとなる)。
アルゴリズムの流れ
BFGS公式に基づく準ニュートン法のアルゴリズムは以下の通り。
- 近似行列の初期値 *6と初期点を定める。
- が十分に小さければ終了。
- 式(5)で探索方向を求める。
- 直線探索で適切なステップ幅を求める。
- 式(2)でを求める。
- 式(9)でを求める。
- 2.に戻る。
実装
import numpy as np import copy # アルミホ条件を満たすαを線形探索 def backtracking_line_search(objective, x, d, tau1, beta): alpha = 1 g = lambda alpha : objective.func(x + alpha * d) g_dash = lambda alpha : objective.grad(x + alpha * d) @ d while(1): if ((g(alpha) <= g(0) + tau1 * g_dash(0) * alpha)): break alpha *= beta return alpha # 目的関数のクラスobjectiveは以下のメンバを持っている必要あり # objective.func(x) : return f(x) # objective.grad(x) : return ∇f(x) # objective.dim : 変数の次元 def quasi_newton(objective, eps = 1e-9, tau1 = 0.5, beta = 0.9): H = np.eye(objective.dim) # = inv(B) x = np.random.randn(objective.dim) while(1): grad = objective.grad(x) if(np.linalg.norm(grad) <= eps): break d = - H @ grad alpha = backtracking_line_search(objective, x, d, tau1, beta) x_new = x + alpha * d s = (x_new - x)[:, None] y = (objective.grad(x_new) - grad)[:, None] I = np.eye(H.shape[0]) sy = (s.T @ y) H = (I - (s @ y.T) / sy) @ H @ (I - (y @ s.T) / sy) + (s @ s.T / sy) x = x_new return x, objective.func(x)
引数objective
に目的関数を表すクラスのインスタンスを入力するが、これはの値を返すメソッドfunc
とを返すメソッドgrad
を実装してる必要がある。準ニュートン法の処理自体は素直に書いており特別なことはしていない。なお、脚注*3にあるようにの正定値性を保証するならウルフ条件を満たすように直線探索するべきだが、alpha
の初期値次第ではウルフ条件を満たすalpha
が見つからず無限ループに陥るなど扱いにくかったのでアルミホ条件のバックトラッキングで妥協した*7。
前回同様、上記のソースコードと検証用コードを以下のgithubリポジトリに上げている。
最後に
今回は制約なしの非線形計画問題を解く準ニュートン法を実装したが、次は制約ありの非線形計画問題を解く内点法を実装する予定。実は内点法の実装自体はもう出来てるので後は記事を書くだけ。。。
参考文献
今回の内容も主にこちらの書籍を参考にして書いた。
しっかり学ぶ数理最適化 モデルからアルゴリズムまで (KS情報科学専門書)
- 作者:梅谷 俊治
- 発売日: 2020/10/26
- メディア: 単行本
BFGS公式がKLダイバージェンスの最小化として導出されることは以下の書籍に書かれている。