MindSpore反向传播配置关键字参数

mindspore · 浏览次数 : 0

小编点评

**MindSpore中的自定义反向传播函数传参规则** 在MindSpore深度学习框架中,自定义反向传播函数需要满足一些约束条件,包括必备参数和关键字参数。 **必备参数** 必备参数是函数的输入参数,必须在函数定义中明确指定。在Bprop函数中,必备参数包括`x`和`out`。 **关键字参数** 关键字参数是函数的输出参数,可以根据需要在函数中定义。在Bprop函数中,`out`和`dout`是关键字参数。 **自定义函数的传参顺序** MindSpore允许自定义函数的传参顺序,但必须遵守以下规则: 1. 关键字参数必须位于必备参数的后面。 2. 如果有多个关键字参数,必须按从左到右的顺序排列。 **示例** ```python import mindspore as ms class Net(nn.Cell): def bprop(self, x, y, out, dout): return msnp.cos(x) + y if y is not None else msnp.cos(x) # 创建网络实例 net = Net() # 打印网络结构 print(net(x, y=1), value_and_grad(net)(x, y=0)) ``` **注意** 在自定义函数中,如果指定了多个关键字参数,它们必须以列表形式提供。

正文

技术背景

在MindSpore深度学习框架中,我们可以向construct函数传输必备参数或者关键字参数,这跟普通的Python函数没有什么区别。但是对于MindSpore中的自定义反向传播bprop函数,因为标准化格式决定了最后的两位函数输入必须是必备参数outdout用于接收函数值和导数值。那么对于一个自定义的反向传播函数而言,我们有可能要传入多个参数。例如这样的一个案例:

import mindspore as ms
from mindspore import nn, Tensor, value_and_grad
from mindspore import numpy as msnp

class Net(nn.Cell):
    def bprop(self, x, y=1, out, dout):
        return msnp.cos(x) + y
    def construct(self, x, y=1):
        return msnp.sin(x) + y

x = Tensor([3.14], ms.float32)
net = Net()
print (net(x, y=1), value_and_grad(net)(x, y=0))

但是因为在Python的函数传参规则下,必备参数必须放在关键字参数之前,也就是out和dout这两个参数要放在前面,否则就会出现这样的报错:

  File "test_rand.py", line 53
    def bprop(self, x, y=1, out, dout):
             ^
SyntaxError: non-default argument follows default argument

按照普通Python函数的传参规则,我们可以把y这个关键字参数的放到最后面去:

import mindspore as ms
from mindspore import nn, Tensor, value_and_grad
from mindspore import numpy as msnp

class Net(nn.Cell):
    def bprop(self, x, out, dout, y=1):
        return msnp.cos(x) + y
    def construct(self, x, y=1):
        return msnp.sin(x) + y

x = Tensor([3.14], ms.float32)
net = Net()
print (net(x, y=1), value_and_grad(net)(x, y=0))

经过这一番调整之后,我们发现没有报错了,可以正常输出结果,但是这个结果似乎不太正常:

[1.0015925] (Tensor(shape=[1], dtype=Float32, value= [ 1.59254798e-03]), Tensor(shape=[1], dtype=Float32, value= [ 1.25169754e-06]))

因为这里x传入了一个近似的\(\pi\),所以在construct函数计算函数值时,得到的结果应该是\(\sin(\pi)+y\),那么这里面\(y\)\(0\)\(1\)所得到的结果都是对的。但是关键问题在反向传播函数的计算,原本应该是\(\cos(\pi)+y=y-1\),但是在这里输入的\(y=0\),而导数的计算结果却是\(0\)而不是正确结果\(-1\)。这就说明,在MindSpore的自定义反向传播函数中,并不支持传入关键字参数。

解决方案

刚好前面写了一篇关于PyTorch的文章,这篇文章中提到的两个Issue就针对此类问题。受到这两个Issue的启发,我们在MindSpore中如果需要自定义反向传播函数,可以这么写:

import mindspore as ms
from mindspore import nn, Tensor, value_and_grad
from mindspore import numpy as msnp

class Net(nn.Cell):
    def bprop(self, x, y, out, dout):
        return msnp.cos(x) + y if y is not None else msnp.cos(x)
    def construct(self, x, y=1):
        return msnp.sin(x) + y

x = Tensor([3.14], ms.float32)
net = Net()
print (net(x, y=1), value_and_grad(net)(x, y=0))

简单来说就是,把原本要传给bprop的关键字参数,转换成必备参数的方式进行传入,然后做一个条件判断:当给定了该输入的时候,执行计算一,如果不给定参数值,或者给一个None,执行计算二。上述代码的执行结果如下所示:

[1.0015925] (Tensor(shape=[1], dtype=Float32, value= [ 1.59254798e-03]), Tensor(shape=[1], dtype=Float32, value= [-9.99998748e-01]))

这里输出的结果都是正确的。

当然,这里因为我们其实是强行把关键字参数按照顺序变成了必备参数进行输入,所以在顺序上一定要严格遵守bprop所定义的必备参数的顺序,否则计算结果也会出错:

