制約なしの最適化 - 最急降下アルゴリズムと Matlab の実装

0 まえがき

  最近忙しすぎて更新が少し遅くなってしまいました。この記事では、一般的に使用されるアルゴリズム、つまり数値解析で言及される最急降下法について更新します。この記事では、最初に勾配の概念を確認し、次に最急降下法について説明し、最後に例を通じてアルゴリズムを理解し、コード作成を実装します。

この記事を読んで何か得るものがあれば幸いです。
次の記事: Matlab のセルフコンパイルされたヤコビ行列 (jacobi) 関数と公式のヤコビ行列 (ヤコビ行列) 関数の比較と革新

今回は、事前にいくつかの matlab 関数を使用する必要があります

Matlab バージョン: 2020a、2022a、(2022.6.5本人Matlab版本更新到了2022a)
字幕は matlab2022b バージョンでは使用できず、直接suptitleに変更されます。sgtitle

  1. ハンドル関数(function_handle)の使用1 ——f=@(变量名) 函数表达式
  2. matlabFunction 2の使用
  3. ノルム関数ノルム
  4. 3次元描画:メッシュ、等高線:等高線、グリッド生成:メッシュグリッド
  5. 各フレーム画像の取得:getframe、更新:drawnow、一時停止遅延:pause(これらは理解として使用できます)

1 数学の知識

  この最急降下法を理解するには、ある程度の数学的知識が必要なので、最初に数学的知識を復習しましょう。

必看:学生が数学の知識を十分に理解していない場合は、最初のセクションの内容をすべて正直に読むことをお勧めします。そうしないと、後で公式の導出で混乱することになります。

1.1 勾配の概念

