見た目上同じでも、同じではない
たとえば、ObjectDetectionAPIにつかうpipeline.configもこのprotocol buffersで書かれているんですが、
train_input_reader {
label_map_path: "PATH_TO_BE_CONFIGURED"
tf_record_input_reader {
input_path: "PATH_TO_BE_CONFIGURED"
}
}
eval_input_reader {
label_map_path: "PATH_TO_BE_CONFIGURED"
tf_record_input_reader {
input_path: "PATH_TO_BE_CONFIGURED"
}
}
というのを見ると、train_input_readerとeval_input_readerは同じ構造に見えるじゃないですか?
そこで、両方のパスを記入しようとして、
pipeline_config_path = 'pipeline.config'
pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
with tf.io.gfile.GFile(pipeline_config_path, "r") as f:
proto_str = f.read()
text_format.Merge(proto_str, pipeline_config)
# train_inputを記入
pipeline_config.train_input_reader.label_map_path = "label_map.pbtxt"
pipeline_config.train_input_reader.tf_record_input_reader.input_path[:] = ["train.tfrecords"]
# eval_inputを記入
pipeline_config.eval_input_reader.label_map_path = "label_map.pbtxt"
pipeline_config.eval_input_reader.tf_record_input_reader.input_path[:] = ["eval.tfrecords"]
とインプットのパスを記入しようとすると、train_input_readerの方は問題なく通って書き込めるのですが、eval_input_readerはエラーになります。
google.protobuf.pyext._message.RepeatedCompositeContainer' object has no attribute 'label_map_path'
全く同じ構造に見えて、全く同じアクセスの仕方をしても、片方がエラーになる謎。
(label_map_pathというアトリビュートあるやん。。。)
で、printしてみると、
print(pipeline_config.train_input_reader)
label_map_path: "/content/drive/My Drive/testing/annotated/model_dir/label_map.pbtxt"
tf_record_input_reader {
input_path: "/content/drive/My Drive/testing/annotated/model_dir/test1.tfrecords"
}
print(pipeline_config.eval_input_reader)
[label_map_path: "/content/drive/My Drive/testing/annotated/model_dir/label_map.pbtxt"
shuffle: false
num_epochs: 1
tf_record_input_reader {
input_path: "/content/drive/My Drive/testing/annotated/model_dir/test1.tfrecords"
}
]
おわかりいただけただろうか? eval_input_readerだけ[ ]で囲まれている謎。
なので、配列としてアクセスすると、きちんと書き込める。
pipeline_config.eval_input_reader[0].label_map_path = "label_map.pbtxt"
pipeline_config.eval_input_reader[0].tf_record_input_reader.input_path[:] = ["eval.tfrecords"]
結果:
train_input_reader {
label_map_path: "label_map.pbtxt"
tf_record_input_reader {
input_path: "train.tfrecords"
}
}
eval_input_reader {
label_map_path: "label_map.pbtxt"
tf_record_input_reader {
input_path: "eval.tfrecords"
}
}
ということで、Protocol Buffersはプリントしてみるとわかりやすい。
あと、単に
pip install --upgrade protobuf
で解決する場合もあるそうです。
ちなみに、Protocol Buffersとは
プロトコルバッファは、構造化データをシリアル化するためのGoogleの言語中立、プラットフォーム中立、拡張可能なメカニズムです。XMLを考えてみてください。ただし、より小さく、より速く、よりシンプルです。データを一度構造化する方法を定義すると、特別に生成されたソースコードを使用して、さまざまなデータストリームとの間で、さまざまな言語を使用して構造化データを簡単に読み書きできます。
とのことです。google公式より。
🐣
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。
🐣
Request for work:
rockyshikoku@gmail.com
We send information related to machine learning.
Twitter
Request for work:
rockyshikoku@gmail.com