1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Google Protocol Buffersの謎性質 AttributeError: 'google.protobuf. {****} ' object has no attribute {****}

Last updated at Posted at 2021-03-30

見た目上同じでも、同じではない

たとえば、ObjectDetectionAPIにつかうpipeline.configもこのprotocol buffersで書かれているんですが、

pipeline.config
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"]

結果:

pipeline.config
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を使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
Medium

🐣


Request for work:
rockyshikoku@gmail.com

We send information related to machine learning.
Twitter
Request for work:
rockyshikoku@gmail.com

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?