2017-02-09 8 views
0

С here,Получение Protobuf сообщение для каждого TensorFlow Операция

Есть несколько способов, чтобы получить список OpDefs для зарегистрированных ОПС:

  • TF_GetAllOpList в C API возвращает все зарегистрированные Сообщения протокола OpDef. Это можно использовать для записи генератора на языке клиента . Для этого требуется, чтобы язык клиента поддерживал поддержку буфера протокола , чтобы интерпретировать сообщения OpDef.
  • Функция C++ OpRegistry :: Global() -> GetRegisteredOps() возвращает тот же список всех зарегистрированных OpDefs (определенный в [tensorflow/core/framework/op.h]). Это можно использовать для записи генератора в C++ (особенно полезно для языков, на которых имеет поддержку буфера протокола).
  • Сериализуемая в ASCII версия этого списка периодически проверяется на [tensorflow/core/ops/ops.pbtxt] с помощью автоматизированного процесса .

Но увы, я хочу сделать это в Python, как,

import tensorflow as tf 
from google.protobuf import json_format 
json_string = json_format.MessageToJson(tf.GetAllOpsList()) 

Я хочу способ получить сообщение Protobuf для каждой операции в Tensorflow, так что я могу сбросить его как JSON с помощью

ответ

2

Это ops.txt. Вот пример перечисления всех сообщений OpDef для ops, которые производят выходы строк.

import tensorflow as tf 

from tensorflow.core.framework import op_def_pb2 
from google.protobuf import text_format 

def get_op_types(op): 
    for attr in op.attr: 
     if attr.type != 'type': 
      continue 
     return list(attr.allowed_values.list.type) 
    return [] 

# directory where you did "git clone" 
tensorflow_git_base = "/Users/yaroslav/tensorflow.git" 
ops_file = tensorflow_git_base+"/tensorflow/tensorflow/core/ops/ops.pbtxt" 
ops = op_def_pb2.OpList() 
text_format.Merge(open(ops_file).read(), ops) 

for op in ops.op: 
    # get templated string types 
    if tf.string in get_op_types(op): 
     print(op.name, op.summary) 
    #for arg in op.input_arg: 
    for arg in op.output_arg: 
     if arg.type == tf.string: 
      print(op.name, op.summary) 
      break 

** Добавлено ** Если вы хотите быть чувствительны к новому опсу добавляемой можно осуществить реинжиниринг как текущие обертки Python сделать это. Например, рассмотрите файл gen_array_ops.py. Он имеет следующий фрагмент

def _InitOpDefLibrary(): 
    op_list = _op_def_pb2.OpList() 
    _text_format.Merge(_InitOpDefLibrary.op_list_ascii, op_list) 
    _op_def_registry.register_op_list(op_list) 
    op_def_lib = _op_def_library.OpDefLibrary() 
    op_def_lib.add_op_list(op_list) 
    return op_def_lib 


_InitOpDefLibrary.op_list_ascii = """op { 
    name: "BatchMatrixBandPart" 
    input_arg { 
    name: "input" 
    type_attr: "T" 
    } 
    input_arg { 
    name: "num_lower" 
    type: DT_INT64 
    } 
    input_arg { 
    name: "num_upper" 
    type: DT_INT64 
    } 
    output_arg { 
    name: "band" 
    type_attr: "T" 
    } 
    attr { 
    name: "T" 
    type: "type" 
    } 
    deprecation { 
    version: 14 
    explanation: "Use MatrixBandPart" 
    } 
} 

Так эти сообщения protobufs генерируется из базового кода C во время генерации gen_array_ops. Для отслеживания того, как они были сгенерированы, см. https://stackoverflow.com/a/41149557/419116

+0

Я бы предпочел использовать Python, чтобы добавить пользовательские операции и получить Protobuf из этих –

+0

Добавлена ​​дополнительная информация. Вы можете либо восстановить «ops.txt», вызвав тот же сценарий генерации, что и во время генерации gen _ * _ ops.py, или найти базовую функциональность C и добавить некоторые обертки swig –

+0

Спасибо! Почти готово. Меня не волнует аський, но мне нужен JSON. Поэтому я изменил его на 'from google.protobuf import json_format' и обнаружил, что' json_format.MessageToJson (gen_array_ops._InitOpDefLibrary() ._ ops ['Const']. Op_def) 'почти дает мне то, что я хочу. Это просто metaInfoDef, но мне нужен блок graphDef слишком –