zoukankan      html  css  js  c++  java
  • tensorflow 1.0 学习:模型的保存与恢复

    模型保存,先要创建一个Saver对象:如

    saver=tf.train.Saver()

    在创建这个Saver对象的时候,有一个参数我们经常会用到,就是 max_to_keep 参数,这个是用来设置保存模型的个数,默认为5,即 max_to_keep=5,保存最近的5个模型。如果你想每训练一代(epoch)就想保存一次模型,则可以将 max_to_keep设置为None或者0,如:

    saver=tf.train.Saver(max_to_keep=0)

    但是这样做除了多占用硬盘,并没有实际多大的用处,因此不推荐。

    当然,如果你只想保存最后一代的模型,则只需要将max_to_keep设置为1即可,即

    saver=tf.train.Saver(max_to_keep=1)

    创建完saver对象后,就可以保存训练好的模型了,如:

    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实例:

    复制代码
    # -*- 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,否则还是需要放在循环内).

    在实验中,最后一代可能并不是验证精度最高的一代,因此我们并不想默认保存最后一代,而是想保存验证精度最高的一代,则加个中间变量和判断语句就可以了。

    复制代码
    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文件用于保存。

    复制代码
    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()来自动获取最后一次保存的模型。如:

    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)
    
    #训练阶段
    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来控制训练和验证两个阶段。

    整个源程序:

    复制代码
    # -*- 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://blog.csdn.net/u011500062/article/details/51728830

     
     
  • 相关阅读:
    Spring使用@Value注解各种类型的值
    Jdom生成xml文件时的特殊字符问题
    将博客搬至CSDN
    ubuntu/mint添加字体
    linux保持ssh连接
    servlet 重定向与转发区别
    u盘写保护
    修改默认终端
    sudo apt-get update 无法获得锁
    logback多线程日志MDC
  • 原文地址:https://www.cnblogs.com/liuyihai/p/9043167.html
Copyright © 2011-2022 走看看