Here is a config file that represents a protobuf object:
model {
faster_rcnn {
num_classes: 37
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
...
I wish to use python to read this into an object, make some changes to some of the values and then write it back to a config file.
A complicating factor is that this is a rather large object which is constructed from many .proto file.
I was able to accomplish the task by converting the protobuf to a dictionary, making edits and then converting back to a protobuf, like so:
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))
I would like to be able to make edits to the protobuf object directly without having to convert to a dictionary. The problem, however, is that is not clear how to "walk the dom" to discover the correct references to the variables whose values I would like to change. This is especially true when there are multiple .proto files involved.
I was able to make the edit like so, but I am hoping there is a better way:
configs.model.ListFields()[0][1].num_classes = 99