【问题标题】:Seeing the float32 weight in a proto file在 proto 文件中查看 float32 权重
【发布时间】:2017-08-23 21:00:26
【问题描述】:

我已经转换了经过 Google Inception 训练的模型 .pb 文件,如下所示:

A
mixed_9/join/concat_dimConst*

dtype0*
value   :
A
mixed_8/join/concat_dimConst*

dtype0*
value   :
A
mixed_7/join/concat_dimConst*

dtype0*
value   :
A
mixed_6/join/concat_dimConst*

使用从标准输入读取的 Google Protobuf --decode_raw。现在,输出读取为.proto 文件,包括层的名称和一些编码数字。这是.proto文件的前30行:

syntax="proto2";
1 {
  1: "mixed_10/join/concat_dim"
  2: "Const"
  5 {
    1: "dtype"
    2 {
      6: 3
    }
  }
  5 {
    1: "value"
    2 {
      8 {
        1: 3
        2: ""
        7: "\003"
      }
    }
  }
1 {
  1: "mixed_9/join/concat_dim"
  2: "Const"
  5 {
    1: "dtype"
    2 {
      6: 3
    }
  }

解析文件,我正在寻找初始模型的训练权重,例如在这种情况下:

1 {
  1: "Mul"
  2 {
    10: 108
    12: 0x7265646c6f686563
  }
  5 {
    1: "dtype"
    2 {
      6: 1
    }
  }
  5 {
    1: "shape"
    2 {
      7: ""
    }
  }
}

另一方面,使用一个小的 python 脚本,我可以打印出 inception 模型中的所有张量:

import tensorflow as tf
from tensorflow.python.platform import gfile

INCEPTION_LOG_DIR = '/tmp/inception_v3_log'

if not os.path.exists(INCEPTION_LOG_DIR):
    os.makedirs(INCEPTION_LOG_DIR)
with tf.Session() as sess:
    model_filename = './model/tensorflow_inception_v3_stripped_optimized_quantized.pb'
    with gfile.FastGFile(model_filename, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        _= tf.import_graph_def(graph_def,name='')
 pprint([out for op in tf.get_default_graph().get_operations() if op.type != 'Placeholder' for out in op.values() if out.dtype == tf.float32])                                                                                             

我已经生成了该模型的所有层。所以,Mul 层对应于我的 Python 脚本输出的中间行:

(<tf.Tensor 'mixed/join/concat_dim:0' shape=() dtype=int32>,)
(<tf.Tensor 'Mul:0' shape=<unknown> dtype=float32>,)
(<tf.Tensor 'conv/conv2d_params_quint8_const:0' shape=(3, 3, 3, 32) dtype=quint8>,)

我的问题是我找不到读取这些 float32 值的方法,我认为这些值是每一层的权重。

我已经在我的.proto 文件上尝试了protocv3.3,但我收到一个错误:

$ protoc inception.proto.utf --print_free_field_numbers
inception.proto.utf:2:1: Expected top-level statement (e.g. "message").

任何帮助将不胜感激。

P.s:inception_model 的.pb 文件在here 可用。

【问题讨论】:

  • 我假设它实际上是 0x7265646c6f686563 并且是 64 位值。我们有机会看到.proto吗?我可能可以告诉你顶部有什么问题。您还可以尝试通过protogen.marcgravell.com/decode 运行二进制输出,IIRC 也显示浮点数 - 因此如果它与您的预期值匹配,它将验证它是哪个字段。
  • 感谢@MarcGravell,我已将.pb 文件的链接放在更新的问题中。
  • @MarcGravell,还使用您的工具测试了该文件的前 1000 行,以下是输出示例:0A = field 1, type String UTF8: MulPlaceholder* dtype0* shape:� 0A = field 1, type String 03 = length 3 payload = 4D-75-6C UTF8: Mul 12 = field 2, type String 0B = length 11 payload = 50-6C-61-63-65-68-6F-6C-64-65-72 UTF8: Placeholder 50 = field 10, type Variant 6C = 108 (raw) or 54 (zigzag) 61 = field 12, type Fixed64 63-65-68-6F-6C-64-65-72 = 8243105109859919203 (integer) or 1.14115223244741E+243 (floating point)
  • 是 1.1411...E+243 你想的数字吗?
  • 嗯,不确定。 @MarcGravell,我有兴趣查看与每个张量层相关的所有权重。我想在一个矩阵中看到它们,就像一个形状来比较和评估。这就是我使用该模型的全部意义所在。在您看来,有什么办法可以做到这一点?

标签: python tensorflow floating-point protocol-buffers


【解决方案1】:

除非您的模型没有任何变量(经过训练的模型参数),或者它们在导出之前已经转换为常量,否则您还需要从单独的检查点文件加载变量值。它们也可能难以加载,因为据我了解 .pb 文件不会保存保存时所在的集合变量。 MetaGraphDefs 正是出于这个原因而创建的,您很有可能最好寻找其中一个相关的。

如果您的模型确实没有任何变量,您应该能够在加载图定义后通过运行会话来获取该层的值。

session.run('Mul:0')

如果模型有占位符,您可能必须使用 feed_dict

注意:这些不是层的权重,而是相乘的结果。

【讨论】:

  • 谢谢@DomJack。是的,我想我需要一个 feed_dict 来作为占位符:InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'Mul' with dtype float [[Node: Mul = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]] 你能提供一个关于这种情况的例子吗?
猜你喜欢
  • 2019-02-06
  • 1970-01-01
  • 2014-05-31
  • 2018-01-06
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多