刘二大人PyTorch深度学习实践-day03

PyTorch 深度学习实践

03. Gradient Descent

刘二大人视频学习笔记,2023年07月08日。

本章是对梯度下降算法的介绍,做一些重要内容的记录,共勉。

(🥺我在电脑用Typora写,最终要存在CSDN上,所以截图很麻烦,尽量以文字形式记录)


0.前言

回忆上一节所讲的题目,采用了线性模型构建一个学习时间和得分之间的学习系统。但是利用穷举法来进行计算,无可避免会被“维度的诅咒”所影响。

所以不用穷举法,而采用分治法,先进行稀疏的搜索,在二维平面先取16个均匀点,然后在最小值处在进行分16个但如此寻找。但是这个方法只适用于光滑的凸函数,对于不规则曲线来说还是很难得到正解。

1.梯度下降算法

1)梯度的定义

用目标函数对权重进行求导数,这样就得到了目标函数的上升方向。(比如导数为负,说明函数向负方向为上升方向)

在这里插入图片描述

对于问题,我们要找的是 ω \omega ω最小值,也即下降方向所以对权重的更新为:
ω = ω − α ∂ c o s t ∂ ω \omega = \omega - \alpha\frac{\partial cost}{\partial \omega} ω=ωαωcost
其中 α \alpha α为学习率,这个学习率通常取小数。

每次迭代都朝着下降最快的方向前进,所以这是一种贪心算法。

其实可以形象的看成在函数图形上放置一个小球,在没有惯性的情况下的运动(我感觉)。但是这样就会引出贪心的一个缺陷,会得到错误的解。

在这里插入图片描述

上面这种函数称为非凸函数,函数中会存在多个最优点,分为局部最优点和全局最优点。(由图可见)

但是梯度下降仍然是广为采用的一种方法,是因为在深度神经网络很少存在局部最优点。

但是在这里面又引出另一个问题——鞍点

鞍点的梯度为0,根据公式,当权重优化到鞍点时,迭代将永远在鞍点死循环,无法进行正常迭代。

梯度的具体算式:
∂ c o s t ∂ ω = ∂ ∂ ω 1 N ∑ n = 1 N ( x n ω − y n ) 2 = 1 N ∑ n = 1 N ∂ ∂ ω ( x n ω − y n ) 2 = 1 N ∑ n = 1 N 2 ( x n ω − y n ) ∂ ( x n ω − y n ) ∂ ω = 1 N ∑ n = 1 N 2 x n ( x n ω − y n ) \frac{\partial cost}{\partial \omega} = \frac{\partial}{\partial \omega}\frac{1}{N}\sum^N_{n=1}(x_n\omega-y_n)^2\\ =\frac{1}{N}\sum^N_{n=1}\frac{\partial}{\partial \omega}(x_n\omega-y_n)^2\\ =\frac{1}{N}\sum^N_{n=1}2(x_n\omega-y_n)\frac{\partial (x_n\omega-y_n)}{\partial \omega}\\ =\frac{1}{N}\sum^N_{n=1}2x_n(x_n\omega-y_n) ωcost=ωN1n=1N(xnωyn)2=N1n=1Nω(xnωyn)2=N1n=1N2(xnωyn)ω(xnωyn)=N1n=1N2xn(xnωyn)

所以可以带回原来的公式得到:
ω = ω − α 1 N ∑ n = 1 N 2 x n ( x n ω − y n ) \omega = \omega - \alpha\frac{1}{N}\sum^N_{n=1}2x_n(x_n\omega-y_n) ω=ωαN1n=1N2xn(xnωyn)

2)代码实现
import numpy as np
import matplotlib.pyplot as plt

# prepare the training set
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

# initial guess of weight
w = 1.0


# y-hat
def forward(x):
    return x * w


# cost/MSE
def cost(xs, ys):
    cost = 0
    for x, y in zip(xs, ys):
        y_pred = forward(x)
        cost += (y_pred - y) ** 2
    return cost / len(xs)


