Вот файл конфигурации , который представляет объект protobuf:
model {
faster_rcnn {
num_classes: 37
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
...
Я хочу использовать python, чтобы прочитать это в объект, внести некоторые изменения в некоторые значения и затем записать его обратно в файл конфигурации.
Осложняющим фактором является то, что это довольно большой объект, построенный из множества файлов .proto.
Мне удалось выполнить задачу, преобразовав протобуф в словарь, внеся изменения, а затем преобразовав обратно в протобуф, например:
import tensorflow as tf
from google.protobuf.json_format import MessageToDict
from google.protobuf.json_format import ParseDict
from google.protobuf import text_format
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)
return pipeline_config
configs = get_configs_from_pipeline_file('faster_rcnn_resnet101_pets.config')
d = MessageToDict(configs)
d['model']['fasterRcnn']['numClasses']=999
config2 = pipeline_pb2.TrainEvalPipelineConfig()
c = ParseDict(d, config2)
s = text_format.MessageToString(c)
with open('/path/test.config', 'w+') as fh:
fh.write(str(s))
Я хотел бы иметь возможность вносить изменения в объект protobuf напрямую, без необходимости преобразования в словарь. Проблема, однако, заключается в том, что неясно, как «пройтись по дому», чтобы найти правильные ссылки на переменные, значения которых я хотел бы изменить. Это особенно верно, когда задействовано несколько файлов .proto.
Мне удалось выполнить редактирование примерно так, но я надеюсь, что есть лучший способ:
configs.model.ListFields()[0][1].num_classes = 99