tensorflow1.0學(xué)習(xí)之模型的保存與恢復(fù)(Saver)
將訓(xùn)練好的模型參數(shù)保存起來(lái),以便以后進(jìn)行驗(yàn)證或測(cè)試,這是我們經(jīng)常要做的事情。tf里面提供模型保存的是tf.train.Saver()模塊。
模型保存,先要?jiǎng)?chuàng)建一個(gè)Saver對(duì)象:如
saver=tf.train.Saver()
在創(chuàng)建這個(gè)Saver對(duì)象的時(shí)候,有一個(gè)參數(shù)我們經(jīng)常會(huì)用到,就是 max_to_keep 參數(shù),這個(gè)是用來(lái)設(shè)置保存模型的個(gè)數(shù),默認(rèn)為5,即 max_to_keep=5,保存最近的5個(gè)模型。如果你想每訓(xùn)練一代(epoch)就想保存一次模型,則可以將 max_to_keep設(shè)置為None或者0,如:
saver=tf.train.Saver(max_to_keep=0)
但是這樣做除了多占用硬盤(pán),并沒(méi)有實(shí)際多大的用處,因此不推薦。
當(dāng)然,如果你只想保存最后一代的模型,則只需要將max_to_keep設(shè)置為1即可,即
saver=tf.train.Saver(max_to_keep=1)
創(chuàng)建完saver對(duì)象后,就可以保存訓(xùn)練好的模型了,如:
saver.save(sess,'ckpt/mnist.ckpt',global_step=step)
第一個(gè)參數(shù)sess,這個(gè)就不用說(shuō)了。第二個(gè)參數(shù)設(shè)定保存的路徑和名字,第三個(gè)參數(shù)將訓(xùn)練的次數(shù)作為后綴加入到模型名字中。
saver.save(sess, 'my-model', global_step=0) ==> filename: 'my-model-0'
...
saver.save(sess, 'my-model', global_step=1000) ==> filename: 'my-model-1000'
看一個(gè)mnist實(shí)例:
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 4 10:29:48 2017
@author: Administrator
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=False)
x = tf.placeholder(tf.float32, [None, 784])
y_=tf.placeholder(tf.int32,[None,])
dense1 = tf.layers.dense(inputs=x,
units=1024,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
dense2= tf.layers.dense(inputs=dense1,
units=512,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
logits= tf.layers.dense(inputs=dense2,
units=10,
activation=None,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
loss=tf.losses.sparse_softmax_cross_entropy(labels=y_,logits=logits)
train_op=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
saver=tf.train.Saver(max_to_keep=1)
for i in range(100):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_op, feed_dict={x: batch_xs, y_: batch_ys})
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('epoch:%d, val_loss:%f, val_acc:%f'%(i,val_loss,val_acc))
saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
sess.close()
代碼中紅色部分就是保存模型的代碼,雖然我在每訓(xùn)練完一代的時(shí)候,都進(jìn)行了保存,但后一次保存的模型會(huì)覆蓋前一次的,最終只會(huì)保存最后一次。因此我們可以節(jié)省時(shí)間,將保存代碼放到循環(huán)之外(僅適用max_to_keep=1,否則還是需要放在循環(huán)內(nèi)).
在實(shí)驗(yàn)中,最后一代可能并不是驗(yàn)證精度最高的一代,因此我們并不想默認(rèn)保存最后一代,而是想保存驗(yàn)證精度最高的一代,則加個(gè)中間變量和判斷語(yǔ)句就可以了。
saver=tf.train.Saver(max_to_keep=1)
max_acc=0
for i in range(100):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_op, feed_dict={x: batch_xs, y_: batch_ys})
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('epoch:%d, val_loss:%f, val_acc:%f'%(i,val_loss,val_acc))
if val_acc>max_acc:
max_acc=val_acc
saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
sess.close()
如果我們想保存驗(yàn)證精度最高的三代,且把每次的驗(yàn)證精度也隨之保存下來(lái),則我們可以生成一個(gè)txt文件用于保存。
saver=tf.train.Saver(max_to_keep=3)
max_acc=0
f=open('ckpt/acc.txt','w')
for i in range(100):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_op, feed_dict={x: batch_xs, y_: batch_ys})
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('epoch:%d, val_loss:%f, val_acc:%f'%(i,val_loss,val_acc))
f.write(str(i+1)+', val_acc: '+str(val_acc)+'\n')
if val_acc>max_acc:
max_acc=val_acc
saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
f.close()
sess.close()
模型的恢復(fù)用的是restore()函數(shù),它需要兩個(gè)參數(shù)restore(sess, save_path),save_path指的是保存的模型路徑。我們可以使用tf.train.latest_checkpoint()來(lái)自動(dòng)獲取最后一次保存的模型。如:
model_file=tf.train.latest_checkpoint('ckpt/')
saver.restore(sess,model_file)
則程序后半段代碼我們可以改為:
sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
is_train=False
saver=tf.train.Saver(max_to_keep=3)
#訓(xùn)練階段
if is_train:
max_acc=0
f=open('ckpt/acc.txt','w')
for i in range(100):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_op, feed_dict={x: batch_xs, y_: batch_ys})
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('epoch:%d, val_loss:%f, val_acc:%f'%(i,val_loss,val_acc))
f.write(str(i+1)+', val_acc: '+str(val_acc)+'\n')
if val_acc>max_acc:
max_acc=val_acc
saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
f.close()
#驗(yàn)證階段
else:
model_file=tf.train.latest_checkpoint('ckpt/')
saver.restore(sess,model_file)
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('val_loss:%f, val_acc:%f'%(val_loss,val_acc))
sess.close()
標(biāo)紅的地方,就是與保存、恢復(fù)模型相關(guān)的代碼。用一個(gè)bool型變量is_train來(lái)控制訓(xùn)練和驗(yàn)證兩個(gè)階段。
整個(gè)源程序:
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 4 10:29:48 2017
@author: Administrator
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=False)
x = tf.placeholder(tf.float32, [None, 784])
y_=tf.placeholder(tf.int32,[None,])
dense1 = tf.layers.dense(inputs=x,
units=1024,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
dense2= tf.layers.dense(inputs=dense1,
units=512,
activation=tf.nn.relu,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
logits= tf.layers.dense(inputs=dense2,
units=10,
activation=None,
kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
kernel_regularizer=tf.nn.l2_loss)
loss=tf.losses.sparse_softmax_cross_entropy(labels=y_,logits=logits)
train_op=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
is_train=True
saver=tf.train.Saver(max_to_keep=3)
#訓(xùn)練階段
if is_train:
max_acc=0
f=open('ckpt/acc.txt','w')
for i in range(100):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_op, feed_dict={x: batch_xs, y_: batch_ys})
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('epoch:%d, val_loss:%f, val_acc:%f'%(i,val_loss,val_acc))
f.write(str(i+1)+', val_acc: '+str(val_acc)+'\n')
if val_acc>max_acc:
max_acc=val_acc
saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
f.close()
#驗(yàn)證階段
else:
model_file=tf.train.latest_checkpoint('ckpt/')
saver.restore(sess,model_file)
val_loss,val_acc=sess.run([loss,acc], feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print('val_loss:%f, val_acc:%f'%(val_loss,val_acc))
sess.close()
參考文章:http://www.dhdzp.com/article/138779.htm
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python PyQt5實(shí)戰(zhàn)項(xiàng)目之網(wǎng)速監(jiān)控器的實(shí)現(xiàn)
PyQt5以一套Python模塊的形式來(lái)實(shí)現(xiàn)功能。它包含了超過(guò)620個(gè)類,600個(gè)方法和函數(shù)。它是一個(gè)多平臺(tái)的工具套件,它可以運(yùn)行在所有的主流操作系統(tǒng)中,包含Unix,Windows和Mac OS。PyQt5采用雙重許可模式。開(kāi)發(fā)者可以在GPL和社區(qū)授權(quán)之間選擇2021-11-11
Python shelve模塊實(shí)現(xiàn)解析
這篇文章主要介紹了Python shelve模塊實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
詳解在Python程序中解析并修改XML內(nèi)容的方法
這篇文章主要介紹了在Python程序中解析并修改XML內(nèi)容的方法,依賴于解析成樹(shù)狀結(jié)構(gòu)后的節(jié)點(diǎn)進(jìn)行修改,需要的朋友可以參考下2015-11-11
解決Pycharm 中遇到Unresolved reference ''sklearn''的問(wèn)題
這篇文章主要介紹了解決Pycharm 中遇到Unresolved reference 'sklearn'的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
django 按時(shí)間范圍查詢數(shù)據(jù)庫(kù)實(shí)例代碼
這篇文章主要介紹了django 按時(shí)間范圍查詢數(shù)據(jù)庫(kù)實(shí)例代碼,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
在Linux下使用Python的matplotlib繪制數(shù)據(jù)圖的教程
這篇文章主要介紹了在Linux下使用Python的matplotlib繪制數(shù)據(jù)圖的教程,matplotlib基于Numpy進(jìn)行科學(xué)計(jì)算上的延伸,需要的朋友可以參考下2015-06-06
python求解數(shù)組中兩個(gè)字符串的最小距離
這篇文章主要為大家詳細(xì)介紹了python求解數(shù)組中兩個(gè)字符串的最小距離,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
詳解用Python調(diào)用百度地圖正/逆地理編碼API
這篇文章主要介紹了詳解用Python調(diào)用百度地圖正/逆地理編碼API,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

