机器学习梯度下降

关于梯度下降方法的代码

通过代码的方式保存图像

通过代码的方式在每次画好图的同时,直接保存图片

#导入相应的库
import numpy as np
import os
import matplotlib.pyplot as  plt
%matplotlib inline
#随机种子
np.random.seed(42)

#保存图像
PROJECT_ROOT_DIR ='.'
MODEL_ID ='linear_models'

def save_fig(fig_id, tight_layout = True):#定义一个保存图像的函数
    path = os.path.join(PROJECT_ROOT_DIR, 'images',MODEL_ID, fig_id +'.png')
    print('Saving figure',fig_id)#提示函数
    plt.savefig(path, format='png', dpi =300)
    
#把讨厌的讲稿信息过滤
import warnings
warnings.filterwarnings(action = 'ignore',message='internal gelsd')

x = 2*np.random.rand(100,1) #生成训练数据(特征部分)
y = 4+3*x+np.random.randn(100,1)#生成训练数据(标签部分)

plt.plot(x,y, 'b.')#画图
plt.xlabel('$x_1$',fontsize =18)
plt.ylabel('$y$',rotation=0, fontsize =18)
plt.axis([0,2,0,15])
save_fig('generated_data_plot')# 保存图片

训练数据的结果

在这里插入图片描述

#添加新特征
x_b = np.c_[np.ones((100,1)),x]
#创建测试数据
x_new =np.array([[0],[2]])
x_new_b = np.c_[np.ones((2,1)),x_new]

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(x,y)#拟合训练数据
lin_reg.intercept_, lin_reg.coef_  #输出结局,斜率

lin_reg.predict(x_new)#对测试集进行预测

截距和斜率的结果
array([[4.21509616],[9.75532293]])

用批量梯度下降求解线性回归

eta =0.1
n_iterations =1000
m =100   #数量
theta =np.random.randn(2,1)

for iteration in range(n_iterations):
    gradients= 2/m*x_b.T.dot(x_b.dot(theta)-y)
    theta =theta - eta*gradients```
x_new_b.dot(theta)


theta_path_bgd=[]
#定义一个画出图像的函数
def plot_gradient_descent(theta, eta, theta_path=None):
    m =len(x_b)
    plt.plot(x,y,'b.')
    n_iterations =1000  #迭代次数限制为1000
    for iteration in range(n_iterations):
        if iteration < 10:
            y_predict=x_new_b.dot(theta)
            style='r-'
            plt.plot(x_new,y_predict, style)
        gradients = 1/m*x_b.T.dot(x_b.dot(theta)-y)
        theta = theta -eta*gradients
        if theta_path is not None:
            theta_path.append(theta)
    plt.xlabel("$x_1$",fontsize = 18)
    plt.axis([0,2,0,15])
    plt.title(r'$\eta ={}$'.format(eta), fontsize = 16)
    
    np.random.seed(42)
theta =np.random.randn(2,1)

plt.figure(figsize=(10,4))
plt.subplot(131);plot_gradient_descent(theta, eta =0.02)
plt.ylabel('$y$',fontsize=18)
plt.subplot(132);plot_gradient_descent(theta, eta= 0.4, theta_path=theta_path_bgd)
plt.subplot(133);plot_gradient_descent(theta, eta= 0.5)

save_fig('gradient_descent_plot')
plt.show

三种不同eta值所得图

在这里插入图片描述

随机梯度下降法

theta_path_sgd =[]
m = len(x_b)
np.random.seed(42)```

n_epochs = 50
theta = np.random.randn(2,1) #随机初始化

for epoch in range(n_epochs):
    for i in range(m):
        if epoch == 0 and i < 20:
            y_predict =x_new_b.dot(theta)
            style='r-'
            plt.plot(x_new, y_predict,style)
        random_index = np.random.randint(m)
        xi=x_b[random_index:random_index+1]
        yi=y[random_index:random_index+1]
        gradients =2*xi.T.dot(xi.dot(theta)-yi)
        eta =0.1
        theta =theta - eta*gradients
        theta_path_sgd.append(theta)
        
plt.plot(x,y,'b.')
plt.xlabel('$x_1$',fontsize=18)
plt.ylabel('$y$',rotation=0,fontsize=18)
plt.axis([0,2,0,15])
save_fig('sgd_plot')
plt.show()

结果

在这里插入图片描述

直接调用函数(SGD)

from sklearn.linear_model import SGDRegressor
sgd_reg =SGDRegressor(max_iter=50, tol=-np.infty,penalty= None ,eta0 =0.1,random_state=42)
sgd_reg.fit(x,y.ravel())```
print(sgd_reg.intercept_, sgd_reg.coef_)
所求的截距和斜率结果
(array([4.16782089]), array([2.72603052]))

三种方法在一个图上的对比

theta_path_mgd =[]
n_iterations =50
minibatch_size =20   #小批量

np.random.seed(42)   #随机种子
theta = np.random.randn(2,1)

for epoch in range(n_iterations):
    shuffled_indices = np.random.permutation(m)
    x_b_shuffled =x_b[shuffled_indices]
    y_shuffled = y[shuffled_indices]
    for i in range(0, m,minibatch_size):
        xi =x_b_shuffled[i:i+minibatch_size]
        yi =y_shuffled[i:i+minibatch_size]
        gradients = 2/minibatch_size*xi.T.dot(xi.dot(theta)-yi)
        eta =0.1
        theta =theta-eta*gradients
        theta_path_mgd.append(theta)```
        
theta_path_bgd =np.array(theta_path_bgd)
theta_path_sgd =np.array(theta_path_sgd)
theta_path_mgd =np.array(theta_path_mgd)
#画图阶段
plt.figure(figsize=(7,4))
plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1],'r-s',linewidth=1,label='Stochastic')
plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1],'g-+',linewidth=2,label='Mini_batch')
plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1],'b-o',linewidth=3,label='Batch')
#设置图像信息
plt.legend(loc='upper left', fontsize =16)
plt.xlabel(r'$\theta_0$',fontsize=20)
plt.ylabel(r'$\theta_1$',fontsize=20)
plt.axis([2.5,4.5,2.3,3.9])
save_fig('gradient-descent_paths_plot')
plt.show()

三种图综合效果图

在这里插入图片描述

三种不同的图分开效果

plt.figure(figsize=(7,4))

plt.subplot(221)
plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1],'r-s',linewidth=1,label='Stochastic')
plt.subplot(222)
plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1],'g-+',linewidth=2,label='Mini_batch')
plt.subplot(223)
plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1],'b-o',linewidth=3,label='Batch')



plt.legend(loc='upper left', fontsize =16)
plt.xlabel(r'$\theta_0$',fontsize=20)
plt.ylabel(r'$\theta_1$',fontsize=20)
plt.axis([2.5,4.5,2.3,3.9])
save_fig('gradient-descent_paths_plot')
plt.show()

分别展示效果图

在这里插入图片描述

结论:

批量梯度下降的方法最准确,但是速度是最慢的,随机梯度下降的方法速度最快,但是可能得不到局部最小值,小批量梯度下降法介于两者之间,具有速度的同时,保证的一定的准确度.但是每次梯度估计的方向都不确定.建议大量数据时用小批量梯度下降的方法,少量数据用随机梯度下降或者批量梯度下降的方法.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值