【PyTorch】深度学习——梯度下降算法

视频学习:03.梯度下降算法_哔哩哔哩_bilibili

问题:

实际上,真正的学习过程中,cost(w)不会是一个平滑的曲线。当只要有一个维度时,还可以做线性搜索。但当权重个数为两个或多个时,如 \hat{y}( \omega_{1},\omega_{2},x),此时搜索量剧增

优化问题

优化问题:求目标函数(cost(w))的权重组合

 梯度下降算法(Gradient Descent)

假设在某个损失函数里,模型的损失cost 与 一个权重w 的关系如下图。

权重w 目前在该红点处。此时,如果求出该点的梯度\frac{\partial cost}{\partial \omega } ,就可以知道该点该往右走还是往左走能使损失函数cost的值达到最小,即梯度为0的点。

 

 更新权重w,其中 \alpha 为学习率,学习率一般取得较小。此时,通过计算可以得到前进的距离(步长)。

\omega = \omega - \alpha \frac{\partial cost}{\partial \omega}

问题

然而,在梯度下降会遇到最优化问题中两个常见的问题:局部最小值和鞍点。

局部最小值 

有时我们计算出的损失函数,可能会存在多个局部最小值,此时梯度下降法只是找到其中的一个局部最小值而停止,不能找到全局最优。

我们可以通过取多个不同的初始值执行算法,来选择算是函数最小的初始值。

鞍点

鞍点:函数在此点的梯度为0。此时,导致w没办法进行迭代。

随机梯度下降

实际上,在深度学习中,常用的是随机梯度下降(Stochastic Gradient Descent)。区别在于,不再是计算整个目标函数的损失,而是计算单个样本的损失,以此,引入了随机噪声,即使陷入鞍点,随机噪声可能使 权重w 在更新的过程中跨越鞍点。

 代码

梯度下降:

import numpy as np
import matplotlib.pyplot as plt

# 数据
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]

w = 1.0   # 猜测初始权重
epoch_list=[]     # 存储数据,方便后期画图
cost_list = []

# 定义前馈函数
def forward(x):
    return x * w

# 损失函数
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)

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

print('Predict (before training)', 4, forward(4))

# 训练
for epoch in range(100):
    cost_val = cost(x_data, y_data)
    grad_val = gradient(x_data, y_data)
    w -= 0.01 * grad_val
    epoch_list.append(epoch)
    cost_list.append(cost_val)
    print('Epoch:', epoch, 'w=', w, 'loss=', cost_val)
print('Predict (after training)', 4, forward(4))

# 绘图
plt.plot( epoch_list, cost_list)
plt.ylabel('w')
plt.xlabel('epoch')
plt.show

输出:

随机梯度下降:

import numpy as np
import matplotlib.pyplot as plt

x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]

w = 1.0   # 猜测初始权重
epoch_list=[]
cost_list = []

# 定义前馈函数
def forward(x):
    return x * w

# 损失函数 求单个样本的损失
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2

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

print('Predict (before training)', 4, forward(4))

# 训练
for epoch in range(100):
    for x, y in zip(x_data, y_data):
        # 对每个样本求梯度
        grad = gradient(x, y)
        # 更新
        w = w - 0.01 * grad
        print("\tgrad:", x, y, grad)
        # 计算目前的损失
        l = loss(x, y) 
        epoch_list.append(epoch)
        cost_list.append(l)
    print('progress:', epoch, 'w=', w, 'loss=', 1)
print('Predict (after training)', 4, forward(4))

# 绘图
plt.plot( epoch_list, cost_list)
plt.ylabel('w')
plt.xlabel('epoch')
plt.show

输出:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值