TensorFlow模型儲存和提取的方法,tensorflow模型提取
一、TensorFlow模型儲存和提取方法
1. TensorFlow通過tf.train.Saver類實現神經網路模型的儲存和提取。tf.train.Saver對象saver的save方法將TensorFlow模型儲存到指定路徑中,saver.save(sess,"Model/model.ckpt") ,實際在這個檔案目錄下會產生4個人檔案:
checkpoint檔案儲存了一個錄下多有的模型檔案清單,model.ckpt.meta儲存了TensorFlow計算圖的結構資訊,model.ckpt儲存每個變數的取值,此處檔案名稱的寫入方式會因不同參數的設定而不同,但載入restore時的檔案路徑名是以checkpoint檔案中的“model_checkpoint_path”值決定的。
2. 載入這個已儲存的TensorFlow模型的方法是saver.restore(sess,"./Model/model.ckpt") ,載入模型的代碼中也要定義TensorFlow計算圖上的所有運算並聲明一個tf.train.Saver類,不同的是載入模型時不需要進行變數的初始化,而是將變數的取值通過儲存的模型載入進來,注意載入路徑的寫法。若不希望重複定義計算圖上的運算,可直接載入已經持久化的圖,saver =tf.train.import_meta_graph("Model/model.ckpt.meta") 。
3.tf.train.Saver類也支援在儲存和載入時給變數重新命名,聲明Saver類對象的時候使用一個字典dict重新命名變數即可,{"已儲存的變數的名稱name": 重新命名變數名},saver = tf.train.Saver({"v1":u1, "v2": u2})即原來名稱name為v1的變數現在載入到變數u1(名稱name為other-v1)中。
4. 上一條做的目的之一就是方便使用變數的滑動平均值。如果在載入模型時直接將影子變數映射到變數自身,則在使用訓練好的模型時就不需要再調用函數來擷取變數的滑動平均值了。載入時,聲明Saver類對象時通過一個字典將滑動平均值直接載入到新的變數中,saver = tf.train.Saver({"v/ExponentialMovingAverage": v}),另通過tf.train.ExponentialMovingAverage的variables_to_restore()函數擷取變數重新命名字典。
此外,通過convert_variables_to_constants函數將計算圖中的變數及其取值通過常量的方式儲存於一個檔案中。
二、TensorFlow程式實現
# 本檔案程式為配合教材及學習進度漸進進行,請按照注釋分段執行 # 執行時要注意IDE的當前工作過路徑,最好每段重啟控制器一次,輸出結果更準確 # Part1: 通過tf.train.Saver類實現儲存和載入神經網路模型 # 執行本段程式時注意當前的工作路徑 import tensorflow as tf v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1") v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2") result = v1 + v2 saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) saver.save(sess, "Model/model.ckpt") # Part2: 載入TensorFlow模型的方法 import tensorflow as tf v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1") v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2") result = v1 + v2 saver = tf.train.Saver() with tf.Session() as sess: saver.restore(sess, "./Model/model.ckpt") # 注意此處路徑前添加"./" print(sess.run(result)) # [ 3.] # Part3: 若不希望重複定義計算圖上的運算,可直接載入已經持久化的圖 import tensorflow as tf saver = tf.train.import_meta_graph("Model/model.ckpt.meta") with tf.Session() as sess: saver.restore(sess, "./Model/model.ckpt") # 注意路徑寫法 print(sess.run(tf.get_default_graph().get_tensor_by_name("add:0"))) # [ 3.] # Part4: tf.train.Saver類也支援在儲存和載入時給變數重新命名 import tensorflow as tf # 聲明的變數名稱name與已儲存的模型中的變數名稱name不一致 u1 = tf.Variable(tf.constant(1.0, shape=[1]), name="other-v1") u2 = tf.Variable(tf.constant(2.0, shape=[1]), name="other-v2") result = u1 + u2 # 若直接生命Saver類對象,會報錯變數找不到 # 使用一個字典dict重新命名變數即可,{"已儲存的變數的名稱name": 重新命名變數名} # 原來名稱name為v1的變數現在載入到變數u1(名稱name為other-v1)中 saver = tf.train.Saver({"v1": u1, "v2": u2}) with tf.Session() as sess: saver.restore(sess, "./Model/model.ckpt") print(sess.run(result)) # [ 3.] # Part5: 儲存滑動平均模型 import tensorflow as tf v = tf.Variable(0, dtype=tf.float32, name="v") for variables in tf.global_variables(): print(variables.name) # v:0 ema = tf.train.ExponentialMovingAverage(0.99) maintain_averages_op = ema.apply(tf.global_variables()) for variables in tf.global_variables(): print(variables.name) # v:0 # v/ExponentialMovingAverage:0 saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(tf.assign(v, 10)) sess.run(maintain_averages_op) saver.save(sess, "Model/model_ema.ckpt") print(sess.run([v, ema.average(v)])) # [10.0, 0.099999905] # Part6: 通過變數重新命名直接讀取變數的滑動平均值 import tensorflow as tf v = tf.Variable(0, dtype=tf.float32, name="v") saver = tf.train.Saver({"v/ExponentialMovingAverage": v}) with tf.Session() as sess: saver.restore(sess, "./Model/model_ema.ckpt") print(sess.run(v)) # 0.0999999 # Part7: 通過tf.train.ExponentialMovingAverage的variables_to_restore()函數擷取變數重新命名字典 import tensorflow as tf v = tf.Variable(0, dtype=tf.float32, name="v") # 注意此處的變數名稱name一定要與已儲存的變數名稱一致 ema = tf.train.ExponentialMovingAverage(0.99) print(ema.variables_to_restore()) # {'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>} # 此處的v取自上面變數v的名稱name="v" saver = tf.train.Saver(ema.variables_to_restore()) with tf.Session() as sess: saver.restore(sess, "./Model/model_ema.ckpt") print(sess.run(v)) # 0.0999999 # Part8: 通過convert_variables_to_constants函數將計算圖中的變數及其取值通過常量的方式儲存於一個檔案中 import tensorflow as tf from tensorflow.python.framework import graph_util v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1") v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2") result = v1 + v2 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 匯出當前計算圖的GraphDef部分,即從輸入層到輸出層的計算過程部分 graph_def = tf.get_default_graph().as_graph_def() output_graph_def = graph_util.convert_variables_to_constants(sess, graph_def, ['add']) with tf.gfile.GFile("Model/combined_model.pb", 'wb') as f: f.write(output_graph_def.SerializeToString()) # Part9: 載入包含變數及其取值的模型 import tensorflow as tf from tensorflow.python.platform import gfile with tf.Session() as sess: model_filename = "Model/combined_model.pb" with gfile.FastGFile(model_filename, 'rb') as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) result = tf.import_graph_def(graph_def, return_elements=["add:0"]) print(sess.run(result)) # [array([ 3.], dtype=float32)]
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。