選自Medium,做者:Alex Wiltschko、Dan Moldovan、Wolff Dobson,機器之心編輯部。git
近日,谷歌發佈了一項新的 TensorFlow 工具「AutoGraph」,能將 print() 函數和其它 Python 代碼轉化爲純 TensorFlow 計算圖代碼。這一工具極大地增強了 TensorFlow 在調用純 Python 語句時的性能,開發者能夠輕鬆在 TensorFlow 上實現更好的模型性能。
項目地址:github.com/tensorflow/…github
通常而言,在寫 TensorFlow 代碼時,咱們須要構建整個算法的計算圖,或者規劃全部數據流的計算過程,而後再投入數據並快速執行整個或局部計算圖。固然由於當前 PyTorch 和 Keras 等動態計算圖的流行,TensorFlow 也發佈了 Eager Execution,它能夠幫助用戶自動構建計算圖。但通常的 TensorFlow 仍是常使用靜態計算圖的方式,由於它的構建邏輯與部署都很是有優點。算法
然而對於入門開發者而言,理解靜態計算圖是比較困難的,所以很容易引發開發者的困惑。尤爲是在一些涉及更復雜模型場景中,例如使用 if 和 while 等 Python 語句,或使用 print() 與接受結構化輸入等,它們都會引發咱們對計算圖的困惑。編程
因此爲何 TensorFlow 須要使用計算圖呢?計算圖容許各類各樣的優化,例如移除公共的子表達式和內核融合等。此外,計算圖簡化了分佈式訓練和部署時的環境配置,所以它們可被視爲一種獨立於平臺的模型計算形式。這一特性對於在多 GPU 或 TPU 上的分佈式訓練極其重要,固然基於 TensorFlow Lite 在移動端和 IoT 上部署模型也很是重要。數組
如下是一個很是簡單的操做示例:bash
def huber_loss(a):
if tf.abs(a) <= delta:
loss = a * a / 2
else:
loss = delta * (tf.abs(a) - delta / 2)
return loss
複製代碼
使用 Eager Execution,這只是「正確運行」而已,可是此類操做可能會比較慢,由於 Python 解釋器衆所周知在實現地比較慢,且須要的計算比較複雜,這會令它錯過許多程序優化的機會。app
爲了給圖執行作好準備,你須要重寫代碼,使用 tf.cond() 等語句,可是這很繁瑣且難以實現。AutoGraph 能夠自動完成該轉換,保持 Eager 編程的簡易性,同時還提高了計算圖執行的性能。less
在該示例中,咱們可使用 autograph.convert() 佈置咱們的函數,AutoGraph 將自動生成圖可用的代碼。分佈式
使用 AutoGraph,因爲 decorator,下列代碼:ide
@autograph.convert()
def huber_loss(a):
if tf.abs(a) <= delta:
loss = a * a / 2
else:
loss = delta * (tf.abs(a) - delta / 2)
return loss
複製代碼
在執行時變成以下代碼:
def tf__huber_loss(a):
with tf.name_scope('huber_loss'):
def if_true():
with tf.name_scope('if_true'):
loss = a * a / 2
return loss,
def if_false():
with tf.name_scope('if_false'):
loss = delta * (tf.abs(a) - delta / 2)
return loss,
loss = ag__.utils.run_cond(tf.less_equal(tf.abs(a), delta), if_true,
if_false)
return loss
複製代碼
接下來,你能夠調用你的代碼,就像使用通常的 TensorFlow op 同樣:
with tf.Graph().as_default():
x_tensor = tf.constant(9.0)
# The converted function works like a regular op: tensors in, tensors out.
huber_loss_tensor = huber_loss(x_tensor)
with tf.Session() as sess:
print('TensorFlow result: %2.2f\n' % sess.run(huber_loss_tensor))
複製代碼
如你所見,AutoGraph 鏈接起 Eager execution 和 Graph。AutoGraph 使用 Eager-style 的 Python 代碼,而後將其轉換成圖生成代碼。
AutoGraph 不僅是有用宏命令的集合,它還可使用源代碼轉換來覆寫 Python 語言的任意部分,包括控制流、函數應用和分配,生成樣板代碼,重構慣用 Python,以使轉換成圖的過程變得簡單。
使用任意編譯器,都會對錯誤信息可讀性產生擔心;爲此,AutoGraph 能夠建立錯誤信息,並堆疊揭示原始源代碼中錯誤來源的多個軌跡,而不是僅僅顯示生成代碼的 reference。
可運行示例
那麼,AutoGraph 能夠爲咱們作什麼呢?如下有一些示例代碼,它們能夠直接轉換爲圖代碼而不須要任何的改寫。若是你想實際運行這些操做,谷歌在這個 GitHub 的 Colab 中提供了一個 notebook 可供使用。
GitHub:github.com/tensorflow/…
Colab:colab.research.google.com/github/tens…
如下咱們使用循環和分支來測試「科拉茲猜測」。注意,考慮到多樣性,咱們將不使用 decorator,而使用 AutoGraph 的.to_graph() 函數將其轉換爲圖。
def collatz(a):
counter = 0
while a != 1:
if a % 2 == 0:
a = a // 2
else:
a = 3 * a + 1
counter = counter + 1
return counter
graph_mode_collatz = autograph.to_graph(collatz)
# The code is human-readable, too
print(autograph.to_code(collatz))
collatz_tensor = graph_mode_collatz(tf.constant(n))
複製代碼
AutoGraph 能夠支持任意的嵌套控制流,例如:
def f(n):
if n >= 0:
while n < 5:
n += 1
print(n)
return n
複製代碼
AutoGraph 容許你在循環中添加元素到數組中。爲了讓其工做,咱們使用一些 AutoGraph 輔助工具,set_element_type 和 stack。
def f(n):
z = []
# We ask you to tell us the element dtype of the list
autograph.set_element_type(z, tf.int32)
for i in range(n):
z.append(i)
# when you're done with the list, stack it
# (this is just like np.stack)
return autograph.stack(z)
複製代碼
咱們還支持 break、continue,甚至 print 和 assert 等語句。當轉換完成後,這個片斷的 Python assert 使用合適的 tf.Assert 將其轉換爲 TensorFlow 計算圖。
def f(x):
assert x != 0, 'Do not pass zero!'
return x * x
複製代碼
具有輕易地添加循環、控制流等到圖上的能力意味着能夠很容易將訓練循環轉移到圖中。能夠在這個 Colab 的 notebook 中找到一個示例,其中使用了一個 RNN 訓練循環,並用一個 sess.run() 調用來執行它。當你須要傳遞一個完整的訓練循環到加速器時,這頗有用,比經過 CPU 控制器管理訓練過程更好。
AutoGraph 打開了構建和訓練模型的新思路。谷歌在將來將基於開發者社區建議嘗試添加更多的功能到 AutoGraph 上,請提出你的建議吧!
Graph Performance 對比 Eager Execution
Eager Execution 至關合用,但圖更快。儘管對比基準較爲複雜(由應用以及硬件配置決定),但在一些簡單示例中咱們能夠看到,當從 Eager 轉換到 AutoGraph 代碼時有極大的加速,使用了大量 if 和 while 等語句。
最終,AutoGraph 讓你能夠在 GPU 和 Cloud TPU 這樣的加速器硬件上使用動態和流控制極嚴模型,這對在大量數據上訓練大型模型很是有幫助。
AutoGraph 和 Eager Execution
雖然使用 Eager Execution,你也能經過 tf.contrib.eager.defun 對部分代碼根據計算圖執行。但這須要你使用 tf.cond() 這樣計算圖類的 TensorFlow ops。將來,AutoGraph 將無縫與 defun 融合,讓你用簡單的 eager-style Python 編寫圖代碼。當成爲現實時,經過選擇性的把 eager 代碼轉換到圖分段,你就能夠期待使用 AutoGraph 加速熱點了。
結論
AutoGraph 可以讓你輕鬆的創建在 TensorFlow 圖中輕鬆運行的直觀性、複雜模型。這是目前在 contrib 中運行的實驗性工具,但咱們指望可以儘快把它加入到 TensorFlow 核心模塊。