TVP

# 手搓自动微分

DechinPhy

1430

## 自动微分框架的使用

import numpy as np
from mindspore import numpy as msnp
# 定义一个自变量x
x = Tensor(np.array([1., 2., 3.], np.float32))
# 定义一个复合函数
f = lambda x: msnp.sin(msnp.cos(x))
# 函数求导
# 计算自动微分结果
print (gf(x))
# [-0.7216062  -0.831692   -0.07743199]

print (-msnp.cos(msnp.cos(x))*msnp.sin(x))
# [-0.7216062  -0.831692   -0.07743199]

## 手搓自动微分

import numpy as np
class SIN:
def __call__(self, x):
"""计算正弦值"""
return np.sin(x)
"""计算正弦函数的导数值"""
return np.cos(x)

def grad(obj):
"""直接调用输入操作的自动微分函数"""
return obj.__grad__

class ValueAndGrad:
def __init__(self, obj):
"""初始化输入对象的求值函数和求导函数"""
self.obj1 = obj
def __call__(self, x):
"""用元组的形式将值和导数的计算结果返回"""
return (self.obj1(x), self.obj2(x))
"""初始化求值求导对象"""
return ValueAndGrad(obj)

class SIN:
def __init__(self, obj=None):
"""给定一个其他的函数"""
self.obj = obj
def __call__(self, x):
"""没有复合函数时直接返回结果，有复合函数就递归计算"""
return np.sin(x) if self.obj is None else np.sin(self.obj(x))
"""没有复合函数时直接返回导数结果，有复合函数就按照链式法则递归计算"""
return COS()(x) if self.obj is None else COS()(self.obj(x))*self.obj.__grad__(x)

import numpy as np
import mindspore as ms
from mindspore import Tensor
from mindspore import numpy as msnp

class SIN:
"""自定义正弦类"""
def __init__(self, obj=None):
self.obj = obj
def __call__(self, x):
return np.sin(x) if self.obj is None else np.sin(self.obj(x))
return COS()(x) if self.obj is None else COS()(self.obj(x))*self.obj.__grad__(x)

class COS:
"""自定义余弦类"""
def __init__(self, obj=None):
self.obj = obj
def __call__(self, x):
return np.cos(x) if self.obj is None else np.cos(self.obj(x))
return -SIN()(x) if self.obj is None else -SIN()(self.obj(x))*self.obj.__grad__(x)

"""自定义求值求导类"""
def __init__(self, obj):
self.obj1 = obj
def __call__(self, x):
return (self.obj1(x), self.obj2(x))

"""自定义求导函数"""

"""自定义求值求导函数"""

# 定义自变量
x = np.array([0., 1., 2., 3.,], np.float32)
# 单体函数验证
assert np.allclose(SIN()(x), np.sin(x))
# 单体函数求导验证
# 单体函数求值求导验证
assert np.allclose(v, np.sin(x))
assert np.allclose(g, np.cos(x))
# 双复合函数验证
assert np.allclose(SIN(SIN())(x), np.sin(np.sin(x)))
assert np.allclose(SIN(COS())(x), np.sin(np.cos(x)))
assert np.allclose(COS(SIN())(x), np.cos(np.sin(x)))
assert np.allclose(COS(COS())(x), np.cos(np.cos(x)))
# 三复合函数验证
assert np.allclose(SIN(COS(SIN()))(x), np.sin(np.cos(np.sin(x))))
# 双复合函数求导验证
tensor_x = Tensor(x, ms.float32)
ms_func1 = lambda x: msnp.sin(msnp.cos(x))
ms_func2 = lambda x: msnp.cos(msnp.sin(x))
ms_func3 = lambda x: msnp.cos(msnp.sin(msnp.cos(x)))
# 三复合函数求导验证
assert np.allclose(grad(COS(SIN(COS())))(x), msgrad(ms_func3)(tensor_x).asnumpy())

0 条评论

LV.

• 技术背景
• 链式法则
• 自动微分框架的使用
• 手搓自动微分
• 总结概要
• 版权声明