# gradient
def gradient(xs, ys):
    grad = 0
    for x, y in zip(xs, ys):
        grad += 2 * x * (x * w - y)
    return grad / len(xs)


cost_list = []
e_list = []
print('Predict (before training)', 4, forward(4))
# do the update epoch-迭代次数,学习率为0.01
for epoch in range(100):
    cost_val = cost(x_data, y_data)
    grad_val = gradient(x_data, y_data)
    w -= 0.01 * grad_val
    print('Epoch', epoch, 'w=', w, 'loss=', cost_val)
    cost_list.append(cost_val)
    e_list.append(epoch)
print('Predict (after training)', 4, forward(4))

plt.plot(e_list, cost_list)
plt.ylabel('cost')
plt.xlabel('epoch')
plt.show()

在这里插入图片描述

实际情况曲线不会这么平滑,会存在局部震荡。所以一般绘图的时候用指数加权均值的方法,来光滑函数。

指数加权均值光滑:

Cost的值为: c 0 , c 1 , … c_0,c_1,\dots c0,c1,

更新之后的值为: c 0 ′ , c 1 ′ , … c^{\prime}_0,c^{\prime}_1,\dots c0,c1,

则有:
c 0 ′ = c 0 … c i ′ = β c i + c i − 1 c^{\prime}_0 = c_0\\ \dots\\ c^{\prime}_i = \beta c_i + c_{i-1} c0=c0ci=βci+ci1

但如果函数有向上趋势,并不认为最低点是最小值,说明训练发散,可能是学习率取太大了,需要重新训练。

2.随机梯度下降

一般应用的是梯度下降算法的一个变体,就是随机梯度下降。梯度下降计算是用平均损失来计算,而随机梯度下降是随机从N中选取一个损失进行计算。
ω = ω − α ∂ l o s s ∂ ω ∂ l o s s n ∂ ω = 2 ⋅ x n ⋅ ( x n ⋅ ω − y n ) \omega = \omega - \alpha\frac{\partial loss}{\partial \omega}\\ \frac{\partial loss_n}{\partial \omega}=2 \cdot x_n\cdot(x_n\cdot \omega-y_n) ω=ωαωlossωlossn=2xn(xnωyn)
这样面对鞍点的问题,就可以通过产生一个随机误差(或者说从噪声数据拿到的随机噪声)来推动函数越过鞍点。这种方法是被证明有效的一种方法。

import numpy as np
import matplotlib.pyplot as plt

# prepare the training set
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

# initial guess of weight
w = 1.0


# y-hat
def forward(x):
    return x * w


# calculate loss
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2


# gradient
def gradient(x, y):
    return 2 * x * (x * w - y)


cost_list = []
e_list = []
print('Predict (before training)', 4, forward(4))
# update weight by every grad of sample of train set
for epoch in range(100):
    for x,y in zip(x_data,y_data):
        grad_val = gradient(x, y)
        w -= 0.01 * grad_val
        print('\tgrad:',x,y,grad_val)
        l = loss(x,y)
    print('progress:',epoch,'w=',w,'loss=',l)
print('Predict (after training)', 4, forward(4))

但是在真正的深度学习过程中会遇到这样的问题:

对于随机梯度下降来说, f ( x i ) 和 f ( x i + 1 ) f(x_i)和f(x_{i+1}) f(xi)f(xi+1)互不相关,所以在计算梯度的时候是可以并行计算的(因为用的COST是总体得来的)。但是对于随机梯度下降的时候,由于每次的 ω \omega ω是由上次计算结果得来的,所以不能并行(因为每次计算用的随机的LOSS)。

梯度下降算法随机梯度下降算法
性能
时间

所以在深度学习过程中会采用折中的算法,采用Batch

Batch:批量的随机梯度下降。将样本几个一组,进行随机梯度下降。一般Batch指的是全部样本,所以这种方法也叫做Mini(小批量)-Batch

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值