1. 程式人生 > 程式設計 >python中幾種自動微分庫解析

python中幾種自動微分庫解析

前言

簡單介紹下python的幾個自動求導工具,tangent、autograd、sympy;

在各種機器學習、深度學習框架中都包含了自動微分,微分主要有這麼四種:手動微分法、數值微分法、符號微分法、自動微分法,這裡分別簡單走馬觀花(hello world式)的介紹下下面幾種微分框架;

sympy 強大的科學計算庫,使用的是符號微分,通過生成符號表達式進行求導;求得的導數不一定為最簡的,當函式較為複雜時所生成的表示式樹異常複雜;

autograd自動微分先將符號微分用於基本的運算元,帶入數值並儲存中間結果,後應用於整個函式;自動微分本質上就是圖計算,容易做很多優化所以廣泛應用於各種機器學習深度學習框架中;

tangent 為源到源(source-to-source)的自動微分框架,在計算函式f微分時他通過生成新函式f_grad來計算該函式的微分,與目前所存在的所有自動微分框架都有所不同;由於它是通過生成全新的函式來計算微分所以具有非常搞的可讀性、可調式性這也是官方所說的與當前自動微分框架的重大不同;

sympy 求導

 def grad():
   # 定義表示式的變數名稱
   x,y = symbols('x y')
   # 定義表示式
   z = x**2 +y**2
   # 計算z關於y對應的偏導數
   return diff(z,y)
 func = grad()

輸出結果表示式z的導函式z‘=2*y

print(func) 

把y 等於6 帶入計算 結果 為12

print(func.evalf(subs ={'y':3}))

Autograd求偏導

 import autograd.numpy as np
 from autograd import grad
 #表示式 f(x,y)=x^2+3xy+y^2
 #df/dx = 2x+3y
 #df/dy = 3x+2y
 #x=1,y=2
 #df/dx=8
 #df/dy=7
 def fun(x,y):
  z=x**2+3*x*y+y**2
  return z
 fun_grad = grad(fun)
 fun_grad(2.,1.)

輸出:7.0

tangent求導

 import tangent
 def fun(x,y):
  z=x**2+3*x*y+y**2
  return z

預設為求z關於x的偏導數

dy_dx = tangent.grad(fun)

輸出偏導數值為 8 ,z' = 2 * x,此處x傳任何值都是一樣的

df(4,y=1)

可通過使用wrt引數指定求關於某個引數的偏導數,下面為求z關於y的偏導數

df = tangent.grad(funs,wrt=([1]))

輸出值為10,z' = 2 *y,此處x傳任何值都是一樣的

df(x=0,y=5)

上面說了那麼多也沒體現出tangent的核心:源到源(source-to-source)

在生成導函式的時候加入verbose=1引數,即可看到tangent為我們生成的用於計算導數的函式,預設情況下該值為0所以我們沒感覺到tangent的求導與別的自動微分框架有什麼區別;

 def df(x):
   z = x**2
   return z
 df = tangent.grad(df,verbose=1)
 df(x=2)

在執行完上述程式碼後,我們看到了tangent為我們所生成用於求導數的函式:

 def ddfdx(x,bz=1.0):
  z = x ** 2
  assert tangent.shapes_match(z,bz),'Shape mismatch between return value (%s) and seed derivative (%s)' % (numpy.shape(z),numpy.shape(bz))
 # Grad of: z = x ** 2
 _bx = 2 * x * bz
 bx = _bx
 return bx

ddfdx函式就是所生成的函式,從中我們也可以看到表示式z的導函式z'=2 * x,tangent就是通過執行該函式用於求得導數的;

sympy 中的自動微分只是它強大的功能之一,autograd 從名字也可知它就是為了自動微分而生的,tangent初出茅廬2017年底Google才釋出的自動微分方法也比較新穎,從17年發v0.1.8版本後也沒見發版,原始碼更新也不夠活躍;sympy、autograd比較成熟,tangent還有待觀察;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。