TensorFlow極簡教程:創建、保存和恢復機器學習模型

2021-01-08 機器之心Pro

選自Github機器之心編譯參與:Jane W、李澤南

TensorFlow 是一個由谷歌發布的機器學習框架,在這篇文章中,我們將闡述 TensorFlow 的一些本質概念。相信你不會找到比本文更簡單的介紹。

TensorFlow 機器學習範例——Naked Tensor

連結:https://github.com/jostmey/NakedTensor?bare

在每個例子中,我們用一條直線擬合一些數據。使用梯度下降(gradient descent)確定最適合數據的線的斜率和 y 截距的值。如果你不知道梯度下降,請查看維基百科:

https://en.wikipedia.org/wiki/Gradient_descent

創建所需的變量後,數據和線之間的誤差是可以被定義(計算)的。定義的誤差被嵌入到優化器(optimizer)中。然後啟動 TensorFlow,並重複調用優化器。通過不斷迭代最小化誤差來達到數據與直線的最佳擬合。

按照順序閱讀下列腳本:

serial.pytensor.pybigdata.py

Serial.py

這個腳本的目的是說明 TensorFlow 模型的基本要點。這個腳本使你更容易理解模型是如何組合在一起的。我們使用 for 循環來定義數據與線之間的誤差。由於定義誤差的方式為循環,該腳本以序列化(串行)計算的方式運行。

Tensor.py

這個腳本比 serial.py 更進一步,雖然實際上這個腳本的代碼行更少。代碼的結構與之前相同,唯一不同的是這次使用張量(tensor)操作來定義誤差。使用張量可以並行(parallel)運行代碼。

每個數據點被看作是來自獨立同分布的樣本。因為每個數據點假定是獨立的,所以計算也是獨立的。當使用張量時,每個數據點都在分隔的計算內核上運行。我們有 8 個數據點,所以如果你有一個有八個內核的計算機,它的運行速度應該快八倍。

BigData.py

你現在距離專業水平僅有一個流行語之遙。我們現在不需要將一條線擬合到 8 個數據點,而是將一條線擬合到 800 萬個數據點。歡迎來到大數據時代。

代碼中有兩處主要的修改。第一點變化是簿記(bookkeeping),因為所有數據必須使用佔位符(placeholder)而不是實際數據來定義誤差。在代碼的後半部分,數據需要通過佔位符饋送(feed)入模型。第二點變化是,因為我們的數據量是巨大的,在給定的任意時間我們僅將一個樣本數據傳入模型。每次調用梯度下降操作時,新的數據樣本將被饋送到模型中。通過對數據集進行抽樣,TensorFlow 不需要一次處理整個數據集。這樣抽樣的效果出奇的好,並有理論支持這種方法:

https://en.wikipedia.org/wiki/Stochastic_gradient_descent

理論上需要滿足一些重要的條件,如步長(step size)必須隨每次迭代而縮短。不管是否滿足條件,這種方法至少是有效的。

結論

當你運行腳本時,你可能看到怎樣定義任何你想要的誤差。它可能是一組圖像和卷積神經網絡(convolutional neural network)之間的誤差。它可能是古典音樂和循環神經網絡(recurrent neural network)之間的誤差。它讓你的想像力瘋狂。一旦定義了誤差,你就可以使用 TensorFlow 進行嘗試並最小化誤差。

希望你從這個教程中得到啟發。

需求

