tensorflow1.0模型的保存、加载、在训练

1.checkpoint文件总览

tensorflow保存的模型文件如下所示:
报错的模型文件

  • .meta文件保存的是图结构,meta文件是pb(protocol buffer)格式文件,包含变量、op、集合等。
  • ckpt文件是二进制文件,保存了所有的weights、biases、gradients等变量。在tensorflow 0.11之前,保存在**.ckpt**文件中。0.11后,通过.data和.index两个文件保存
  • checkpoint文件,该文件是个文本文件,里面记录了保存的最新的checkpoint文件以及其它checkpoint文件列表(如果保存了多个模型的话)。在inference时,可以通过修改这个文件,指定使用哪个model

2.模型保存

模型保存可以在每一轮epoch更新后保存,或者epoch全部迭代完以后保存。或者没迭代多少epoch保存一次。 在会话session外定义 tf.train.Saver()。在会话内调用saver.save()保存。
看个简单的例子

import tensorflow as tf

w1 = tf.Variable(tf.random_normal(shape=[2]), name='w1')
w2 = tf.Variable(tf.random_normal(shape=[5]), name='w2')
saver = tf.train.Saver()
sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver.save(sess, './model_checkpoint/')   #指定文件夹即可

在实际训练中,我们可能会在每1000次迭代中保存一次模型数据,但是由于图是不变的,没必要每次都去保存,可以通过如下方式指定不保存图:

saver.save(sess, './checkpoint_dir/MyModel',global_step=step,write_meta_graph=False)

另一种比较实用的是,如果你希望每2小时保存一次模型,并且只保存最近的5个模型文件:

tf.train.Saver(max_to_keep=5, keep_checkpoint_every_n_hours=2)

注意:tensorflow默认只会保存最近的5个模型文件,如果你希望保存更多,可以通过max_to_keep来指定

如果我们不对tf.train.Saver指定任何参数,默认会保存所有变量。如果你不想保存所有变量,而只保存一部分变量,可以通过指定variables/collections。在创建tf.train.Saver实例时,通过将需要保存的变量构造list或者dictionary,传入到Saver中:

import tensorflow as tf
w1 = tf.Variable(tf.random_normal(shape=[2]), name='w1')
w2 = tf.Variable(tf.random_normal(shape=[5]), name='w2')
saver = tf.train.Saver([w1,w2])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver.save(sess, './checkpoint_dir/MyModel',global_step=1000)

3.模型的加载

3.1构造网络图

这里指定的是保存的第5个模型的meta文件,如果只有一个的话 默认应该是 “.meta”

saver = tf.train.import_meta_graph('./model_checkpoint/-5.meta')   #构造网络图,参数具体到.meta文件

3.2加载参数

仅仅有图并没有用,更重要的是,我们需要前面训练好的模型参数(即weights、biases,embedding等),变量值需要依赖于Session,因此在加载参数时,先要构造好Session:

import tensorflow as tf
with tf.Session() as sess:
          saver = tf.train.import_meta_graph('./model_checkpoint/-5.meta')   #构造网络图,参数具体到.meta文件
        # saver.restore(sess, './model_checkpoint/')#加载参数,给出文件夹路径即可.  如果保存的模型只有这一个,用这个即可。 如果保存了多个模型用下面的一句
        saver.restore(sess, tf.train.latest_checkpoint('./model_checkpoint/'))
        print(sess.run('vin_id:0'))          #输出变量名的值, 注意需要加 ‘:0’

3.3利用加载后的模型进行预测等操作

前面我们理解了如何保存和恢复模型,很多时候,我们希望使用一些已经训练好的模型,如prediction、fine-tuning以及进一步训练等。这时候,我们可能需要获取训练好的模型中的一些中间结果值,可以通过 graph.get_tensor_by_name(‘vin_id:0’)来获取,注意vin_id:0是tensor的name。

graph = tf.get_default_graph()    #获取当前默认计算图
        golden = graph.get_tensor_by_name("golden:0")   #得到需要输入数据的 placeholder变量
        vin_id = graph.get_tensor_by_name("vin_id:0")
        his_id = graph.get_tensor_by_name("his_id:0")
        tar_id = graph.get_tensor_by_name("tar_id:0")
		
		#得到需要操作执行的op变量
        loss_op = graph.get_tensor_by_name("loss_op:0")
        acc_op = graph.get_tensor_by_name("acc_op:0")

		#预测
		batch_loss, batch_acc  = sess.run([loss_op, acc_op],
                feed_dict={
                           vin_id: batch_x[:,0].reshape(-1,1).astype(int),
                     his_id: dd,#np.array(batch_x)[:,1].reshape(-1,2),#batch_x[:][1],
                     tar_id: cc,#batch_x[:][2],
                     golden:batch_y.astype(int)
                           })

通过上述代码就可以得到 模型需要的输入 input tensor 以及需要的操作tensor.
在 session中 喂入对应的输入参数,即可得到预测结果和loss等信息。

注意: 保存模型时,placeholder里面的值不会被保存,只会保存变量的名称等信息,具体的值需要在根据任务喂给模型

3.4基于训练好的模型加入新的op

如果你不仅仅是用训练好的模型,还要加入一些op,或者说加入一些layers并训练新的模型,可以通过一个简单例子来看如何操作:

import tensorflow as tf

sess = tf.Session()
# 先加载图和变量
saver = tf.train.import_meta_graph('my_test_model-1000.meta')
saver.restore(sess, tf.train.latest_checkpoint('./'))

# 访问placeholders变量,并且创建feed-dict来作为placeholders的新值
graph = tf.get_default_graph()
w1 = graph.get_tensor_by_name("w1:0")
w2 = graph.get_tensor_by_name("w2:0")
feed_dict = {w1: 13.0, w2: 17.0}

#接下来,访问你想要执行的op
op_to_restore = graph.get_tensor_by_name("op_to_restore:0")

# 在当前图中能够加入op
add_on_op = tf.multiply(op_to_restore, 2)

print (sess.run(add_on_op, feed_dict))
# 打印120.0==>(13+17)*2*2


果只想恢复图的一部分,并且再加入其它的op用于fine-tuning。只需通过graph.get_tensor_by_name()方法获取需要的op,并且在此基础上建立图,看一个简单例子,假设我们需要在训练好的VGG网络使用图,并且修改最后一层,将输出改为2,用于fine-tuning新数据:

......
......
saver = tf.train.import_meta_graph('vgg.meta')
# 访问图
graph = tf.get_default_graph() 
 
#访问用于fine-tuning的output
fc7= graph.get_tensor_by_name('fc7:0')
 
#如果你想修改最后一层梯度,需要如下
fc7 = tf.stop_gradient(fc7) # It's an identity function
fc7_shape= fc7.get_shape().as_list()

new_outputs=2
weights = tf.Variable(tf.truncated_normal([fc7_shape[3], num_outputs], stddev=0.05))
biases = tf.Variable(tf.constant(0.05, shape=[num_outputs]))
output = tf.matmul(fc7, weights) + biases
pred = tf.nn.softmax(output)

# Now, you run this with fine-tuning data in sess.run()

参考:https://blog.csdn.net/huachao1001/article/details/78501928/

你可能感兴趣的:(python机器学习,tensorflow,深度学习,python)