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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tensorflow 模型的保存和加载

發(fā)布時間:2024/9/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tensorflow 模型的保存和加载 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

為了讓訓(xùn)練結(jié)果可以復(fù)用,需要將訓(xùn)練得到的神經(jīng)網(wǎng)絡(luò)模型持久化,也就是把模型的參數(shù)保存下來,并保證可以持久化后的模型文件中還原出保存的模型。

1. 保存模型

tensorflow提供了一個API可以方便的保存和還原神經(jīng)網(wǎng)絡(luò)的模型。這個API就是tf.train.saver類。

import tensorflow as tf# 保存計算兩個變量和的模型 v1 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) v2 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) result = v1 + v2init_op = tf.global_variables_initializer() # 聲明tf.train.Saver()類用于保存模型 saver = tf.train.Saver() # 加載保存了兩個變量和的模型 with tf.Session() as sess:print("save here...")sess.run(init_op)# 保存模型到下面路徑下saver.save(sess,"/Users/lilong/Desktop/tt/model.ckpt")print(sess.run(result))

運行結(jié)果:

save here... [-1.6226364]

這里的代碼實現(xiàn)了一個簡單的加法功能,通過saver.save函數(shù)把模型保存到了相應(yīng)的路徑下,這里一定要注意第一次保存一定是saver.save,而不是saver.restore。
雖然上面的模型保存路徑只提供了一個,但是這個目錄下一般會出現(xiàn)三個文件,這是因為tensorflow會將計算圖的結(jié)構(gòu)和圖上的參數(shù)值分開保存。

  • model.ckpt.meta:保存了計算圖的網(wǎng)路結(jié)構(gòu)
  • model.ckpt.data.:保存了變量的取值
  • checkpoint:保存了一個目錄下的所有的模型文件列表

2. 加載保存的模型

import tensorflow as tf# 保存計算兩個變量和的模型 v1 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) v2 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) result = v1 + v2# 加載模型的代碼和保存模型的代碼的區(qū)別是:沒有運行變量的初始化過程,而是將變量的值通過已經(jīng)保存的模型加載進(jìn)來 #init_op = tf.global_variables_initializer()saver = tf.train.Saver() # 加載保存了兩個變量和的模型 with tf.Session() as sess:print("Reading checkpoints...")# 加載已經(jīng)保存的模型saver.restore(sess,"/Users/lilong/Desktop/tt/model.ckpt")print(sess.run(result))

這里要注意的是加載模型和保存模型的區(qū)別是:加載模型的代碼沒有運行變量的初始化過程,而是將變量的值通過已經(jīng)保存的模型加載進(jìn)來。

上面是單獨加載模型,當(dāng)然也可以如下面這樣保存好模型后直接加載:

import tensorflow as tf# 保存計算兩個變量和的模型 v1 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) v2 = tf.Variable(tf.random_normal([1], stddev=1, seed=1)) result = v1 + v2init_op = tf.global_variables_initializer() # 聲明tf.train.Saver()類用于保存模型 saver = tf.train.Saver() # 加載保存了兩個變量和的模型 with tf.Session() as sess:print("save here...")sess.run(init_op)# 保存模型到下面路徑下saver.save(sess,"/Users/lilong/Desktop/tt/model.ckpt")print(sess.run(result))# 加載保存了兩個變量和的模型 with tf.Session() as sess:print("Reading checkpoints...")# 加載已經(jīng)保存的模型saver.restore(sess,"/Users/lilong/Desktop/tt/model.ckpt")print(sess.run(result))

運行結(jié)果:

save here... [-1.6226364] Reading checkpoints... INFO:tensorflow:Restoring parameters from /Users/lilong/Desktop/tt/model.ckpt [-1.6226364]

還可以這樣加載已經(jīng)持久化的模型:

import tensorflow as tf # 直接加載持久化的圖。 saver = tf.train.import_meta_graph("/Users/lilong/Desktop/tt/model.ckpt.meta")with tf.Session() as sess:print('get here...')saver.restore(sess, "/Users/lilong/Desktop/tt/model.ckpt")print(sess.run(tf.get_default_graph().get_tensor_by_name("add:0")))

