将训练好的模型参数保存起来,以便以后进行验证或测试,这是我们经常要做的事情。tf里面提供模型保存的是tf.train.Saver()模块。
模型保存,先要创建一个Saver对象:如
1
|
saver = tf.train.Saver() |
在创建这个Saver对象的时候,有一个参数我们经常会用到,就是 max_to_keep 参数,这个是用来设置保存模型的个数,默认为5,即 max_to_keep=5,保存最近的5个模型。如果你想每训练一代(epoch)就想保存一次模型,则可以将 max_to_keep设置为None或者0,如:
1
|
saver = tf.train.Saver(max_to_keep = 0 ) |
但是这样做除了多占用硬盘,并没有实际多大的用处,因此不推荐。
当然,如果你只想保存最后一代的模型,则只需要将max_to_keep设置为1即可,即
1
|
saver = tf.train.Saver(max_to_keep = 1 ) |
创建完saver对象后,就可以保存训练好的模型了,如:
1
|
saver.save(sess, 'ckpt/mnist.ckpt' ,global_step = step) |
第一个参数sess,这个就不用说了。第二个参数设定保存的路径和名字,第三个参数将训练的次数作为后缀加入到模型名字中。
saver.save(sess, 'my-model', global_step=0) ==> filename: 'my-model-0'
...
saver.save(sess, 'my-model', global_step=1000) ==> filename: 'my-model-1000'
看一个mnist实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# -*- 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() |
代码中红色部分就是保存模型的代码,虽然我在每训练完一代的时候,都进行了保存,但后一次保存的模型会覆盖前一次的,最终只会保存最后一次。因此我们可以节省时间,将保存代码放到循环之外(仅适用max_to_keep=1,否则还是需要放在循环内).
在实验中,最后一代可能并不是验证精度最高的一代,因此我们并不想默认保存最后一代,而是想保存验证精度最高的一代,则加个中间变量和判断语句就可以了。
1
2
3
4
5
6
7
8
9
10
11
|
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() |
如果我们想保存验证精度最高的三代,且把每次的验证精度也随之保存下来,则我们可以生成一个txt文件用于保存。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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) + ' ' ) if val_acc>max_acc: max_acc = val_acc saver.save(sess, 'ckpt/mnist.ckpt' ,global_step = i + 1 ) f.close() sess.close() |
模型的恢复用的是restore()函数,它需要两个参数restore(sess, save_path),save_path指的是保存的模型路径。我们可以使用tf.train.latest_checkpoint()来自动获取最后一次保存的模型。如:
1
2
|
model_file = tf.train.latest_checkpoint( 'ckpt/' ) saver.restore(sess,model_file) |
则程序后半段代码我们可以改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
sess = tf.InteractiveSession() sess.run(tf.global_variables_initializer()) is_train = False saver = tf.train.Saver(max_to_keep = 3 ) #训练阶段 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) + ' ' ) if val_acc>max_acc: max_acc = val_acc saver.save(sess, 'ckpt/mnist.ckpt' ,global_step = i + 1 ) f.close() #验证阶段 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() |
标红的地方,就是与保存、恢复模型相关的代码。用一个bool型变量is_train来控制训练和验证两个阶段。
整个源程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# -*- 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 ) #训练阶段 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) + ' ' ) if val_acc>max_acc: max_acc = val_acc saver.save(sess, 'ckpt/mnist.ckpt' ,global_step = i + 1 ) f.close() #验证阶段 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.zzvips.com/article/138370.html
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.cnblogs.com/denny402/p/6940134.html