网站模板之家免费模板,哈尔滨网站建设30t,德国 网站建设,搭建一个平台要多少钱上一篇关于反向传播的代码仅支持单变量的梯度计算#xff0c;下面我们将扩展代码使其支持多个输入/输出。增加了对多输入函数#xff08;如 Add#xff09;#xff0c;以实现的计算。
1.关于前向传播可变长参数的改进-修改Function类 修改方法#xff1a; Function用于对…上一篇关于反向传播的代码仅支持单变量的梯度计算下面我们将扩展代码使其支持多个输入/输出。增加了对多输入函数如 Add以实现的计算。
1.关于前向传播可变长参数的改进-修改Function类 修改方法 Function用于对输入输出做规定帮助实现右图的效果接受inputs 返回outputs 2.关于反向传播可变长参数的改进 修改函数类的反向传播 修改Variable类的反向传播
改进前 获取y.creator,获取输入creator.inputs根据y.grads计算x.grads:creator.backward(y.grads)
2.3两步的解包和打包操作 最后修改square方法 完整代码
import numpy as npclass Variable:def __init__(self, data):if data is not None:if not isinstance(data, np.ndarray):raise TypeError({} is not supported.format(type(data)))self.data dataself.grad Noneself.creator Nonedef set_creator(self, func):self.creator funcdef backward(self):if self.grad is None:self.grad np.ones_like(self.data)funcs [self.creator]while funcs:f funcs.pop()gys [output.grad for output in f.outputs] # 获取所有输出的梯度gxs f.backward(*gys) # 调用 backward 方法if not isinstance(gxs, tuple): # 确保 gxs 是元组gxs (gxs,)for x, gx in zip(f.inputs, gxs): # 为每个输入分配梯度x.grad gxif x.creator is not None:funcs.append(x.creator)class Function:def __call__(self, *inputs):xs [x.data for x in inputs] # 提取输入数据ys self.forward(*xs) # 前向传播解包if not isinstance(ys, tuple): # 确保 ys 是元组ys (ys,)outputs [Variable(as_array(y)) for y in ys] # 创建输出变量for output in outputs:output.set_creator(self)self.inputs inputs # 保存输入self.outputs outputs # 保存输出return outputs if len(outputs) 1 else outputs[0] # 根据输出数量返回def forward(self, *xs):raise NotImplementedError()def backward(self, *gys):raise NotImplementedError()# 实现具体的函数类
class Square(Function):def forward(self, x):return x ** 2def backward(self, gy):x self.inputs[0].data # 从 inputs 中获取数据gx 2 * x * gyreturn gxclass Add(Function):def forward(self, x0, x1):y x0 x1return ydef backward(self, gy):return gy, gy # 对两个输入返回相同的梯度# 定义便捷函数
def square(x):return Square()(x)def add(x0, x1):return Add()(x0, x1)# 定义 as_array 函数
def as_array(x):if np.isscalar(x):return np.array(x)return x# 测试代码
x Variable(np.array(2.0))
y Variable(np.array(3.0))
z add(square(x), square(y))
z.backward()
print(z.data) # 输出结果: 13.0 (2^2 3^2 4 9 13)
print(x.grad) # 输出梯度: 4.0 (dz/dx 2 * 2 4)
print(y.grad) # 输出梯度: 6.0 (dz/dy 2 * 3 6)
运行结果