机器学习笔记——梯度下降、反向传播

系列文章目录

机器学习笔记——梯度下降、反向传播
机器学习笔记——用pytorch实现线性回归
机器学习笔记——pytorch实现逻辑斯蒂回归Logistic regression
机器学习笔记——多层线性(回归)模型 Multilevel (Linear Regression) Model
深度学习笔记——pytorch构造数据集 Dataset and Dataloader
深度学习笔记——pytorch解决多分类问题 Multi-Class Classification
深度学习笔记——pytorch实现卷积神经网络CNN
深度学习笔记——卷积神经网络CNN进阶
深度学习笔记——循环神经网络 RNN
深度学习笔记——pytorch实现GRU



前言

参考视频——B站刘二大人《PyTorch深度学习实践》


一、梯度下降 Gradient-Descent

梯度就是导数,梯度下降法就是一种通过求目标函数的导数来寻找目标函数最小化的方法。

最优化问题在机器学习中有非常重要的地位,很多机器学习算法最后都归结为求解最优化问题。最优化问题是求解函数极值的问题,包括极大值和极小值。在各种最优化算法中,梯度下降法是最简单、最常见的一种,在深度学习的训练中被广为使用。

写了半天发现有个博主把我想写的都写了,而且人家还写得更好(哈哈哈哈),直接贴链接了。
什么是梯度下降

权重更新的公式推导

在这里插入图片描述

本文最后一节贴有代码

二、反向传播 Back-propagation

反向传播(BP, back propagation)是“误差反向传播”的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见方法。

后向计算
完成前向计算之后,根据链式求导法则,进行后向计算,可以求出梯度值。算出梯度值之后根据完成梯度下降计算。

两层的神经元结构
两层的神经网络结构
在这里插入图片描述
然而发现,在多层的这种线性结构中,最终都可以简化为一层,做多少层都没有意义。
在这里插入图片描述
所以需要在此结构中加入一个非线性函数(如sigmod函数)
多层的神经元结构
通过这种方式可以构建起一个多层的神经网络。

三、Tensor简介

Tensor,中文叫做张量。在深度学习里,Tensor实际上就是一个多维数组(multidimensional array)。在概念上与numpy中的ndarrays是一样的,很多用法类似于numpy中的ndarrays。使用Tensor的目的是能够创造更高维度的矩阵、向量。Tensor可以在gpu或其他专用硬件上运行来加速计算。
在pytorch中tensor可以用来构建计算图,计算梯度。
Tensor
tensor包含data和grad,用来保存权重和梯度(损失值对权重的导数)。data和grad的数据类型也是tensor。
tensor和tensor进行计算时,会构建计算图。tensor和非tensor类型数据进行乘除运算时,会将该数据转为tensor类型后进行计算。
pytorch完成后向计算后,保存梯度,自动释放计算图。

四、示例

1.梯度下降

代码实现:

#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
    梯度下降法
    求y=2x
"""
import matplotlib.pyplot as plt

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

w = 1.0  # 系数初始值
learn_val = 0.01  # 学习率
epoch_list = []
cost_list = []


# 前向函数
def forward(x):
    return x * w


# 损失函数
def cost(xs, ys):
    cost_val = 0  # 损失值
    for x, y in zip(xs, ys):
        y_pred = forward(x)
        cost_val += (y_pred - y) ** 2
    return cost_val / len(xs)  # 返回损失的平均值


# 梯度函数
def gradient(xs, ys):
    grad_val = 0  # 梯度值
    for x, y in zip(xs, ys):
        grad_val += 2 * x * (x * w - y)
    return grad_val / len(xs)  # 返回梯度的平均值


print('predict(before training):', 4, forward(4))
# 开始训练
for epoch in range(100):  # 进行一百轮训练
    cost_value = cost(x_data, y_data)  # 计算损失值
    grad_value = gradient(x_data, y_data)  # 计算梯度
    w -= learn_val * grad_value
    epoch_list.append(epoch)
    cost_list.append(cost_value)
    print('epoch:', epoch, 'cost:', cost_value, 'grad:', grad_value, 'w=', w)
print('predict:', 4, forward(4))

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

结果:
在这里插入图片描述
在这里插入图片描述

2.反向传播

在这里插入图片描述
以y=2x为例

实现代码:

#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
    反向传播
    线性模型 y=2x 作为例子
"""
import torch

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

# 系数初始值
w = torch.Tensor([1.0])
# 需要计算梯度
w.requires_grad = True


