优化算法——牛顿法(Newton Method)
生活随笔
收集整理的這篇文章主要介紹了
优化算法——牛顿法(Newton Method)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
大家好,又見面了,我是你們的朋友風君子。
一、牛頓法概述
除了前面說的梯度下降法,牛頓法也是機器學習中用的比較多的一種優化算法。牛頓法的基本思想是利用迭代點
處的一階導數(梯度)和二階導數(Hessen矩陣)對目標函數進行二次函數近似,然后把二次模型的極小點作為新的迭代點,并不斷重復這一過程,直至求得滿足精度的近似極小值。牛頓法的速度相當快,而且能高度逼近最優值。牛頓法分為基本的牛頓法和全局牛頓法。
二、基本牛頓法
1、基本牛頓法的原理
基本牛頓法是一種是用導數的算法,它每一步的迭代方向都是沿著當前點函數值下降的方向。 我們主要集中討論在一維的情形,對于一個需要求解的優化函數
,求函數的極值的問題可以轉化為求導函數
。對函數
進行泰勒展開到二階,得到 對上式求導并令其為0,則為 即得到 這就是牛頓法的更新公式。
2、基本牛頓法的流程
- 給定終止誤差值,初始點,令;
- 計算,若,則停止,輸出;
- 計算,并求解線性方程組得解:;
- 令,,并轉2。
三、全局牛頓法
牛頓法最突出的優點是收斂速度快,具有局部二階收斂性,但是,基本牛頓法初始點需要足夠“靠近”極小點,否則,有可能導致算法不收斂。這樣就引入了全局牛頓法。
1、全局牛頓法的流程
- 給定終止誤差值,,,初始點,令;
- 計算,若,則停止,輸出;
- 計算,并求解線性方程組得解:;
- 記是不滿足下列不等式的最小非負整數:;
- 令,,,并轉2。
2、Armijo搜索
全局牛頓法是基于Armijo的搜索,滿足Armijo準則: 給定
,
,令步長因子
,其中
是滿足下列不等式的最小非負整數:
四、算法實現
實驗部分使用Java實現,需要優化的函數
,最小值為
。
1、基本牛頓法Java實現
package org.algorithm.newtonmethod;
/**
* Newton法
*
* @author dell
*
*/
public class NewtonMethod {
private double originalX;// 初始點
private double e;// 誤差閾值
private double maxCycle;// 最大循環次數
/**
* 構造方法
*
* @param originalX初始值
* @param e誤差閾值
* @param maxCycle最大循環次數
*/
public NewtonMethod(double originalX, double e, double maxCycle) {
this.setOriginalX(originalX);
this.setE(e);
this.setMaxCycle(maxCycle);
}
// 一系列get和set方法
public double getOriginalX() {
return originalX;
}
public void setOriginalX(double originalX) {
this.originalX = originalX;
}
public double getE() {
return e;
}
public void setE(double e) {
this.e = e;
}
public double getMaxCycle() {
return maxCycle;
}
public void setMaxCycle(double maxCycle) {
this.maxCycle = maxCycle;
}
/**
* 原始函數
*
* @param x變量
* @return 原始函數的值
*/
public double getOriginal(double x) {
return x * x - 3 * x + 2;
}
/**
* 一次導函數
*
* @param x變量
* @return 一次導函數的值
*/
public double getOneDerivative(double x) {
return 2 * x - 3;
}
/**
* 二次導函數
*
* @param x變量
* @return 二次導函數的值
*/
public double getTwoDerivative(double x) {
return 2;
}
/**
* 利用牛頓法求解
*
* @return
*/
public double getNewtonMin() {
double x = this.getOriginalX();
double y = 0;
double k = 1;
// 更新公式
while (k <= this.getMaxCycle()) {
y = this.getOriginal(x);
double one = this.getOneDerivative(x);
if (Math.abs(one) <= e) {
break;
}
double two = this.getTwoDerivative(x);
x = x - one / two;
k++;
}
return y;
}
}
2、全局牛頓法Java實現
package org.algorithm.newtonmethod;
/**
* 全局牛頓法
*
* @author dell
*
*/
public class GlobalNewtonMethod {
private double originalX;
private double delta;
private double sigma;
private double e;
private double maxCycle;
public GlobalNewtonMethod(double originalX, double delta, double sigma,
double e, double maxCycle) {
this.setOriginalX(originalX);
this.setDelta(delta);
this.setSigma(sigma);
this.setE(e);
this.setMaxCycle(maxCycle);
}
public double getOriginalX() {
return originalX;
}
public void setOriginalX(double originalX) {
this.originalX = originalX;
}
public double getDelta() {
return delta;
}
public void setDelta(double delta) {
this.delta = delta;
}
public double getSigma() {
return sigma;
}
public void setSigma(double sigma) {
this.sigma = sigma;
}
public double getE() {
return e;
}
public void setE(double e) {
this.e = e;
}
public double getMaxCycle() {
return maxCycle;
}
public void setMaxCycle(double maxCycle) {
this.maxCycle = maxCycle;
}
/**
* 原始函數
*
* @param x變量
* @return 原始函數的值
*/
public double getOriginal(double x) {
return x * x - 3 * x + 2;
}
/**
* 一次導函數
*
* @param x變量
* @return 一次導函數的值
*/
public double getOneDerivative(double x) {
return 2 * x - 3;
}
/**
* 二次導函數
*
* @param x變量
* @return 二次導函數的值
*/
public double getTwoDerivative(double x) {
return 2;
}
/**
* 利用牛頓法求解
*
* @return
*/
public double getGlobalNewtonMin() {
double x = this.getOriginalX();
double y = 0;
double k = 1;
// 更新公式
while (k <= this.getMaxCycle()) {
y = this.getOriginal(x);
double one = this.getOneDerivative(x);
if (Math.abs(one) <= e) {
break;
}
double two = this.getTwoDerivative(x);
double dk = -one / two;// 搜索的方向
double m = 0;
double mk = 0;
while (m < 20) {
double left = this.getOriginal(x + Math.pow(this.getDelta(), m)
* dk);
double right = this.getOriginal(x) + this.getSigma()
* Math.pow(this.getDelta(), m)
* this.getOneDerivative(x) * dk;
if (left <= right) {
mk = m;
break;
}
m++;
}
x = x + Math.pow(this.getDelta(), mk)*dk;
k++;
}
return y;
}
}
3、主函數
package org.algorithm.newtonmethod;
/**
* 測試函數
* @author dell
*
*/
public class TestNewton {
public static void main(String args[]) {
NewtonMethod newton = new NewtonMethod(0, 0.00001, 100);
System.out.println("基本牛頓法求解:" + newton.getNewtonMin());
GlobalNewtonMethod gNewton = new GlobalNewtonMethod(0, 0.55, 0.4,
0.00001, 100);
System.out.println("全局牛頓法求解:" + gNewton.getGlobalNewtonMin());
}
}
總結
以上是生活随笔為你收集整理的优化算法——牛顿法(Newton Method)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 域名ICP备案个人备案写网站名称注意事项
- 下一篇: 特斯拉公布2022财报:2023预计交付