TensorFlow模型保存和提取的方法
一、TensorFlow模型保存和提取方法
1. TensorFlow通過tf.train.Saver類實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的保存和提取。tf.train.Saver對(duì)象saver的save方法將TensorFlow模型保存到指定路徑中,saver.save(sess,"Model/model.ckpt") ,實(shí)際在這個(gè)文件目錄下會(huì)生成4個(gè)人文件:

checkpoint文件保存了一個(gè)錄下多有的模型文件列表,model.ckpt.meta保存了TensorFlow計(jì)算圖的結(jié)構(gòu)信息,model.ckpt保存每個(gè)變量的取值,此處文件名的寫入方式會(huì)因不同參數(shù)的設(shè)置而不同,但加載restore時(shí)的文件路徑名是以checkpoint文件中的“model_checkpoint_path”值決定的。
2. 加載這個(gè)已保存的TensorFlow模型的方法是saver.restore(sess,"./Model/model.ckpt") ,加載模型的代碼中也要定義TensorFlow計(jì)算圖上的所有運(yùn)算并聲明一個(gè)tf.train.Saver類,不同的是加載模型時(shí)不需要進(jìn)行變量的初始化,而是將變量的取值通過保存的模型加載進(jìn)來,注意加載路徑的寫法。若不希望重復(fù)定義計(jì)算圖上的運(yùn)算,可直接加載已經(jīng)持久化的圖,saver =tf.train.import_meta_graph("Model/model.ckpt.meta") 。
3.tf.train.Saver類也支持在保存和加載時(shí)給變量重命名,聲明Saver類對(duì)象的時(shí)候使用一個(gè)字典dict重命名變量即可,{"已保存的變量的名稱name": 重命名變量名},saver = tf.train.Saver({"v1":u1, "v2": u2})即原來名稱name為v1的變量現(xiàn)在加載到變量u1(名稱name為other-v1)中。
4. 上一條做的目的之一就是方便使用變量的滑動(dòng)平均值。如果在加載模型時(shí)直接將影子變量映射到變量自身,則在使用訓(xùn)練好的模型時(shí)就不需要再調(diào)用函數(shù)來獲取變量的滑動(dòng)平均值了。載入時(shí),聲明Saver類對(duì)象時(shí)通過一個(gè)字典將滑動(dòng)平均值直接加載到新的變量中,saver = tf.train.Saver({"v/ExponentialMovingAverage": v}),另通過tf.train.ExponentialMovingAverage的variables_to_restore()函數(shù)獲取變量重命名字典。
此外,通過convert_variables_to_constants函數(shù)將計(jì)算圖中的變量及其取值通過常量的方式保存于一個(gè)文件中。
二、TensorFlow程序?qū)崿F(xiàn)
# 本文件程序?yàn)榕浜辖滩募皩W(xué)習(xí)進(jìn)度漸進(jìn)進(jìn)行,請(qǐng)按照注釋分段執(zhí)行
# 執(zhí)行時(shí)要注意IDE的當(dāng)前工作過路徑,最好每段重啟控制器一次,輸出結(jié)果更準(zhǔn)確
# Part1: 通過tf.train.Saver類實(shí)現(xiàn)保存和載入神經(jīng)網(wǎng)絡(luò)模型
# 執(zhí)行本段程序時(shí)注意當(dāng)前的工作路徑
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: 若不希望重復(fù)定義計(jì)算圖上的運(yùn)算,可直接加載已經(jīng)持久化的圖
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類也支持在保存和加載時(shí)給變量重命名
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類對(duì)象,會(huì)報(bào)錯(cuò)變量找不到
# 使用一個(gè)字典dict重命名變量即可,{"已保存的變量的名稱name": 重命名變量名}
# 原來名稱name為v1的變量現(xiàn)在加載到變量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: 保存滑動(dòng)平均模型
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: 通過變量重命名直接讀取變量的滑動(dòng)平均值
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()函數(shù)獲取變量重命名字典
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函數(shù)將計(jì)算圖中的變量及其取值通過常量的方式保存于一個(gè)文件中
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())
# 導(dǎo)出當(dāng)前計(jì)算圖的GraphDef部分,即從輸入層到輸出層的計(jì)算過程部分
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)]
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python判斷一個(gè)三位數(shù)是否為水仙花數(shù)的示例
今天小編就為大家分享一篇Python判斷一個(gè)三位數(shù)是否為水仙花數(shù)的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-11-11
pytorch實(shí)現(xiàn)MNIST手寫體識(shí)別
這篇文章主要為大家詳細(xì)介紹了pytorch實(shí)現(xiàn)MNIST手寫體識(shí)別,使用全連接神經(jīng)網(wǎng)絡(luò),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
python實(shí)現(xiàn)將json多行數(shù)據(jù)傳入到mysql中使用
這篇文章主要介紹了python實(shí)現(xiàn)將json多行數(shù)據(jù)傳入到mysql中使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
pytorch 實(shí)現(xiàn)計(jì)算 kl散度 F.kl_div()
這篇文章主要介紹了pytorch 實(shí)現(xiàn)計(jì)算 kl散度 F.kl_div(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(五):socket的一些補(bǔ)充
前面已經(jīng)為大家介紹了python socket的一些相關(guān)知識(shí),這里為大家補(bǔ)充下,方便需要的朋友2014-06-06

