tensorflow保存数据为.pb格式和加载.pb文件(转)

本文深入探讨了TensorFlow中PB模型的使用,包括其优势、保存及加载过程。介绍了PB模型如何实现模型创建与使用的解耦,适用于不同语言和框架间模型的读取与迁移,特别强调了其在移动端应用的价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近接触了tensorflow的object detection API发现里面读取的预先训练模型都是pb格式。

谷歌推荐的保存模型的方式是保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。

它的主要使用场景是实现创建模型与使用模型的解耦, 使得前向推导 inference的代码统一。

另外的好处是保存为 PB 文件时候,模型的变量都会变成固定的,导致模型的大小会大大减小,适合在手机端运行。

还有一个就是,真正离线测试使用的时候,pb格式的数据能够保证数据不会更新变动,就是不会进行反馈调节啦。

保存 PB 文件的代码:

  1. import tensorflow as tf
  2. import os
  3. from tensorflow.python.framework import graph_util
  4. pb_file_path = os.getcwd()
  5. with tf.Session(graph=tf.Graph()) as sess:
  6. x = tf.placeholder(tf.int32, name='x')
  7. y = tf.placeholder(tf.int32, name='y')
  8. b = tf.Variable(1, name='b')
  9. xy = tf.multiply(x, y)
  10. # 这里的输出需要加上name属性
  11. op = tf.add(xy, b, name='op_to_store')
  12. sess.run(tf.global_variables_initializer())
  13. # convert_variables_to_constants 需要指定output_node_names,list(),可以多个
  14. constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['op_to_store'])
  15. # 测试 OP
  16. feed_dict = {x: 10, y: 3}
  17. print(sess.run(op, feed_dict))
  18. # 写入序列化的 PB 文件
  19. with tf.gfile.FastGFile(pb_file_path+'model.pb', mode='wb') as f:
  20. f.write(constant_graph.SerializeToString())
  21. # 输出
  22. # INFO:tensorflow:Froze 1 variables.
  23. # Converted 1 variables to const ops.
  24. # 31

加载 PB 模型文件典型代码:

  1. from tensorflow.python.platform import gfile
  2. sess = tf.Session()
  3. with gfile.FastGFile(pb_file_path+'model.pb', 'rb') as f:
  4. graph_def = tf.GraphDef()
  5. graph_def.ParseFromString(f.read())
  6. sess.graph.as_default()
  7. tf.import_graph_def(graph_def, name='') # 导入计算图
  8. # 需要有一个初始化的过程
  9. sess.run(tf.global_variables_initializer())
  10. # 需要先复原变量
  11. print(sess.run('b:0'))
  12. # 1
  13. # 输入
  14. input_x = sess.graph.get_tensor_by_name('x:0')
  15. input_y = sess.graph.get_tensor_by_name('y:0')
  16. op = sess.graph.get_tensor_by_name('op_to_store:0')
  17. ret = sess.run(op, feed_dict={input_x: 5, input_y: 5})
  18. print(ret)
  19. # 输出 26


保存为 save model 格式也可以生成模型的 PB 文件,并且更加简单。

保存好以后到saved_model_dir目录下,会有一个saved_model.pb文件以及variables文件夹。顾名思义,variables保存所有变量,saved_model.pb用于保存模型结构等信息。

  1. import tensorflow as tf
  2. import os
  3. from tensorflow.python.framework import graph_util
  4. pb_file_path = os.getcwd()
  5. with tf.Session(graph=tf.Graph()) as sess:
  6. x = tf.placeholder(tf.int32, name='x')
  7. y = tf.placeholder(tf.int32, name='y')
  8. b = tf.Variable(1, name='b')
  9. xy = tf.multiply(x, y)
  10. # 这里的输出需要加上name属性
  11. op = tf.add(xy, b, name='op_to_store')
  12. sess.run(tf.global_variables_initializer())
  13. # convert_variables_to_constants 需要指定output_node_names,list(),可以多个
  14. constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['op_to_store'])
  15. # 测试 OP
  16. feed_dict = {x: 10, y: 3}
  17. print(sess.run(op, feed_dict))
  18. # 写入序列化的 PB 文件
  19. with tf.gfile.FastGFile(pb_file_path+'model.pb', mode='wb') as f:
  20. f.write(constant_graph.SerializeToString())
  21. # INFO:tensorflow:Froze 1 variables.
  22. # Converted 1 variables to const ops.
  23. # 31
  24. # 官网有误,写成了 saved_model_builder
  25. builder = tf.saved_model.builder.SavedModelBuilder(pb_file_path+'savemodel')
  26. # 构造模型保存的内容,指定要保存的 session,特定的 tag,
  27. # 输入输出信息字典,额外的信息
  28. builder.add_meta_graph_and_variables(sess,
  29. ['cpu_server_1'])
  30. # 添加第二个 MetaGraphDef
  31. #with tf.Session(graph=tf.Graph()) as sess:
  32. # ...
  33. # builder.add_meta_graph([tag_constants.SERVING])
  34. #...
  35. builder.save() # 保存 PB 模型

