梯度下降
BGD
def batchGradientDescent(x, y, theta, alpha, m, maxInteration):
'''批梯度下降算法简单实现
x: 输入
y: 输出
theta: w 和 b 组成的向量
alpha: 学习率
m: 批数据数量
maxInteration:最大迭代次数
'''
x_train = x.transpose() # 转置
for i in range(0, maxInteration):
# 预测值
hypothesis = np.dot(x, theta)
# 预测误差
error = hypothesis - y
# 下降梯度
gradient = np.dot(x_train, error) / m
# 更新theta
theta = theta - alpha * gradient
return theta
SGD(Stochastic gradient descent)
def stochasticGradientDescent(x, y, theta, alpha, maxInteration):
'''批梯度下降算法简单实现
x: 输入
y: 输出
theta: w 和 b 组成的向量
alpha: 学习率
m: 批数据数量
maxInteration:最大迭代次数
'''
data = []
for i in range(4):
data.append(i)
for i in range(0, maxInteration):
hypothesis = np.dot(x, theta)
# 预测误差
error = hypothesis - y
# 选取一个随机数
index = random.sample(data, 1) # 从列表data中随机选取一个数据
index1 = index[0]
# 下降梯度
gradient = error[index1] * x[index1]
# 求导之后得到theta
theta = theta - alpha * gradient
return theta
MBGD
def miniBatchGradientDescent(x, y, theta, alpha, m, batch_size, epochs):
'''
x: 输入
y: 输出
theta: w 和 b 组成的向量
alpha: 学习率
m: 数据集的数据量
batch_size:一个批次的数据量
epochs:数据集最大迭代次数
'''
for epoch in range(epochs):
# 生成索引列表
indexs_list = np.arange(m)
# 按批次迭代
for batch in range(m // batch_size):
# 生成批次数据索引
index_list = indexs_list[batch*batch_size : batch*batch_size+batch_size]
# 获取批次数据
x_batch = x[index_list]
y_batch = y[index_list]
# 预测值
hypothesis = np.dot(x_batch, theta)
# 预测误差
error = hypothesis - y_batch
# 下降梯度
gradient = np.dot(x_batch.T, error) / m
# 更新theta
theta = theta - alpha * gradient
return theta
MSGD
def mini_batch_stochastic_gradient_descent(x, y, theta, alpha, m, batch_size, epochs):
'''
x: 输入
y: 输出
theta: w 和 b 组成的向量
alpha: 学习率
m: 数据集的数据量
batch_size:一个批次的数据量
epochs:数据集最大迭代次数
'''
for epoch in range(epochs):
# 生成索引列表
data_index = np.arange(m)
# 打乱样本顺序
np.random.shuffle(data_index)
# 按批次迭代
for batch in range(m // batch_size):
# 生成批次数据索引
batch_index = data_index[batch*batch_size : batch*batch_size+batch_size]
# 获取批次数据
x_batch = x[batch_index]
y_batch = y[batch_index]
# 预测值
hypothesis = np.dot(x_batch, theta)
# 预测误差
error = hypothesis - y_batch
# 下降梯度
gradient = np.dot(x_batch.T, error) / m
# 更新theta
theta = theta - alpha * gradient
return theta
Momentum
def momentum(x_start, step, g, discount = 0.7):
'''
x_start: 是优化的起始点,即优化算法的初始参数
step: 是学习率,用于控制参数更新的步长
g: 是一个函数,用于计算参数 x 处的梯度
discount: 是动量的衰减因子,默认值为 0.7
'''
x = np.array(x_start, dtype='float64')
# 创建一个与参数 x 具有相同形状的零数组,用于存储上一步的 梯度信息
pre_grad = np.zeros_like(x)
for i in range(50):
grad = g(x)
pre_grad = pre_grad * discount + grad * step
x -= pre_grad
print '[ Epoch {0} ] grad = {1}, x = {2}'.format(i, grad, x)
if abs(sum(grad)) < 1e-6:
break;
return x
Nesterov
def nesterov(x_start, step, g, discount = 0.7):
'''
x_start: 是优化的起始点,即优化算法的初始参数
step: 是学习率,用于控制参数更新的步长
g: 是一个函数,用于计算参数 x 处的梯度
discount: 是 Nesterov 加速梯度下降中的动量衰减因子,默认值 为 0.7
'''
x = np.array(x_start, dtype='float64')
pre_grad = np.zeros_like(x)
for i in range(50):
# 预测未来的参数位置,利用当前参数 x 和动量信息来计 算。
x_future = x - step * discount * pre_grad
# 计算预测位置处的梯度
grad = g(x_future)
# 更新动量信息,结合上一步的动量信息和当前的梯度信息。
pre_grad = pre_grad * 0.7 + grad
x -= pre_grad * step
print '[ Epoch {0} ] grad = {1}, x = {2}'.format(i, grad, x)
if abs(sum(grad)) < 1e-6:
break;
return x
nesterov([150,75], 0.012, g)