【Pytorch深度学习实践】B站up刘二大人之 Gradient Descend-代码理解与实现(2/9)

2023-05-16

开篇几句题外话:

  • 以往的代码,都是随便看看就过去了,没有这样较真过,以至于看了很久的深度学习和Python,都没有能够形成编程能力;

  • 这次算是废寝忘食的深入进去了,踏实地把每一个代码都理解透,包括其中的数学原理(目前涉及的还很浅)和代码语句实现的功能;也是得益于疫情封闭在寝室,才有如此踏实的心情和宽松的时间,最重要的是周边的环境,没有干扰。

Lecture03——Gradient Descent 梯度下降(cost function)

说在前面:这部分分两块,一个是基于cost function的,也就是全数据集上的代价函数,另一个是从中随机抽取一个数据,基于loss function的,也就是损失函数,二者在forward、loss的函数构建、训练过程中的数据加载环节都有所区别,要注意区分,搞清搞透;

详细过程:

  • 本课程的主要任务是构建第一个带有初始权重和训练过程的梯度下降模型:
    • 导入numpymatplotlib库;
    • 导入数据 x_datay_data;
    • 定义前向传播函数:
      • forward:输出是预测值y_hat
    • 定义代价函数:
      • cost:损失函数定义为MSE:均方根误差
      • 此处要使用循环,把数据集中的数据对儿,一组一组地取出来,再做计算;
      • 返回值需要归一化至单个数据的损失值;
    • 定义梯度计算函数:
      • 这个函数gradient很有意思,也不简单:需要根据反向传播,计算出代价函数对于权重的梯度,计算结果为grad += 2 * x * (x * w - y);
      • 返回值同样需要归一化至单个数据的梯度;
    • 创建两个空列表,因为后面绘图的时候要用:
      • 分别是横轴的w_list和纵轴的mse_list
    • 开始训练:
      • 循环的次数epoch可以自定义:
        • 首先调用代价函数cost计算数据集的代价值,注意,这里要传入所有数据,而不是再去用·zip·函数配合·for·循环每次取一个,因为在`cost·函数当中,已经写过单个数据对儿从数据集调出的过程;
        • 再调用梯度计算函数grad,与上个函数相同;
        • 核心来了——更新权重:
          • 就是最经典的权重更新公式,用现有权重,减去学习率乘以梯度的乘积,每轮(epoch)训练都要循环更新;
          • 此处尚不涉及权重清零的问题,这个问题后面也要详细记录,务必搞得非常透彻,因为它涉及到计算图的是否构建,以及tensor数据类型具有data和grad两个属性的问题(TBD);
          • 随意打印想要看到的内容,一般是打印x_valy_valloss_val
          • 在循环中要把计算的结果,放进之前的空列表,用于绘图;
  • 在获得了打印所需的数据列表只有,模式化地打印图像:
    -略

Lecture03——Gradient Descent 梯度下降(loss function)

详细过程:

  • 回头仔细看了看代码,其实区别并不大;
  • 之前没理解的原因,不在于costloss的区别,而在于权重更新那里我没有懂透;
  • 区别:
    • forward函数没有变化;
    • lossgradient函数有变化,把cost当中,原本需要把数据对儿从数据集中取出的过程,全部转移到训练过程中,这个过程不是难点,不过刚动手写的时候,就会很困惑,尤其是别的地方也有困惑,就觉得难度很大,应付不过来;

完整代码:

import matplotlib.pyplot as plt

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

w = 1.0


def forward(x):
    return x * w


def cost(xs, ys):
    cost = 0
    for x, y in zip(xs, ys):
        y_hat = forward(x)
        cost += (y_hat - 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))

epoch_list = []
cost_list = []
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)
    epoch_list.append(epoch_val)
print('Predict (after training)', 4, forward(4))

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

运行结果:

(后经过对比发现此图有错误,并不是想要的epoch横轴的训练损失输出曲线,正确的结果请往后文看)
在这里插入图片描述

默写出的错误:

import matplotlib.pyplot as plt

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

w = 1.0


def forward(x):
    return x * w


def cost(xs, ys):  # 此函数和下面函数传入的是数据集x_data和y_data,并不是上一个文件里的单独一个数据;
    cost = 0
    for x, y in zip(xs, ys):
        y_hat = forward(x)
        cost += (y_hat - y) ** 2
    return cost / len(xs)


def gradient(xs, ys):  # 此函数和上面函数传入的是数据集x_data和y_data,并不是上一个文件里的单独一个数据;
    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))

cost_list = []
grad_list = []
for epoch in range(100):
    for x, y in zip(x_data, y_data):  # 不用再去提取数据了,我在cost和gradient两个函数里,都已经有相关的提取了
    cost_val = cost(x,y)
    grad_val = gradient(x,y)
    w -= 0.01 * grad_val
    print('Predict (after training)', 'w=', w, 'loss=', cost_val)

    cost_list.append(cost_val)
    grad_list.append(grad_val)

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


  • 训练那里,不需要再去x_datay_data当中提取数据了,直接把数据集扔进去就可以了;

  • 原因是:在costgradient两个函数当中,已经有对数据集的提取了;

  • 复原老师的代码也有错误:那个横坐标写的不对;横坐标应该是epoch的值,而不是原来写的cost_val

  • 有个错误是导致我运行失败的原因:

    • 我传入costgradient函数的,不再是上一篇文章中说的单个数据,而是数据集;
  • costgradient函数内部也出过问题,我没有写成+=的形式,而是直接用了=;导致曲线下降趋势一直平缓;

  • +=这样写的原因在于要累加cost和grad,不是更新;这是原理没有懂透;

  • return grad / len(xs) # 这里缩进错了,导致最终输出曲线不对,非常细节的问题;return跟for循环并列缩进;作为def函数的结尾,应该是def下仅仅一级的缩进就可以了;

经过修改之后的代码:

import matplotlib.pyplot as plt

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

w = 1.0


def forward(x):
    return x * w


def cost(xs, ys):
    cost = 0
    for x, y in zip(xs, ys):
        y_hat = forward(x)
        cost += (y_hat - 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))

cost_list = []
epoch_list = []
for epoch in range(100):
    # for x, y in zip(x_data, y_data):  # 不用再去提取数据了,我在cost和gradient两个函数里,都已经有相关的提取了
    cost_val = cost(x_data, y_data)
    grad_val = gradient(x_data, y_data)
    w -= 0.01 * grad_val
    print('Predict (after training)', 'w=', w, 'loss=', cost_val)

    cost_list.append(cost_val)
    epoch_list.append(epoch)

plt.plot(epoch_list, cost_list)
plt.xlabel('epoch')
plt.ylabel('cost')
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


def forward(x):
    return x * w


def loss(x, y):
    y_hat = forward(x)
    return (y_hat - y) ** 2


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

epoch_list = []
loss_list = []

for epoch in np.arange(100):
    for x, y in zip(x_data, y_data):
       loss_val = loss(x, y)  # 本行为了绘图时使用,计算过程中没有涉及
       grad_val = gradient(x, y)
       w -= 0.01 * grad_val  # 每个数据进行一次权重更新
       print('Epoch:', epoch, 'w=', w, 'loss=', loss_val)
       loss_list.append(loss_val)
       epoch_list.append(epoch)

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

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

运行效果:

在这里插入图片描述

在这里插入图片描述

上一篇:

【Pytorch深度学习实践】B站up刘二大人之LinearModel -代码理解与实现(1/9)

下一篇:

【Pytorch深度学习实践】B站up刘二大人之 BackPropagation-代码理解与实现(3/9)

目录:

【Pytorch深度学习实践】B站up刘二大人课程笔记——目录与索引(已完结)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Pytorch深度学习实践】B站up刘二大人之 Gradient Descend-代码理解与实现(2/9) 的相关文章

随机推荐

  • ArcFaceSDK3.0 Python Demo

    做服务外包项目需要是用虹软的人脸对比SDK xff0c 项目使用Python进行开发 xff0c 但是网上以及官方社区没有基于Python的3 0版本项目 xff0c 所以自己根据社区里大佬1 1和2 0的Demo修改套了一下 face c
  • 利用Github和Hexo搭建自己的博客

    之前的自己搭的服务器gg了 xff0c 一直也没动手继续去恢复一下 xff0c 前段时间看操作系统教程的时候被NEXT这个主题吸引了 xff0c 再次萌生了整个博客的想法 之前就有听说过Github可以搭博客 xff0c 所以这次也打算试一
  • 面向行业级应用的Kerloud 600 Pro-Cam Pod开发平台

    产品定位 Kerloud 600 Pro Cam Pod是云讷科技 xff08 深圳 xff09 有限公司为行业级无人机解决方案开发者打造的一款高级无人机研发平台 xff0c 产品搭载高算力Nvidia GPU 高清吊舱云台并配备专业的SD
  • swift-网络-URLSession学习

    URLSession 在 2013年随着 iOS7 的发布一起面世的 xff0c 苹果对它的定位是作为 NSURLConnection 的替代者 xff0c 在 iOS9 之后苹果官方已经移除了 NSURLConnection xff0c
  • nil和Nil及NULL和NSNull的区别 - OC

    其实早就想研究一下nil Nil NULL和NSNull之间的区别 xff0c 只是工作上除了nil xff0c 其它的几乎少有用到 xff0c 所以一直拖到今天 有时候感觉自己越来越浮躁 xff0c 对细微处的知识理解不够深入 xff0c
  • Fast-planner代码阅读2-TopoReplan (path searchiing部分)

    文章目录 1 总体流程2 Topo Path Finding Algorithm主要算法及图例3 topoPath路径搜索代码流程3 1 createGraph xff08 xff09 3 1 1 findVisbGUard3 1 2 ne
  • centos7.7 安装google浏览器

    centos7 7 安装google浏览器 添加google chrome 源 cd etc yum repos d vi google chrome repo 添加如下内容 google chrome name 61 google chr
  • mysql5.6漏洞_MySQL 5.6.24 Buffer Overflow

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • java获取gps 串口_从串口读取GPS数据

    网上找来的代码自己修改之后放到这里的 参考地址 xff1a http www pcppc cn kaifa VBjiaocheng kaifa 18010 html http www itqoo com programme ASPNET 2
  • 串口转以太网服务器原理,串口服务器和串口转以太网模块的区别

    现在市面上的串口转以太网产品主要有两种 xff0c 即串口服务器和串口转以太网模块 用户在开始项目前 xff0c 首先需要考虑的是选择串口服务器还是串口转以太网模块 拓普瑞 TP305V1 0 USR TCP232 24 上图所示 xff0
  • 面向未来飞车应用的Kerloud Flyingrover开发平台

    简介 飞行汽车是经常在科幻文学 影视作品中出现的酷炫元素 xff0c 充斥着人们对未来的美好憧憬 随着Google Airbus等科技巨头加入研发阵营 xff0c 配合未来新的空中交通管制系统 xff0c 汽车飞上天终将成为现实 为了满足开
  • 【转载】深蓝学院-运动规划重点笔记

    原文链接 xff1a https blog csdn net wqwqqwqw1231 article details 107310965 基于图搜索的方法 配置空间 xff1a 维度等于机器人的自由度 xff0c 可以理解为一个点可以表示
  • cmake 指定 c++ 编译_CMake入门

    前言 自从 AndroidStudio2 2 开始支持 CMAKE 来构建 C C 43 43 程序之后 xff0c 作为 Android 开发就可以使用 CMake 来替换 Android mk 了 基本使用 在学习 CMAKE 之前 x
  • 蓝牙键盘连接——输入pin码

    台式机搭配苹果蓝牙键盘时 输入键盘PIN怎么办 xff1f 硬件背景 xff1a Win10 系统台式机 xff1b TP Link 蓝牙接收器 xff1b 苹果一代妙控蓝牙键盘 问题描述 xff1a 键盘初次连接时没有问题 xff0c 跟
  • PyCharm —— 缓存过多,系统盘释放(已解决)

    背景 pycharm安装过好多次 xff0c 每次安装之后 xff0c 就会自动加载数据集 xff0c 数据集31Gb xff0c 原本不大的系统盘直接存满 思路 在系统盘中 xff0c 有一个位置会缓存 pycharm 的数据 xff0c
  • macOS 10.15 支持的 xcode版本

    https xcodereleases com xcode11 3 1是macOS 10 14 6支持的最后一个版本 xff0c 从11 4开始 xff0c xcode就需macOS10 15 43 最新的XCode 12也是如此
  • 【PyTorch教程】P6-P7 数据加载

    完整目录 P6 P7 数据加载P8 9 Tensorboard使用P10 11 Transform的用法P12 13 常用的tranformsP14 torchvision中的数据集的使用P15 dataloader的使用P16 nn Mo
  • 【PyTorch教程】制作数据集的标签(label)

    关于制作数据集的label xff1a 在P7视频的最后 xff0c 写了这段 xff0c 用来重新命名文件的label的img 和 label 的管理方法 xff0c 有两种 xff1a 1 用img所在文件夹的名称 xff0c 作为la
  • 【PyTorch教程】pytorch入门系列 ——土堆教程的目录及索引

    一 几句题外话 深度学习上手已经很长时间了 xff0c 还记得最初的入门是跟着B站up小土堆的一步步学起来的 xff0c 从起初的环境配置 xff0c 到现在调整整个模型的进阶 xff0c 非常感谢土堆的贡献 写这个博客的初衷是为了自己看着
  • 【Pytorch深度学习实践】B站up刘二大人之 Gradient Descend-代码理解与实现(2/9)

    开篇几句题外话 xff1a 以往的代码 xff0c 都是随便看看就过去了 xff0c 没有这样较真过 xff0c 以至于看了很久的深度学习和Python xff0c 都没有能够形成编程能力 xff1b 这次算是废寝忘食的深入进去了 xff0