梯度下降法和牛顿法
机器学习问题可以分为两类:
- 给定data求model;
- 给定model求解
θ
θ
:
- SGD或BGD(沿一阶方向)
- Newton(沿二阶方向)
- BFGS(居于一、二阶方向之间)
- L-BFGS
通过一个例子来对比两种求参算法的区别。
问题:求解 a−−√ a
解法一:梯度下降法
令 a−−√=x a = x ,则 x2−a=0 x 2 − a = 0 。
令 f(x)=x2−a f ( x ) = x 2 − a , F(x)=∫+∞−∞f(x)dx F ( x ) = ∫ − ∞ + ∞ f ( x ) d x 。
则问题转为求 F(x) F ( x ) 的极值。
根据梯度下降法的更新公式得:
xn+1=xn−λ×F′(x) x n + 1 = x n − λ × F ′ ( x )
即 xn+1=xn−λ×(xn2−a) x n + 1 = x n − λ × ( x n 2 − a )
解法二:牛顿法
f(x) f ( x ) 由泰勒展开,忽略高阶导数可得: f(x)≈f(x0)+f′(x0)×(x−x0)+f′(x0)2×(x−x0)2 f ( x ) ≈ f ( x 0 ) + f ′ ( x 0 ) × ( x − x 0 ) + f ′ ( x 0 ) 2 × ( x − x 0 ) 2 。
令 g(x)=f′(x) g ( x ) = f ′ ( x ) ,将上式两边同时对 x x 求导,可得: g(x)=f′(x0)+f′′(x0)×(x−x0) g ( x ) = f ′ ( x 0 ) + f ″ ( x 0 ) × ( x − x 0 ) 。
进一步可得: g(x)f′′(x0)=f′(x0)f′′(x0)+x−x0 g ( x ) f ″ ( x 0 ) = f ′ ( x 0 ) f ″ ( x 0 ) + x − x 0
即: x=x0−f′(x0)f′′(x0)+g(x)f′′(x0) x = x 0 − f ′ ( x 0 ) f ″ ( x 0 ) + g ( x ) f ″ ( x 0 )
当取得极值点时, g(x)=0 g ( x ) = 0 ,所以: x=x0−1f′′(x0)×f′(x0) x = x 0 − 1 f ″ ( x 0 ) × f ′ ( x 0 ) 。即牛顿法的更新公式。
- 如果将 1f′′(x0) 1 f ″ ( x 0 ) 改为 λ λ ,即 λ λ 随意取值,则退化为了随机梯度下降法。换句话说,如果随机梯度下降法的 λ λ 不是随意选的,而是选为了 1f′′(x0) 1 f ″ ( x 0 ) ,即为牛顿法。
- 带阻尼的牛顿法: x=x0−λ1f′′(x0)×f′(x0) x = x 0 − λ 1 f ″ ( x 0 ) × f ′ ( x 0 )
回到求解 a−−√ a 的问题中:
令 f(x)=x2−a f ( x ) = x 2 − a , F′(x)=f(x) F ′ ( x ) = f ( x ) ,则问题依然是转为求解 F(x) F ( x ) 的极值。根据牛顿法得到更新公式: x=x0−F′(x0)F′′(x0)=x0−x02−a2×x0=12×(x0+ax0) x = x 0 − F ′ ( x 0 ) F ″ ( x 0 ) = x 0 − x 0 2 − a 2 × x 0 = 1 2 × ( x 0 + a x 0 ) 。
求解代码如下:
import math
# 梯度下降法
a = 85
learning_rate = 0.01
x = 0
for i in range(1000):
x -= learning_rate * (x ** 2 - a)
print('{0}的平方根(近似)为: {1}, 真实值是: {2}, 误差为: {3}'.format(a, x, math.sqrt(a), x-math.sqrt(a)))
# 牛顿法
x = 1
for i in range(1000000):
x = (x + a/x) / 2
print('{0}的平方根(近似)为: {1}, 真实值是: {2}, 误差为: {3}'.format(a, x, math.sqrt(a), x-math.sqrt(a)))