この概念詳細な説明は参考文献3にあります。勾配の概念は次のとおりです。

  梯度:はベクトルであり、この点での関数の方向導関数がこの方向に沿って最大値を取得することを示します。(1) サイズの場合: 変化率が最大になります (勾配の係数); (2) 方向の場合: この点で関数はこの方向 (勾配の方向) に沿って最も速く変化します4

  定義: z = f ( x , y ) z = f(x,y)とします。z=f ( x ,y )P 0 ( x 0 , y 0 ) P_0(x_0,y_0)P0( ×0y0)偏導関数fx ' ( x 0 , y 0 ) f'_x(x_0,y_0) がfバツ( ×0y0)fy ' ( x 0 , y 0 ) f'_y(x_0,y_0)fy( ×0y0) , 则称向量{ fx ' ( x 0 , y 0 ) , fy ' ( x 0 , y 0 ) } \{f'_x(x_0,y_0) ,f'_y(x_0,y_0)\}{ fバツ( ×0y0fy( ×0y0)}であるf ( x , y ) f(x,y)f ( x ,y )P 0 ( x 0 , y 0 ) P_0(x_0,y_0)P0( ×0y0)として表され、 ∇ f ∣ P 0 、 ∇ z ∣ P 0 、 gradf ⁡ ∣ P 0 または gradz ⁡ ∣ P 0 \left.\nabla f\right|_{P_{0}},\left.\ nabla z \right|_{P_{0}},\left.\operatorname{gradf}\right|_{P_{0}} \text { or}\left.\operatorname{gradz}\right|_{P_ {0 }}f P0∇z∣ _ _P0卒業生P0 また グラーツP0
∴ ∇ f ∣ P 0 = gradf ⁡ ∣ P 0 = { fx ′ ( x 0 , y 0 ) , fy ′ ( x 0 , y 0 ) } \therefore \left.\nabla f\right|_{P_{0 }}=\left.\operatorname{gradf}\right|_{P_{0}}=\{f'_x(x_0,y_0) ,f'_y(x_0,y_0)\}f P0=卒業生P0={ fバツ( ×0y0fy( ×0y0)}

ここで∇ \nabla (ナブラ)算子: ∇ = ∂ ∂ xi + ∂ ∂ yj \nabla = \frac{\partial}{\partial x}i + \frac{\partial}{\partial y}j=×+∂y _j

1.2 勾配関数

  定義: f ( x , y ) f(x,y)の場合f ( x ,y ) DD_Dのどこにでも偏導関数があるため、 ∇ f = { fx ' ( x , y ) , fy ' ( x , y ) } \nbla f= \{f'_x(x,y) ,f'_y(x, y)\}∇f _={ fバツ( x ,y ) fy( x ,y )}であるf ( x , y ) f(x,y)f ( x ,y ) D の勾配関数

(1) 定義: ∣ ∇ f ∣ = [ fx ' ( x , y ) ] 2 + [ fy ' ( x , y ) ] 2 |\nabla f|=\sqrt{\left[f_{x}^ {\素数}(x, y)\right]^{2}+\left[f_{y}^{\素数}(x,y)\right]^{2}}∣∇ f =[ fバツ( x ,y ) ]2+[ fy( x ,y ) ]2
(2) 勾配の方向:

  设v = { v 1 , v 2 } ( ∣ v ∣ = 1 ) v=\{v_1,v_2\} (|v|=1)v={ v1v2} ( v =1 ) が任意の方向である場合、∇ f \nbla ffvvvθ \thetaθ有: ∂ f ∂ v ∣ P 0 = fx ' ( x 0 , y 0 ) v 1 + fy ' ( x 0 , y 0 ) v 2 = { fx ' ( x 0 , y 0 ) , fy ' ( x 0 , y 0 ) } ∙ { v 1 , v 2 } = ∇ f ∣ P 0 ∙ v = ∣ ∇ f ∣ P 0 ∣ ⋅ ∣ v ∣ cos ⁡ θ \begin{aligned} \left.\frac{\partial f}{\partial v}\right|_{P_{0}} &=f_{x}^{\prime}\left(x_{0}, y_{0}\right) v_{1}+f_{ y}^{\prime}\left(x_{0}, y_{0}\right) v_{2} \\ &=\left\{f_{x}^{\prime}\left(x_{0} , y_{0}\right), f_{y}^{\prime}\left(x_{0}, y_{0}\right)\right\} \bullet\left\{v_{1}, v_{ 2}\right\} \\ &=\left.\nabla f\right|_{P_{0}} \bullet v=|\nabla f|_{P_{0}}|\cdot |v| \cos \theta \end{整列}∂v _∂f _ P0=fバツ( ×0y0)v1+fy( ×0y0)v2={ fバツ( ×0y0)fy( ×0y0) }{ v1v2}=f P0v=∣∇ f P0v コス
∣ v ∣ = 1 |v|=1なのでv =1したがって、上の式は次のようになります。∂ f ∂ v ∣ P 0 = ∣ ∇ f ∣ P 0 ∣ cos ⁡ θ \frac{\partial f}{\partial v}|_{P_{0}} =|\nabla f | _{P_{0}}|\cos \theta∂v _∂f _P0=∣∇ f P0コス

補足知識(高校内容): 既知の 2 つのベクトルv 1 → = ( a , b ) , v 2 → = ( c , d ) \overrightarrow{v_1} =(a,b),\overrightarrow{v_2 } =( c, d)v1 =( _b v2 =( c d )、次に 2 つのベクトルの内積:v 1 v 2 = ac + bd = ∣ v 1 → ∣ ∣ v 2 → ∣ cos ⁡ θ v_1v_2=ac+bd=|\overrightarrow{v_1}||\overrightarrow{ v_2 }|\cos\θv1v2=ac _+b d=v1 ∣∣v2 コスθ、ただし:cos ⁡ θ = ac + bd ∣ v 1 → ∣ ∣ v 2 → ∣ \cos\theta=\frac{ac+bd}{|\overrightarrow{v_1}||\overrightarrow{v_2}|}コス=v1 ∣∣v2 a c + b d

∴ \したがってP 0 P_0P0vvの方向vと勾配の方向∇ f ∣ P 0 \nabla f|_{P_{0}}f P0角度は0 0最大値は0で得られます。これは、関数の値が勾配方向に沿って最も速く変化することを証明します。また、この式は、勾配の5が、指定された点で関数が最も速く上昇する方向であることを証明します。勾配の反対方向は当然、関数が最も減少する方向です。高速方向6:

  • P 0 P_0の場合P0勾配方向に沿って歩き続けると関数値が増加します
  • θ = 180 ° \theta = 180° =180°は勾配の逆方向に歩くことを意味し、関数値は減少します
  • 勾配方向に垂直な場合、関数値は変化しません。つまり、等高線です。

以上三个总结之后会用到, そして最急降下法のアルゴリズム説明が始まります。

1.3 ヘッセ行列

  グラデーションの効果は、その変化を表すベクトル場を与えることです。したがって、勾配と微分はむしろファミリーのようなものだと思います。二次近似に移ります: Q ( x ) = f ( x 0 ) + f ' ( x 0 ) ( x − x 0 ) + 1 2 f ' ' ( x 0 ) ( x − x 0 ) 2 Q(x )=f\left(x_{0}\right)+f^{\prime}\left(x_{0}\right)\left(x-x_{0}\right)+\frac{1}{2 } f^{\prime \prime}\left(x_{0}\right)\left(x-x_{0}\right)^{2}Q ( × )=f( ×0)+f( ×0)( ×バツ0)+21f「」( ×0)( ×バツ0)2これを多変量関数に拡張したい場合は、前の部分を除いて同様の状況になるはずだと考えます。L ( x , y ) = a + b ( x 0 , y 0 ) + c ( x 0 , y 0 ) L(x,y)=a+b(x_0,y_0)+c(x_0,y_0)L ( x ,y =ある+b ( ×0y0)+c ( x0y0)の場合、二次部分を追加します: d ( x − x 0 ) 2 + e ( x − x 0 ) ( y − y 0 ) + f ( y − y 0 ) 2 d(x-x_0 )^2 +e(x-x_0)(y-y_0)+f(y-y_0)^2d ( xバツ0)2+そして( xバツ0) ( yy0)+f ( yy0)2
Q ( x , y ) = f ( x 0 , y 0 ) + fx ( x 0 , y 0 ) ( x − x 0 ) + fy ( x 0 , y 0 ) ( y − y 0 ) + 1 2 fxx ( x 0 , y 0 ) ( x − x 0 ) 2 + fxy ( x − x 0 ) ( y − y 0 ) + 1 2 fyy ( x 0 , y 0 ) ( y − y 0 ) 2 \begin{array }{c} Q(x, y)=f\left(x_{0}, y_{0}\right)+f_{x}\left(x_{0}, y_{0}\right)\left( x-x_{0}\right)+f_{y}\left(x_{0}, y_{0}\right)\left(y-y_{0}\right) \\ +\frac{1}{ 2} f_{xx}\left(x_{0}, y_{0}\right)\left(x-x_{0}\right)^{2}+f_{xy}\left(x-x_{0 }\right)\left(y-y_{0}\right)+\frac{1}{2} f_{yy}\left(x_{0}, y_{0}\right)\left(y-y_ {0}\right)^{2} \end{配列}Q ( x ,y =f( ×0y0)+f×( ×0y0)( ×バツ0)+fはい( ×0y0)( yy0)+21fxx( ×0y0)( ×バツ0)2+f( ×バツ0)( yy0)+21fやあ( ×0y0)( yy0)2
類推または計算を通じて、上記の 2 次近似の結果を得ることができます。次に、二次近似のベクトル形式を導出することができます。Q ( x ) = f ( x 0 ) + ∇ f ( x 0 ) ⋅ ( x − x 0 ) + 1 2 ( x − x 0 ) TH ( x 0 ) ( x − x 0 ) Q(\mathbf{x})=f\left(\mathbf{x}_{0}\right)+\nabla f\left(\mathbf{x}_{\mathbf {0} }\right) \cdot\left(\mathbf{x}-\mathbf{x}_{\mathbf{0}}\right)+\frac{1}{2}\left(\mathbf{x }-\ mathbf{x}_{0}\right)^{T} H\left(\mathbf{x}_{0}\right)\left(\mathbf{x}-\mathbf{x}_{ 0}\右)Q ( × )=f( ×0)+∇f _( ×0)( ×バツ0)+21( ×バツ0)TH( ×0)( ×バツ0)
ここで、HHHはヘッセ行列 : ∇ ( ∇ f ) = H = [ ∂ f ∂ x 2 ∂ f ∂ x ∂ y ∂ f ∂ y ∂ x ∂ f ∂ y 2 ] \nabla (\nabla f)=H=\left[ \begin{array}{cc} \frac{\partial f}{\partial x^{2}} & \frac{\partial f}{\partial x \partial y} \\ \frac{\partial f}{ \partial y \partial x} & \frac{\partial f}{\partial y^{2}} \end{array}\right]( f )=H=[×2∂f _y x∂f _x y∂f _∂y _2∂f _]
もちろん、より高い次元まで推論することもできます:H = [ ∂ 2 f ∂ x 1 2 ∂ 2 f ∂ x 1 ∂ x 2 ⋯ ∂ 2 f ∂ x 1 ∂ xn ∂ 2 f ∂ x 2 ∂ x 1 ∂ 2 f ∂ x 2 2 ⋯ ∂ 2 f ∂ x 2 ∂ xn ⋮ ⋮ ⋱ ⋮ ∂ 2 f ∂ xn ∂ x 1 ∂ 2 f ∂ xn ∂ x 2 ⋯ ∂ 2 f ∂ xn 2 ] \mathbf{H}=\ left[\begin{array}{cccc} \frac{\partial^{2} f}{\partial x_{1}^{2}} & \frac{\partial^{2} f}{\partial x_{ 1} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{\partial x_{1} \partial x_{n}} \\ \frac{\partial^{2} f }{\partial x_{2} \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{2}^{2}} & \cdots & \frac{\partial^{ 2} f}{\partial x_{2} \partial x_{n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial^{2} f}{\partial x_{n } \partial x_{1}} & \frac{\partial^{2} f}{\partial x_{n} \partial x_{2}} & \cdots & \frac{\partial^{2} f}{ \部分 x_{n}^{2}} \end{配列}\right]H= ×122f _×2×12f _××12f _×1×22f _×222f _××22f _×1×2f _×2×2f _×n22f _ ヘッセ行列は対称行列でなければなりません

2 最急降下法

  上記の勾配の知識を復習することで、このアルゴリズムをもう一度見ても迷うことはなくなるでしょう。最速の勾配降下法: 解く問題は制約のない最適化問題であり、いわゆる制約のない最適化問題は、次の最小値を見つけるなど、制約なしで目的関数を解くことです: minf ( x ) min f (バツ)最小f ( x )

ここで、関数f : R n → R f:R^n \to Rf:RnR .

このような問題の解決は、最適条件法と反復法という 2 つのカテゴリに分類できます。

2.1 コンセプト7

最急降下法 (最急降下法) は、勾配降下法をより具体的に実装したもので、各反復で適切なステップ サイズ α k \alpha_kを選択するという考え方です。ある、目的関数の値を最小にすることができます。

各反復では、勾配の逆方向に沿って、常に a x ( k + 1 ) = xk − α k ⋅ ∇ f ( x ( k ) ) x^{(k+1)} = x^k - を見つけることができます\ alpha_k \cdot \nabla f(x^{(k)})バツ( k + 1 )=バツkあるf ( x( k ) )、この方向ではf ( x ( k + 1 ) ) f(x^{(k+1)})f ( x( k + 1 ) )がデフォルトの場合、α ( k ) = argmin ⁡ f ( xk − α ⋅ ∇ f ( x ( k ) ) ) \alpha_{(k)}=\operatorname{argmin}f\left ( x^{k}-\alpha \cdot \nabla f\left(x^{(k)}\right)\right)ある( k )=アルグミンf( ×kある∇f _( ×( k ) )_

次に投稿できる興味深い点は、最急降下法の各更新の軌跡が前の軌跡に対して垂直であることです (証明プロセスは 2.3 で説明します)。

2.2 アルゴリズムステップ7

最急降下法の計算手順は次のとおりです。

ステップ 1: 初期点x 0 x^0を選択します。バツ0、終了エラーが与えられた場合ε > 0 \varepsilon >0e>0k = 0 k=0k=0

ステップ 2: ∇ f ( xk ) \nbla f(x^k)を計算します。f ( xk )∣ ∣ ∇ f ( xk ) ∣ ∣ ≤ ε ||\nabla f(x^k)||とします\le \バレプシロン∣∣∇ f ( xk )∣∣ε、反復を停止、出力xkx^kバツkそれ以外の場合は、3 番目のステップに進みます。

ステップ 3: pk = − ∇ f ( xk ) p^k = -\nabla f(x^k) を計算します。pk=f ( xk )

ステップ 4: 1 次元検索を実行してλ k \lambda_kを見つけます。, ( xk + λ kpk ) = min ⁡ λ ≥ 0 f ( xk + λ pk ) f\left(x^{k}+\lambda_{k} p^{k}\right)=\min _{ の定義\lambda \geq 0} f\left(x^{k}+\lambda p^{k}\right)f( ×k+pk )=λ 0f( ×k+p_ _k )k, k=k+1, \text{turnステップ2}バツk + 1=バツk+pkk=k+1 ステップ 2 に進みます

2.3 原理の詳細説明8

   任x = x ( k ) + λ p ( k ) x=x^{(k)}+\lambda p^{(k)}バツ=バツ( k )+p_ _( k ) x( k ) x^{(k)}バツ点( k )で 1 次テイラー展開を実行します。f ( x ) = f ( x ( k ) + λ p ( k ) ) = f ( x ( k ) ) + λ ∇ f ( x ( k ) ) T p ( k ) + O ( ∣ ∣ λ p ( k ) ∣ ∣ ) f(x)=f(x^{(k)}+\lambda p^{(k)}) = f(x^{(k) }) +\lambda \nabla f(x^{(k)})^{T} p^{(k)}+O(||\lambda p^{(k)}||)f ( x )=f ( x( k )+p_ _( k ) _=f ( x( k ) _+λ f ( x( k ) _Tp _( k )+O ( ∣∣ λ p( k ) ∣∣)を除く( ∣ ∣ λ p ( k ) ∣ ∣ ) = O ( ∣ ∣ λ ∣ ∣ ) O(||\lambda p^{(k)}||)=O(||\ラムダ||)O ( ∣∣ λ p( k ) ∣∣)=O ( ∣∣ λ ∣∣ )はλ \lambdaの比ですλ高次無限小、および∣ ∣ p ( k ) ∣ ∣ = 1 ||p^{(k)}||=1∣∣ p( k ) ∣∣=1 .

( x ( k + 1 ) ) − f ( x ( k ) ) ≈ λ ∇ f ( x ( k ) ) T p ( k ) f(x^{(k+1)})-f(x の^ {(k)}) \about \lambda \nabla f(x^{(k)})^{T} p^{(k)}f ( x( k + 1 ) )f ( x( k ) _λ f ( x( k ) _Tp _( k )
∇ f ( x ( k ) ) T p ( k ) = ∣ ∣ ∇ f ( x ( k ) ) ∣ ∣ ⋅ ∣ ∣ p ( k ) ∣ ∣ cos ⁡ θ = ∣ ∣ ∇ f ( x ( k ) ) ) ∣ ∣ ⋅ cos ⁡ θ \equation f(x^{(k)})^{T} p^{(k)}=||\equation f(x^{(k)})||\ cdot ||p^{(k)}|| \cos \theta=||\write f(x^{(k)})||\cdot\cos \thetaf ( x( k ) _Tp _( k )=∣∣∇ f ( x( k ) )∣∣∣∣ p( k ) ∣∣コス=∣∣∇ f ( x( k ) )∣∣コス

探索方向 p ( k ) p^{(k)}p( k ) : 最初のセクションでは、 θ = 180 ° \theta = 180°を取ると説明されています。=180°の勾配が負の方向になる理由。∴ \したがって p ( k ) = − ∇ f ( x ( k ) ) p^{(k)}=-\nabla f(x^{(k)})p( k )=f ( x( k ) _

勾配ベクトルの大きさを求めます。∣ ∣ ∇ f ( x ( k ) ) T ∣ ∣ ||\nabla f(x^{(k)})^{T}||∣∣∇ f ( x( k ) _T ∣∣

  • 次に、f ( x ( k ) ) T ∣ ∣ < ε ||\nabla f(x^{(k)})^{T}|| < \バレプシロン∣∣∇ f ( x( k ) _T ∣∣<ε、計算を停止、出力x ( k ) x^{(k)}バツ( k )を最小点近似として使用します。
  • 次に、f ( x ( k ) ) T ∣ ∣ > ε ||\nabla f(x^{(k)})^{T}|| > \バレプシロン∣∣∇ f ( x( k ) _T ∣∣>ε、次のステップに進みます

この部分は多くの説明で詳しく説明されておらず、実際、勾配ベクトル ∣ ∣ ∇ f ( x ( k ) ) T ∣ ∣ < ε ||\の法長を証明するだけでよい理由がよくわかりませんでした。ナブラ f(x^{(k)})^{T}|| < \varepsilon∣∣∇ f ( x( k ) _T ∣∣<εでいいでしょう。

証明:実際、式 ( ∣ ∣ p ( k ) ∣ ∣ = 1 ||p^{(k)}||=1 は
  組み合わせることができます。∣∣ p( k ) ∣∣=1 ):f ( x ( k + 1 ) ) − f ( x ( k ) ) ≈ λ ∇ f ( x ( k ) ) T p ( k ) = ∣ ∣ ∇ f ( x ( k ) ) ∣ ∣ ⋅ cos ⁡ θ f(x^{(k+1)})-f(x^{(k)}) \about \lambda \nabla f(x^{(k)})^{T} p^{(k )}=||\nabble f(x^{(k)})||\cdot\cos\thetaf ( x( k + 1 ) )f ( x( k ) _λ f ( x( k ) _Tp _( k )=∣∣∇ f ( x( k ) )∣∣コスθ、ここでf ( x ( k + 1 ) ) f(x^{(k+1)})f ( x( k + 1 ) )は次の最適化値f ( x ( k ) ) f(x^{(k)}) をf ( x( k ) )は現在の反復値を表します:
左边式子的含义:現在値と将来値の差はますます小さくなり、変化の速度がますます遅くなることを意味します。速度が遅くなったとしても、それは意味するものではありません。最適な最小点が近づいています。
右边式子含义:左の 2 つの式の差は、最終的に勾配のサイズ∣ ∣ ∇ f ( x ( k ) ) ∣ ∣ ||\nabla f(x^{(k)})|| に∣∣∇ f ( x( k ) )∣∣×cos ⁡ θ \cos \thetaコスθ、誰もがcos ⁡ θ ∈ [ 0 , 1 ] \cos \theta \in [0,1] をコス[ 0 ,1 ]∴ \したがって∣ ∣ ∇ f ( x ( k ) ) T ∣ ∣ < ε ||\nabla f(x^{(k)})^{T}|| < \バレプシロン∣∣∇ f ( x( k ) _T ∣∣<ε のときは、求めている値が近似的に最小値とみなせることを意味しており、x ( k ) x^{(k)}バツ( k )は最小点です。

最適なステップ サイズλ k \lambda_k

f ( x ) f(x)  とします。f ( x )には 2 次の連続偏導関数があり、それをx ( k ) x^{(k)}バツ( k )点作二阶泰勒展开:f ( x ( k ) − λ ∇ f ( x ( k ) ) ) = f ( x ( k ) ) + ∇ f ( x ( k ) ) T ( − λ ∇ f ( x ( k ) ) ) + 1 2 ( − λ ∇ f ( x ( k ) ) ) TH ( x ( k ) ) ( − λ ∇ f ( x ( k ) ) ) + O ( ∥ λ ∇ f ( x ( k ) ∥ 2 ) \begin{aligned} f\left(x^{(k)}-\lambda \nabla f\left(x^{(k)}\right)\right) &=f\left( x^{(k)}\right)+\nabla f\left(x^{(k)}\right)^{T}\left(-\lambda \nabla f\left(x^{(k)} \right)\right) \\ &+\frac{1}{2}\left(-\lambda \nabla f\left(x^{(k)}\right)\right)^{T} H\left (x^{(k)}\right)\left(-\lambda \nabla f\left(x^{(k)}\right)\right) \\ &+O\left(\| \lambda \nabla f\left(x^{(k)} \|^{2}\right)\right. \end{aligned}f( ×( k )λ f( ×( k ) )_=f( ×( k ) _+∇f _( ×( k ) _T(λ f( ×( k ) )_+21(λ f( ×( k ) )_TH( ×( k ) _(λ f( ×( k ) )_+(λ f( ×( k )2 )
上式の主要部分をH ( λ ) H(\lambda)と表します。H ( λ ) H ( λ ) = f ( x ( k ) ) + ∇ f ( x ( k ) ) T ( − λ ∇ f ( x ( k ) ) ) + 1 2 ( − λ ∇ f ( x ( k ) ) ) ) TH ( x ( k ) ) ( − λ ∇ f ( x ( k ) ) ) H(\lambda)= f\left(x^{(k)}\right)+\nabla f\left(x ^{(k)}\right)^{T}\left(-\lambda \nabla f\left(x^{(k)}\right)\right)+\frac{1}{2}\left( -\lambda \nabla f\left(x^{(k)}\right)\right)^{T} H\left(x^{(k)}\right)\left(-\lambda \nabla f\ left(x^{(k)}\right)\right)H ( l )=f( ×( k ) _+∇f _( ×( k ) _T(λ f( ×( k ) )_+21(λ f( ×( k ) )_TH( ×( k ) _(λ f( ×( k ) ))
関数H ( λ ) H(\lambda)H ( λ )の唯一の極点H ' ( λ ) = 0 H'(\lambda)=0 とH' (λ)=0 の場合、 λ \lambdaを見つけることができます。λ)=: λ k = ∇ f ( x ( k ) ) T ∇ f ( x ( k ) ) ∇ f ( x ( k ) ) TH ( x ( k ) ) ∇ f ( x ( k ) ) \lambda_{ k}=\frac{\nabla f\left(x^{(k)}\right)^{T} \nabla f\left(x^{(k)}\right)}{\nabla f\left( x^{(k)}\right)^{T} H\left(x^{(k)}\right) \nabla f\left(x^{(k)}\right)}=∇f _( ×( k ) _TH( ×( k ) _∇f _( ×( k ) _∇f _( ×( k ) _T∇f _( ×( k ) )
ここでH ( x ( k ) ) H(x^{(k)})H ( ×セクション 1 で述べた( k ) ) はヘッセ行列です

ここで、上記の垂直関係を証明するには、次のように証明します。

x ( k + 1 ) = x ( k ) + λ pkx^{(k+1)}=x^{(k)}+\lambda p^{k}バツ( k + 1 )=バツ( k )+p_ _kを関数f ( x ) f(x)f ( x )では、f ' ( x ) = 0 f'(x)=0f( × )_=0方程式: f ' ( x ( k + 1 ) ) = f ' ( x ( k ) + λ pk ) = ∇ f ( x ( k ) + λ pk ) T p ( k ) = 0 f'(x^ {(k+1)})=f'(x^{(k)}+\lambda p^{k})=\f(x^{(k)}+\lambda p^{k}) にすることもできます^ {T}p^{(k)}=0f' (x( k + 1 ) )=f' (x( k )+p_ _k )=f ( x( k )+p_ _k )Tp _( k )=0
p(k) = − ∇ f(x(k)) p^{(k)}=-\nabla f(x^{(k)})p( k )=f ( x( k ) )微分:− ∇ f ( x ( k ) + λ pk ) T ∇ f ( x ( k ) ) = − ∇ f ( x ( k + 1 ) ) T ∇ f ( x ( k ) ) . = 0 -\equation f(x^{(k)}+\lambda p^{k})^{T}\equation f(x^{(k)})=-\equation f(x^{(k) . +1)})^{T}\方程式 f(x^{(k)})=0f ( x( k )+p_ _k )Tf(x( k ) _=f ( x( k + 1 ) )Tf(x( k ) _=0
これは、前の点と次の点の間の勾配が垂直であることを証明するものではありません

ステップサイズλ \lambdaについて話しましょう図 1 に示すように、1 つの変数の二次関数を例として、大きいラムダまたは小さいラムダを選択した場合の影響を示します (この図は matlab で描画しました。コードは最後に拡大されます)。 図 1 \ text{
ここに画像の説明を挿入
Figure 1} 1は、この図から、最適なステップ サイズがλ op \lambda_{op}
であることがわかります。ああ_,input ∈ ( 0 , λ op ) ∪ ( λ op , 2 λ op ) \lambda \in(0,\lambda_{op}) \cup (\lambda_{op},2\lambda_{op})( 0 ,ああ_)( lああ_2ああ_反復回数が多いと、収束速度が非常に遅くなります。興味深いことに、λ = 2 λ op \lambda =2\lambda _{op}=2ああ_時々反復せず、等高線上で直接前後に反復してください。λ ∈ ( 2 λ op , ∞ ) \lambda \in(2\lambda_{op},\infty)のとき( 2ああ_)を最小点から遠ざけて逆に繰り返します。

2.4 欠点7

特定の点の負の勾配方向は、通常、この点付近での最急降下の特性のみを持ちます。

最急降下法では、目的関数の一次勾配を使用して降下して解くため、鋸歯状現象が発生しやすくなります (下図を参照)。最初の数ステップでは、目的関数は急速に減少しますが、その後、目的関数が減少します。が最小点に近いため、長時間にわたって収束速度は理想的ではありません。特に、適切な目的関数の等高線が比較的平らな楕円である場合、収束はさらに遅くなります。
ここに画像の説明を挿入
したがって、実際には最急降下法と他の方法を組み合わせて使用​​することが多く、初期段階では最急降下法を使用し、極小点に近づく場合には収束の速い他の方法を使用することができます

3 例

  この例では、この記事の例9を使用していますが、彼の例が使用されています。私のコードは彼のコードとは完全に異なります。興味があれば、この人のコードも見てみてください。さて、くだらない話はやめて、次のトピックについて話しましょう: minf ( x ) = x 1 2 + 2 x 2 2 − 2 x 1 x 2 − 2 x 2 min f(x) = x_1^{2}+2x_2^2 -2x_1x_2- 2x_2最小f ( x )=バツ12+2倍_222倍_1バツ22倍_2其中 x = ( x 1 , x 2 ) T x=(x_1,x_2)^T バツ=( ×1バツ2)Tx 0 = ( 0 , 0 ) T x^{0}=(0,0)^Tバツ0=( 0 ,0 )

(1) 勾配関数∇ f ( x ) = ( 2 x 1 − 2 x 2 4 x 2 − 2 x 1 − 2 ) \nabla f(x)=\begin{pmatrix} 2x_1-2x_2\\ 4x_2- を求めます。 2x_1 -2\end{pマトリックス}f ( x )=(2倍_12倍_24x _22倍_12)ヘッセ関数H ( x ) = ∇ ( ∇ f ( x ) ) = ( 2 − 2 − 2 4 ) H(x)=\exponent(\exponent f(x))=\begin{pmatrix} 2&-2\ \-2&4\end{p行列}H ( × )=( f ( x ))=(2 224)

(2) x ( 0 ) = ( 0 , 0 ) T x^{(0)}=(0,0)^T と置きます。バツ( 0 )=( 0 ,0 )上記の式 (1) にTを代入すると、 ∇ f ( x ( 0 ) ) = ( 0 − 2 ) \nabla f(x^{(0)})=\begin{pmatrix} 0\\ -2\ が得られます。終了{ピマトリックス}f ( x( 0 ) )=(0 2)、つまりp ( 0 ) = − ∇ f ( x ( 0 ) ) = ( 0 2 ) p^{(0)}=-\nabla f(x^{(0)})=\begin{pmatrix} 0 \\ 2\end{p行列}p( 0 )=f ( x( 0 ) )=(02)

(3) H ( x ( 0 ) ) = ( 2 − 2 − 2 4 ) H(x^{(0)})=\begin{pmatrix} 2&-2\\ -2&4\end{pmatrix}H ( ×( 0 ) )=(2 224)∇ f ( x ( 0 ) ) \nabla f(x^{(0)})f ( x( 0 ) )代入λ k = ∇ f ( x ( k ) ) T ∇ f ( x ( k ) ) ∇ f ( x ( k ) ) TH ( x ( k ) ) ∇ f ( x ( k ) ) \lambda_ {k}=\frac{\nabla f\left(x^{(k)}\right)^{T} \nabla f\left(x^{(k)}\right)}{\nabla f\left (x^{(k)}\right)^{T} H\left(x^{(k)}\right) \nabla f\left(x^{(k)}\right)}=∇f _( ×( k ) _TH( ×( k ) _∇f _( ×( k ) _∇f _( ×( k ) _T∇f _( ×( k ) )
得到 λ = ( 0 − 2 ) ( 0 − 2 ) ( 0 − 2 ) ( 2 − 2 − 2 4 ) ( 0 − 2 ) = 1 4 \lambda=\frac{\begin{pmatrix} 0& -2\end{pmatrix} \begin{pmatrix} 0\\ -2\end{pmatrix}}{\begin{pmatrix} 0& -2\end{pmatrix}\begin{pmatrix} 2&-2\\ -2&4\end{pmatrix} \begin{pmatrix} 0\\ -2\end{pmatrix}}=\frac{1}{4} λ=(02)(2224)(02)(02)(02)=41
(4) x ( 1 ) = x ( 0 ) + λ p ( 0 ) = ( 0 1 2 ) x^{(1)}=x^{(0)}+\lambda p^{(0)}=\begin{pmatrix} 0\\ \frac{1}{2}\end{pmatrix} x(1)=x(0)+λp(0)=(021)

同理转回(2)可以一直迭代回去一直到满足条件为止,得到最优解为 x ∗ = ( 1 , 1 ) T , y ∗ = − 1 x^*=(1,1)^T,y^*=-1 x=( 1 1 )Ty=1

4 コードの実装

  上記のメソッド手順によれば、実際には、コードを記述するときに必要なモジュールはほんの数個だけです。 (1) find ∇ f ( x ) \nabla f(x)f ( x )関数、(2) ヘッセ行列H ( x ) H(x)H ( x )モジュール; (3) 前の 2 つの関数を組み合わせて最速降下法を見つける関数を構築; (4) 視覚化のために、 GIF を生成する動的最急降下法の描画関数を追加しました。

声明

  • 構築: df=nabla_f(fun,x)、∇ f ( x ) \nabla f(x)を見つけます。f ( x )の関数
  • 構築: H=Hesse(df,x,x0,n)、ヘッセ行列H ( x ) H(x)を求めます。H ( x )のモジュール
  • 構築: [x0,i] = GD(f,x,x0,epsilon)、最急降下法の関数
  • 構築: GDplot(f,x0,i,x1,x2,GIFname)、最急降下描画関数
  • 私のコードは、最小点を見つけるために勾配降下を実行するバイナリn 回関数に適しています。( (2022.5.30)现已经解决了限制,可以实现n元n次函数,GDplot()画图函数只能绘制三维图)

注意: 次のいくつかの簡単なコードには、最初にいくつかの関数が必要であることを全員に思い出させるアプリケーションが含まれます。

結果を最初に置きます:
ここに画像の説明を挿入
生成された GIF 画像:
ここに画像の説明を挿入

4.1 ∇ f ( x ) \nf(x)f ( x )関数モジュールのコード実装

この関数には 2 つの入力があります: (1) fun: 関数式を示します。これは通常、MATLAB ではハンドル関数の形式で表現されます。ハンドル関数の書き方は記事の冒頭に書いてありますが、知らない学生は最初の参考文献を読んでください。(2) x: 変数文字列を示します。ここでは通常x 1 、 x 2 x_1、x_2です。バツ1バツ2、例も以下に示します。
出力: df: はハンドル関数です

コードは以下のように表示されます。

function df=nabla_f(fun,x)
%  ∇f 求梯度
    df=[];
    x=str2sym(x);
    for i=1:length(x)
        df1 = diff(fun,x(i));
        df=[df;df1];
    end
    df= matlabFunction(df);
end

たとえば、次のコードを入力して実行すると、dfハンドル関数を取得できます。

f=@(x1,x2) x1.^2+2*x2.^2-2*x1.*x2-2*x2;
x ='[x1,x2]';
df=nabla_f(f,x)

出力:
ここに画像の説明を挿入

4.2 ヘッセ行列H ( x ) H(x)H ( x )のモジュール コード実装

この関数に4 つの入力があります: (1) df: ∇ f ∇fとして表されます。f、関数 nabla_f の結果。(2)x: 変数文字列を示します。ここでは通常x 1 、 x 2 x_1、x_2バツ1バツ2(3) x0: 初期値x ( 0 ) x^{(0)}を示します。バツ( 0 )(4)n: 現在の反復回数を示します。
出力:df: はハンドル関数です

コードは以下のように表示されます。

function H = Hesse(df,x,x0,n)
%  Hesse矩阵 H(x)=(∇f) 
%  df 为 ∇f,即为函数nabla_f的结果 ∇f
    H=[];
    x=str2sym(x);
    for i=1:length(x)
        df1 = diff(df,x(i));
        H=[H,df1];
    end
%     H = matlabFunction(H);
    s=char(H);
    if find(s=='x')
        H = matlabFunction(H);
        H = H(x0{
    
    n}(1),x0{
    
    n}(2));
    else
        H = double(H);
    end
end

4.3 最急降下法機能モジュールのコード実装

入力: (1) f: 上記で定義したハンドル関数の場合 例: f= @(x1,x2) 2*x1.^2+2*x2.^2+2*x1.*x2+x1-x2。(2) x: 変数文字列を表すには、通常x 1 、 x 2 x_1、x_2となります。バツ1バツ2.(3) x0: 開始点を示しますx ( 0 ) x^{(0)}バツ( 0 )。(4)ε 歌うεε精度

コードは以下のように表示されます。

function [x0,i] = GD(f,x,x0,epsilon)
% 梯度下降法 也可以称:最速下降法
% input:f 为上面定义的句柄函数 例如:f= @(x1,x2) 2*x1.^2+2*x2.^2+2*x1.*x2+x1-x2;
%        x 为表示变量字符串,这里一般是 x1,x2
%        x0 表示起始点
%        epsilon 为ε精度
% output:x0 为GD函数出来的从起始点x0寻优到极小值点的所有点集合
%        i 为GD函数寻优过程得到点的个数即:i==length(x0)
%        可以打印出最小值 min{
    
    f},以及极小值值点 x
%

    i=1;
    df = nabla_f(f,x);
    H = Hesse(df,x,x0,i);
    dfx=df(x0{
    
    1}(1),x0{
    
    1}(2));
   
    er=norm(dfx);
    while er > epsilon                
            p = -dfx;
            lambda = dfx'*dfx/(dfx'*H*dfx);
            i=i+1;
            x0{
    
    i} = x0{
    
    i-1}+lambda*p;
            dfx = df(x0{
    
    i}(1),x0{
    
    i}(2));
            H = Hesse(df,x,x0,i);
            er = norm(dfx);     
    end
    fmin = f(x0{
    
    i}(1),x0{
    
    i}(2));
    disp('极小值点:');
    disp(['x1 = ',num2str(x0{
    
    i}(1))]);
    disp(['x2 = ',num2str(x0{
    
    i}(2))]);
    fprintf('\nf最小值:\n min{f}=%f\n',fmin);
end

※4.4 最急降下法描画機能モジュールのコード実装

この関数コードに興味のある学生は見てください。説明はせずにコードを載せておきます。一番の理由は、長時間書くのは疲れるので、怠けるのはもったいないです!

创新点:1. グラフのタイトルは f の式に従って自動的に生成されるため、グラフのタイトルを手動で描画したり、任意のffを入力したりする必要はありません。f は任意のffを実装できますfの図のタイトルは、これがすべて、ハンドル関数形式 (function_handle) からT ex Texへの変換を実現する f2t() 関数の記述のおかげであることを示しています。T e x形式の文字列

更新2022-11-6suptitleをsgtitleに変更し、f2s関数をアップロードしました

コードは以下のように表示されます。

function GDplot(f,x0,i,x1,x2,GIFname)
% input:f 为上面定义的句柄函数 例如:f= @(x1,x2) 2*x1.^2+2*x2.^2+2*x1.*x2+x1-x2;
%        x0 为GD函数出来的从起始点x0寻优到极小值点的所有点集合
%        i 为GD函数寻优过程得到点的个数即:i==length(x0)
%        x1 为f函数中第一个变量的取值范围
%        x2 为f函数中第二个变量的取值范围
% 
% output:生成一个gif

        [x1,x2]=meshgrid(x1,x2);
        z=f(x1,x2);
        figure('color','w')
        sgtitle(['\it f=',f2s(f)])
        subplot(211) 
        mesh(x1,x2,z)
        axis off
        view([-35,45])
        hold on
        subplot(212)
        contour(x1,x2,z,20)
        zlim([0,0.5])
        set(gca,'ZTick',[],'zcolor','w')
        axis off
        view([-35,45])
        hold on

        pic_num = 1;

        for j =1:i-1    
            a=[x0{
    
    j}(1),x0{
    
    j}(2),f(x0{
    
    j}(1),x0{
    
    j}(2))];
            b=[x0{
    
    j+1}(1),x0{
    
    j+1}(2),f(x0{
    
    j+1}(1),x0{
    
    j+1}(2))];
            c=[a',b'];
            a1=[x0{
    
    j}(1),x0{
    
    j}(2)];
            b1=[x0{
    
    j+1}(1),x0{
    
    j+1}(2)];
            c1=[a1',b1'];
    
            subplot(211)
            plot3(x0{
    
    j}(1),x0{
    
    j}(2),f(x0{
    
    j}(1),x0{
    
    j}(2)),'r.','MarkerSize',10)
            subplot(212)
            plot(x0{
    
    j}(1),x0{
    
    j}(2),'r.','MarkerSize',10)
            drawnow
            F(j)=getframe(gcf);
            pause(0.5)

            subplot(211)
            plot3(c(1,:),c(2,:),c(3,:),'r--')    
            subplot(212)
            plot(c1(1,:),c1(2,:),'r--')
            drawnow 
            F(2*j)=getframe(gcf);
            pause(0.5)
            
            % 绘制并保存gif
            I=frame2im(F(j));
            [I,map]=rgb2ind(I,256);
            I1=frame2im(F(2*j));
            [I1,map1]=rgb2ind(I1,256);
            if pic_num == 1
                imwrite(I,map, GIFname ,'gif', 'Loopcount',inf,'DelayTime',0.5);
            else
                imwrite(I,map, GIFname ,'gif','WriteMode','append','DelayTime',0.5);
                imwrite(I1,map1, GIFname ,'gif','WriteMode','append','DelayTime',0.5);
            end
            pic_num = pic_num + 1;
        end
        subplot(211)
        plot3(x0{
    
    i}(1),x0{
    
    i}(2),f(x0{
    
    i}(1),x0{
    
    i}(2)),'r.','MarkerSize',9)
        subplot(212)
        plot(x0{
    
    i}(1),x0{
    
    i}(2),'r.','MarkerSize',9)
        F(2*i-1)=getframe(gcf);
        I=frame2im(F(2*i-1));
        [I,map]=rgb2ind(I,256);
        imwrite(I,map, GIFname ,'gif','WriteMode','append','DelayTime',0.5);
end

function s = f2s(fun)
% 句柄函数的转换为字符串 
% 主要是用来画图title用的,可自动将句柄函数转为字符串函数
% 在绘制画图时可以自动生成函数表达式 title(并且以Latex形式显示出来),避免手动敲击函数公式
    s = func2str(fun);
    s = char(s);
    c = strfind(s,')');
    s(1:c(1))=[];
    c1 = strfind(s,'.');
    s(c1)=[];
    c2 = strfind(s,'*');
    s(c2)=[];
    c3 = strfind(s,'x');
    for  i = 1:length(c3)
       s = insertAfter(s,c3(i)+i-1,'_'); 
    end   
end

4.5 主な機能

コードは以下のように表示されます。

clc
clear all
close all
% f= @(x1,x2) 2*x1.^2+2*x2.^2+2*x1.*x2+x1-x2;
f= @(x1,x2) x1.^2+2*x2.^2-2*x1.*x2-2*x2;      % 句柄函数表达式
% f= @(x1,x2) (x1-1).^2+(x2-1).^2;
% f=@(x1,x2) x1.^4+3*x1.^2*x2-x2.^4;
x0{
    
    1}=[0;0];
x ='[x1,x2]';      % 函数变量字符串
epsilon=0.001;     % ε为误差精度
[x0,i] = GD(f,x,x0,epsilon);
x1=0:0.01:2;
x2=x1;
GIFname = 'f1.gif';
GDplot(f,x0,i,x1,x2,GIFname)

4.6 上の図 1 のコード

図 1 コード直接ダウンロード ファイルのリンク:ここをクリックしてコード ファイルをダウンロードします

4.7 完全なコードファイル

Xiaobai の学生の場合は、この完全なコード (この記事のコードと図 1 のコードを含む) をダウンロードできます。
コードは個人用 GitHub に配置されています: https://github.com/cug-auto -zp/CSDN/tree/ main/gradient が
GitHub リーダーにアクセスできない場合は、リソースのダウンロード リンクもあります:リソース リンク

5 まとめ

この記事を書いてくれたブロガーには今でも感謝したいし、個人的にも彼らの記事を読んで得たものはたくさんあると感じています。コードを提供することは誰もが学ぶのに便利である一方で、Matlab には私が知らない機能がたくさんあることも、大手の記事や公開コードを通じて知りました。 MATLAB については、実際のところ、意図的に学ぶ必要はなく、常に観察して蓄積していく過程で、MATLAB についての知識を広げています。したがって、私は個人的に、このオープンソース コードのアイデアを継続することを強く主張します。

6 参考文献の引用


  1. ハンドル機能 ↩︎

  2. Matlab 公式ドキュメント - matlabFunction: https://ww2.mathworks.cn/help/symbolic/matlabfunction.html ↩︎

  3. 方向導関数と勾配: https://blog.csdn.net/myarrow/article/details/51332421 ↩︎

  4. グラデーションとは正確には何ですか? 物理的および数学的意味は何ですか? : https://www.zhihu.com/question/29151564 ↩︎

  5. グラデーション、発散、カール: https://zhuanlan.zhihu.com/p/97545154 ↩︎

  6. 第8回講義 勾配降下法:https://zhuanlan.zhihu.com/p/335191534 ↩︎

  7. 制約なしの最適化問題 - 最急降下法: https://zhuanlan.zhihu.com/p/445223282 ↩︎ ↩︎ ↩︎

  8. 最急降下法 (上): https://www.bilibili.com/video/BV1RK4y1a75C/
    最急降下法 (下):
    https://www.bilibili.com/video/BV1ey4y1k7jY/?spm_id_from=333.788.recommend_more_video.- 1 ↩︎

  9. 最適化アルゴリズム - 最急降下法: https://blog.csdn.net/m0_37570854/article/details/88559619 ↩︎

おすすめ

転載: blog.csdn.net/cugautozp/article/details/124895678