日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【干货】TensorFlow 2.0官方风格与设计模式指南(附示例代码)

發布時間:2024/9/15 asp.net 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【干货】TensorFlow 2.0官方风格与设计模式指南(附示例代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉自專知

【導讀】TensorFlow 1.0并不友好的靜態圖開發體驗使得眾多開發者望而卻步,而TensorFlow?2.0解決了這個問題。不僅僅是默認開啟動態圖模式,還引入了大量提升編程體驗的新特性。本文通過官方2.0的風格指南來介紹新版本的開發體驗。


TensorFlow 2.0做了大量的改進來提升開發者的生產力,移除了冗余的API,讓API更加一致(統一的RNN、統一的優化器),將動態圖模式(Eager Execution)與Python運行時集成地更加緊密。


下面先簡單介紹一下主要的變更


API清理


TensorFlow 2.0刪除或移動了許多API。例如,刪除了tf.app、tf.flags和tf.logging,將tf.contrib下的工程搬家。通過將低頻使用的方法放到子包的方法來清理tf.*,例如tf.math。一些API被替換成了等價API,如tf.summary、tf.keras.metrics和tf.keras.optimizers。


Eager Execution(動態圖模式)


TensorFlow 1.X 要求用戶手動構建靜態圖,并通過sess.run來執行。而TensorFlow 2.0可以像Python普通程序那樣直接執行,其中的Graph和Session更像是實現細節。

Eager模式使得tf.control_dependencies()不再被需要,因為代碼會按照代碼順序執行。(使用tf.function時,有副作用的代碼會按照代碼順序執行)。


TensorFlow 1.X 要求用戶手動構建靜態圖,并通過sess.run來執行。而TensorFlow 2.0可以像Python普通程序那樣直接執行,其中的Graph和Session更像是實現細節。


不再有全局


TensorFlow 1.X 非常依賴于隱式的全局命名空間,當你調用tf.Variable()時,變量會被放到默認圖中,就算你丟失了指向它的Python變量,它依然會存在。之后你可以通過通過它的變量名來恢復它。當你并不能控制變量的創建時,這就變得非常艱難。因此,許多機制都在幫助用戶找回變量和幫助框架找回用戶創建的變量:Variable scopes、global collections、一些幫助函數如tf.get_global_step()、tf.global_variables_initializer()以及優化器也在隱式地為所有可訓練變量計算梯度等。TensorFlow 2.0刪除了所有這些機制,而采用了默認機制:跟蹤你自己的變量!如果你丟失了對某個變量的跟蹤,它會被垃圾回收機制回收。

這樣的機制給用戶增加了額外的工作,但使用Keras對象會減輕用戶的負擔。


函數,不是會話


調用session.run()幾乎像是一個函數調用:你指定輸入和需要調用的函數,然后你得到輸出集合。在TensorFlow 2.0中,你可以用tf.function來裝飾一個Python函數來使用JIT編譯,這樣TensorFlow會將它當成一個單獨的圖來執行。這使得TensorFlow可以得益于圖模式:

  • 性能:函數可以被優化(節點剪枝、核融合等)

  • 便攜式:函數可以被導出/導入,用戶可以復用和分享模塊化的TensorFlow函數


# TensorFlow 1.X
outputs = session.run(f(placeholder), feed_dict={placeholder: input})
# TensorFlow 2.0
outputs = f(input)

由于用戶可以將Python和TensorFlow代碼混寫,我們希望用戶可以充分利用Python的表達性。但是便攜式的TensorFlow要在沒用Python解釋器的環境下運行 - 移動端、C++和JS。為了避免用戶重寫代碼,當使用@tf.function時,AutoGraph會將Python結構的子集轉換為TensorFlow等價物:

    • for/while -> tf.while_loop (支持break和continue)

    • if -> tf.cond

    • for _ in dataset -> dataset.reduce



AutoGraph支持嵌套的控制流,使得許多復雜機器學習的開發變得精簡,且能保證效率,例如序列模型、強化學習、定制化的訓練循環等。


下面介紹TensorFlow 2.0的風格和設計模式


將代碼重構為一些小函數


TensorFlow 1.X的常見用例模式是"kitchen sink"策略,所有可能的計算都被事先統一構建好,然后用session.run()來執行所選的張量。在TensorFlow 2.0中,用戶應該講代碼按需重構為一些小函數。一般情況下,并不需要將所有小函數用tf.function來裝飾;只要用tf.function來裝飾高級計算 - 例如訓練的一步、或者模型的前向傳播。


用Keras層和模型來管理變量


Keras模型和層提供了便利的variables和trainable_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_ib_i,并且它們的形狀的定義在代碼的其他地方K

Keras版本:

# Each layer can be called, with a signature equivalent to 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對象直接保存和導出SavedModel變得可能。你并不需要使用Keras的fit() API來使用這些集成特性。

這里有一個遷移學習的例子,可以展現Keras如何輕松地收集相關變量子集。比如你正在訓練一個共享主干的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])

