线性回归的全批次、MiniBatch以及随机梯度下降方法
线性回归
线性回归是机器学习中最简单的一个方法,关于详细的公式推导网上很多,我就不详细展开,可
以在周志华老师的西瓜书上找到详尽的推理。对于线性回归的求逆的方法也不再次做介绍,有可
能以后会搞一搞,但在第一篇博客中就不做介绍。本篇就记录下本人对全批次梯度下降方法、
MiniBatch梯度下降方法以及随机梯度下降方法的代码实现。仅作为记录!
关于理论性的推导懒得再手写了,有个老哥写的真是不错,几乎把西瓜书上的搬了下来,在这边附个链接
https://www.cnblogs.com/geo-will/p/10468253.html
全批次梯度下降方法
把所有训练样本都放入进行训练
MiniBatch梯度下降方法
随机生成一个样本list,打乱list,用一个MiniBatch的样本数进行训练,计算损失,每一次循环一整个样本容量,但是不重复。
随机梯度下降方法
每次从样本中抽出随机的一个进行训练,提高收敛速度。
年轻人要讲码德,上本人代码
import matplotlib.pyplot as plt
import numpy as np
import random
class LinearRegressionClass(object):
def __init__(self, X, Y, learningRate, loopNum):
# X为输入的矩阵,一行代表一份数据,行数代表样本的数量,列数代表样本的维数
# Y为对应的结果值
# learningRate表示学习率
# loopNum表示训练的次数
self.dataX = X
self.dataY = Y
self.learningRate = learningRate
self.loopNum = loopNum
self.y = np.array([self.dataY]).T
self.X = np.column_stack((X, np.repeat(1, X.shape[0]))) # 扩充矩阵一列全1,变成广义矩阵,作用是与偏置项进行乘积
self.parameter = np.array([np.ones(self.X.shape[1])]).T # 最后一位为偏置项
def Overall_Linear_Regression(self):
for i in range(self.loopNum):
# 迭代训练
predict_y = np.dot(self.X, self.parameter)
error_y = predict_y - self.y
cost = np.dot(error_y.T, error_y)
derivative = 0.5 * np.dot(error_y.T, self.X) / self.X.shape[0]
self.parameter -= self.learningRate * derivative.T
# 显示
self.show_Linear_Regression(predict_y, i, cost)
plt.show()
return self.parameter
def Random_Linear_Regression(self):
for i in range(self.loopNum):
# 迭代训练
cost = 0
List_NoRepeat_Random = random.sample(range(0, self.X.shape[0]), self.X.shape[0])
for X_random in List_NoRepeat_Random:
predict_y = np.dot(self.X[X_random], self.parameter)
error_y = predict_y - self.y[X_random]
cost += np.dot(error_y.T, error_y)
derivative = 0.5 * np.dot(error_y.T, X_random)
self.parameter -= self.learningRate * derivative.T
# 显示
predict_y = np.dot(self.X, self.parameter)
self.show_Linear_Regression(predict_y, i, cost)
plt.show()
return self.parameter
def miniBatch_Linear_Regression(self, miniBatch):
# miniBatch为一个批次的样本数量
for i in range(self.loopNum):
# 迭代训练
List_NoRepeat_Random = random.sample(range(0, self.X.shape[0]), self.X.shape[0])
mini_cost = 0.
Batch_num = int(self.X.shape[0] / miniBatch) if self.X.shape[0] % miniBatch == 0 else int(
self.X.shape[0] / miniBatch) + 1
for batch in range(0, Batch_num):
index = List_NoRepeat_Random[batch * miniBatch:(batch + 1) * miniBatch]
mini_X = self.X[index]
mini_y = self.y[index]
mini_predict_y = np.dot(mini_X, self.parameter)
mini_error_y = mini_predict_y - mini_y
mini_cost += np.dot(mini_error_y.T, mini_error_y)
derivative = 0.5 * np.dot(mini_error_y.T, mini_X) / mini_X.shape[0]
self.parameter -= self.learningRate * derivative.T
# 显示
predict_y = np.dot(self.X, self.parameter)
self.show_Linear_Regression(predict_y, i, mini_cost)
plt.show()
return self.parameter
def show_Linear_Regression(self, predict_y, range_i, cost):
plt.clf()
plt.scatter(self.dataX, self.dataY, color='blue')
plt.plot(self.dataX, predict_y, color='red', linewidth=2)
plt.pause(0.03)
np.set_printoptions(precision=4)
if (range_i + 1) % 5 == 0:
print("range", range_i + 1, "cost =", cost)
def print_Para(parameter):
print("y=", parameter[0][0], "x+", parameter[1][0])
def dataSet():
x_parameter = np.array([[150.], [200.], [250.], [300.], [350.], [400.], [600.]])
y_parameter = np.array([6450., 7450., 8450., 9450., 11450., 15450., 18450.])
return x_parameter, y_parameter
if __name__ == '__main__':
data_X, data_Y = dataSet()
# LROverall = LinearRegressionClass(data_X, data_Y, 0.000005, 100)
# para = LROverall.Overall_Linear_Regression() # 全批量线性回归
# LRRandom = LinearRegressionClass(data_X, data_Y, 0.00005, 100)
# para = LRRandom.Random_Linear_Regression() # 随机梯度下降线性回归
LRMiniBatch = LinearRegressionClass(data_X, data_Y, 0.0000005, 100)
para = LRMiniBatch.miniBatch_Linear_Regression(1) # MiniBatch批量线性回归
print_Para(para)
结果如下: