谷歌推出Tangent開源庫,在Python源代碼上做自動微分
谷歌今天推出了一個新的開源Python自動微分庫:Tangent。
和現有的機器學習庫不同,Tangent是一個源代碼到源代碼的系統,使用Python函數f,并用一個新的Python函數來計算f的梯度。這能幫用戶更好地看清梯度計算,并更簡單地對梯度進行用戶級編輯和調試。
此外,Tangent還有更多調試和設計機器學習模型的功能:
- 輕松調試反向傳遞過程(backward pass)
- 快速的gradient surgery
- 正向模式自動微分
- 高校的Hessian向量積
- 代碼優化
本文簡要介紹了Tangent API,包括如何用它在Python中生成易于理解、調試和修改的梯度代碼。
神經網絡為機器學習帶來了巨大的進步,而我們訓練神經網絡來完成各類任務的基本思想已經存在30年了,它就是反向模式自動微分(reverse-mode automatic differentiation),也就是我們常說的反向傳播(backpropagation)。反向傳播的過程包含兩次通過神經網絡:首先是運行“正向傳遞”來計算每個節點的輸出值,然后再運行“反向傳遞”計算一系列導數,來確定如何更新權重以提高模型準確性。
訓練神經網絡、研究新架構,就需要我們正確、高效、方便地計算這些導數。當模型訓練不好時,或者嘗試構建我們不了解的新東西時,也需要能調試這些導數。自動微分(簡稱autodiff)就能夠計算里表示某些數學函數的計算機程序的導數,而且幾乎所有機器學習庫都能實現它。
現有的機器學習庫通過跟蹤程序的執行(在運行時,比如TensorFlow Eager、PyTorch、Autograd),或者構建動態數據流圖然后微分它(提前,比如TensorFlow)來實現自動微分。
Tangent采用了與它們都不同的方式,在Python源代碼上提前執行自動微分,并生成Python源代碼作為輸出。
于是,你可以像讀取程序其他部分一樣,來讀取自動導數代碼。
對于那些不僅想用Python來寫模型,還想在不犧牲速度和靈活性的情況下來讀取、調試自動生成的導數代碼的研究人員和學生來說,Tangent非常有用。
檢查和調試Tangent模型不需要特殊的工具,Tangent可以在Python龐大又不斷增長的子集上工作,為其他Python機器學習庫提供它們所沒有的自動微分特性。它性能高,且與TensorFlow、NumPy兼容。
怎樣自動為Python代碼生成導數呢?
像tf.exp或tf.log這樣的數學函數具有導數,我們可以編寫出來構建反向傳遞,子例程、條件、循環等語法片段也同樣具有反向傳遞版本。Tangent能為任何Python語法、以及很多Numpy和TensorFlow函數調用生成導數代碼。
Tangent有一個單一功能API:
下面的動圖展示了當我們在Python函數上調用tangent.grad時會發生什么:
如果你想列出自己的導數,可以運行:
對于Python語法的導數和TensorFlow Eager函數,Tangent有一個巨大的recipe庫。tangent.grad會抓取你傳遞給它的Python函數源代碼,然后反向遍歷它,從自己的庫中查找匹配的反向傳遞recipe,并把它加到導數函數的末尾。
這項技術的名字——反向模式自動微分——就來源于這種逆向處理。
上面的函數df只適用于張量(非數組)輸入。Tangent也支持:
- 用TensorFlow Eager函數來處理數組
- 子例程
- 控制流
谷歌在博客文章中強調,雖然Tangent從支持TensorFlow Eager開始,但它并不和某一個庫綁定,他們也愿意接受添加PyTorch或者MXNet導數recipe的請求。