import mindspore as ms
from mindspore import nn, Tensor, value_and_grad
from mindspore import numpy as msnp

class Net(nn.Cell):
    def bprop(self, x, w, y, out, dout):
        return w*msnp.cos(x) + y if y is not None else msnp.cos(x)
    def construct(self, x, w=1, y=1):
        return msnp.sin(x) + y

x = Tensor([3.14], ms.float32)
net = Net()
print (net(x, y=1), value_and_grad(net)(x, y=0, w=2))

输出的结果为:

[1.0015925] (Tensor(shape=[1], dtype=Float32, value= [ 1.59254798e-03]), Tensor(shape=[1], dtype=Float32, value= [ 2.00000000e+00]))

那么很显然,这个结果就是因为在执行函数时给定的关键字参数跟必备参数顺序不一致,所以才出错的。

总结概要

继上一篇文章从Torch的两个Issue中找到一些类似的问题之后,可以发现深度学习框架对于自定义反向传播函数中的传参还是比较依赖于必备参数,而不是关键字参数,MindSpore深度学习框架也是如此。但是我们可以使用一些临时的解决方案,对此问题进行一定程度上的规避,只要能够自定义的传参顺序传入关键字参数即可。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/bprop-kwargs.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

参考链接

  1. https://www.cnblogs.com/dechinphy/p/18179248/torch

与MindSpore反向传播配置关键字参数相似的内容:

MindSpore反向传播配置关键字参数

继上一篇文章从Torch的两个Issue中找到一些类似的问题之后,可以发现深度学习框架对于自定义反向传播函数中的传参还是比较依赖于必备参数,而不是关键字参数,MindSpore深度学习框架也是如此。但是我们可以使用一些临时的解决方案,对此问题进行一定程度上的规避,只要能够自定义的传参顺序传入关键字参...

MindSponge分子动力学模拟——体系控制(2024.05)

本文是一个比较泛的分子体系控制器实现方案,因为MindSponge分子动力学模拟框架基于Python编程语言和MindSpore框架开发,因此在高度定制化的控制器实现上有先天的优势。我们可以在MindSponge中基于力对体系进行控制、基于坐标对体系进行控制,还能基于反应坐标对体系进行控制。

昇腾开发全流程 之 MindSpore华为云模型训练

学会如何安装配置华为云ModelArts、开发板Atlas 200I DK A2, 并打通一个训练到推理的全流程思路。 > 在本篇章,首先我们开始进入训练阶段!

MindSpore梯度进阶操作

这篇文章主要介绍了mindspore深度学习框架中基于InsertGradientOf算子的进阶梯度操作。InsertGradientOf算子的功能跟此前介绍过的bprop功能有些类似,也是自定义梯度,但bprop更倾向于计算梯度,而InsertGradientOf算子更倾向于修改梯度,这里介绍了一...

基于MindSpore实现BERT对话情绪识别

本文分享自华为云社区《【昇思25天学习打卡营打卡指南-第二十四天】基于 MindSpore 实现 BERT 对话情绪识别》,作者:JeffDing。 模型简介 BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Trans

教你基于MindSpore用DCGAN生成漫画头像

本文分享自华为云社区《【昇思25天学习打卡营打卡指南-第二十天】DCGAN生成漫画头像》,作者:JeffDing。 DCGAN生成漫画头像 在下面的教程中,我们将通过示例代码说明DCGAN网络如何设置网络、优化器、如何计算损失函数以及如何初始化模型权重。在本教程中,使用的动漫头像数据集共有70,17

一文教你在MindSpore中实现A2C算法训练

文中的配置定义了 Actor-Critic 算法在 MindSpore 框架中的具体实现,包括 Actor 和 Learner 的设置、策略和网络的参数,以及训练和评估环境的配置。

MindSpore强化学习:使用PPO配合环境HalfCheetah-v2进行训练

本文分享自华为云社区《MindSpore强化学习:使用PPO配合环境HalfCheetah-v2进行训练》,作者: irrational。 半猎豹(Half Cheetah)是一个基于MuJoCo的强化学习环境,由P. Wawrzyński在“A Cat-Like Robot Real-Time L

Win11系统下的MindSpore环境搭建

本文介绍了一个在Win11系统下,通过WSL2+Docker+VSCode的方案搭建了一个mindspore-gpu的编程环境。这种方案既可以实现Linux系统编程以及部署的便捷性,又可以兼顾Windows系统强大的办公软件生态,甚至还可以借助Docker达到一定的软件可迁移性和可复制性。

这是你没见过的MindSpore 2.0.0 for Windows GPU版

摘要:一文带你看看MindSpore 2.0.0 for Windows GPU版。 本文分享自华为云社区《MindSpore 2.0.0 for Windows GPU泄漏版尝鲜》,作者:张辉 。 在看了MindSpore架构师王磊老师的帖子( https://zhuanlan.zhihu.com