ckpt模型和pb模型介绍:
ckpt:
1.这种模型文件是依赖 TensorFlow 的,只能在其框架下使用;
2.在恢复模型之前还需要再定义一遍网络结构,然后才能把变量的值恢复到网络中。
pb:
1.谷歌推荐的保存模型的方式是保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型;
2. 保存为 PB 文件时候,模型的变量都会变成固定的,导致模型的大小会大大减小,适合在手机端运行。
所以要写ffmpeg的filter必须要用pb模型,而无法解析checkpoint。即
ckpt只能用在tensorflow的框架,pb可以使用在大多数的语言框架
再使用 tf.train.Saver() 保存参数通常会生成以下文件
那么这些文件具体是什么呢?
.ckpt文件:是旧版本的输出saver.save(sess),相当于你的.ckpt-data
“checkpoint”:文件仅用于告知某些TF函数,这是最新的检查点文件。
.ckpt-meta:包含元图,即计算图的结构,没有变量的值(基本上你可以在tensorboard / graph中看到)。
.ckpt-data:包含所有变量的值,没有结构。
.ckpt-index:可能是内部需要的某种索引来正确映射前两个文件,它通常不是必需的
可以只用 .ckpt-meta 和恢复一个模型 .ckpt-data
已知ckpt模型转pb模型
1.查看输出节点名称
# function: get the node name of ckpt model
from tensorflow.python import pywrap_tensorflow
# checkpoint_path = 'model.ckpt-xxx' #保留ckpt的文件目录
checkpoint_path = './DnCNN_tensorflow1_4/checkpoint_demo/DnCNN-tensorflow-67336'
reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path)
var_to_shape_map = reader.get_variable_to_shape_map()
for key in var_to_shape_map:
print("tensor_name: ", key)
得到输出节点结果为:
tensor_name: block1/conv2d/kernel
tensor_name: block17/conv2d/bias
tensor_name: block14/batch_normalization/beta/AdamOptimizer
tensor_name: block14/batch_normalization/gamma/AdamOptimizer_1
tensor_name: block17/conv2d/bias/AdamOptimizer
tensor_name: block17/conv2d/bias/AdamOptimizer_1
tensor_name: block15/conv15/kernel
tensor_name: block8/batch_normalization/gamma
tensor_name: block17/conv2d/kernel
tensor_name: block17/conv2d/kernel/AdamOptimizer
tensor_name: block17/conv2d/kernel/AdamOptimizer_1
tensor_name: block7/batch_normalization/beta
tensor_name: block2/batch_normalization/beta
因为使用的是Dncnn网络模型的ckpt,总共只有17层,模型代码端并没有写入节点名称,所以节点保存采用默认层数方式,所以这里输出节点名称为:block17/conv2d/kernel
可以观察Dncnn网络模型代码:
def dncnn(input, is_training=True, output_channels=1):
with tf.variable_scope('block1'):
output = tf.layers.conv2d(input, 64, 3, padding='same', activation=tf.nn.relu)
for layers in range(2, 16 + 1):
with tf.variable_scope('block%d' % layers):
output = tf.layers.conv2d(output, 64, 3, padding='same', name='conv%d' % layers, use_bias=False)
output = tf.nn.relu(tf.layers.batch_normalization(output, training=is_training))
with tf.variable_scope('block17'):
output = tf.layers.conv2d(output, output_channels, 3, padding='same')
return input - output
若想知道模型输出节点,也可以通过在层数中加入name来表示。
2.知道输出节点后转pb模型
import tensorflow as tf
from tensorflow.python.framework.graph_util import convert_variables_to_constants
sess = tf.Session()
#meta文件路径
saver = tf.train.import_meta_graph("./DnCNN_tensorflow1_4/checkpoint_demo/DnCNN-tensorflow-67336.meta")
#checkpoint文件上级目录
saver.restore(sess, tf.train.latest_checkpoint("./DnCNN_tensorflow1_4/checkpoint_demo"))
graph = tf.get_default_graph()
#output_node_names=['输出节点名称']
output_graph_def = convert_variables_to_constants(sess, sess.graph_def, output_node_names=['block17/conv2d/kernel'])
#要输出pb模型名称
with tf.gfile.FastGFile('dncnn.pb', mode='wb') as f:
f.write(output_graph_def.SerializeToString())
即可看到输出的dncnn.pb文件。