首页 > 编程知识 正文

Python函数,python 求导

时间:2023-05-04 04:18:41 阅读:112745 作者:1628

动机

作者fzdlz

因为最近求出了各种导数,所以想写自动求出导数的算法。 其实,python的theano有这个功能,但是仔细想想,想法并不难,就动手实现了一个。

我本想在C上实现,但在C上写了各种各样的问题,发现内存管理、操作人员过载都不如意。 花了点时间,决定换个词。 Java是第一种熟练语言,但不支持操作员重载。 我该怎么办? 于是转战了python。

源代码路径

想法

##函数的显示

将函数表达式表示为表达式树。

这个表达式树是怎么构建的? 你自己写语法分析吗? 因为很麻烦,所以有一种比较简单的方法,就是使用操作员重载来实现。

定义e类,重载其- */** (幂)操作,并在重载过程中构建二叉树。

节点类型

此表达式树主要需要三种节点类型。

其一,常数节点。 例如2、3

其二,变量节点,例如a、b、x、y等。

其三,操作节点。 例如-、*、/、乘方等。

寻求指引

如果有由公式构成的二叉树,接下来就要寻求指导。

推导常数节点后,结果为0。

向变量节点寻求引导有两种情况。 例如

$$f(a,b )=a^2) 3b$$

如果该函数对$a$求偏导数,则b节点被视为常数,求导数的结果为0。

对于保存有a的节点,求导结果为1。

寻求指引的方法是寻求这些指引的公式,例如:

$$(xy ) )=x' y' $$

上式是对根为‘’的二叉树,分别对左边的子树和右边的子树求导,将求导的结果相加而成。

那么,如何引导左边的树呢? 递归调用这个引导方法就可以了。

乘方节点很难处理。

首先向左边的子树f求导,向右边的子树g求导。

f求导为0表示指数函数,g求导为0表示幂函数,分别适用公式。

对于$f(x ) ^g ) x ) $这种形式,推导公式有点复杂,需要请教数学上快的车。 我还没做。

简化

求导不是最难的事,最难的是简化。 例如,1/(1e^(-) w*xb () ) ) ) ) )根据上述算法进行推导,结果如下:

(0* ) 1e^(-) w*xb ) ) (-1e^ )-(w * XB ) ) )0* (w * XB )-) )1*xw*0) ) ) 1e ) 652

这需要简化。 我实现了简化的几个构想:

)1)将0 x、x 0 x-0这一简单化设为x。0x x0 0/x降级为0

在上图中,左图的c节点为0时,请使a直接指向d。 删除c和b节点。 右图为1x图,请使a直接指向d。

)2)直接简化为x1 1x x/1

)3)两个常数进行运算,F F、F-F、F F、F/F均简化为单个节点。

)4)更复杂的节点集成。

在上图中,右边的子树有3个算法,左边的子树有4个算法

如果右边的子树是常量节点,请在左边的子树中找到与p点节点符号相同的节点。 经过三个星号,找到了4,然后是3*4 -12。 然后,我们删除了原始p指向的节点,使p直接指向原始左侧的树。

(5) $x*x=x^2 $

(6) $ 0-x=-1*x $

)7) x^1=x

(8) log e - 1

代码实现

本项目

运行测试

以sigmoid函数为例,求导。

求导函数

1/(1e^(-) w*xb ) )

求导后,精简前

(0* ) 1e^(-) w*xb ) ) (-1e^ )-(w * XB ) ) )0* (w * XB )-) )1*xw*0) ) ) 1e ) 652

简化后,中间也有1。 问题在哪里,太晚了,我查不出来。 结果是正确的。

e^(-) w*xb ) )1*x/) 1e^(-) w*xb ) ) 2

托多

分数化简

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。