梯度下降代码线性回归为例

bgd 批量梯度下降

sbd 随机梯度下降

mbfd 小批量随机梯度下降

  1import numpy as np
  2import random
  3
  4def gen_line_data(sample_num=100):
  5    """
  6    y = 6*x1 + 40*x2
  7    :return:
  8    """
  9    x1 = np.linspace(0, 9, sample_num)
 10    x2 = np.linspace(4, 13, sample_num)
 11    x = np.concatenate(([x1], [x2]), axis=0).T
 12    y = np.dot(x, np.array([, 4]).T)  # y 列向量
 13    return x, y
 14
 15def my_bgd(samples, y, step_size=0.01, max_iter_count=10000):
 16    len_x,dim = samples.shape
 17    X = samples
 18    y = y.flatten()
 19    w = np.zeros((dim,), dtype=np.float32)
 20    iter_count = 0
 21    while(iter_count!=max_iter_count):
 22        # 求出每一维损失
 23        err = 0 
 24        error_w = np.zeros((dim,), dtype=np.float32)
 25        for i in range(len(X)):
 26            pre_y = np.dot(w.T,X[i])
 27            for j in range(dim):
 28                error_w[j] += (y[i]-pre_y) * X[i][j]
 29
 30        #针对每一维更新w
 31        for j in range(dim):
 32            w[j] += error_w[j] * step_size /len_x
 33        
 34        #算每次迭代的error function
 35        for i in range(len(X)):
 36            pre_y = np.dot(w.T,X[i])
 37            loss = (1 / (len_x * 2)) * np.power((pre_y - y[i]), 2)
 38            err += loss
 39        iter_count += 1
 40        
 41    return w
 42
 43def my_sgd(samples, y, step_size=0.01, max_iter_count=10000):
 44    len_x,dim = samples.shape
 45    X = samples
 46    y = y.flatten()
 47    w = np.ones((dim,), dtype=np.float32)
 48    iter_count = 0
 49    err = 10
 50    while(err > 0.001 and iter_count!=max_iter_count):
 51        # 求出每一维损失
 52        err = 0 
 53        error_w = np.zeros((dim,), dtype=np.float32)
 54        for i in range(len(X)):
 55            pre_y = np.dot(w.T,X[i])
 56            for j in range(dim):
 57                error_w[j] += (y[i]-pre_y) * X[i][j]
 58                w[j] += error_w[j] * step_size /len_x
 59        
 60        #算每次迭代的error function
 61        for i in range(len(X)):
 62            pre_y = np.dot(w.T,X[i])
 63            loss = (1 / (len_x * 2)) * np.power((pre_y - y[i]), 2)
 64            err += loss
 65        iter_count += 1
 66    return w
 67
 68def my_mbgd(samples, y, step_size=0.01, max_iter_count=10000,batch_size=0.2):
 69    len_x,dim = samples.shape
 70    X = samples
 71    y = y.flatten()
 72    w = np.zeros((dim,), dtype=np.float32)
 73    iter_count = 0
 74    while(iter_count!=max_iter_count):
 75        # 求出每一维损失
 76        err = 0 
 77        error_w = np.zeros((dim,), dtype=np.float32)
 78        index = random.sample(range(len_x),
 79                              int(np.ceil(len_x * batch_size)))
 80        batch_samples = samples[index]
 81        batch_y = y[index]
 82        
 83        for i in range(len(batch_samples)):
 84            predict_y = np.dot(w.T, batch_samples[i])
 85            for j in range(dim):
 86                error_w[j] += (batch_y[i] - predict_y) * batch_samples[i][j]
 87
 88        for j in range(dim):
 89            w[j] += step_size * error_w[j] / len_x
 90
 91        for i in range(len_x):
 92            predict_y = np.dot(w.T, samples[i])
 93            loss = (1 / (len_x * 2)) * np.power((predict_y - y[i]), 2)
 94            err += loss
 95
 96        iter_count += 1
 97        
 98    return w
 99
100samples, y = gen_line_data()
1%%time
2my_sgd(samples, y)
CPU times: user 108 ms, sys: 4 ms, total: 112 ms
Wall time: 106 ms
array([ 5.9729414, 40.014584 ], dtype=float32)