#简易的随机梯度下降:
def dj_sgd(theta,x_b_i,y_i):
return x_b_i.T.dot(x_b_i.dot(theta) - y_i) * 2
def sgd(x_b,y,initial_theta,n_iters):
t0 = 5
t1 = 50
def learing_rate(t):
return t0/(t+t1)
theta = initial_theta
for cur_iters in range(n_iters):
rand_i = np.random.randint(0,len(x_b))
gradient = dj_sgd(theta,x_b[rand_i],y[rand_i])
theta = theta - learing_rate(cur_iters)*gradient
return theta
m = 100000
x = np.random.normal(size= m)
X = x.reshape(-1,1)
y = 4.*x + 3. + np.random.normal(0,3,size=m)
%%time
x_b = np.hstack([np.ones((len(x),1)),X])
initial_theta = np.zeros(x_b.shape[1])
theta = sgd(x_b,y,initial_theta,n_iters = len(x_b)//3)
#自带的SGD:
boston = datasets.load_boston()
x = boston.data
y = boston.target
x = x[y<50]
y = y[y<50]
#必须对数据归一化
x_train,x_test,y_train,y_test = train_test_split(x,y)
from sklearn.preprocessing import StandardScaler
standard_scaler = StandardScaler()
standard_scaler.fit(x_train)
x_train_standard = standard_scaler.transform(x_train)
x_test_standard = standard_scaler.transform(x_test)
### scikit-learn中的SGD
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=1000,n_iter_no_change=10)
%time sgd_reg.fit(x_train_standard,y_train)
sgd_reg.score(x_test_standard,y_test)
BGD:每次更新参数时是需要计算所有样本的,通过对整个数据集的所有样本的计算来求解梯度的方向。这种计算方法被称为:批量梯度下降法BGD(Batch Gradient Descent)。BGD可以确保梯度朝着同一个方向变化。
SGD:随机梯度下降法SGD(stochastic gradient descent),随机梯度下降是每次迭代使用一个样本来对参数进行更新。虽然不是每次迭代得到的损失函数都向着全局最优方向,但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。
学习率的选择:这是因为如果学习率一直取一个固定值,所以可能会导致点已经取到最小值附近了,但是固定的步长导致点的取值又跳去了这个点的范围。因此我们希望在随机梯度下降法中,学习率是逐渐递减的。