本文用一个很简单的一元线性回归问题为例,实现了梯度下降(SGD), Momentum, Nesterov Accelerated Gradient, AdaGrad, RMSProp and Adam.
梯度下降
我们首先回顾一下梯度下降,以本系列第一篇文章《python机器学习手写算法系列——线性回归》为例。
目标函数:
y = f ( θ , x ) y=f(\theta,x) y=f(θ,x)
线性回归目标函数为:
y = a x + b + ε y=ax+b+ε y=ax+b+ε
y ^ = a x + b \hat{y}=ax+b y^=ax+b
损失函数为:
J ( θ ) J(\theta) J(θ)
线性回归损失函数为:
J ( a , b ) = 1 2 n ∑ i = 0 n ( y i − y ^ i ) 2 J(a,b)=\frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2 J(a,b)=2n1i=0∑n(yi−y^i)2
优化函数:
θ = θ − α ∂ J ∂ θ \theta = \theta - \alpha \frac{\partial J}{\partial \theta} θ=θ−α∂θ∂J
对于一元线性回归的优化函数:
a = a − α ∂ J ∂ a a = a - \alpha \frac{\partial J}{\partial a} a=a−α∂a∂J
b = b − α ∂ J ∂ b b = b - \alpha \frac{\partial J}{\partial b} b=b−α∂b∂J
这里 ∂ J ∂ a \frac{\partial J}{\partial a} ∂a∂J 和 ∂ J ∂ b \frac{\partial J}{\partial b} ∂b∂J 分别是:
∂ J ∂ a = 1 n ∑ i = 0 n x ( y ^ i − y i ) \frac{\partial J}{\partial a} = \frac{1}{n}\sum_{i=0}^{n}x(\hat{y}_i-y_i) ∂a∂J=n1i=0∑nx(y^i−yi)
∂ J ∂ b = 1 n ∑ i = 0 n ( y ^ i − y i ) \frac{\partial J}{\partial b} = \frac{1}{n}\sum_{i=0}^{n}(\hat{y}_i-y_i) ∂b∂J=n1i=0∑n(y^i−yi)
这里 y ^ \hat{y} y^是y的估计值, θ \theta θ是参数, J J J是损失函数, α \alpha α是学习率,下同。
这里用python实现的代码如下
def model(a, b, x):
return a*x + b
def cost_function(a, b, x, y):
n = 5
return 0.5/n * (np.square(y-a*x-b)).sum()
def sgd(a,b,x,y):
n = 5
alpha = 1e-1
y_hat = model(a,b,x)
da = (1.0/n) * ((y_hat-y)