# 模型
# 前馈计算
def forward(x):
    return x * w  # w是一个Tensor  Tensor在做乘法运算时,会将x自动类型转换为Tensor,做Tensor与Tensor之间的数乘


# 损失函数  loss的本质是构建一个计算图
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2


print('predict(before training):', 4, forward(4))
for epoch in range(100):  # 进行一百轮的训练
    for x, y in zip(x_data, y_data):
        loss_val = loss(x, y)  # 前馈计算   构建计算图     loss_val也是一个Tensor
        loss_val.backward()  # 反馈计算   torch会将梯度存在w里面,之后释放计算图
        print('x:', x, 'y=', y, 'grad=', w.grad.item())
        w.data -= 0.01 * w.grad.data  # 更新系数
        w.grad.data.zero_()  # 下一轮计算前,将梯度清零
    print('progress:', epoch, 'loss_value=', loss_val.item())
print('predict(after training):', 4, forward(4))

结果:
前两轮:
在这里插入图片描述
最后两轮:
在这里插入图片描述

课后习题
课后习题
在这里插入图片描述

#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
    反向传播
    y=w1*x^2+w2*x+b

    w1=2  w2=3 b=5
"""
import torch
import matplotlib.pyplot as plt

# 数据集
x_data = [1.0, 2.0, 3.0]
y_data = [10.0, 19.0, 32.0]

# 初始化
# 创建tensor
w1 = torch.Tensor([1.0])
w2 = torch.Tensor([1.0])
b = torch.Tensor([0.0])
# 设置需要计算梯度
w1.requires_grad = True
w2.requires_grad = True
b.requires_grad = True
# 设置学习率
rate = 0.02
# 绘图需要的数据
epoch_list = []
loss_list = []


# 模型
# 前向计算
def forward(x):
    return w1 * x * x + w2 * x + b


# 损失函数
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2


print('predict(before training):', 4, forward(4))
for epoch in range(100):  # 进行一百轮的训练
    for x, y in zip(x_data, y_data):
        loss_val = loss(x, y)  # 前向计算
        loss_val.backward()  # 后向计算
        # 更新权重
        w1.data -= rate * w1.grad.data
        w2.data -= rate * w2.grad.data
        b.data -= rate * b.grad.data
        print('x:', x, 'y:', y, 'w1 grad:', w1.grad.item(), 'w2 grad:', w2.grad.item(), 'b grad:', b.grad.item())
        # 梯度清零
        w1.grad.data.zero_()
        w2.grad.data.zero_()
        b.grad.data.zero_()
        # 绘图数据
        epoch_list.append(epoch)
        loss_list.append(loss_val.item())
    print('progress:', epoch, 'loss_value:', loss_val.item())
print('predict(after training):', 4, forward(4))

# 绘图
plt.plot(epoch_list, loss_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

结果:
在这里插入图片描述

在这里插入图片描述

  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
梯度下降算法是机器学习中一种广泛应用的最优化算法,其主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。梯度下降算法的原理可以从一个下山的场景开始理解。算法的基本思想是沿着目标函数梯度的方向更新参数值,以期望达到目标函数的最小值。 在机器学习中,梯度下降算法常常用于求解损失函数的最小值。在简单的线性回归中,我们可以使用最小二乘法来求解损失函数的最小值。然而,在绝大多数情况下,损失函数是非线性的且复杂。因此,梯度下降算法在机器学习领域得到了广泛的应用。实际上,许多优秀的算法都是在梯度下降算法的启发下诞生的,例如AdaGrad、RMSProp、Momentum等等。 梯度下降算法的核心思想是通过计算目标函数的梯度来确定参数更新的方向。梯度表示了函数在某一点上的变化率,沿着梯度的方向可以使函数值快速减小。因此,梯度下降算法沿着梯度的反方向更新参数值,朝着目标函数的最小值靠近。算法的迭代过程会持续更新参数值,直到收敛到最小值或达到停止条件。 在实际应用中,为了提高算法的效率和准确性,通常会对梯度下降算法进行改进和优化。例如,可以使用学习率来控制参数值的更新步长,或者采用批量梯度下降来同时计算多个样本的梯度。这些改进可以帮助算法更快地收敛并找到更好的解。 总之,梯度下降算法是一种重要的最优化算法,在机器学习中被广泛应用。其原理是通过计算目标函数的梯度来更新参数值,以期望达到最小值。通过迭代的方式,梯度下降算法可以找到目标函数的最优解或者接近最优解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值