【一起撸个DL框架】3 前向传播

简介: 3 前向传播🥝3.1 前情提要上一篇:【一起撸个DL框架】2 节点与计算图的搭建

3 前向传播🥝

3.1 前情提要

上一篇:【一起撸个DL框架】2 节点与计算图的搭建

在上一节中,我们定义了加法节点和变量节点类,搭建计算图并实现了加法功能。但还有一个小问题,那就是节点类的定义中,只有父节点有值时,才能调用compute()方法计算本节点的值。而当存在多个节点串联时,就无法直接调用结果节点的compute()方法。因此,这一节我们将采用递归来解决这个问题。

2948636f553c458c88bf0bf91f20ff1e.png

3.2 前向传播:递归的forward方法

我们只需要修改Node类,在其中添加一个forword()方法。当父节点的值为空时,递归地调用forward()计算节点的值,然后再调用compute()计算本节点的值。

class Node:
    def __init__(self, parent1=None, parent2=None) -> None:
        self.parent1 = parent1
        self.parent2 = parent2
        self.value = None
    def set_value(self, value):
        self.value = value
    def compute(self):
        pass
    def forward(self):
        for parent in [self.parent1, self.parent2]:
            if parent.value is None:
                parent.forward()
        self.compute()
        return self.value

然后,我们就可以使用修改过的节点类,搭建出图1中的计算图,并计算节点add2的值。

if __name__ == '__main__':
    # 搭建计算图
    x1 = Varrible()
    x2 = Varrible()
    add1 = Add(x1, x2)
    x3 = Varrible()
    add2 = Add(add1, x3)
    # 输入
    x1.set_value(int(input('请输入x1:')))
    x2.set_value(int(input('请输入x2:')))
    x3.set_value(int(input('请输入x3:')))
    # 前向传播
    y = add2.forward()
    print(y)

运行代码效果如下:

请输入x1:1
请输入x2:2
请输入x3:3
6

3.3 再添乘法节点:搭建函数y=2x+1

函数y = 2 x + 1 y=2x+1y=2x+1的计算图如图2所示,与图1很相似,只是其中一个加法节点换成了乘法节点。但不同之处是,在函数y = 2 x + 1 y=2x+1y=2x+1的计算图中,只有x一个自变量,其余变量节点称为参数。

49b1b0684af74bfa826c48664ee94a39.png

乘法节点类的实现与加法节点差不多,如下所示:

class Mul(Node):
    def __init__(self, parent1=None, parent2=None) -> None:
        super().__init__(parent1, parent2)
    def compute(self):
        self.value = self.parent1.value * self.parent2.value

下面是图2中计算图的搭建:

if __name__ == '__main__':
    # 搭建计算图
    w = Varrible()
    x = Varrible()
    mul = Mul(w, x)
    b = Varrible()
    add = Add(mul, b)
    # 输入
    w.set_value(2)
    b.set_value(1)
    x.set_value(int(input('请输入x:')))
    # 前向传播
    y = add.forward()
    print(y)
请输入x:2
5

3.4 小结

这一节的内容比较简单,我们用递归实现了前向传播,并搭建了一个一次函数:y = 2 x + 1  


相关文章
|
7月前
【论文实操】从ACNet中得到启发:非对称卷积块的使用可以有效提高ACC。即插即用!
【论文实操】从ACNet中得到启发:非对称卷积块的使用可以有效提高ACC。即插即用!
350 0
【论文实操】从ACNet中得到启发:非对称卷积块的使用可以有效提高ACC。即插即用!
|
7月前
|
机器学习/深度学习 Java 网络架构
YOLOv5改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
YOLOv5改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
367 0
|
7月前
|
机器学习/深度学习
【一起撸个DL框架】4 反向传播求梯度
4 反向传播求梯度🥥 4.1 简介 上一篇:【一起撸个DL框架】3 前向传播 前面我们已经介绍了前向传播,而本节即将介绍的反向传播中的自动微分机制,可以说是深度学习框架的一个核心功能。因为计算图中的参数正是按照着梯度的指引来更新的。
68 0
|
7月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv8改进 | 注意力机制 | 添加全局注意力机制 GcNet【附代码+小白必备】
本文介绍了如何在YOLOv8中集成GcNet,以增强网络对全局上下文的捕获能力。GcNet通过全局上下文模块、通道和空间注意力机制提升CNN对全局信息的利用。教程详细阐述了GcNet的原理,并提供了将GcNet添加到YOLOv8的代码实现步骤,包括创建ContextBlock类、修改init.py、task.py以及配置yaml文件。此外,还提供了训练和运行示例代码。完整代码和更多进阶内容可在作者的博客中找到。
|
7月前
|
机器学习/深度学习 算法 计算机视觉
YOLOv8改进 | 注意力机制 | 添加双重注意力机制 DoubleAttention【附完整代码+小白必备】
在这个教程中,作者介绍了如何在YOLOv8图像识别模型中集成DoubleAttention模块,以提升模型捕捉长距离关系的效率。DoubleAttention通过全局和局部注意力模块捕获图像的全局和局部信息。教程详细阐述了DoubleAttention的工作原理,并提供了相应的代码实现。读者将学习到如何在YOLOv8的网络结构中添加这一组件,并给出了完整的代码示例。此外,还分享了GFLOPs的计算,以及鼓励读者尝试在不同位置添加注意力机制作为进阶练习。完整代码和更多详情可在提供的链接中获取。
|
7月前
|
机器学习/深度学习 Python
【初窥CBAM】实操版即插即用的注意力机制模块
【初窥CBAM】实操版即插即用的注意力机制模块
240 0
【初窥CBAM】实操版即插即用的注意力机制模块
|
7月前
|
机器学习/深度学习 Java 网络架构
YOLOv8改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
YOLOv8改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)
1132 0
|
7月前
|
机器学习/深度学习 算法 网络安全
【一起撸个DL框架】5 实现:自适应线性单元
5 实现:自适应线性单元🍇 1 简介 上一篇:【一起撸个DL框架】4 反向传播求梯度 上一节我们实现了计算图的反向传播,可以求结果节点关于任意节点的梯度。下面我们将使用梯度来更新参数,实现一个简单的自适应线性单元。
66 0
|
机器学习/深度学习 传感器 安全
【SIR传播】基于matlab模拟复杂网络SIR传播模型
【SIR传播】基于matlab模拟复杂网络SIR传播模型
|
机器学习/深度学习 PyTorch 算法框架/工具
Dropout的深入理解(基础介绍、模型描述、原理深入、代码实现以及变种)
Dropout的深入理解(基础介绍、模型描述、原理深入、代码实现以及变种)