Преобразовать pipeline_pb2.TrainEvalPipelineConfig в файл JSON или YAML для API обнаружения объектов tensorflow

#json #dictionary #tensorflow #yaml #object-detection-api

#json #словарь #tensorflow #yaml #object-detection-api

Вопрос:

Я хочу преобразовать pipeline_pb2.TrainEvalPipelineConfig в формат JSON или YAML для API обнаружения объектов tensorflow. Я попытался преобразовать файл protobuf с помощью :

 import tensorflow as tf
from google.protobuf import text_format
import yaml

from object_detection.protos import pipeline_pb2

def get_configs_from_pipeline_file(pipeline_config_path, config_override=None):

  '''
  read .config and convert it to proto_buffer_object
  '''

  pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
  with tf.gfile.GFile(pipeline_config_path, "r") as f:
    proto_str = f.read()
    text_format.Merge(proto_str, pipeline_config)
  if config_override:
    text_format.Merge(config_override, pipeline_config)
  #print(pipeline_config)
  return pipeline_config


def create_configs_from_pipeline_proto(pipeline_config):
  '''
  Returns the configurations as dictionary
  '''

  configs = {}
  configs["model"] = pipeline_config.model
  configs["train_config"] = pipeline_config.train_config
  configs["train_input_config"] = pipeline_config.train_input_reader
  configs["eval_config"] = pipeline_config.eval_config
  configs["eval_input_configs"] = pipeline_config.eval_input_reader
  # Keeps eval_input_config only for backwards compatibility. All clients should
  # read eval_input_configs instead.
  if configs["eval_input_configs"]:
    configs["eval_input_config"] = configs["eval_input_configs"][0]
  if pipeline_config.HasField("graph_rewriter"):
    configs["graph_rewriter_config"] = pipeline_config.graph_rewriter

  return configs


configs = get_configs_from_pipeline_file('pipeline.config')
config_as_dict = create_configs_from_pipeline_proto(configs)
  

Но когда я пытаюсь преобразовать этот возвращенный словарь в YAML с помощью yaml.dump(config_as_dict) , он говорит

 TypeError: can't pickle google.protobuf.pyext._message.RepeatedCompositeContainer objects
  

Для json.dump(config_as_dict) этого говорится :

 Traceback (most recent call last):
  File "config_file_parsing.py", line 48, in <module>
    config_as_json = json.dumps(config_as_dict)
  File "/usr/lib/python3.5/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.5/json/encoder.py", line 198, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.5/json/encoder.py", line 256, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.5/json/encoder.py", line 179, in default
    raise TypeError(repr(o)   " is not JSON serializable")
TypeError: label_map_path: "label_map.pbtxt"
shuffle: true
tf_record_input_reader {
  input_path: "dataset.record"
}
 is not JSON serializable
  

Был бы признателен за некоторую помощь здесь.

Комментарии:

1. Мы были бы признательны за включение реального вопроса, такого как «Предполагается, что Python может создавать дамп классов Python, почему я получаю ошибку?» , поскольку это показало бы ваш уровень знаний (или невежества). Бесполезно заявлять, что вы цените помощь, мы уже знаем, что вам нужна помощь, иначе вас бы здесь не было, и оценка усилий не должна выражаться словами в вопросе.

Ответ №1:

JSON может выводить только подмножество примитивов python primtivies и коллекций dict и list (с ограничением на самоссылки).

YAML более мощный и может использоваться для дампа произвольных объектов Python. Но только в том случае, если эти объекты могут быть «исследованы» на этапе представления дампа, что существенно ограничивает это экземплярами чистых классов Python. Для объектов, созданных на уровне C, можно создать явные дамперы, и если они недоступны, Python попытается использовать протокол pickle для сброса данных в YAML.

Проверка protobuf в PyPI показывает мне, что доступны нестандартные диски, что всегда указывает на некоторую оптимизацию кода на C. Проверка одного из этих файлов действительно показывает предварительно скомпилированный общий объект.

Хотя вы создаете dict из конфигурации, этот dict, конечно, может быть удален только тогда, когда все его ключи и все его значения могут быть удалены. Поскольку ваши ключи представляют собой строки (необходимые для JSON), вам нужно просмотреть каждое из значений, найти то, которое не выводит данные, и преобразовать его в структуру объекта с возможностью вывода (dict / list для JSON, чистый класс Python для YAML).

Возможно, вы захотите взглянуть на модуль json_format