美文网首页
自制框架学习-第一步

自制框架学习-第一步

作者: 平头哥2 | 来源:发表于2023-05-04 18:58 被阅读0次

第一步

类的定义

import numpy as np


def as_array(x):
    if np.isscalar(x):
        return np.array(x)
    return x


class Variable:
    def __init__(self, data):
        self.data = data
        self.grad = None  # 定义梯度
        self.creator = None  # 定义创建者

    # 设置创建变量的函数,函数是变量的创建者
    def set_creator(self, func):
        self.creator = func

    # def backward(self):
    #     f = self.creator  # 获取到函数
    #     if f is not None:  # 如果函数是None,说明变量是用户输入变量
    #         x = f.input  # 获取到函数的输入
    #         x.grad = f.backward(self.grad)  # 通过函数和当前变量计算前一个变量的梯度
    #         x.backward()  # 递归调用前一个变量的梯度

    # 递归修改为循环
    def backward(self):

        # 为了省去 y.grad = np.array(1.0), 引入如下的代码
        if self.grad is None:
            self.grad = np.zeros_like(self.data)

        funcs = [self.creator]
        while funcs:
            f = funcs.pop()
            x, y = f.input, f.output
            x.grad = f.backward(y.grad)

            if x.creator is not None:
                funcs.append(x.creator)


class Function:
    def __call__(self, input2):
        print(type(input2))
        x = input2.data
        y = self.forward(x)
        output = Variable(as_array(y))
        output.set_creator(self)  # 让输出变量保存创建者的信息,动态建立连接的核心
        self.input = input2  # 保存输入的变量
        self.output = output  # 也保存输出变量
        return output

    def forward(self, x):
        raise NotImplementedError

    def backward(self, gy):
        raise NotImplementedError


class SquareFunction(Function):

    def forward(self, x):
        y = x ** 2
        return y

    def backward(self, gy):
        x = self.input.data
        gx = 2 * x * gy
        return gx


class ExpFunction(Function):

    def forward(self, x):
        return np.exp(x)

    def backward(self, gy):
        x = self.input.data
        gx = np.exp(x) * gy
        return gx

测试

import unittest
import numpy as np

from step01 import Variable, Function, ExpFunction, SquareFunction

# class MyTestCase(unittest.TestCase):
#     def test_something(self):
#         self.assertEqual(True, False)  # add assertion here
#
#
# if __name__ == '__main__':
#     unittest.main()


f1 = SquareFunction()
f2 = ExpFunction()
f3 = SquareFunction()

inputArr = np.array(0.5)

x = Variable(inputArr)
a = f1(x)
print(a.data)
b = f2(a)
print(b.data)
y = f3(b)
print(y.data)

y.grad = np.array(1.0)
b.grad = f3.backward(y.grad)
print(b.grad)
a.grad = f2.backward(b.grad)
print(b.grad)
x.grad = f1.backward(a.grad)
print(x.grad)

assert y.creator == f3
assert y.creator.input == b
assert y.creator.input.creator == f2
assert y.creator.input.creator.input == a
assert y.creator.input.creator.input.creator == f1
assert y.creator.input.creator.input.creator.input == x

# 反向传播的计算流程
# 1. 获取函数
# 2. 获取函数的输入
# 3. 调用函数的backward方法

# 从y到b的反向传播
f3 = y.creator
b = f3.input
b.grad = f3.backward(y.grad)

# 从b到a的反向传播
f2 = b.creator
a = f2.input
a.grad = f2.backward(b.grad)

# 从 a 到 x 的方向传播
f1 = a.creator
x = f1.input
x.grad = f1.backward(a.grad)
print(x.grad)

# 通过递归来计算梯度
y.grad = np.array(1.0)
y.backward()
print(x.grad)


def square(x):
    return SquareFunction()(x)


def exp(x):
    return ExpFunction()(x)


x = Variable(np.array(0.5))
a = square(x)
b = exp(a)
y = square(b)

y.grad = np.array(1.0)
y.backward()
print("------------------")
print(x.grad)

相关文章

  • 自制UI框架

    代码使用文档 搭建 vue + parcel (后期改用vue-cli)测试采用 karma + mocha持续集...

  • #新年觉醒Day10#《成功,动机与目标》:自制与乐观

    自制力 分两点来谈自制力,一是自制力的锻炼,二是自制力的恢复。 提高自制力力的第一步是找一件符合自己生活状态及当前...

  • 设计模式--命令模式

    架构学习经验(学习分析框架的思想) 第一步:基本概念(了解)第二步:确定框架模式第三步:分析角色(每一种设计模式里...

  • Cackle,cackle,Mother Goose

    第一步:跟着阅读手册搭建学习框架一、课前引导1、带着Who、Where、When、What、How去观察图片,引导...

  • 一篇就够 | 教你用maven搭建自己的开发框架

    这篇文章先会讨论什么是"框架",然后向你展示一个基于 maven 特性搭建的自制开发框架与该框架的使用示例,最后将...

  • 工作六年,才懂了那句“不懂项目管理,还敢拼职场”

    因为工作的需要,决定系统学习项目管理。 要学习当然第一步是建立框架,可是最为经典的PMBOOK看着无从下手,于是,...

  • laravel之一二

    第一天:开始学习laravel 框架 首先 了解 laravel的运行流程 第一步:包含自动加载文件 requir...

  • 吃饱了才能撑着

    第一天:开始学习laravel 框架 首先 了解 laravel的运行流程 第一步:包含自动加载文件 requir...

  • React简单入门

    前几天学习了React框架的一些基础知识,这里就做个总结吧: 开发环境 在学习React的时候第一步就难住了,那就...

  • 2022-11-02

    1、白天要把每个模型细细的细致化,弄的完全掌握,要和其他知识链接,用起来 2.学习就是学习内容的框架,这是第一步 ...

网友评论

      本文标题:自制框架学习-第一步

      本文链接:https://www.haomeiwen.com/subject/wkaxsdtx.html