牛客题解 | 实现基本自动微分操作

news/2025/3/12 13:03:23/文章来源:https://www.cnblogs.com/wc529065/p/18767303

题目

题目链接

实现基本自动微分操作(Basic Automatic Differentiation)是一种常用的自动微分方法,用于计算函数的导数。
所谓的自动计算微分,就是通过计算图,从输入到输出,反向传播,计算每个节点的导数。而这个计算图,通俗点来说就是高中所学到的链式法则需要画的函数关系图,也可以理解为深度学习中神经网络的结构图。
举个例子来说:假设有函数\(f(x) = ReLU(x^2 + 2x + 1)\),那么其计算图可以大致表示为以下几层:

  1. 第一层为输入值x
  2. 第二层为两个节点,分别为\(x^2\)\(2x\)
  3. 第三层为一个节点,为\(x^2 + 2x + 1\)
  4. 第四层为一个节点,为\(ReLU(x^2 + 2x + 1)\),也即是\(f(x)\)
    那么在前向传播中,从输入开始,根据计算图的结构,就可以算出来每一个节点的值;在反向传播中,从输出开始,根据计算图的结构,即每条边对应的函数的导数是可知的,就可以算出来每一个节点的导数。这里不再赘述。
    在本题中,Value类的前驱节点通过children参数初始化为一个集合,则是因为在实际上,对于一个节点来说,并不需要知道前驱节点的顺序,只需要知道前驱节点是谁即可。而对于整个计算图来说,并不需要知道每一层的连接方式具体是什么,只需要知道每一层有哪些节点即可。

总的来说,整个流程可以归结为以下几个步骤:

  1. 构建计算图(神经网络),这在main函数中已经给出。
  2. 前向传播,计算每个节点的值
    从输入开始,根据计算图的结构,计算每个节点的值。
  3. 反向传播,计算每个节点的导数
    从输出开始,根据计算图的结构,计算每个节点的导数,这里用到的最关键的技术就是链式法则,此处不再赘述。由于选择集合作为前驱节点的存储结构,你需要通过拓扑排序来计算每个节点的导数。具体细节可参考图论的算法。

值得注意的是,在本题的代码中,你需要将梯度进行累加,而不是直接赋值。其原因在于,一个节点往往会被多个节点所使用,因此需要将所有使用该节点的节点的梯度进行累加。

标准代码如下

class Value:def __init__(self, data, _children=(), _op=""):self.data = dataself.grad = 0self._backward = lambda: Noneself._prev = set(_children)self._op = _opdef __add__(self, other):other = other if isinstance(other, Value) else Value(other)out = Value(self.data + other.data, (self, other), "+")def _backward():self.grad += out.gradother.grad += out.gradout._backward = _backwardreturn outdef __mul__(self, other):other = other if isinstance(other, Value) else Value(other)out = Value(self.data * other.data, (self, other), "*")def _backward():self.grad += other.data * out.gradother.grad += self.data * out.gradout._backward = _backwardreturn outdef relu(self):out = Value(0 if self.data < 0 else self.data, (self,), "ReLU")def _backward():self.grad += (out.data > 0) * out.gradout._backward = _backwardreturn outdef backward(self):topo = []visited = set()def build_topo(v):if v not in visited:visited.add(v)for child in v._prev:build_topo(child)topo.append(v)build_topo(self)self.grad = 1for v in reversed(topo):v._backward()def __repr__(self):return f"Value(data={self.data}, grad={self.grad})"

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Processing (Java) 中实现2D任意图形的鼠标悬停检测 2D射线检测 模拟按钮 点击事件

引言 如果使用Processing开发应用,画面中需要设定一些按钮,而且这些按钮是不规则图形样式,甚至是以一张图片形式呈现,如何判定其轮廓,定义悬停事件、点击事件是非常核心的算法需求。本文浅析这一问题的通用解决方案。因为Processing是Java衍生语言,同样适合java语言体系。…

运行窗口无法打开软件程序的解决办法

事情起因:  本人安装了 Notepad-- 文本编辑软件,但是通过Win+R,打开运行窗口,输入Notepad-- 无法打开该软件;报错如下: 解决办法  此电脑-属性-高级系统设置-高级-环境变量  在 系统变量 里,找到 Path 变量 添加软件安装路径,并上移 确定保存,电脑重启,系统环…

牛客题解 | 为数据集行创建复合超向量

牛客题库题解题目 题目链接 复合超向量是一种将多个向量组合成一个向量的方法,其计算公式为: \[composite\ hypervector = \sum_{i=1}^{n} w_i \times v_i \]其中,\(w_i\) 是权重,\(v_i\) 是向量。 在本题中,这是一个使用超维计算(HDC)的任务,需要通过以下步骤处理数据…

【设计模式】从事件驱动到即时更新:掌握观察者模式的核心技巧

概述 定义:又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 结构 在观察者模式中有如下角色:Subject:抽象主题(抽象被…

【设计模式】探索状态模式在现代软件开发中的应用

概述 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能进行开门操作,而如果电梯门是停止状态,就可以执行开门操作。 类图如下:代码…

团队展示 (组长:金帝彪)

一、团队介绍 1.1 团队概况 1.1.1 博客展示链接 团队名称,彩虹小分队 https://www.cnblogs.com/JINjin20040207 1.1.2 团队项目描述 健康体重管理平台 1.1.3 队员风采 姓名:金帝彪 风格:谋定后动 擅长的技术:业务分析 编程的兴趣:C 希望的软工角色:业务分析师 一句话宣言:…

3.12 数字逻辑电路

1.时序逻辑电路 1.1 与组合逻辑电路(比如译码器,多路选择器,全加法器)的区别:时许逻辑电路可以存储信息 1.2 基本存储元件 1.2.1 RS锁存器(存储一个byte位的信息)(低电频使能) R:reset复位;S:set置位 R和S是两个输入端,A和B希望是两个取反状态 当S=0,表示要置位(低…

day:19 html实战

一、认识标签 1、标题标题 h1--h6 格式: <!doctype html>认识标签第一大标题 第二大标题 第三大标题 第四大标题 第五大标题 第六大标题 </body>2、常用标签 代码:常用标签段落标签,也叫p标签 斜体标签,也叫em标签 b标签,也是加粗 斜体标签 加粗标签 下划线 删…

Properties-读取配置文件中的内容

读取配置文件中的内容Properties-读取配置文件中的内容 新建子项目properties 修改POM 父POM中加上子项目module。子项目依赖父项目,打包方式jar。引入spring-boot-configuration-processor和lombok(Lombok 的安装与使用)spring-boot-configuration-processor的作用是生成配置…

matlab实现Arduino的PIL硬件仿真

使用 Arduino 硬件上的 PIL 进行代码验证和验证1. 尝试arduino的PIL程序例程-arduino_pil_bolck 1.1 准备安装包 安装arduino 硬件支持包安装编辑器MinG-w64 1.2实现步骤https: //ww2.mathworks.cn/help/simulink/supportpkg/arduino_ref/code-verification-and-validation-wit…

【设计模式】责任链模式教你如何优雅地分发任务

概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必…

macOS Sequoia 15.3.2 (24D81 | 24D2082) 正式版 ISO、IPSW、PKG 下载

macOS Sequoia 15.3.2 (24D81 | 24D2082) 正式版 ISO、IPSW、PKG 下载macOS Sequoia 15.3.2 (24D81 | 24D2082) 正式版 ISO、IPSW、PKG 下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org…