# 自动微分¶

MindSpore计算一阶导数方法mindspore.ops.GradOperation (get_all=False, get_by_list=False, sens_param=False)，其中get_allFalse时，只会对第一个输入求导，为True时，会对所有输入求导；get_by_listFalse时，不会对权重求导，为True时，会对权重求导；sens_param对网络的输出值做缩放以改变最终梯度。下面用MatMul算子的求导做深入分析。

[1]:

import numpy as np
import mindspore.nn as nn
import mindspore.ops as ops
from mindspore import Tensor
from mindspore import ParameterTuple, Parameter
from mindspore import dtype as mstype


## 对输入求一阶导¶

[2]:

class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.matmul = ops.MatMul()
self.z = Parameter(Tensor(np.array([1.0], np.float32)), name='z')

def construct(self, x, y):
x = x * self.z
out = self.matmul(x, y)
return out


[3]:

class GradNetWrtX(nn.Cell):
def __init__(self, net):
self.net = net

def construct(self, x, y):


[4]:

x = Tensor([[0.8, 0.6, 0.2], [1.8, 1.3, 1.1]], dtype=mstype.float32)
y = Tensor([[0.11, 3.3, 1.1], [1.1, 0.2, 1.4], [1.1, 2.2, 0.3]], dtype=mstype.float32)
print(output)

[[4.5099998 2.7       3.6000001]
[4.5099998 2.7       3.6000001]]


## 对权重求一阶导¶

GradNetWrtX结构为：

[5]:

class GradNetWrtX(nn.Cell):
def __init__(self, net):
self.net = net
self.params = ParameterTuple(net.trainable_params())

def construct(self, x, y):


[6]:

output = GradNetWrtX(Net())(x, y)
print(output)

(Tensor(shape=[1], dtype=Float32, value= [ 2.15359993e+01]),)


self.z = Parameter(Tensor(np.array([1.0], np.float32)), name='z', requires_grad=False)


## 梯度值缩放¶

self.grad_wrt_output = Tensor([[s1, s2, s3], [s4, s5, s6]])


GradNetWrtX结构为：

[7]:

class GradNetWrtX(nn.Cell):
def __init__(self, net):
self.net = net
self.grad_wrt_output = Tensor([[0.1, 0.6, 0.2], [0.8, 1.3, 1.1]], dtype=mstype.float32)

def construct(self, x, y):

print(output)

[[2.211 0.51  1.49 ]
[5.588 2.68  4.07 ]]


## 停止计算梯度¶

[ ]:

import numpy as np
import mindspore.nn as nn
import mindspore.ops as ops
from mindspore import Tensor
from mindspore import ParameterTuple, Parameter
from mindspore import dtype as mstype

class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.matmul = ops.MatMul()

def construct(self, x, y):
out1 = self.matmul(x, y)
out2 = self.matmul(x, y)
out = out1 + out2
return out

def __init__(self, net):
self.net = net

def construct(self, x, y):

x = Tensor([[0.8, 0.6, 0.2], [1.8, 1.3, 1.1]], dtype=mstype.float32)
y = Tensor([[0.11, 3.3, 1.1], [1.1, 0.2, 1.4], [1.1, 2.2, 0.3]], dtype=mstype.float32)
print(output)

[[4.5 2.7 3.6]
[4.5 2.7 3.6]]


[ ]:

output = GradNetWrtX(Net())(x, y)
print(output)

[[9.0 5.4 7.2]
[9.0 5.4 7.2]]