TensorFlow 模型載入方法匯總(小結(jié))
一、TensorFlow常規(guī)模型加載方法
保存模型
tf.train.Saver()類,.save(sess, ckpt文件目錄)方法
參數(shù)名稱 | 功能說(shuō)明 | 默認(rèn)值 |
var_list | Saver中存儲(chǔ)變量集合 | 全局變量集合 |
reshape | 加載時(shí)是否恢復(fù)變量形狀 | True |
sharded | 是否將變量輪循放在所有設(shè)備上 | True |
max_to_keep | 保留最近檢查點(diǎn)個(gè)數(shù) | 5 |
restore_sequentially | 是否按順序恢復(fù)變量,模型較大時(shí)順序恢復(fù)內(nèi)存消耗小 | True |
var_list是字典形式{變量名字符串: 變量符號(hào)},相對(duì)應(yīng)的restore也根據(jù)同樣形式的字典將ckpt中的字符串對(duì)應(yīng)的變量加載給程序中的符號(hào)。
如果Saver給定了字典作為加載方式,則按照字典來(lái),如:saver = tf.train.Saver({"v/ExponentialMovingAverage":v}),否則每個(gè)變量尋找自己的name屬性在ckpt中的對(duì)應(yīng)值進(jìn)行加載。
加載模型
當(dāng)我們基于checkpoint文件(ckpt)加載參數(shù)時(shí),實(shí)際上我們使用Saver.restore取代了initializer的初始化
checkpoint文件會(huì)記錄保存信息,通過(guò)它可以定位最新保存的模型:
ckpt = tf.train.get_checkpoint_state('./model/') print(ckpt.model_checkpoint_path)
.meta文件保存了當(dāng)前圖結(jié)構(gòu)
.index文件保存了當(dāng)前參數(shù)名
.data文件保存了當(dāng)前參數(shù)值
tf.train.import_meta_graph函數(shù)給出model.ckpt-n.meta的路徑后會(huì)加載圖結(jié)構(gòu),并返回saver對(duì)象
ckpt = tf.train.get_checkpoint_state('./model/')
tf.train.Saver函數(shù)會(huì)返回加載默認(rèn)圖的saver對(duì)象,saver對(duì)象初始化時(shí)可以指定變量映射方式,根據(jù)名字映射變量(『TensorFlow』滑動(dòng)平均)
saver = tf.train.Saver({"v/ExponentialMovingAverage":v})
saver.restore函數(shù)給出model.ckpt-n的路徑后會(huì)自動(dòng)尋找參數(shù)名-值文件進(jìn)行加載
saver.restore(sess,'./model/model.ckpt-0') saver.restore(sess,ckpt.model_checkpoint_path)
1.不加載圖結(jié)構(gòu),只加載參數(shù)
由于實(shí)際上我們參數(shù)保存的都是Variable變量的值,所以其他的參數(shù)值(例如batch_size)等,我們?cè)趓estore時(shí)可能希望修改,但是圖結(jié)構(gòu)在train時(shí)一般就已經(jīng)確定了,所以我們可以使用tf.Graph().as_default()新建一個(gè)默認(rèn)圖(建議使用上下文環(huán)境),利用這個(gè)新圖修改和變量無(wú)關(guān)的參值大小,從而達(dá)到目的。
''' 使用原網(wǎng)絡(luò)保存的模型加載到自己重新定義的圖上 可以使用python變量名加載模型,也可以使用節(jié)點(diǎn)名 ''' import AlexNet as Net import AlexNet_train as train import random import tensorflow as tf IMAGE_PATH = './flower_photos/daisy/5673728_71b8cb57eb.jpg' with tf.Graph().as_default() as g: x = tf.placeholder(tf.float32, [1, train.INPUT_SIZE[0], train.INPUT_SIZE[1], 3]) y = Net.inference_1(x, N_CLASS=5, train=False) with tf.Session() as sess: # 程序前面得有 Variable 供 save or restore 才不報(bào)錯(cuò) # 否則會(huì)提示沒(méi)有可保存的變量 saver = tf.train.Saver() ckpt = tf.train.get_checkpoint_state('./model/') img_raw = tf.gfile.FastGFile(IMAGE_PATH, 'rb').read() img = sess.run(tf.expand_dims(tf.image.resize_images( tf.image.decode_jpeg(img_raw),[224,224],method=random.randint(0,3)),0)) if ckpt and ckpt.model_checkpoint_path: print(ckpt.model_checkpoint_path) saver.restore(sess,'./model/model.ckpt-0') global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1] res = sess.run(y, feed_dict={x: img}) print(global_step,sess.run(tf.argmax(res,1)))
2.加載圖結(jié)構(gòu)和參數(shù)
''' 直接使用使用保存好的圖 無(wú)需加載python定義的結(jié)構(gòu),直接使用節(jié)點(diǎn)名稱加載模型 由于節(jié)點(diǎn)形狀已經(jīng)定下來(lái)了,所以有不便之處,placeholder定義batch后單張傳會(huì)報(bào)錯(cuò) 現(xiàn)階段不推薦使用,以后如果理解深入了可能會(huì)找到使用方法 ''' import AlexNet_train as train import random import tensorflow as tf IMAGE_PATH = './flower_photos/daisy/5673728_71b8cb57eb.jpg' ckpt = tf.train.get_checkpoint_state('./model/') # 通過(guò)檢查點(diǎn)文件鎖定最新的模型 saver = tf.train.import_meta_graph(ckpt.model_checkpoint_path +'.meta') # 載入圖結(jié)構(gòu),保存在.meta文件中 with tf.Session() as sess: saver.restore(sess,ckpt.model_checkpoint_path) # 載入?yún)?shù),參數(shù)保存在兩個(gè)文件中,不過(guò)restore會(huì)自己尋找 img_raw = tf.gfile.FastGFile(IMAGE_PATH, 'rb').read() img = sess.run(tf.image.resize_images( tf.image.decode_jpeg(img_raw), train.INPUT_SIZE, method=random.randint(0, 3))) imgs = [] for i in range(128): imgs.append(img) print(sess.run(tf.get_default_graph().get_tensor_by_name('fc3:0'),feed_dict={'Placeholder:0': imgs})) ''' img = sess.run(tf.expand_dims(tf.image.resize_images( tf.image.decode_jpeg(img_raw), train.INPUT_SIZE, method=random.randint(0, 3)), 0)) print(img) imgs = [] for i in range(128): imgs.append(img) print(sess.run(tf.get_default_graph().get_tensor_by_name('conv1:0'), feed_dict={'Placeholder:0':img}))
注意,在所有兩種方式中都可以通過(guò)調(diào)用節(jié)點(diǎn)名稱使用節(jié)點(diǎn)輸出張量,節(jié)點(diǎn).name屬性返回節(jié)點(diǎn)名稱。
3.簡(jiǎn)化版本
# 連同圖結(jié)構(gòu)一同加載 ckpt = tf.train.get_checkpoint_state('./model/') saver = tf.train.import_meta_graph(ckpt.model_checkpoint_path +'.meta') with tf.Session() as sess: saver.restore(sess,ckpt.model_checkpoint_path) # 只加載數(shù)據(jù),不加載圖結(jié)構(gòu),可以在新圖中改變batch_size等的值 # 不過(guò)需要注意,Saver對(duì)象實(shí)例化之前需要定義好新的圖結(jié)構(gòu),否則會(huì)報(bào)錯(cuò) saver = tf.train.Saver() with tf.Session() as sess: ckpt = tf.train.get_checkpoint_state('./model/') saver.restore(sess,ckpt.model_checkpoint_path)
二、TensorFlow二進(jìn)制模型加載方法
這種加載方法一般是對(duì)應(yīng)網(wǎng)上各大公司已經(jīng)訓(xùn)練好的網(wǎng)絡(luò)模型進(jìn)行修改的工作
# 新建空白圖 self.graph = tf.Graph() # 空白圖列為默認(rèn)圖 with self.graph.as_default(): # 二進(jìn)制讀取模型文件 with tf.gfile.FastGFile(os.path.join(model_dir,model_name),'rb') as f: # 新建GraphDef文件,用于臨時(shí)載入模型中的圖 graph_def = tf.GraphDef() # GraphDef加載模型中的圖 graph_def.ParseFromString(f.read()) # 在空白圖中加載GraphDef中的圖 tf.import_graph_def(graph_def,name='') # 在圖中獲取張量需要使用graph.get_tensor_by_name加張量名 # 這里的張量可以直接用于session的run方法求值了 # 補(bǔ)充一個(gè)基礎(chǔ)知識(shí),形如'conv1'是節(jié)點(diǎn)名稱,而'conv1:0'是張量名稱,表示節(jié)點(diǎn)的第一個(gè)輸出張量 self.input_tensor = self.graph.get_tensor_by_name(self.input_tensor_name) self.layer_tensors = [self.graph.get_tensor_by_name(name + ':0') for name in self.layer_operation_names]
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
一款強(qiáng)大的端到端測(cè)試工具Playwright介紹
這篇文章主要為大家介紹了一款強(qiáng)大的端到端測(cè)試工具Playwright介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Python+OpenCV實(shí)現(xiàn)定位二維碼
這篇文章主要為大家詳細(xì)介紹了如何利用Python和OpenCV實(shí)現(xiàn)定位二維碼功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12Python實(shí)現(xiàn)將視頻按照時(shí)間維度剪切
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)將視頻按照時(shí)間維度進(jìn)行剪切,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12Python+Pygame實(shí)現(xiàn)懷舊游戲飛機(jī)大戰(zhàn)
第一次見(jiàn)到飛機(jī)大戰(zhàn)是在小學(xué)五年級(jí)下半學(xué)期的時(shí)候,這個(gè)游戲中可以說(shuō)包含了幾乎所有我目前可接觸到的pygame知識(shí)。本文就來(lái)利用Pygame實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲,需要的可以參考一下2022-11-11python中如何實(shí)現(xiàn)徑向基核函數(shù)
這篇文章主要介紹了python中如何實(shí)現(xiàn)徑向基核函數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02python print出共軛復(fù)數(shù)的方法詳解
在本篇內(nèi)容里小編給大家分享的是關(guān)于python print出共軛復(fù)數(shù)的方法總結(jié)內(nèi)容,有需要的讀者們可以學(xué)習(xí)下。2019-06-06關(guān)于Python的一些學(xué)習(xí)總結(jié)
這篇文章主要介紹了關(guān)于Python的一些總結(jié),希望自己以后在學(xué)習(xí)Python的過(guò)程中可以邊學(xué)習(xí)邊總結(jié),就自己之前的學(xué)習(xí)先做以總結(jié),之后將不斷總結(jié)更新2018-05-05python字典翻轉(zhuǎn)的實(shí)現(xiàn)
本文主要介紹了python字典翻轉(zhuǎn)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05python 對(duì)dataframe下面的值進(jìn)行大規(guī)模賦值方法
今天小編就為大家分享一篇python 對(duì)dataframe下面的值進(jìn)行大規(guī)模賦值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06