这种方法对应的导入模型的方法:

  1. with tf.Session(graph=tf.Graph()) as sess:
  2. tf.saved_model.loader.load(sess, ['cpu_1'], pb_file_path+'savemodel')
  3. sess.run(tf.global_variables_initializer())
  4. input_x = sess.graph.get_tensor_by_name('x:0')
  5. input_y = sess.graph.get_tensor_by_name('y:0')
  6. op = sess.graph.get_tensor_by_name('op_to_store:0')
  7. ret = sess.run(op, feed_dict={input_x: 5, input_y: 5})
  8. print(ret)
  9. # 只需要指定要恢复模型的 session,模型的 tag,模型的保存路径即可,使用起来更加简单

这样和之前的导入 PB 模型一样,也是要知道tensor的name。那么如何可以在不知道tensor name的情况下使用呢,实现彻底的解耦呢? 给add_meta_graph_and_variables方法传入第三个参数,signature_def_map即可。


参考:

https://zhuanlan.zhihu.com/p/32887066



要将训练好的 TensorFlow 模型保存.pb 文件,您可以按照以下步骤进行操作: 1. 定义模型结构:在保存模型之前,您需要定义模型的结构,包括输入输出节点的名称、形状数据类型。您可以使用 TensorFlow 的高级 API(如 Keras)或自定义模型来定义模型结构。 2. 加载模型权重:将训练好的模型权重加载到定义的模型结构中。这可以通过加载保存模型权重文件(如 .h5、.ckpt 等)或通过重新训练模型来实现。 3. 创建 SavedModel:使用 TensorFlow 的 `tf.saved_model.save` 函数将模型保存为 SavedModel 格式。SavedModelTensorFlow 的一种标准模型保存格式,可以包含模型的计算图变量值。 ```python import tensorflow as tf # 定义加载模型权重 model = ... # 定义模型结构 model.load_weights('model_weights.h5') # 加载模型权重 # 保存为 SavedModel 格式 tf.saved_model.save(model, 'saved_model') ``` 这将会在指定路径下创建一个名为 `saved_model` 的文件夹,其中包含了模型的计算图变量值。 4. 导出为 .pb 文件:从 SavedModel 中导出所需的 .pb 文件。可以使用 TensorFlow 的 `tf.compat.v1.graph_util.convert_variables_to_constants` 函数将 SavedModel 的计算图变量值换为常量,并保存.pb 文件。 ```python from tensorflow.python.framework import graph_util # 加载 SavedModel saved_model_dir = 'saved_model' saved_model = tf.saved_model.load(saved_model_dir) # 将 SavedModel 换为 .pb 文件 output_pb_file = 'model.pb' graph_def = graph_util.convert_variables_to_constants( saved_model.sess, saved_model.sess.graph_def, ['output_node_name']) with tf.io.gfile.GFile(output_pb_file, 'wb') as f: f.write(graph_def.SerializeToString()) ``` 将上述代码中的 `'output_node_name'` 替换为模型输出节点的名称。 现在,您应该已经成功将训练好的 TensorFlow 模型保存.pb 文件。请注意,这只是一个基本示例,具体的实现细节可能因您的模型结构需求而有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值