神经网络反向传播算法

今天我们来看一下神经网络中的反向传播算法,之前介绍了梯度下降与正向传播~       神经网络的反向传播

专栏:💎实战PyTorch💎

反向传播算法(Back Propagation,简称BP)是一种用于训练神经网络的算法。 

反向传播算法是神经网络中非常重要的一个概念,它由Rumelhart、Hinton和Williams于1986年提出。这种算法基于梯度下降法来优化误差函数,利用了神经网络的层次结构来有效地计算梯度,从而更新网络中的权重和偏置。

基本工作流程:

  1. 通过正向传播得到误差,所谓正向传播指的是数据从输入到输出层,经过层层计算得到预测值,并利用损失函数得到预测值和真实值之前的误差。
  2. 通过反向传播把误差传递给模型的参数,从而对网络参数进行适当的调整,缩小预测值和真实值之间的误差。
  3. 反向传播算法是利用链式法则进行梯度求解,然后进行参数更新。对于复杂的复合函数,我们将其拆分为一系列的加减乘除或指数,对数,三角函数等初等函数,通过链式法则完成复合函数的求导。

我们通过一个例子来简单理解下 BP 算法进行网络参数更新的过程🧧:

如图我们在最下边输入两个维度的值进入神经网络:0.05、0.1 ,经过两个隐藏层(每层两个神经元),每个神经元有两个值,左边为输入值,右边是经过激活函数后的输出值;经过这个神经网络后的输出值为:m1、m2,实际值为0.01、0.99 🌠

设置的初始权重w1,w2,...w8分别为0.15、0.20、0.25、0.30、0.30、0.35、0.55、0.60

我们通过计算得到损失函数Error = 1/2 ((m1- target1)2 + (m2 - target2)2) = 0.2988

w5和w7均可以通过求三次导来求梯度,而w1,w3则不能直接通过L降序求导,我们需要求从L到m1,m1到o1,o1到k1,k1到h1,h1到w1:

由于w1是输出两个方向分别到o1和o2,所以是两个方向的梯度求和~

我们也发现所以激活函数都是要可微的~

其他的网络参数更新过程和上面的求导过程是一样的,这里就不过多赘述,我们直接看一下代码。

反向传播代码 

我们先来回顾一些Python中类的一些小细节:

🌈在Python中,使用super()函数可以调用父类的方法。这在子类中重写父类方法时非常有用,因为它允许你调用父类的实现,而不是完全覆盖它

class Parent:
    def __init__(self):
        print("Parent init")

class Child(Parent):
    def __init__(self):
        super().__init__()
        print("Child init")

c = Child()

# 输出
Parent init
Child init

🌈当我们创建一个Child类的实例时,它会首先调用Parent类的__init__方法(通过super().__init__()),然后执行Child类的__init__方法,与类的__init__方法(构造方法)对应的类关闭时自动调用的方法是__del__方法。对象不再被使用时,Python解释器会自动调用这个方法。通常在这个方法中进行一些清理工作,比如释放资源、关闭文件等。

反向传播实现

import torch
import torch.nn as nn
import torch.optim as optim


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.linear1 = nn.Linear(2, 2)
        self.linear2 = nn.Linear(2, 2)

        # 网络参数初始化w1/w2/w3/w4
        self.linear1.weight.data = torch.tensor([[0.15, 0.20], [0.25, 0.30]])
        # w5/w6/w7/w8
        self.linear2.weight.data = torch.tensor([[0.40, 0.45], [0.50, 0.55]])
        # 截距b
        self.linear1.bias.data = torch.tensor([0.35, 0.35])
        self.linear2.bias.data = torch.tensor([0.60, 0.60])
    # 定义前向传播的行径
    def forward(self, x):

        x = self.linear1(x)
        x = torch.sigmoid(x)
        x = self.linear2(x)
        x = torch.sigmoid(x)

        return x


if __name__ == '__main__':

    inputs = torch.tensor([[0.05, 0.10]])
    target = torch.tensor([[0.01, 0.99]])

    # 获得网络输出值
    net = Net()
    output = net(inputs)
    # print(output)  # tensor([[0.7514, 0.7729]], grad_fn=<SigmoidBackward>)

    # 计算误差
    loss = torch.sum((output - target) ** 2) / 2
    # print(loss)  # tensor(0.2984, grad_fn=<DivBackward0>)

    # 优化方法
    optimizer = optim.SGD(net.parameters(), lr=0.5)

    # 梯度清零
    optimizer.zero_grad()

    # 反向传播
    loss.backward()

    # 打印 w5、w7、w1 的梯度值
    print(net.linear1.weight.grad.data)
    # tensor([[0.0004, 0.0009],
    #         [0.0005, 0.0010]])

    print(net.linear2.weight.grad.data)
    # tensor([[ 0.0822,  0.0827],
    #         [-0.0226, -0.0227]])

    # 打印网络参数
    optimizer.step()
    print(net.state_dict())
    # OrderedDict([('linear1.weight', tensor([[0.1498, 0.1996], [0.2498, 0.2995]])),
    #              ('linear1.bias', tensor([0.3456, 0.3450])),
    #              ('linear2.weight', tensor([[0.3589, 0.4087], [0.5113, 0.5614]])),
    #              ('linear2.bias', tensor([0.5308, 0.6190]))])
  • optimizer.step() 相当于是将w和b所有参数更新一步的过程

