近日,谷歌在其官方博客上開源了「Tangent」,一個(gè)用于自動(dòng)微分的源到源 Python 庫;它通過 Python 函數(shù) f 生成新函數(shù),來計(jì)算 f 的梯度,從而實(shí)現(xiàn)更好的梯度計(jì)算可視化,幫助用戶更容易地編輯和調(diào)試梯度;本文還扼要概述了 Tangent API,包括如何使用 Tangent 在 Python 中生成易于理解、調(diào)試和修改的梯度代碼。
Tangent 是一個(gè)免費(fèi)、開源的新 Python庫,用于自動(dòng)微分。和目前已有的機(jī)器學(xué)習(xí)庫不同,Tangent 是一個(gè)源到源(source-to-source)的系統(tǒng),利用 Python 函數(shù) f 生成一個(gè)新的 Python 函數(shù),來計(jì)算 f 的梯度。這為用戶提供了更好的梯度計(jì)算可視化,使用戶可以容易地對(duì)梯度進(jìn)行編輯和調(diào)試。Tangent 在調(diào)試和設(shè)計(jì)機(jī)器學(xué)習(xí)模型上有如下特征:
易于調(diào)試反向傳播過程
快速編輯和調(diào)試梯度
正向模式(Forward mode)自動(dòng)微分
高效的 Hessian 向量內(nèi)積(Hessian-vector products)
代碼優(yōu)化
本文對(duì) Tangent API 進(jìn)行了概述,包括如何使用 Tangent 在 Python 中生成易于理解、調(diào)試和修改的梯度代碼。
神經(jīng)網(wǎng)絡(luò)(NN)使機(jī)器學(xué)習(xí)模型處理圖像、視頻、音頻和文本的能力出現(xiàn)巨大進(jìn)步。訓(xùn)練神經(jīng)網(wǎng)絡(luò)在這些任務(wù)上獲得高性能的基本抽象概念是一個(gè)有著 30 年歷史的思想——「反向模式自動(dòng)微分」(也叫做反向傳播),它由神經(jīng)網(wǎng)絡(luò)中的兩個(gè)傳播過程組成:首先運(yùn)行「前向傳播」計(jì)算每一個(gè)節(jié)點(diǎn)的輸出,然后運(yùn)行「反向傳播」計(jì)算一系列導(dǎo)數(shù)以決定權(quán)重的更新率,從而提高模型的準(zhǔn)確性。
訓(xùn)練神經(jīng)網(wǎng)絡(luò)和在新型架構(gòu)上做研究需要準(zhǔn)確、高效和簡易地計(jì)算這些導(dǎo)數(shù)。當(dāng)模型訓(xùn)練結(jié)果不好時(shí),或者嘗試建立一些尚未理解的東西時(shí),調(diào)試這些導(dǎo)數(shù)的能力非常必要。自動(dòng)微分,或簡稱為「autodiff」,是一種計(jì)算表征一些數(shù)學(xué)函數(shù)的計(jì)算機(jī)程序的導(dǎo)數(shù)的技術(shù),并可以在幾乎所有的機(jī)器學(xué)習(xí)庫中實(shí)現(xiàn)。
目前已有的庫通過追蹤程序的執(zhí)行(在運(yùn)行時(shí),比如 TF Eager、PyTorch 和 Autograd)或建立動(dòng)態(tài)數(shù)據(jù)流圖然后對(duì)圖微分(預(yù)編,比如 TensorFlow),實(shí)現(xiàn)自動(dòng)微分。與之相反,Tangent 能自主在 Python 源代碼上進(jìn)行預(yù)編的自動(dòng)微分,并生成 Python 源代碼作為其輸出。
因此,你可以把自動(dòng)微分代碼當(dāng)做程序的余下部分進(jìn)行閱讀。對(duì)于那些不僅想在 Python 編寫模型,還希望在不犧牲速度和靈活性的前提下閱讀和調(diào)試自動(dòng)生成導(dǎo)數(shù)的代碼的研究者和學(xué)生,Tangent 是很有用的。
用 Tangent 編寫的模型易于檢查和調(diào)試,而不需要特殊的工具或間接的方式。Tangent 能提供其它 Python 機(jī)器學(xué)習(xí)庫沒有的額外自動(dòng)微分的特征,具有強(qiáng)大的性能,并和 TensorFlow 以及 Numpy 兼容。
Python 代碼的自動(dòng)微分
我們?nèi)绾巫詣?dòng)生成純 Python 代碼的導(dǎo)數(shù)?數(shù)學(xué)函數(shù)比如 tf.exp 或 tf.log 含有可以用來構(gòu)建反向傳播的導(dǎo)數(shù)。相似地,句法片段(比如子程序、條件和循環(huán))也有反向傳播版本。Tangent 有辦法為每個(gè) Python 句法片段生成生成導(dǎo)數(shù)代碼,同時(shí)調(diào)用很多的 NumPy 和 TensorFlow 函數(shù)。
Tangent 有一個(gè)單一函數(shù) API:
下面的動(dòng)圖展示了如何一個(gè) Python 函數(shù)上調(diào)用 tangent.grad:
在 hood 之下,tangent.grad 首先抓取你傳遞給它的 Python 函數(shù)源代碼。Tangent 有一個(gè) Python 句法導(dǎo)數(shù)和 TensorFlow Eager 函數(shù)的大型方法庫。tangent.grad 函數(shù)逆序運(yùn)行你的代碼,查找匹配的反向傳播方法,并將其添加到導(dǎo)數(shù)函數(shù)的尾部。這一逆序處理技術(shù)被稱之為反向模式自動(dòng)微分(reverse-mode automatic differentiation)。
df 函數(shù)只適用于標(biāo)量(非數(shù)組)輸入。Tangent 同樣支持
使用 TensorFlow Eager 函數(shù)處理數(shù)字?jǐn)?shù)組
子程序
控制流
盡管我們從 TensorFlow Eager 支持開始,Tangent 并沒有受限于任何數(shù)字庫,我們非常歡迎添加 PyTorch 或 MXNet 導(dǎo)數(shù)方法的請(qǐng)求。
下一步
Tangent 現(xiàn)在是開源的(github.com/google/tangent),但仍處于試驗(yàn)階段,難免存在一些 bug,如果你能在 GitHub 上指出,我們將很快修復(fù)。
我們正致力于在 Tangent 支持 Python 語言的更多屬性(比如閉包、內(nèi)嵌函數(shù)定義、類、更多的 Numpy 和 TensorFlow 函數(shù)),同樣計(jì)劃在未來添加更多高級(jí)的自動(dòng)微分和編譯功能,比如內(nèi)存與計(jì)算之間的自動(dòng)博弈,更主動(dòng)的優(yōu)化以及λ升降。最后,我們非常期望能與社區(qū)一起開發(fā) Tangent。