文章目录
1,介绍
基本原理
梯度下降
不是一个机器学习的算法
是一个基于搜索的最优化方法
作用:最小化一个损失函数
梯度上升法:最大化一个效用函数
(不管在最低点哪一侧都会是,都会是下降的)
关于参数eta
并不是所有函数都有唯一的极值点
解决方法:
多次运行,随机化初始点
梯度下降法的初始值也是一个超参数
2,代码实现
会用到的库
import numpy as np
import matplotlib.pyplot as plt
原材料
首先建立一个简单的数据
# [-1,6]的等差数列,包含141个数值
plot_x = np.linspace(-1, 6, 141)
不同的算法会有不同的损失函数
# 损失函数
plot_y = (plot_x-2.5)**2-1
def J(theta):
return (theta-2.5)**2-1
大概长成这个样子
plt.plot(plot_x,plot_y)
plt.show()
损失函数求导
def dJ(theta):
return 2*(theta-2.5)
简单地梯度下降
eta:参数eta
epsilon:精度(不能保证刚好能取到最低点,所以当临近两次结果差值小于精度时停止)
theta_history:所有的损失值
theta:起始点
eta = 0.1
epsilon = 0.01
theta_history = [theta]
theta = 0.0
while True:
gradient = dJ(theta)
last_theat = theta #为了进行对比需要存储上一个损失值
theta = theta - eta*gradient
theta_history.append(theta)
if (abs(J(theta) - J(last_theat)) < epsilon):
break
print(theta)
print(J(theta))
plt.plot(plot_x,J(plot_x))
plt.scatter(np.array(theta_history),J(np.array(theta_history)),color='r',marker='+')
plt.show()
>>>2.499891109642585
>>>-0.99999998814289
下降了15次
len(theta_history)
>>>15
3,简单地封装一下
class Gradient_Descent:
def __init__(self, x, y):
self.theta_history = None
self.x = x
self.y = y
# 损失函数求导
def _dJ(theta):
return 2 * (theta - 2.5)
# 损失函数(根据不同算法是会变的)
def _J(theta):
return (theta - 2.5) ** 2 - 1
def gradinet_descent(self,initial_theta, eta, n_iters=100, epsilon=1e-8):
"""
:param initial_theta: 起始值
:param eta: 每次下降的步幅
:param n_iters: 最大下降次数,以防eta过大导致无限循环
:param epsilon: 精度
"""
theta = initial_theta
self.theta_history.append(initial_theta)
i_iters = 0
while i_iters < n_iters:
gradient = self._dJ(theta)
last_theat = theta
theta = theta - eta * gradient
self.theta_history.append(theta)
if abs(self._J(theta) - self._J(last_theat)) < epsilon:
break
i_iters += 1
def plot_theta_history(self):
"""
观察下降走势
:return:
"""
plt.plot(self.x, self._J(self.x))
plt.plot(np.array