🌈关于nn.Linear的使用

import torch
import torch.nn.functional as F
import torch.nn as nn

# 均匀分布随机初始化

linear = nn.Linear(5, 3)
# 从0-1均匀分布产生参数
nn.init.uniform_(linear.weight)
print(linear.weight.data)

nn.Linear是PyTorch中用于创建线性层的类,也被称为全连接层。它的主要作用是将输入数据与权重矩阵相乘并加上偏置,然后通常会通过一个非线性激活函数进行转换。 

  1. 在函数内部,创建一个线性层,输入维度为5,输出维度为3;
  2. 使用nn.init.uniform_()函数对线性层的权重进行均匀分布随机初始化;
  3. 打印线性层的权重数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/586344.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

qt5-入门-2D绘图-Graphics View 架构

参考&#xff1a; Qt Graphics View Framework_w3cschool https://www.w3cschool.cn/learnroadqt/4mvj1j53.html C GUI Programming with Qt 4, Second Edition 本地环境&#xff1a; win10专业版&#xff0c;64位&#xff0c;Qt 5.12 基础知识 QPainter比较适合少量绘图的情…

蓝桥杯如何准备国赛?

目录 一、赛前准备 1、如何刷题&#xff0c;刷哪些题&#xff1f; 2、记录&#xff08;主要看个人习惯&#xff09; CSDN博客 写注释 3、暴力骗分 4、从出题人的角度出发&#xff0c;应该如何骗分 二、赛中注意事项 一、赛前准备 1、如何刷题&#xff0c;刷哪些题&…

Ubuntu 24.04安装搜狗输入法-解决闪屏问题

问题描述 在Ubuntu 24.04 LTS系统中按照官方安装指导《Ubuntu20.04安装搜狗输入法步骤》安装搜狗输入法后&#xff1a; 会出现屏幕闪烁&#xff0c;无法正常使用的问题&#xff1b;系统搜索框和gnome-text-editor无法使用搜狗输入法&#xff1b; 原因分析 闪屏可能是Ubuntu…

ESP32-C3第二路串口(非调试)串口打通(1)

1. 概述与引脚复用 《ESP32-C3 系列芯片技术规格书》中提到&#xff0c;ESP32-C3系列芯片中有两路串口。 第1路串口就是常用的调试串口&#xff0c;在笔者使用的ESP32-C3-DevKitC-02开发板中&#xff0c;这一路串口通过CP2102 USB转UART桥芯片与电脑的USB口相连接&#xff0c;…

c4d渲染动画只能渲染1帧怎么回事?c4d云渲染解决1秒停止

当您在C4D中尝试渲染动画时&#xff0c;如果只渲染出了一个静止的帧&#xff0c;这通常意味着您的设置中存在一些问题。动画本身是由一系列连续的静态图像&#xff08;帧&#xff09;组成的&#xff0c;如果只生成了一帧&#xff0c;那么显然是渲染设置出现了错误。为了解决这个…

如何利用快解析远程访问NAS、FTP、Web服务

什么是内网、外网&#xff1f; 所谓内网就是内部建立的局域网络或办公网络。一家公司或一个家庭有多台计算机&#xff0c;他们利用不同网络布局将这一台或多台计算机或其它设备连接起来构成一个局部的办公或者资源共享网络&#xff0c;我们就称它为内部网络&#xff0c;也叫内…

微服务之SpringCloud AlibabaSeata处理分布式事务

一、概述 1.1背景 一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用&#xff0c;就会产生分布式事务问题 but 关系型数据库提供的能力是基于单机事务的&#xff0c;一旦遇到分布式事务场景&#xff0c;就需要通过更多其他技术手段来解决问题。 全局事务&#xff1a;…

计算机网络4——网络层4内部路由选择协议

文章目录 一、有关路由选择协议的几个基本概念1、理想的路由算法2、分层次的路由选择协议 二、内部网关协议 RIP1、协议 RIP 的工作原理2、特点3、距离向量算法4、坏消息传播慢 三、内部网关协议 OSPF1、基本特点2、OSPF 的五种分组类型 本节将讨论几种常用的路由选择协议&…

【Mac】mac 安装 prometheus 报错 prometheus: prometheus: cannot execute binary file

