我们提供安全,免费的手游软件下载!
自动微分技术是大多数深度学习框架中的核心功能之一,它基于链式法则,旨在加速梯度计算,并且可以避免符号微分的表达式爆炸问题以及手动微分的困难推导问题。本文将介绍在MindSpore框架中几种自动微分的使用技巧。
以下是关于文章作者和发表信息,以及MindSpore版本信息:
Name: mindspore
Version: 2.2.13
Summary: MindSpore is a new open source deep learning training/inference framework that could be used for mobile, edge and cloud scenarios.
Home-page: https://www.mindspore.cn
Author: The MindSpore Authors
Author-email: contact@mindspore.cn
License: Apache 2.0
Location: /home/dechin/anaconda3/envs/mindspore-latest/lib/python3.7/site-packages
Requires: packaging, pillow, protobuf, asttokens, numpy, psutil, scipy, astunparse
Required-by:
首先我们定义一个函数E,其中包含三个输入变量x、y和z,其python函数实现如下:
def fE(x, y, z):
return x*z+y
在MindSpore中,只需使用grad函数便可对这个函数进行自动微分:
import mindspore as ms
from mindspore import ops, Tensor
gfE = ops.grad(fE)
x = Tensor([2.0], ms.float32)
y = Tensor([5.0], ms.float32)
print (gfE(x, y, Tensor([3.], ms.float32)))
# [3.]
接下来,我们可以配置函数中的求导位置,如下:
gfE = ops.grad(fE, grad_position=(2, ))
print (gfE(x, y, Tensor([3.], ms.float32)))
# [2.]
gfE = ops.grad(fE, grad_position=(0, 1, 2))
print (gfE(x, y, Tensor([3.], ms.float32)))
# (Tensor(shape=[1], dtype=Float32, value= [ 3.00000000e+00]),
# Tensor(shape=[1], dtype=Float32, value= [ 1.00000000e+00]),
# Tensor(shape=[1], dtype=Float32, value= [ 2.00000000e+00]))
在函数求导中,如果导数只有一项,则结果将是一个Tensor;如果针对多个输入进行求导,则结果是一个Tuple类型。
接下来,我们将讨论如何对MindSpore中的一个Cell类进行求导:
与函数求导不同,Cell类会包含超参数的概念,需要特别处理参数和超参数,以及可变参数(Parameter)和不可变参数(Tensor)的区分。下方给出了一个E类的示例:
import mindspore as ms
from mindspore import nn, Parameter, Tensor
class E(nn.Cell):
def __init__(self):
super(E, self).__init__()
self.z = Parameter(Tensor([3.], ms.float32), requires_grad=True, name='z')
def construct(self, x, y):
return x*self.z+y
我们可以使用grad函数直接对这个类进行求导:
nt = E()
gE = ops.grad(nt)
print (gE(x, y))
# [3.]
gE = ops.grad(nt, grad_position=(0, 1))
print (gE(x, y))
# (Tensor(shape=[1], dtype=Float32, value= [ 3.00000000e+00]),
# Tensor(shape=[1], dtype=Float32, value= [ 1.00000000e+00]))
然而,这种形式的求导仅对不可变的输入参数有效,不能涵盖在初始化对象时使用的可变参数。不过MindSpore内部还支持了一些可以对Cell类进行求导的类,例如GradOperation。
GradOperation类支持get_by_list参数,可以配置一些可变参数作为求导对象,如下:
nt = E()
grad_net = ops.GradOperation(get_by_list=True)(nt, nt.z)
print (grad_net(x, y))
# [2.]
总之,自动微分技术不仅速度极高,还避免了手动推导微分的繁琐。本文通过几个案例介绍了在MindSpore深度学习框架中的使用技巧。
本文首发链接为: https://www.cnblogs.com/dechinphy/p/grad_operation.html
作者ID:DechinPhy
更多原著文章: https://www.cnblogs.com/dechinphy/
请博主喝咖啡: https://www.cnblogs.com/dechinphy/gallery/image/379634.html
热门资讯