高效的TensorFlow 2.0 (tensorflow2官方教程翻譯)

高效的TensorFlow 2.0 (tensorflow2官方教程翻譯)

最新版本:http://www.mashangxue123.com/tensorflow/tf2-guide-effective_tf2.html
英文版本:https://tensorflow.google.cn/alpha/guide/effective_tf2
翻譯建議PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/guide/effective_tf2.md

TensorFlow 2.0中有多處更改,以使TensorFlow用戶使用更高效问裕。TensorFlow 2.0刪除冗余 APIs,使API更加一致(統(tǒng)一 RNNs,統(tǒng)一優(yōu)化器),并通過Eager execution模式更好地與Python運行時集成

許多RFCs已經解釋了TensorFlow 2.0所帶來的變化。本指南介紹了TensorFlow 2.0應該是什么樣的開發(fā)凌盯,假設您對TensorFlow 1.x有一定的了解。

1. 主要變化的簡要總結

1.1. API清理

許多API在tensorflow 2.0中消失或移動烹玉。一些主要的變化包括刪除tf.app十气、tf.flagstf.logging ,轉而支持現在開源的absl-py春霍,重新安置tf.contrib中的項目砸西,并清理主要的 tf.*命名空間,將不常用的函數移動到像 tf.math這樣的子包中址儒。一些API已被2.0版本等效替換芹枷,如tf.summary, tf.keras.metricstf.keras.optimizers
自動應用這些重命名的最簡單方法是使用v2升級腳本莲趣。

1.2. Eager execution

TensorFlow 1.X要求用戶通過進行tf.* API調用鸳慈,手動將抽象語法樹(圖形)拼接在一起。然后要求用戶通過將一組輸出張量和輸入張量傳遞給session.run()來手動編譯抽象語法樹喧伞。
TensorFlow 2.0 默認Eager execution模式走芋,馬上就執(zhí)行代碼(就像Python通常那樣),在2.0中潘鲫,圖形和會話應該像實現細節(jié)一樣翁逞。

Eager execution的一個值得注意的地方是不在需要tf.control_dependencies() ,因為所有代碼按順序執(zhí)行(在tf.function中溉仑,帶有副作用的代碼按寫入的順序執(zhí)行)挖函。

1.3. 沒有更多的全局變量

TensorFlow 1.X嚴重依賴于隱式全局命名空間。當你調用tf.Variable()時浊竟,它會被放入默認圖形中怨喘,保留在那里,即使你忘記了指向它的Python變量振定。
然后必怜,您可以恢復該tf.Variable,但前提是您知道它已創(chuàng)建的名稱后频,如果您無法控制變量的創(chuàng)建梳庆,這很難做到。結果,各種機制激增靠益,試圖幫助用戶再次找到他們的變量,并尋找框架來查找用戶創(chuàng)建的變量:變量范圍残揉、全局集合胧后、輔助方法如tf.get_global_step(), tf.global_variables_initializer()、優(yōu)化器隱式計算所有可訓練變量的梯度等等抱环。

TensorFlow 2.0取消了所有這些機制(Variables 2.0 RFC)壳快,支持默認機制:跟蹤變量!如果你失去了對tf.Variable的追蹤镇草,就會垃圾收集回收眶痰。

跟蹤變量的要求為用戶創(chuàng)建了一些額外的工作,但是使用Keras對象(見下文)梯啤,負擔被最小化竖伯。

1.4. Functions, not sessions

session.run()調用幾乎就像一個函數調用:指定輸入和要調用的函數,然后返回一組輸出因宇。
在TensorFlow 2.0中七婴,您可以使用tf.function() 來裝飾Python函數以將其標記為JIT編譯,以便TensorFlow將其作為單個圖形運行(Functions 2.0 RFC)察滑。這種機制允許TensorFlow 2.0獲得圖形模式的所有好處:

  • 性能:可以優(yōu)化功能(節(jié)點修剪打厘,內核融合等)
  • 可移植性:該功能可以導出/重新導入(SavedModel 2.0 RFC),允許用戶重用和共享模塊化TensorFlow功能贺辰。
# TensorFlow 1.X
outputs = session.run(f(placeholder), feed_dict={placeholder: input})
# TensorFlow 2.0
outputs = f(input)

憑借能夠自由穿插Python和TensorFlow代碼户盯,我們希望用戶能夠充分利用Python的表現力。但是可移植的TensorFlow在沒有Python解釋器的情況下執(zhí)行-移動端饲化、C++和JS莽鸭,幫助用戶避免在添加 @tf.function時重寫代碼,AutoGraph將把Python構造的一個子集轉換成它們等效的TensorFlow:

  • for/while -> tf.while_loop (支持breakcontinue)
  • if -> tf.cond
  • for _ in dataset -> dataset.reduce

AutoGraph支持控制流的任意嵌套吃靠,這使得高效和簡潔地實現許多復雜的ML程序成為可能蒋川,比如序列模型、強化學習撩笆、自定義訓練循環(huán)等等捺球。

2. 使用TensorFlow 2.0的建議

2.1. 將代碼重構為更小的函數

