梯度下降简介

梯度下降简介

梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。

在这里插入图片描述

基本思想

L o s s = f ( α , β , . . . , θ ) ( 1 ) θ i + 1 = θ i − l e a r n i n g _ r a t e ∗ ∂ L o s s ∂ θ i ( 2 ) Loss = f(\alpha,\beta,...,\theta) \quad (1) \\ \quad \\ \theta_{i+1} = \theta_i - learning\_rate*\frac {\partial Loss}{\partial \theta_i} \quad (2) \\ \quad \\ Loss=f(α,β,...,θ)(1)θi+1=θilearning_rateθiLoss(2)

Loss可以表示成若干参数的函数,每个参数更新时朝着负梯度的方向前进

常见梯度下降法:

全量梯度下降法(Batch gradient descent):

学习使用整个训练集,因此每次更新都会朝着正确的方向进行,缺陷就是学习时间太长

SGD(Stochastic Gradient Descent):

随机梯度下降法,按照一个随机样本的梯度下降

小批量梯度下降法(Mini-Batch Gradient Descent)

Momentum梯度下降法:

θ i + 1 = θ i − l e a r n i n g _ r a t e ∗ ∂ L o s s ∂ θ i − m o m e n t u m ∗ l e a r n i n g _ r a t e ∗ ∂ L o s s ∂ θ i − 1 ( 3 ) \theta_{i+1} = \theta_i -learning\_rate*\frac {\partial Loss}{\partial \theta_i} - momentum*learning\_rate*\frac {\partial Loss}{\partial \theta_{i-1}} \quad (3) θi+1=θilearning_rateθiLossmomentumlearning_rateθi1Loss(3)

这种方法可以减小震荡,见下图中下面那条折线

在这里插入图片描述