輸出:

get here... INFO:tensorflow:Restoring parameters from /Users/lilong/Desktop/tt/model.ckpt [-1.6226364]

這里得到的是指定的張量的值。

4. 加載模型時給變量重命名

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu Aug 16 16:17:17 2018@author: lilong """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") result1 = v1 + v2init_op = tf.global_variables_initializer() saver = tf.train.Saver() # 加載保存了兩個變量和的模型 with tf.Session() as sess:print("save here...")sess.run(init_op)# 保存模型到下面路徑下saver.save(sess,"/Users/lilong/Desktop/qq/model.ckpt")print(sess.run(result1))for variables in tf.global_variables(): print ('variables_1:',variables.name)# 這里聲明的變量和已經(jīng)保存的模型中的變量名稱不同 v1 = tf.Variable(tf.constant(1.0, shape=[1]), name = "other-v1") v2 = tf.Variable(tf.constant(2.0, shape=[1]), name = "other-v2") result2 = v1 + v2saver1 = tf.train.Saver({"v1": v1, "v2": v2}) #saver1 = tf.train.Saver()# 加載保存了兩個變量和的模型 with tf.Session() as sess:print("Reading checkpoints...")# 加載已經(jīng)保存的模型saver1.restore(sess,"/Users/lilong/Desktop/qq/model.ckpt")print(sess.run(result2))for variables in tf.global_variables(): print ('variables_2:',variables.name)

運行:

save here... [3.] variables_1: v1:0 variables_1: v2:0 Reading checkpoints... INFO:tensorflow:Restoring parameters from /Users/lilong/Desktop/qq/model.ckpt [3.] variables_2: v1:0 variables_2: v2:0 variables_2: other-v1:0 variables_2: other-v2:0

這里對變量v1,v2的名稱進(jìn)行了修改,所以如果直接使用tf.train.Saver()來保存默認(rèn)的模型,那么程序就會報找不到變量的錯誤,因為模型保存時和加載時的名稱不一致,這個時候可以使用字典把模型保存時的變量名和需要加載的變量聯(lián)系起來。
這樣的好處之一是方便使用變量的滑動平均值,在tensorflow中的每一個變量的滑動平均值是通過影子變量維護(hù)的,所以要獲取變量的滑動平均值實際就是獲取影子變量的值,如果在加載模型時直接將影子變量映射到變量自身,那么在使用訓(xùn)練好的模型時就不需要調(diào)用函數(shù)來獲取滑動平均值了。

4. 保存滑動平均模型

import tensorflow as tfv = tf.Variable(0, dtype=tf.float32, name="v") # 在沒有申請滑動平均值時只有一個變量 for variables in tf.global_variables(): print('Before MovingAverage:',variables.name)ema = tf.train.ExponentialMovingAverage(0.99) maintain_averages_op = ema.apply(tf.global_variables()) # 在申請滑動平均模型之后,tensorflow會自動生成一個影子變量:v/ExponentialMovingAverage:0 for variables in tf.global_variables(): print ('After MovingAverage:',variables.name)# 保存滑動平均模型 saver = tf.train.Saver() with tf.Session() as sess:init_op = tf.global_variables_initializer()sess.run(init_op)sess.run(tf.assign(v, 10))sess.run(maintain_averages_op)# 保存的時候會將v:0 v/ExponentialMovingAverage:0這兩個變量都存下來。saver.save(sess, "model/model2.ckpt")print ('last:',sess.run([v, ema.average(v)])) # 輸出:[10.0, 0.099999905]# 通過變量重命名直接讀取變量的滑動平均值,通過這個方法就可以用完全一樣的代碼來計算滑動平均模型的前向傳播的結(jié)果 v_1 = tf.Variable(0, dtype=tf.float32, name="v") # 通過變量重命名將原來變量v的滑動平均值直接賦值給v。 saver = tf.train.Saver({"v/ExponentialMovingAverage": v_1}) with tf.Session() as sess:saver.restore(sess, "model/model2.ckpt")print('here:',sess.run(v_1)) # 輸出0.099999905,這個值就是原來模型中變量v的滑動平均值

運行結(jié)果:

Before MovingAverage: v:0 After MovingAverage: v:0 After MovingAverage: v/ExponentialMovingAverage:0 last: [10.0, 0.099999905] INFO:tensorflow:Restoring parameters from model/model2.ckpt here: 0.099999905

可以看到通過變量重命名直接讀取變量的滑動平均值。

為了方便加載時重命名滑動平均變量,tensorflow提供了variables_to_restore()函數(shù),來生成tf.train.Saver類需要的變量重命名字典:

import tensorflow as tfv = tf.Variable(0, dtype=tf.float32, name="v") ema = tf.train.ExponentialMovingAverage(0.99) # variables_to_restore()函數(shù)可以直接生成字典 print('here:',ema.variables_to_restore())#saver = tf.train.Saver({"v/ExponentialMovingAverage": v}) saver = tf.train.Saver(ema.variables_to_restore()) with tf.Session() as sess:print("Reading checkpoints...")saver.restore(sess, "model/model2.ckpt")print ('run:',sess.run(v))

運行結(jié)果:

here: {'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>} Reading checkpoints... INFO:tensorflow:Restoring parameters from model/model2.ckpt run: 0.099999905

使用tf.train.Saver會保存運行tensorflow中程序所需要的全部信息,而某些情況下并不需要全部的信息,比如測試或離線預(yù)測時,只需知道如何從神經(jīng)網(wǎng)絡(luò)的輸入層經(jīng)過前向傳播計算得到輸出層即可,而不需要其他的一些信息,有時將變量取值和計算圖分成不同的文件存儲也不方便,于是有了convert_variables_to_constants函數(shù),該函數(shù)可以將計算圖中的變量及其取值通過常量的方式保存,這樣整個tensorflow圖可以統(tǒng)一保存在一個文件中。
示例:

import tensorflow as tf from tensorflow.python.framework import graph_utilv1 = tf.Variable(tf.constant(1.0, shape=[1]), name = "v1") v2 = tf.Variable(tf.constant(2.0, shape=[1]), name = "v2") result = v1 + v2init_op = tf.global_variables_initializer() with tf.Session() as sess:sess.run(init_op)# 導(dǎo)出當(dāng)前計算圖的graphdef部分,只需要這一部分就可以完成從輸入層到輸出層的計算過程graph_def = tf.get_default_graph().as_graph_def()# 將圖中的變量及其取值轉(zhuǎn)化為常量,同時將圖中不必要的節(jié)點。這里我們只關(guān)心程序中的某些計算節(jié)點,# 和這些無關(guān)的計算節(jié)點就沒有計算并保存了。'add'是計算機(jī)節(jié)點名字output_graph_def = graph_util.convert_variables_to_constants(sess, graph_def, ['add'])# 將導(dǎo)入的模型存入文件with tf.gfile.GFile("model/combined_model.pb", "wb") as f:f.write(output_graph_def.SerializeToString())# 通過下面的程序就可以直接計算定義的加法運算的結(jié)果,該方法可以用于遷移學(xué)習(xí) from tensorflow.python.platform import gfile with tf.Session() as sess:model_filename = "model/combined_model.pb"# 讀取保存的模型文件,并將文件解析成對應(yīng)的graph protocol bufferwith gfile.FastGFile(model_filename, 'rb') as f:graph_def = tf.GraphDef()graph_def.ParseFromString(f.read())# graph_def中保存的圖加載到當(dāng)前的圖中。return_elements給出返回的張量的名稱。# 這里的add不是計算機(jī)節(jié)點的名稱,而是張量的名稱,所以會是add:0result = tf.import_graph_def(graph_def, return_elements=["add:0"])print('run:',sess.run(result))

輸出:

INFO:tensorflow:Froze 2 variables. INFO:tensorflow:Converted 2 variables to const ops. run: [array([3.], dtype=float32)]

參考:《Tensorflow實戰(zhàn)Google深度學(xué)習(xí)框架》

總結(jié)

以上是生活随笔為你收集整理的tensorflow 模型的保存和加载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。