线性回归的全批次、MiniBatch以及随机梯度下降方法

线性回归的全批次、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)

结果如下:
线性回归的全批次、MiniBatch以及随机梯度下降方法

上一篇:Mybatis中使用注解进行模糊查询


下一篇:FPGA——IIC状态机实现及仿真