TensorFlow 1.X中常見的使用模式是“kitchen sink”策略,在該策略中夕冲,所有可能的計算的并集被預先安排好氮兵,然后通過session.run()對所選的張量進行評估。

TensorFlow 2.0中歹鱼,用戶應該根據需要將代碼重構為更小的函數泣栈。一般來說,沒有必須要使用tf.function來修飾這些小函數,只用tf.function來修飾高級計算-例如南片,一個訓練步驟掺涛,或者模型的前向傳遞。

2.2. 使用Keras層和模型來管理變量

Keras模型和層提供了方便的variablestrainable_variables屬性疼进,它們遞歸地收集所有的因變量薪缆。這使得本地管理變量到使用它們的地方變得非常容易。

對比如下:

def dense(x, W, b):
  return tf.nn.sigmoid(tf.matmul(x, W) + b)

@tf.function
def multilayer_perceptron(x, w0, b0, w1, b1, w2, b2 ...):
  x = dense(x, w0, b0)
  x = dense(x, w1, b1)
  x = dense(x, w2, b2)
  ...
  
# 您仍然必須管理w_i和b_i伞广,它們是在代碼的其他地方定義的拣帽。

Keras版本如下:

# 每個圖層都可以調用,其簽名等價于linear(x)
layers = [tf.keras.layers.Dense(hidden_size, activation=tf.nn.sigmoid) for _ in range(n)]
perceptron = tf.keras.Sequential(layers)

# layers[3].trainable_variables => returns [w3, b3]
# perceptron.trainable_variables => returns [w0, b0, ...]

Keras 層/模型繼承自 tf.train.Checkpointable 并與@tf.function集成嚼锄,這使得從Keras對象導出保存模型成為可能减拭。
您不必使用Keras的.fit() API來利用這些集成。

下面是一個轉移學習示例区丑,演示了Keras如何簡化收集相關變量子集的工作拧粪。假設你正在訓練一個擁有共享trunk的multi-headed模型:

trunk = tf.keras.Sequential([...])
head1 = tf.keras.Sequential([...])
head2 = tf.keras.Sequential([...])

path1 = tf.keras.Sequential([trunk, head1])
path2 = tf.keras.Sequential([trunk, head2])

# 訓練主要數據集
for x, y in main_dataset:
  with tf.GradientTape() as tape:
    prediction = path1(x)
    loss = loss_fn_head1(prediction, y)
  # 同時優(yōu)化trunk和head1的權重
  gradients = tape.gradient(loss, path1.trainable_variables)
  optimizer.apply_gradients(zip(gradients, path1.trainable_variables))

# 微調第二個頭部,重用trunk
for x, y in small_dataset:
  with tf.GradientTape() as tape:
    prediction = path2(x)
    loss = loss_fn_head2(prediction, y)
  # 只優(yōu)化head2的權重沧侥,不是trunk的權重
  gradients = tape.gradient(loss, head2.trainable_variables)
  optimizer.apply_gradients(zip(gradients, head2.trainable_variables))

# 你可以發(fā)布trunk計算既们,以便他人重用。
tf.saved_model.save(trunk, output_path)

2.3. 結合tf.data.Datesets和@tf.function

當迭代適合內存訓練的數據時正什,可以隨意使用常規(guī)的Python迭代啥纸。除此之外,tf.data.Datesets是從磁盤中傳輸訓練數據的最佳方式婴氮。
數據集可迭代(但不是迭代器)斯棒,就像其他Python迭代器在Eager模式下工作一樣。
您可以通過將代碼包裝在tf.function()中來充分利用數據集異步預取/流功能主经,該代碼將Python迭代替換為使用AutoGraph的等效圖形操作荣暮。

@tf.function
def train(model, dataset, optimizer):
  for x, y in dataset:
    with tf.GradientTape() as tape:
      prediction = model(x)
      loss = loss_fn(prediction, y)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

如果使用Keras.fit()API,就不必擔心數據集迭代:

model.compile(optimizer=optimizer, loss=loss_fn)
model.fit(dataset)

2.4. 利用AutoGraph和Python控制流程

AutoGraph提供了一種將依賴于數據的控制流轉換為圖形模式等價的方法罩驻,如tf.condtf.while_loop穗酥。

數據依賴控制流出現的一個常見位置是序列模型。tf.keras.layers.RNN封裝一個RNN單元格惠遏,允許你您靜態(tài)或動態(tài)展開遞歸砾跃。
為了演示,您可以重新實現動態(tài)展開如下:

class DynamicRNN(tf.keras.Model):

  def __init__(self, rnn_cell):
    super(DynamicRNN, self).__init__(self)
    self.cell = rnn_cell

  def call(self, input_data):
    # [batch, time, features] -> [time, batch, features]
    input_data = tf.transpose(input_data, [1, 0, 2])
    outputs = tf.TensorArray(tf.float32, input_data.shape[0])
    state = self.cell.zero_state(input_data.shape[1], dtype=tf.float32)
    for i in tf.range(input_data.shape[0]):
      output, state = self.cell(input_data[i], state)
      outputs = outputs.write(i, output)
    return tf.transpose(outputs.stack(), [1, 0, 2]), state

