共役勾配法を用いた最適化について

このQ&Aのポイント
  • 共役勾配法を用いて24変数の関数の極小値を求めるプログラムを作成していますが、うまくいきません。
  • 停留ポテンシャル法を使い、弾性体の変形を見るためにひずみエネルギーを目的関数に設定しました。
  • 問題の原因として、共役勾配法の理解に誤りがある可能性があるので、教えていただきたいです。
回答を見る
  • ベストアンサー

共役勾配法を用いた最適化について

弾性体の変形を見るために,停留ポテンシャル法を用いようとしているのですが,その際に目的関数にひずみエネルギーをとり 独立な24変数の関数の極小値を共役勾配法で求めようとしています. Hesse行列を手計算でだし,最適化を行うプログラムを書いたのですが どうも上手くいきません. 下にプログラムの一部分をのせます. 共役勾配法について勘違いしている可能性もあるので 問題点を教えて頂ければ幸いです. x_vectorは24変数ベクトルで,dは探索方向,HはHesse行列です. for(i=0;i<10;i++) { lambda = (x_vector*d)/(d*H*d); x_save_vector = x_vector; x_vector=x_vector - lambda*H*d;//変数べクトル再設定 if(i==0) { // 初期値 gamma = 1; } else { gamma =x_vector*x_vector/(x_save_vector*x_save_vector); } d = x_vector + gamma*d;//探索方向再設定 }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

おはようございます. 私の読解能力が無いのかも知れませんが…良く分からなくなってます. 論点を整理しますと,私は非線型関数F(x)の最小化に共役勾配法を直接適用するつもりで回答しています. これは,質問者様の最初の補足がそうなっているからです. > Newton法は使用せず、共役勾配法のみで解こうとしています。 Hessianを使わない「普通の」共役勾配法では, F(x)を直接相手にするわけですから, ある探索方向dが決まったとして,その方向に沿った切断面が二次関数になるとは限りません. また,dに沿った切断面の評価関数の微分を計算したり(最小値候補が解析的に計算できます), 値を調べるのに計算コストがかかる場合があります (そもそも共役勾配法はこうした大規模問題に適用するものです). ですから,最低3点の値を評価して評価関数の切断面を二次関数であるものとし, その最小値の予測を反復する必要が生じるわけです. 参考文献[2]にも「評価関数(f(x))が二次関数の時」,「厳密直線探索」すれば… と書いてあります. これは二次の評価関数 x^T*A*x の場合に, ある探索方向dに関する評価関数 (x+αd)^T*A*(x+αd) をαで微分して零として最小値を与えるαを解析的に計算すれば, 厳密直線探索ができるという流れです. 非線型関数のHessianを使うとはどこにも書いてないですよね? ですが,質問者様は ・Hessianを利用する ・αは解析的に決める ことにこだわっています. ここから推測される状況はNewton法の更新方程式 H*d = -g と等価な 二次の最小化問題 d^T*H*d/2 + g'*d を解こうとしているとしか思えません(gは勾配). この場合はHessianが正定値になりさえすれば,αを解析的に求めて良いでしょう. 「二次近似した」評価関数の切断面が二次関数になると分かっているからです(つまり微分して零の点が唯一の最小値). Newton法のHessianが極端に疎だったり大規模だったりする場合に, H*d = -gの求解に共役勾配法のような反復解法を用いることは考えられます. この場合,Newton法の内部で利用される共役勾配法が収束して初めて元の問題の解を更新することになります. 共役勾配法の評価関数はd^T*H*d/2 + g'*dであり(ここでHとgは定数として扱う), 元の問題のものではありません. 色々と書きましたが,文献を読むなら,いきなり「参考にして」ではなく, まずは「書いてあるままに」実装することをおすすめします. 何らかの改良を加えたい様子ですが, 「自分が何をしているか明解に説明できない」ものは「改良」とは言いません. うまく動作しないならなおさらです. 「回答する」といいながら非常に申し訳ないのですが, 一度閉じることを検討した方がいいのではないかと思います.

konboi_bon
質問者

お礼

おはようございます。 >非線型関数のHessianを使うとはどこにも書いてないですよね? 確かに正定値対象行列Aと書いてあるけど、Hesse行列とは 書いてないですね…。 私自身の理解が足りないと思うので、 参考書をゆっくり読んで、もう一回考え直してきます。 何回も丁寧な回答ありがとうございました。

その他の回答 (2)

回答No.2

こんにちは. いくつかの誤解があるように思います. >共役勾配法のみで 共役勾配法のみで計算を行うなら24回云々は忘れてください. その代わり勾配ベクタを反復ごとに再計算してください. また,ステップ幅αと共役方向生成βに混同(?)が見られます. 質問者様のβはおそらくFletcher-Reeves公式であると思われますが, αは私は見たことがありません. 無論私が見たことが無いから間違いだなどとは言いませんが, このαは普通は直線探索で決定するものです. 一方,質問者様のαはdkに対してH-共役な方向を生成するように読めます. 再度指摘しますが,普通の共役勾配法ではHessianは用いません. 用いるものがあってもそれはβの計算で,それも毎回は更新しないというものだったと思います. また,定期的な再出発(リスタート)が必要です. これは何回かごとにβ=0として探索方向を勾配方向にとりなおすものです. >目的関数の値が増大する 直線探索をする以外に解決案はないと思われます. 共役勾配法は「勾配を基準としつつも前の数回とは違う方向を向く(共役方向と言います)」 ことを指針とします. ここで,「どちらに進むか」を決めるのがβ,「どれだけ進むのか」を決めるのがαです. そして勾配(=局所的に最も減る方向)とはβだけ違う方向を向くというのが微妙で, 要するに目的関数が減少することを保証できません. なので,その方向の最小値を計算するために, 「どれだけ進むのか」を毎回計算で求めます. これがαに関する一次元最小化問題 min F(xk+α) です(直線探索). これは種々の方法がありますが,簡単にやるなら二次内挿でいいでしょう. 大雑把に言って以下のものです. (1)F(xk) > F(xk+0.5α) かつ F(xk+0.5α) < F(xk+α)のαを見つける (2)上記の範囲の最小値を与えるαを確定 これはF(xk),F(xk+0.5α) ,F(xk+α)を通る下に凸の二次関数を計算しながら, その最小値を予測するものです. 詳しく聞きたい場合は再び補足してください.

konboi_bon
質問者

補足

こんばんわ。 丁寧な回答ありがとうございます。 βの決め方はFletcher-Reevesの公式から決めています。 αですが、私が参考にしている本[1]の共役方向法の所に書いてあったので それを参考にきめました。 ネット上では[2]の共役方向法の部分と同じように決めました。 ひょっとしたら私は共役方向法を使っているのかもしれません。 最適化は独学なので勘違いが多い可能性は高いです。 直線探索について 二次内挿というのは2次補間法のことですよね? 今プログラムを直し直しシミュレーションをしているのですが 一応最初よりましになってきました。 [1]非線形計画法 著者:今野浩,山下浩 [2]http://www.az.cs.is.nagoya-u.ac.jp/jsiam/tutorial-shape-opt-4.pdf

回答No.1

こんばんは. コードはあまり読んでませんが… 気になる点があるので補足をお願いします. まず何よりも「どうも上手くいきません」の内容を補足してください. また,Hessianまで考えているということは非線型関数の最適化という意味での共役勾配法と思われますが, ・探索方向に勾配(最急降下方向)を計算する部分が無い ・直線探索関数が無い の2点が気になります. それとも,最適化の本命はNewton法で, その更新方程式 H*d = -g を解くために線型共役勾配法を適用しよう, ということでしょうか. 普通の非線型共役勾配法はHessianを陽に計算しないからです(一部例外もありますが). とりあえず,後者を仮定します. この場合,10回以内に H*d = -g の解が収束することを期待していることになりますが, 変数の次元を考えるとこれは無理である気がします. Hessianが正定値だとして,厳密な直線探索を行えば 24回以内の探索で収束が保証されますが, Hessianの固有値の分布によっては非常に収束が遅くなりますし,直線探索無しではかなり厳しいでしょう.

konboi_bon
質問者

補足

回答ありがとうございます。 「どうも上手くいきません」というのは、目的関数の値 が増大していくことです. やろうとしていることは非線形関数の最適化です。 ・探索方向に勾配(最急降下方向)を計算する部分が無い ・直線探索関数が無い の二点ですが、私の不勉強でした。 今、参考書をよんでいるのですが、上の二つについて 確かに書いてありました。 さらに直線探索の回数についても記述してありました。 だからソースコードは間違ってます。すいません… Newton法は使用せず、共役勾配法のみで解こうとしています。 直線探索関数については、まだあまりわかっていません。 とりあえず次のように探索していこうと考えています。 Δf(x_k):勾配ベクトル, Q:Hesse行列 ステップ幅:α_k=-{Δf(x_k).d_k}/{(d_k)^T.Q.d_k} 探索方向での探索:x_k+1 = x_k + α_k .d_k 探索を24回以上行い,探索方向を再決定 探索方向は次のように求めようとしています。 β_k+1={Δf(x_k+1).Δf(x_k+1)}/{Δf(x_k).Δf(x_k)} d_k+1 = -Δf(x_k+1) + β_k+1.d_k

関連するQ&A

  • 下の関数の勾配ベクトルとヘッセ行列の求め方を教えて下さい!

    下の関数の勾配ベクトルとヘッセ行列の求め方を教えて下さい! 勾配ベクトルとヘッセ行列の求め方は大体わかっていると思うのですが、微分の仕方があやふやな為よくわかりません(;_;) よろしくお願いします!

  • 不完全LU分解前処理つき双共役勾配法についておしえてください。

    連立方程式を解くために不完全LU分解前処理つき双共役勾配法 について勉強しています。 前処理の際に、行列Aを不完全LU分解しその逆行列(LU)^(-1)というのを使用します。LU分解まではできたのですが、この逆行列は普通にLU分解+直接法という形でもとめるのでしょうか。だとしたら、直接法をつかっていてあまり高速化が期待できない様な気がしました。 不完全コレスキー分解つき共役勾配法(ICCG)のときは、不完全コレスキー分解後、間接的にAの逆行列をもとめて使用する方法がありましたのでなにかいい方法があるのかと思い質問しました。 はじめてのプログラミングで見当違いなことをいっているかもしれませんがよろしくおねがいします。

  • ラプラス方程式の解法(情報処理として)と共役勾配法

    情報処理の数学はカテゴリ違いかもしれませんが、適当なところを見出せませんでしたので。 (以下、長文で申し訳ありません。) ラプラス方程式やポアソン方程式の境界値問題を解く方法にSOR法が あります。これは連立一次方程式の反復解法の1つだとも言えると思い ます。連立一次方程式の解法は通常AX=BとなってマトリックスAと既知 ベクトルBに対して未知ベクトルXを解くわけですが、ラプラス方程式 をSOR法で解く場合、AX=Bという形にはしません(そういう風に表現 はできますが)。例えば2次元を考えると100×100の2次元の領域を解く 場合、未知数は10000個です。これをAX=Bという風に考えたら、10000元 連立一次方程式を解くことになり、A(10000,10000)のようにメモリ確保 も大変ですが、実際にはそのように解きませんね。マトリックスAとい うメモリの取り方をしないのです。 100×100の格子領域でSOR法で解くとプログラムステップとしては数十 行ぐらいとなり、大したことはありませんね。 しかし、情報処理の連立一次方程式の解法の本を見ると、それはあくま でも連立1次方程式があった場合ということを前提としているのでその ようなメモリの確保から解説がスタートするようです。 そこで質問ですが、ラプラスやポアソン方程式を(前処理付)共役勾配 法などで解く場合、メモリ確保の前提条件としては連立一次方程式の形 ではないはずです。本を見るとマトリックス解法としての共役勾配法が 出ていますが、ラプラス方程式、ポアソン方程式の特化して解説してい る本などないでしょうか。また、簡単に説明できるのであれば教えて頂 きたいのですが。

  • 勾配ベクトルについて

    勾配ベクトルと方向微分についての問題です。(2変数の場合) 平面状の点(x0、y0)と直線ax+by=cの距離dは d=|ax0+by0-c|/√a^2+b^2  ・・・★  となる事を示す。 直線ax+by=cを平面z=ax+byの等高線(高さc)と考えるとき、 (x0、y0)を通り、ax+by=cに平行な直線は ax+by=(1) であるので、2つの等高線 ax+by=cと ax+by=(1)との高さの差(正の値)は(2)となる。 2変数関数 ax+byの勾配ベクトルの大きさ(3)は(4)を表すから、点(x0、y0)と直線ax+by=cの距離をdとすれば、 (3)=(6)/(5)となる。 これにより★が成り立つ。 (4)には言葉が、それ以外は数式が入るようです。 どなたか、よろしくお願いします!!

  • 準ニュートン法の直線探索と収束性

     プログラムとして直線探索を実装した準ニュートン法を作成しました。 これについて、2次関数で試行すると、ヘッセ行列の逆は理論値の[0.5 0; 0 0.5]に収束することが確認できました。  他方で、直線探索を外し、一定値の間隔で進む?ようにしますと、逆行列の理論値から外れた値に収束することが見受けられました(探索点は2次関数の最小値に収束します)。 これは、プログラムミスなのか、準ニュートン法で直線探索をしないことによる帰結なのか、どちらなのでしょうか?また、後者であれば、その理由は数学的に明らかにされているのでしょうか?

  • 4階層型ニューラルネットワークで学習(準ニュートン法)

    準ニュートン法の学習方法の中に出てくるヘッセ行列の逆行列の近似行列Hについてなんですが、よく最適化についての本に更新式が載っているのを見るのですけど、(DFP法やBFGS法)アルゴリズムの中に探索方向の計算についてあるんですが、4層のニューラルネットに準ニュートン法を導入すると、それぞれ入力層-中間層1と中間層1-中間層2と中間層2-出力層の3つの所でそれぞれ重みwや微分式∇f(w)の更新を行うと思うのですが、このときにHをそれぞれの層間で探索方向を用いて次のHを更新するみたいですが、このHはよく初期値として単位行列を設定しているようなのですが、これはそれぞれの層のユニット数を同じにする必要とかあるのでしょうか?例えば中間1-2層のユニット数は10個とか

  • 臨界点でHessianが0の時の極値の判定

    微分可能な実多変数関数の臨界点(全ての1回導関数が0になる点)でHessianが0でないときはHesse行列の固有値によってこの点が極値かどうかの判定ができることはよく知られていますが、Hessianが0になるときの判定法を書いてある本は少ないようです。私が考えた結果、次の結論に至りました。 (1)Hesse行列の0以外の固有値に符号が異なるものがあるときはこの点は極値ではない。なぜならば固有値が正の固有ベクトルの方向に関しては極小点となっており、固有値が負の固有ベクトルの方向に関しては極大点となっているから。 (2)Hesse行列の0以外の固有値がすべて同符号で固有値0の空間が1次元であるときは、固有値0の固有ベクトルの方向に関して極値になっているかを調べれば良い。これは1変数関数の極値の判定に帰着するので容易。 (3)Hesse行列の固有値0の独立な固有ベクトルが2個以上のときは、各固有ベクトルの方向に関して調べてもこの点が極値であるかどうかの判定はできない。 そこで、やっと質問ですが、(3)の場合は極値の判定はどの様にしたら良いのでしょうか。

  • 共役複素数

    a、b、c、dは実数の定数である 方程式x^4+ax^2+bx^2+cx+d=0は4つの虚数解を持つ その解の内、ある2つの和は19+2iであり、他の2つの積は4+5iである このときa、b、c、dの値を求めよ 2つの解α、βを、 α=p+qi、β=r+si とおくと、その共役複素数 ¬α=p-qi、¬β=r-si も解で、 x^4+ax^2+bx^2+cx+d=(x-α)(x-β)(x-¬α)(x-¬β)と表せられる ここでα+β=19+2iとすると、 (x-α)(x-β)=x^2-(19-2i)x+(4+5i) (x-¬α)(x-¬β)=x^2-(19+2i)x+(4-5i) であり、x^4+ax^2+bx^2+cx+d=(x-α)(x-β)(x-¬α)(x-¬β)と表せることから、この右辺の積がx^4+ax^2+bx^2+cx+dと同じになる というところまで様々な方のおかげでたどり着いたのですが、右辺をかけると、-38x^3が出たりx^2の係数に虚数があったりとx^4+ax^2+bx^2+cx+dに合わなくなってしまったんです どうすればいいでしょうか?教えてください

  • 全微分や勾配ベクトルの幾何学的な意味

    数学があんまり得意じゃないのに、今ライブラリを使って3Dのプログラミングで遊んでるんですけど 数学として、行列とか三角関数とか普通の微分とかは、座標系の回転だとか微分でキャラクタの進行方向の決定とか、直接使うのですんなりイメージできるんですけど 具体的な例で言うと全微分や勾配ベクトルってどういう場面でつかうんですか?教えてください、イメージできなくて困ってます。偏微分はあるパラメタにおけるニ変数関数の断面という理解は出来るんですが・・・

  • 多変数関数の局所近似の問題です

    【問題文】 滑らかなp変数関数 f(x)=f(x1,...,xp) のグラフ z=f(x) を、点 x=a の近傍で、 (p+1)次元ユークリッド空間の2次曲面 L:z=q(x) で近似することを考える。 ただし、q(x) は p変数2次関数である。 いま、y=x-a なる変数変換を行って、Lを表す y に関する方程式 z=r(y) を求めるとする。 このときの、r(y) の (1)2次の項(斉2次項) (2)1次項  (3)定数項 はどのように表すことができるか。 ただし、関数 f(x) の傾斜(勾配)ベクトルを g(x)=grad f(x) で、ヘッセ行列を H(x) で 表すものとする。 (1)、(2)、(3) ご教授お願いします。