# Train on primary dataset
for x, y in main_dataset:
?with tf.GradientTape() as tape:
? ?prediction = path1(x)
? ?loss = loss_fn_head1(prediction, y)
?# Simultaneously optimize trunk and head1 weights.
?
gradients = tape.gradients(loss, path1.trainable_variables)
?optimizer.apply_gradients(gradients, path1.trainable_variables)

# Fine-tune second head, reusing the trunk
for x, y in small_dataset:
?with tf.GradientTape() as tape:
? ?prediction = path2(x)
? ?loss = loss_fn_head2(prediction, y)
?# Only optimize head2 weights, not trunk weights
?
gradients = tape.gradients(loss, head2.trainable_variables)
?optimizer.apply_gradients(gradients, head2.trainable_variables)

# You can publish just the trunk computation for other people to reuse.
tf.saved_model.save(trunk, output_path)


結合tf.data.Datasets和@tf.function


當迭代使用內存中的訓練數據時,可以用普通的Python迭代來完成,否則,tf.data.Dataset是最好的從硬盤流式使用訓練數據的方法。Datasets是iterables (不是iterators),和Eager模式下其他Python的iterables類似。通過tf.function()來封裝你的代碼,可以充分利用數據集異步預抓取/流式特性,它會用AutoGraph將Python迭代器替換為等價的圖操作。

@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.gradients(loss, model.trainable_variables)
? ?optimizer.apply_gradients(gradients, model.trainable_variables)

如果用的是Keras的.fit() API,你不必關心數據集迭代:

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


利用AutoGraph和Python控制流


AutoGraph提供了一種將依賴數據的控制流轉換為圖模式的等價物,如tf.cond和tf.while_loop。

序列模型中經常出現依賴數據的控制流。tf.keras.layers.RNN封裝了RNN單元,讓你可以靜態或動態地來展開循環。你可以將動態展開實現如下:

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的特性可以在下面鏈接中查看:

https://github.com/tensorflow/docs/blob/master/site/en/r2/guide/autograph.ipynb


tf.metrics來合計數據和用tf.summary來記錄數據


完整的tf.summary符號即將推出。你可以通過下面方法來使用TensorFlow 2.0的tf.summary:

from tensorflow.python.ops import summary_ops_v2

你可以使用tf.summary.(scalar|histogram|...)來記錄數據,獨立使用它時并不會做任何事情,你需要利用上下文管理器將它重定向到合適的file writer。(這避免了硬編碼將日志寫入特定文件)

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

為了在記錄前合計數據,你可以使用tf.metrics。Metrics是有狀態的,它們會累積值并在你調用.reuslt()方法時返回一個累計結果。你可以用.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):
? ? ?summary_ops_v2.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)
?summary_ops_v2.scalar('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)即可將生成的記錄可視化。


參考鏈接:

  • https://github.com/tensorflow/docs/blob/master/site/en/r2/guide/effective_tf2.md


-END-

總結

以上是生活随笔為你收集整理的【干货】TensorFlow 2.0官方风格与设计模式指南(附示例代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。