有關AutoGraph功能的更詳細概述节吮,請參閱指南.抽高。

2.5. 使用tf.metrics聚合數據和tf.summary來記錄它

要記錄摘要,請使用tf.summary.(scalar|histogram|...) 并使用上下文管理器將其重定向到writer透绩。(如果省略上下文管理器翘骂,則不會發(fā)生任何事情壁熄。)與TF 1.x不同,摘要直接發(fā)送給writer碳竟;沒有單獨的merger操作草丧,也沒有單獨的add_summary()調用,這意味著必須在調用點提供步驟值莹桅。

summary_writer = tf.summary.create_file_writer('/tmp/summaries')
with summary_writer.as_default():
  tf.summary.scalar('loss', 0.1, step=42)

要在將數據記錄為摘要之前聚合數據昌执,請使用tf.metrics,Metrics是有狀態(tài)的统翩;
當你調用.result()時,它們會累計值并返回累計結果此洲。使用.reset_states()清除累計值厂汗。

def train(model, optimizer, dataset, log_freq=10):
  avg_loss = tf.keras.metrics.Mean(name='loss', dtype=tf.float32)
  for images, labels in dataset:
    loss = train_step(model, optimizer, images, labels)
    avg_loss.update_state(loss)
    if tf.equal(optimizer.iterations % log_freq, 0):
      tf.summary.scalar('loss', avg_loss.result(), step=optimizer.iterations)
      avg_loss.reset_states()

def test(model, test_x, test_y, step_num):
  loss = loss_fn(model(test_x), test_y)
  tf.summary.scalar('loss', loss, step=step_num)

train_summary_writer = tf.summary.create_file_writer('/tmp/summaries/train')
test_summary_writer = tf.summary.create_file_writer('/tmp/summaries/test')

with train_summary_writer.as_default():
  train(model, optimizer, dataset)

with test_summary_writer.as_default():
  test(model, test_x, test_y, optimizer.iterations)

通過將TensorBoard指向摘要日志目錄來顯示生成的摘要:

tensorboard --logdir /tmp/summaries

最新版本:http://www.mashangxue123.com/tensorflow/tf2-guide-effective_tf2.html
英文版本:https://tensorflow.google.cn/alpha/guide/effective_tf2
翻譯建議PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/guide/effective_tf2.md

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呜师,隨后出現的幾起案子娶桦,更是在濱河造成了極大的恐慌,老刑警劉巖汁汗,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衷畦,死亡現場離奇詭異,居然都是意外死亡知牌,警方通過查閱死者的電腦和手機祈争,發(fā)現死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來角寸,“玉大人菩混,你說我怎么就攤上這事”馀海” “怎么了沮峡?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亿柑。 經常有香客問我邢疙,道長,這世上最難降的妖魔是什么望薄? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任疟游,我火速辦了婚禮,結果婚禮上痕支,老公的妹妹穿的比我還像新娘乡摹。我一直安慰自己,他們只是感情好采转,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布聪廉。 她就那樣靜靜地躺著瞬痘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪板熊。 梳的紋絲不亂的頭發(fā)上框全,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音干签,去河邊找鬼津辩。 笑死,一個胖子當著我的面吹牛容劳,可吹牛的內容都是我干的喘沿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼竭贩,長吁一口氣:“原來是場噩夢啊……” “哼蚜印!你這毒婦竟也來了?” 一聲冷哼從身側響起留量,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤窄赋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后楼熄,有當地人在樹林里發(fā)現了一具尸體忆绰,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年可岂,在試婚紗的時候發(fā)現自己被綠了错敢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡缕粹,死狀恐怖伐债,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情致开,我是刑警寧澤峰锁,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站双戳,受9級特大地震影響虹蒋,放射性物質發(fā)生泄漏。R本人自食惡果不足惜飒货,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一魄衅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塘辅,春花似錦晃虫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扛吞。三九已至,卻和暖如春荆责,著一層夾襖步出監(jiān)牢的瞬間滥比,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工做院, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盲泛,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓键耕,卻偏偏與公主長得像寺滚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屈雄,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容

  • 水天浩淼嘆空闊村视,老病淸凄捱晨昏。遙想家園樂融融棚亩,忍看異鄉(xiāng)雪紛紛蓖议。夜夜魂夢歸故里虏杰,高朋滿座酒滿樽讥蟆。
    成都獨行俠閱讀 176評論 0 2
  • 此在 夜晚變成瞬間 眼瞼一碰,就是一天 潛在 暗夜無限伸長 席卷一切可能的星光 萬事纺阔,都付與千鐘 獨歸 肩負一夕炊煙
    七星葫閱讀 186評論 0 0
  • 組群笛钝、用戶與權限 改變所屬群組, chgrp:chgrp [-R] dirname/filename 改變文件擁有...
    不會逃跑的木頭人閱讀 272評論 0 1
  • 基礎屬性 設置字間距和行間距 字間距: 行間距: Android系統(tǒng)中TextView默認顯示中文時會比較緊湊质况,為...
    大灰狼zz閱讀 7,822評論 0 2