模型保存可以在每一轮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)
这里指定的是保存的第5个模型的meta文件,如果只有一个的话 默认应该是 “.meta”
saver = tf.train.import_meta_graph('./model_checkpoint/-5.meta') #构造网络图,参数具体到.meta文件
仅仅有图并没有用,更重要的是,我们需要前面训练好的模型参数(即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’
前面我们理解了如何保存和恢复模型,很多时候,我们希望使用一些已经训练好的模型,如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里面的值不会被保存,只会保存变量的名称等信息,具体的值需要在根据任务喂给模型
如果你不仅仅是用训练好的模型,还要加入一些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/