NAG(Nesterov Accelerated Gradient

不仅仅把SGD梯度下降以前的方向考虑,还将Momentum梯度变化的幅度也考虑了进来。

AdaGrad

二阶动量; 对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。

AdaDelta / RMSProp

AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。这也就是AdaDelta名称中Delta的来历(指数移动平均

Adam(最常用)

是前述方法的集大成者。我们看到,SGD-Momentum在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。

全量梯度下降法举例

y ^ = a x 2 + b x ( 4 ) y = x 2 + 2 x ( 5 ) L o s s = 1 n ∑ i = 1 n ( y i ^ − y i ) 2 ( 6 ) a = a − l e a r n i n g _ r a t e ∗ ∂ L o s s ∂ a ( 7 ) b = b − l e a r n i n g _ r a t e ∗ ∂ L o s s ∂ b ( 8 ) ∂ L o s s ∂ a = 1 n ∑ i = 1 n 2 x i 2 [ ( a − 1 ) x i 2 + ( b − 2 ) x i ] = 2 x 2 [ ( a − 1 ) x 2 + ( b − 2 ) x ] ( 9 ) ∂ L o s s ∂ b = 1 n ∑ i = 1 n 2 x i [ ( a − 1 ) x i 2 + ( b − 2 ) x i ] = 2 x [ ( a − 1 ) x 2 + ( b − 2 ) x ] ( 10 ) \hat{y} = ax^2+bx \quad (4) \\ \quad \\ y = x^2+2x \quad (5) \\ \quad \\ Loss = \frac{1}{n}\sum_{i=1}^n(\hat{y_i}-y_i)^2\quad (6) \\ \quad \\ a = {a - learning\_rate*\frac{\partial{Loss}}{\partial{a}}} \quad(7) \\ \quad \\ b = {b - learning\_rate*\frac{\partial{Loss}}{\partial{b}}} \quad(8) \\ \quad \\ \frac{\partial{Loss}}{\partial{a}} = \frac{1}{n}\sum_{i=1}^n2x_i^2[(a-1)x_i^2+(b-2)x_i]=2x^2[(a-1)x^2+(b-2)x]\quad (9) \\ \quad \\ \frac{\partial{Loss}}{\partial{b}} = \frac{1}{n}\sum_{i=1}^n2x_i[(a-1)x_i^2+(b-2)x_i]=2x[(a-1)x^2+(b-2)x]\quad (10) y^=ax2+bx(4)y=x2+2x(5)Loss=n1i=1n(yi^yi)2(6)a=alearning_rateaLoss(7)b=blearning_ratebLoss(8)aLoss=n1i=1n2xi2[(a1)xi2+(b2)xi]=2x2[(a1)x2+(b2)x](9)bLoss=n1i=1n2xi[(a1)xi2+(b2)xi]=2x[(a1)x2+(b2)x](10)

一个简单的二次曲线拟合,先生成公式(5)中二次函数,然后添加随机扰动,最后尝试去用公式(4)

拟合,拟合示意图和代码如下:

在这里插入图片描述

在这里插入图片描述

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import os
###设置GPU###
#os.environ["CUDA_VISIBLE_DEVICES"] = "0" #GPU编号
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.6) #GPU使用率
###自定义数据###
x_data=np.linspace(-5,5,1000)[:,np.newaxis]
noise=np.random.normal(0,1,x_data.shape)
y_data=np.square(x_data)+noise+2*x_data
a_init=-2
b_init=-2
x_square = np.square(x_data)



"""tensorflow code"""
###定义变量###
weights =tf.Variable(initial_value=[a_init,b_init],dtype=tf.float32)
###占位符###
with tf.name_scope('Inputs'):
    x_placehold=tf.placeholder(tf.float32,[None,1],name='x_input')
    y_placehold=tf.placeholder(tf.float32,[None,1],name='y_input')
###定义一个无常数项的二次函数###

prediction = weights[0]*x_data*x_data + weights[1]*x_data

###损失###
with tf.name_scope('Loss'):
    loss=tf.reduce_mean(tf.reduce_sum(tf.square(y_placehold-prediction),reduction_indices=[1]),name='loss')
    tf.summary.scalar('loss',loss)
###训练步骤(主要指定方式)###
with tf.name_scope('Train'):
    train_step=tf.train.GradientDescentOptimizer(0.001,name="GD").minimize(loss,name='train')

###初始化所有变量###
init=tf.global_variables_initializer()
###设置迭代步数###
steps=1000
###绘制并显示初始数据###
fig=plt.figure()
fig=fig.add_subplot(1,1,1)
fig.set_title('fitting process')
fig.scatter(x_data,y_data)
plt.ion()
plt.show()
fig2=plt.figure()
fig2_a = fig2.add_subplot(1,2,1)
fig2_b = fig2.add_subplot(1,2,2)


fig3 = plt.figure()

fig_3d = Axes3D(fig3)
a = np.arange(-2, 4, 0.25)
b = np.arange(-2, 4, 0.25)
a, b = np.meshgrid(a, b)
Z = np.mean(x_data**4,keepdims=False)*((a-1)**2) + np.mean(x_data**2,keepdims=False)*((b-2)**2) + 2*(a-1)*(b-2)*np.mean(x_data**3) 

fig_3d.set_xlabel('a')
fig_3d.set_ylabel('b')
fig_3d.set_zlabel('loss')
fig_3d.plot_surface(a, b, Z, rstride=1, cstride=1,cmap="Blues",alpha=0.5)
fig_3d.set_title('gradient descent')
### 融合所有可视化信息图表 ###
merged=tf.summary.merge_all()
###创建会话###
with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:
    ### 保存Graph ###
    writer=tf.summary.FileWriter('logs/',sess.graph)
    sess.run(init)
    steps_array, weights_a_array, weights_b_array,loss_array = [], [], [], []
    for i in range(steps):
        sess.run(train_step,feed_dict={x_placehold:x_data,y_placehold:y_data})
        if i%15==0:
            steps_array.append(i)
            try:
                fig.lines.remove(lines_prediction[0])
            except Exception:
                pass
            loss_value = sess.run(loss,feed_dict={x_placehold:x_data,y_placehold:y_data})
            print('step %d  '%i , loss_value)
            prediction_value=sess.run(prediction,feed_dict={x_placehold:x_data})
            lines_prediction=fig.plot(x_data,prediction_value,'r-',lw=5)

            weights_a, weights_b = sess.run(weights)
            weights_a_array.append(weights_a)
            weights_b_array.append(weights_b)
            loss_array.append(loss_value)
            fig2_a.plot(steps_array,weights_a_array)
            fig2_b.plot(steps_array,weights_b_array)
            fig2_a.set_xlabel('step')
            fig2_a.set_ylabel('a')
            fig2_a.set_title('a')
            fig2_b.set_xlabel('step')
            fig2_b.set_ylabel('b')
            fig2_b.set_title('b')
            fig_3d.plot(weights_a_array,weights_b_array,loss_array,'r-',lw=6)
            plt.pause(0.1)
            summary_result=sess.run(merged,feed_dict={x_placehold:x_data,y_placehold:y_data})
            writer.add_summary(summary_result,i)

array,loss_array,‘r-’,lw=6)
plt.pause(0.1)
summary_result=sess.run(merged,feed_dict={x_placehold:x_data,y_placehold:y_data})
writer.add_summary(summary_result,i)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值