Python3 (https://www.python.org/)TensorFlow (https://www.tensorflow.org/)NumPy (http://www.numpy.org/)

TensorFlow:保存/恢復和混合多重模型

在第一個模型成功建立並訓練之後,你或許需要了解如何保存與恢復這些模型。繼續之前,也可以閱讀這個 Tensorflow 小入門:

https://blog.metaflow.fr/tensorflow-a-primer-4b3fa0978be3#.wxlmweb8h

你有必要了解這些信息,因為了解如何保存不同級別的代碼是非常重要的,這可以避免混亂無序。

如何實際保存和加載

保存(saver)對象

可以使用 Saver 對象處理不同會話(session)中任何與文件系統有持續數據傳輸的交互。構造函數(constructor)允許你控制以下 3 個事物:

目標(target):在分布式架構的情況下用於處理計算。可以指定要計算的 TF 伺服器或「目標」。圖(graph):你希望會話處理的圖。對於初學者來說,棘手的事情是:TF 中總存在一個默認的圖,其中所有操作的設置都是默認的,所以你的操作範圍總在一個「默認的圖」中。配置(config):你可以使用 ConfigProto 配置 TF。查看本文最後的連結資源以獲取更多詳細信息。

Saver 可以處理圖的元數據和變量數據的保存和加載(又稱恢復)。它需要知道的唯一的事情是:需要使用哪個圖和變量?

默認情況下,Saver 會處理默認的圖及其所有包含的變量,但是你可以創建儘可能多的 Saver 來控制你想要的任何圖或子圖的變量。這裡是一個例子:

import tensorflow as tf

import os

dir = os.path.dirname(os.path.realpath(__file__))

# First, you design your mathematical operations

# We are the default graph scope

# Let's design a variable

v1 = tf.Variable(1. , name="v1")

v2 = tf.Variable(2. , name="v2")

# Let's design an operation

a = tf.add(v1, v2)

# Let's create a Saver object

# By default, the Saver handles every Variables related to the default graph

all_saver = tf.train.Saver()

# But you can precise which vars you want to save under which name

v2_saver = tf.train.Saver({"v2": v2})

# By default the Session handles the default graph and all its included variables

with tf.Session() as sess:

# Init v and v2

sess.run(tf.global_variables_initializer())

# Now v1 holds the value 1.0 and v2 holds the value 2.0

# We can now save all those values

all_saver.save(sess, dir + '/data-all.chkp')

# or saves only v2

v2_saver.save(sess, dir + '/data-v2.chkp')

如果查看你的文件夾,它實際上每創建 3 個文件調用一次保存操作並創建一個檢查點(checkpoint)文件,我會在附錄中講述更多的細節。你可以簡單理解為權重被保存到 .chkp.data 文件中,你的圖和元數據被保存到 .chkp.meta 文件中。

恢復操作和其它元數據

一個重要的信息是,Saver 將保存與你的圖相關聯的任何元數據。這意味著加載元檢查點還將恢復與圖相關聯的所有空變量、操作和集合(例如,它將恢復訓練優化器)。

當你恢復一個元檢查點時,實際上是將保存的圖加載到當前默認的圖中。現在你可以通過它來加載任何包含的內容,如張量、操作或集合。

import tensorflow as tf

# Let's load a previously saved meta graph in the default graph

# This function returns a Saver

saver = tf.train.import_meta_graph('results/model.ckpt-1000.meta')

# We can now access the default graph where all our metadata has been loaded

graph = tf.get_default_graph()

# Finally we can retrieve tensors, operations, collections, etc.

global_step_tensor = graph.get_tensor_by_name('loss/global_step:0')

train_op = graph.get_operation_by_name('loss/train_op')

hyperparameters = tf.get_collection('hyperparameters')

恢復權重

請記住,實際的權重只存在於一個會話中。這意味著「恢復」操作必須能夠訪問會話以恢復圖內的權重。理解恢復操作的最好方法是將其簡單地當作一種初始化。

with tf.Session() as sess:

# To initialize values with saved data

saver.restore(sess, 'results/model.ckpt.data-1000-00000-of-00001')

print(sess.run(global_step_tensor)) # returns 1000

在新圖中使用預訓練圖

現在你知道了如何保存和加載,你可能已經明白如何去操作。然而,這裡有一些技巧能夠幫助你走得更快。

一個圖的輸出可以是另一個圖的輸入嗎?

是的,但有一個缺點:我還不知道使梯度流(gradient flow)在圖之間容易傳遞的一種方法,因為你將必須評估第一個圖,獲得結果,並將其饋送到下一個圖。

這樣一直下去是可以的,直到你需要重新訓練第一個圖。在這種情況下,你將需要將輸入梯度饋送到第一個圖的訓練步驟……

我可以在一個圖中混合所有這些不同的圖嗎?

是的,但你需要對命名空間(namespace)倍加小心。好的一點是,這種方法簡化了一切:例如,你可以加載預訓練的 VGG-16,訪問圖中的任何節點,嵌入自己的操作和訓練整個圖!

如果你只想微調(fine-tune)節點,你可以在任意地方停止梯度來避免訓練整個圖。

import tensorflow as tf

# Load the VGG-16 model in the default graph

vgg_saver = tf.train.import_meta_graph(dir + 'gg/resultsgg-16.meta')

# Access the graph

vgg_graph = tf.get_default_graph()

# Retrieve VGG inputs

self.x_plh = vgg_graph.get_tensor_by_name('input:0')

# Choose which node you want to connect your own graph

output_conv =vgg_graph.get_tensor_by_name('conv1_2:0')

# output_conv =vgg_graph.get_tensor_by_name('conv2_2:0')

# output_conv =vgg_graph.get_tensor_by_name('conv3_3:0')

# output_conv =vgg_graph.get_tensor_by_name('conv4_3:0')

# output_conv =vgg_graph.get_tensor_by_name('conv5_3:0')

# Stop the gradient for fine-tuning

output_conv_sg = tf.stop_gradient(output_conv) # It's an identity function

# Build further operations

output_conv_shape = output_conv_sg.get_shape().as_list()

W1 = tf.get_variable('W1', shape=[1, 1, output_conv_shape[3], 32], initializer=tf.random_normal_initializer(stddev=1e-1))

b1 = tf.get_variable('b1', shape=[32], initializer=tf.constant_initializer(0.1))

z1 = tf.nn.conv2d(output_conv_sg, W1, strides=[1, 1, 1, 1], padding='SAME') + b1

a = tf.nn.relu(z1)

附錄:更多關於 TF 數據生態系統的內容

我們在這裡談論谷歌,他們主要使用內部構建的工具來處理他們的工作,所以數據保存的格式為 ProtoBuff 也是不奇怪的。

協議緩衝區

協議緩衝區(Protocol Buffer/簡寫 Protobufs)是 TF 有效存儲和傳輸數據的常用方式。

我不在這裡詳細介紹它,但可以把它當成一個更快的 JSON 格式,當你在存儲/傳輸時需要節省空間/帶寬,你可以壓縮它。簡而言之,你可以使用 Protobufs 作為:

一種未壓縮的、人性化的文本格式,擴展名為 .pbtxt一種壓縮的、機器友好的二進位格式,擴展名為 .pb 或根本沒有擴展名

這就像在開發設置中使用 JSON,並且在遷移到生產環境時為了提高效率而壓縮數據一樣。用 Protobufs 可以做更多的事情,如果你有興趣可以查看教程

整潔的小技巧:在張量流中處理 protobufs 的所有操作都有這個表示「協議緩衝區定義」的「_def」後綴。例如,要加載保存的圖的 protobufs,可以使用函數:tf.import_graph_def。要獲取當前圖作為 protobufs,可以使用:Graph.as_graph_def()。

文件的架構

回到 TF,當保存你的數據時,你會得到 5 種不同類型的文件:

「檢查點」文件「事件(event)」文件「文本 protobufs」文件一些「chkp」文件一些「元 chkp」文件

現在讓我們休息一下。當你想到,當你在做機器學習時可能會保存什麼?你可以保存模型的架構和與其關聯的學習到的權重。你可能希望在訓練或事件整個訓練架構時保存一些訓練特徵,如模型的損失(loss)和準確率(accuracy)。你可能希望保存超參數和其它操作,以便之後重新啟動訓練或重複實現結果。這正是 TensorFlow 的作用。

在這裡,檢查點文件的三種類型用於存儲模型及其權重有關的壓縮後數據。

檢查點文件只是一個簿記文件,你可以結合使用高級輔助程序加載不同時間保存的 chkp 文件。元 chkp 文件包含模型的壓縮 Protobufs 圖以及所有與之關聯的元數據(集合、學習速率、操作等)。chkp 文件保存數據(權重)本身(這一個通常是相當大的大小)。如果你想做一些調試,pbtxt 文件只是模型的非壓縮 Protobufs 圖。最後,事件文件在 TensorBoard 中存儲了所有你需要用來可視化模型和訓練時測量的所有數據。這與保存/恢復模型本身無關。

下面讓我們看一下結果文件夾的屏幕截圖:

一些隨機訓練的結果文件夾的屏幕截圖

該模型已經在步驟 433,858,1000 被保存了 3 次。為什麼這些數字看起來像隨機?因為我設定每 S 秒保存一次模型,而不是每 T 次迭代後保存。chkp 文件比元 chkp 文件更大,因為它包含我們模型的權重pbtxt 文件比元 chkp 文件大一點:它被認為是非壓縮版本!

TF 自帶多個方便的幫助方法,如:

在時間和迭代中處理模型的不同檢查點。它如同一個救生員,以防你的機器在訓練結束前崩潰。

注意:TensorFlow 現在發展很快,這些文章目前是基於 1.0.0 版本編寫的。

參考資源

http://stackoverflow.com/questions/38947658/tensorflow-saving-into-loading-a-graph-from-a-file

http://stackoverflow.com/questions/34343259/is-there-an-example-on-how-to-generate-protobuf-files-holding-trained-tensorflow?rq=1

http://stackoverflow.com/questions/39468640/tensorflow-freeze-graph-py-the-name-save-const0-refers-to-a-tensor-which-doe?rq=1

http://stackoverflow.com/questions/33759623/tensorflow-how-to-restore-a-previously-saved-model-python

http://stackoverflow.com/questions/34500052/tensorflow-saving-and-restoring-session?noredirect=1&lq=1

http://stackoverflow.com/questions/35687678/using-a-pre-trained-word-embedding-word2vec-or-glove-in-tensorflow

https://github.com/jtoy/awesome-tensorflow

相關焦點

  • TensorFlow發布JavaScript開發者的機器學習框架TensorFlow.js
    在下文中,機器之心對 TensorFlow.js 做了細緻介紹:在大會的 Keynote 中,TensorFlow 團隊表示基於網頁的 JavaScript 庫 TensorFlow.js 現在已經能訓練並部署機器學習模型。我們可以使用神經網絡的層級 API 構建模型,並在瀏覽器中使用 WebGL 創建複雜的數據可視化應用。
  • TensorFlow入門教程(五):變量的創建、初始化、保存和加載
    而當我們訓練完一個神經網絡後, 我們常常需要保存網絡參數, 以供後來繼續使用, 所以我們今天給大家介紹下變量的創建、初始化、保存和加載. 在後面的時間裡我們會推出一系列的TensorFlow與PyTorch的入門教程, 希望大家多多轉發與關注。當訓練模型時,用變量來存儲和更新參數。變量包含張量 (Tensor)存放於內存的緩存區。
  • 基於TensorFlow.js的JavaScript機器學習
    擴展:2019年11個javascript機器學習庫很棒的機器學習庫,可以在你的下一個應用程式中添加一些人工智慧!Big.bitsrc.io創建我們可以創建一個使用tensorflow.js在瀏覽器中訓練模型的網頁。考慮到房屋的「avgareanumberofrows」,模型可以學習去預測房屋的「價格」。
  • 在瀏覽器中使用TensorFlow.js和Python構建機器學習模型
    只要一個文本編輯器和一個網絡瀏覽器即可。下面的動圖展示了我們將要構建的應用程式:這多酷啊!我在瀏覽器裡幾分鐘就完成了。那麼,讓我們看一下步驟和代碼,以幫助你在Web瀏覽器中構建自己的圖像分類模型。使用網絡攝像頭在瀏覽器中構建圖像分類模型打開你選擇的文本編輯器並創建一個文件index.html。將以下代碼保存於此文件內:<!
  • 什麼是TensorFlow,TensorFlow教程
    TensorFlow教程|什麼是TensorFlow TensorFlow的歷史DistBelief是TensorFlow在升級之前被調用的,它是在2011年作為一個基於深度學習神經網絡的專有系統構建的。DistBelief的原始碼經過修改,被做成了一個更好的基於應用程式的庫,2015年,它被稱為tensorflow。
  • 機器學習:TensorFlow 2.0中的10個技巧
    用於構建輸入管道的tf.data API從張量構建管道Batch和Shuffle壓縮兩個Datsets映射外部函數1(b). ImageDataGenerator這是tensorflow.keras API的最佳特性之一。
  • TensorFlow 實現流行的機器學習算法的教程匯集
    這是使用 TensorFlow 實現流行的機器學習算法的教程匯集。本匯集的目標是讓讀者可以輕鬆通過案例深入 TensorFlow。這些案例適合那些想要清晰簡明的 TensorFlow 實現案例的初學者。本教程還包含了筆記和帶有註解的代碼。
  • 從框架優缺點說起,這是一份TensorFlow入門極簡教程
    機器之心在本文介紹了 PyTorch 和 Caffe 等深度學習框架的優缺點及 TensorFlow 基礎,包括靜態計算圖、張量、TensorBoard 可視化和模型參數的保存等。機器之心此前也介紹過很多 TensorFlow 的學習資源,讀者可結合這些資源閱讀該系列教程:學習了!
  • TensorFlow.js 進行模型訓練
    你會學到什麼機器學習數據準備的最佳實踐,包括改組和規範化。TensorFlow.js使用tf.layers API創建模型的語法。如何使用tfjs-vis庫監控瀏覽器內培訓。你需要什麼最新版本的Chrome或其他現代瀏覽器。一個文本編輯器,可以在您的機器上本地運行,也可以通過Codepen或Glitch等在Web上運行。
  • 在TensorFlow中使用模型剪枝將機器學習模型變得更小
    導入常見問題我們的第一步導入一些工具、包:Os和Zipfile可以幫助我們評估模型的大小。tensorflow_model_optimization用來修剪模型。load_model用於加載保存的模型。當然還有tensorflow和keras。
  • 模型秒變API只需一行代碼,支持TensorFlow等框架
    選自GitHub機器之心編譯參與:一鳴、杜偉還在為機器學習模型打包成 API 發愁?這個工具能讓你一行代碼直接打包。專注於機器學習應用的人們知道,從訓練好的模型到實際的工業生產工具還有一定的距離。其中工作量很大的地方在於將模型打包,預留 API 接口,並和現有的生產系統相結合。
  • 在TensorFlow中使用模型剪枝將機器學習模型變得更小
    這將會得到更小的模型,並且模型精度非常接近標準模型。在本文中,我們將通過一個例子來觀察剪枝技術對最終模型大小和預測誤差的影響。導入常見問題我們的第一步導入一些工具、包:· Os和Zipfile可以幫助我們評估模型的大小。
  • TensorFlow.js:讓你在瀏覽器中玩轉機器學習
    全文共2000字,預計學習時長4分鐘當談及機器學習和谷歌的TensorFlow時候,相比於JavaScript和其他瀏覽器,大多數人會想到Python和專用硬體。本文解釋了TensorFlow.js的用途,以及機器學習在瀏覽器中運行的意義。
  • kubeflow系列(三):模型即服務,關於tensorflow serving的使用
    模型即服務(Model as a service)作為算法模型最優雅的價值變現,也是最佳的tf算法部署實踐,Tensorflow Serving 作為Tensorflow官方的模型部署方案,也是kubeflow默認的一種tensorflow部署形式,本文介紹如何用 Tensorflow Serving 部署算法模型。
  • 【TensorFlow超級指南】你能想到的TF教程和資源都在這裡了
    教程Martin Grner課程—《無需成為博士即可學會TensorFlow和機器學習》:如果你已經掌握了線性代數,那麼這是一個很好的起點。Jacob Buckman—《TensorFlow:令人困惑的部分(1)》:https://jacobbuckman.com/post/tensorflow-the-confusing-parts-1/Dino Causevic—《TensorFlow入門:機器學習教程》:https://www.toptal.com
  • 小叮噹機器學習:Python3.6配置TensorFlow的GPU版詳細安裝教程
    隨著機器學習,神經網絡的搭建,我們對海量數據的處理需求越來越大。雖然,CPU的發展速度已經放緩,但並行處理的架構卻取得了爆炸式的發展。圖形處理單元(GPU)的大量運用,已經拉開了機器學習迅猛發展的序幕。谷歌的開源機器學習工具TensorFlow,自發布以來,便迅速躋身於激動人心的機器學習庫的行列之中。
  • 將Tensorflow 圖序列化以及反序列化的巧妙方法
    翻譯 |王褘      整理 | MY將類中的欄位和 graph 中的 tensorflow 變量進行自動綁定,並且在不需要手動將變量從 graph 中取出的情況下進行重存,聽起來有沒有很炫酷?可以點擊這裡找到本文所涉及的代碼。Jupyter-notebook 的版本點擊這裡。
  • 資源|TensorFlow推出新工具Seedbank:即刻使用的預訓練模型庫
    今天,TensorFlow 推出 Seedbank,這是一個發現交互式機器學習示例的地方,你可以直接從瀏覽器運行,無需其他設置。每個示例都是啟發你的一顆小種子,你可以對其進行編輯、擴展,甚至將其融入自己的項目和想法中,例如數據分析問題、藝術項目等等。
  • tensorflow安裝教程
    tensorflow是谷歌開源的人工智慧庫,有最完善的生態支持。是進行人工智慧領域開發和科研的必備工具。本文在windows10下,藉助anacondaAnaconda安裝和使用,AkShare入門,安裝tensorflow2.0。
  • TensorFlow Cloud 助力模型訓練無縫「上雲」
    它將雲端的模型訓練過程簡化為單一的簡單函數調用,只需要最少的設置,並且幾乎不需要對模型進行任何更改。TensorFlow Cloud 可以處理雲端特定的任務,例如自動為您的模型創建 VM 實例和分布策略。本文演示了 TensorFlow Cloud 的常見用例和幾點最佳做法。