深度学习(二):梯度下降

1、“比较”这一步会让你知道自己的模型错了多少。误差总是正的。均方误差是评估神经网络准确性的常用方法
2、在“预测”步骤结束时,“学习”这一步会为每项权重计算一个数字。这个数字告诉我们,如果想要减少误差,权重应该向哪个方向变化。然后可以根据这个数字对权重做出相应的调节,直到达到目的

1 冷热学习

1、冷热学习指的是通过扰动权重来确定向哪个方向调整可以使得误差的降低幅度最大,基于此将权重的值向那个方向移动,不断重复这个过程,直到误差趋向于0
2、冷热学习的特点:
(1)简单 在上一次做出预测后,模型又进行了两次预测,一次的权重稍高,一次的权重稍低。权重实际调节的量取决于哪个方向所得到的误差更小
(2)效率低 需要多次预测才能进行一次权重更新
(3)有时无法准确的预测出目标 step_amout 是任意选择的,这可能让你学不到正确的权重值

weight = 0.5
input = 0.5
goal_prediction = 0.8
step_amout = 0.001 #每个迭代,权重应该调节多少
for iteration in range(1101):
    #预测
    prediction = input * weight
    error = (prediction - goal_prediction)**2
    print("Error:" + str(error) + " Prediction:" + str(prediction))
    #权重稍高
    up_prediction = input * (weight + step_amout)
    up_error = (goal_prediction - up_prediction)**2
    #权重稍低
    down_prediction = input * (weight - step_amout)
    down_error = (goal_prediction - down_prediction)**2

    if up_error < down_error:
        weight = weight + step_amout
    if up_error > down_error:
        weight = weight - step_amout
    print('weight:' ,weight)

2 基于误差调节权重

1、相对与冷热学习,更高级的学习形式叫作梯度下降(Gradient-Descent )。它可以在一行代码中同时进行方向和幅度的计算,对权重进行调整以减少错误

2、缩放、负值反转和停止调节 这三个属性的共同作用是将纯误差转换为我们所需要的权重调节的绝对幅度。停止调节: 当输入是0,那么它将强制 direction_and_amount 也为0;负值反转: 即使输入是负值,那么纯误差乘以输入将改变 direction_and_amount 的方向;缩放: 如果输入很大,则权重更新也会变得很大,这更像一种副作用,因为它经常可能失去控制。我们可以使用 alpha 来处理这种情况

weight = 0.5
goal_pred = 0.8
input = 0.5

for iteration in range(20):
    pred = input * weight
    error = (pred - goal_pred)**2
    #pred - goal_pred 为纯误差
    #(pred - goal_pred) *input 纯误差与输入的相乘操作,用于执行缩放、负值反转和停止调节
    direction_and_amount = (pred - goal_pred) *input
    print('direction_and_amount:',direction_and_amount)
    weight = weight - direction_and_amount
    print("Error:" + str(error) + " Prediction:" + str(pred))

3、对于任何 input 和 goal_pred,结合有关 prediction 和 error 的公式,我们可以在误差和权重之间定义一个精确的关系;这里的 input 和 goal_pred 是确定的值,假设他们分别是0.5和0.8,那么 error 和 weight 关系就是下面的一元二次方程和图像;这里需要用到导数的知识,可以用两种方式解释导数:一种方法是,将它理解成函数中的一个变量在你移动另一个变量时是如何变化的。另一种说法是,导数是直线或曲线上一点的斜率

4、神经网络实际上就是一件事情:一堆你可以计算误差函数的权重。对于任何误差函数,基于任意权重值,都可以计算出网络的最终误差。有了这些信息,就可以改变神经网络中的每一项 weight ,将 error 减少到 0 ,这就是你要做的事情

5、微积分就是记忆和练习所有可能存在的函数的每一个可能的导数规则。实际应用中可以在参考资料中查找导数

6、将权重值向导数(derivative)的相反方向移动,就能得到使误差更小的权重值。这种学习方法称为梯度下降法

error = (input * weight - goal_pred)**2
error = (0.5 * weight - 0.8)**2


梯度下降过程如下:

weight,goal_pred,input = (0.0,0.8,1.1)

for iteration in range(4):
    print('weight:',weight)
    pred = input * weight
    error = (pred - goal_pred)**2
    delta = pred - goal_pred
    weight_delta = input * delta
    weight -= weight_delta
    print('Error:' + str(error) + ' Prediction:' + str(pred))
    print('Delta:' + str(delta) + ' Weight Delta:' + str(weight_delta))

7、如果 input 足够大,即使误差很小,也会使权值的增量很大。当你的权重增量(weight_delta = input * delta)很大而误差很小的时候,网络会矫枉过正。这就导致了预测结果爆咋的现象,称为发散

#将 input 值变为2时,产生发散现象
weight,goal_pred,input = (0.5,0.8,2)

for iteration in range(20):
    print('weight:',weight)
    pred = input * weight
    error = (pred - goal_pred)**2
    delta = pred - goal_pred
    weight_delta = input * delta
    weight -= weight_delta
    print('Error:' + str(error) + ' Prediction:' + str(pred))
    print('Delta:' + str(delta) + ' Weight Delta:' + str(weight_delta))

8、对于发散现象,解决方案是将权重的增量乘以一个比较小系数,让它变得更小。将权值增量乘以一个介于0和1之间的实数,称为α(alpha)。随着时间推移,如果误差开始发散(上升),那么alpha值就太高了,需要调低一点。如果学习进展太慢,那么 alpha 值太低,需要调高一些。

weight = 0.5
goal_pred = 0.8
input = 2
alpha = 0.1

for iteration in range(20):
    pred = input * weight
    error = (pred - goal_pred)**2
    delta = pred - goal_pred
    derivative = input*delta
    weight = weight - derivative*alpha
    print('Error:' + str(error) + ' Prediction:' + str(pred))

3 参考资料

《深度学习图解》

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容