1、官网下载 Download | Prometheus 这里下载的是prometheus-2.51.2.linux-amd64.tar.gz 2、现象 解压之后启动Prometheus 启动脚本&#xff1a; nohup ./prometheus --config.fileprometheus.yml > prometheus.out 2>&1 & prometheus.out日志文件&#xff…

【C++】:类和对象(下)

目录 一&#xff0c;再谈构造函数1.初始化列表2. 隐式类型转换的过程及其优化3. 隐式类型转换的使用4. explcit关键字5. 单参数和多参数构造函数的隐式类型转换 二&#xff0c;static成员1.静态成员变量2.静态成员函数 三&#xff0c;友元3.1 友元函数3.2 友元类 四&#xff0c…

Vue ui 创建vue项目,详细使用攻略。

1.安装及启动 1.1 Vue ui 使用前提是全局安装vue.js 命令如下 npm install vue -g 1.2 安装过Vue.js 之后 随便在自己系统的一个地方打开命令面板 1.3 使用命令启动vue ui面板创建项目 vue ui 如图运行后显示这种就是启动成功&#xff0c;成功之后会弹出页面或者直接访问你的…

QT5制做两个独立窗口

目录 增加第二个窗口 主窗口文件添加一个私有成员为子窗口 定义两个槽函数和 关联按钮和子窗口和主窗口 添加子窗口成员 子窗口处理函数 补充回顾 增加第二个窗口 1、 2、 3 主窗口文件添加一个私有成员为子窗口 在mainwidget.h文件 同时添加两个槽&#xff1b;来处理…

Visual studio 2019 编程控制CH341A芯片的USB设备

1、硬件 买了个USB可转IIC、或SPI、或UART的设备&#xff0c;主芯片是CH341A 主要说明USB转SPI的应用&#xff0c;绿色跳线帽选择IIC&SPI&#xff0c;用到CS0、SCK、MOSI、MISO这4个引脚 2、软件 2.1、下载CH341A的驱动 点CH341A官网https://www.wch.cn/downloads/CH34…

人工智能工具的强大之处:我用过的最好用的AI工具

人工智能工具的强大之处&#xff1a;我用过的最好用的AI工具 在当今科技迅速发展的时代&#xff0c;人工智能(AI)工具已经成为我们日常生活和工作中不可或缺的一部分。从语音助手到自动化内容创建工具&#xff0c;再到数据分析软件&#xff0c;AI的应用领域广泛且深远。本篇博…

【antd + vue】InputNumber 数字输入框 输入限制

一、需求说明 只能输入数字和小数点&#xff0c;保留小数点后两位&#xff1b;最多输入6位&#xff1b;删除所有内容时&#xff0c;默认为0&#xff1b; 二、问题说明 问题1&#xff1a;使用 precision 数值精度 时&#xff0c;超出规定小数位数时会自动四舍五入&#xff1b;…

LLM应用:让大模型prompt总结生成Mermaid流程图

生成内容、总结文章让大模型Mermaid流程图展示&#xff1a; mermaid 美人鱼, 是一个类似 markdown&#xff0c;用文本语法来描述文档图形(流程图、 时序图、甘特图)的工具&#xff0c;您可以在文档中嵌入一段 mermaid 文本来生成 SVG 形式的图形 Prompt 示例&#xff1a;用横向…

PDF 正确指定页码后,挂载的书签页码对不上

这个问题与我的另一篇中方法一样 如何让一个大几千页的打开巨慢的 PDF 秒开-CSDN博客 https://blog.csdn.net/u013669912/article/details/138166922 另做一篇原因是一篇文章附带一个与该文章主题不相关的问题时&#xff0c;不利于被遇到该问题的人快速搜索发现以解决其遇到的…

深度学习口型驱动Visemenet使用小结

说明 我前一篇博客《使用共振峰提取元音音素/从声音生成口型动画》探索了使用共振峰分析元音&#xff0c;然后从元音音素映射到视位的口型驱动方案。当时我就在想&#xff0c;如果能用深度学习法方法从音频直接生成音素流&#xff0c;然后转换成对应视位&#xff0c;不就很容易…

Vue项目打包APK----Vue发布App

时隔多年我又来跟新了&#xff0c;今天给大普家及下前端Vue傻瓜式发布App&#xff0c;话不多说直接上干货。 首先准备开发工具HBuilder X&#xff0c;去官网直接下载即可&#xff0c;算了直接给你们上地址吧HBuilderX-高效极客技巧。 打开软件&#xff0c;文件-->新建--&g…

ARM学习(27)链接库依赖学习(二)dlopen failed:library xxxx.so

笔者继续学习一下链接的依赖库。 1、起因 Android下面需要需要一个日志解码库&#xff0c;所以笔者就编译了一个parse.so来进行解码&#xff0c; 编译器&#xff1a;Clang&#xff0c;基于llvm后端的编译器平台&#xff1a;交叉编译&#xff0c;linux -> aarch64 linux An…