2016-04-01 16 views
13

テンソルフローのimageNet trained modelを使用して、画像の新しいデータセットの表現ベクトルとして最後のプールレイヤの特徴を抽出しています。テンソルフローでGraphdefを2GB以下にすることはできません

モデルは次のように新しいイメージに予測される:

python classify_image.py --image_file new_image.jpeg 

私は画像のフォルダを取り、一度にすべての画像上での予測を返し、機能を書くことができるように、私は主な機能を編集しましたcsvファイル内のベクトル。

def main(_): 
    maybe_download_and_extract() 
    #image = (FLAGS.image_file if FLAGS.image_file else 
    #   os.path.join(FLAGS.model_dir, 'cropped_panda.jpg')) 
    #edit to take a directory of image files instead of a one file 
    if FLAGS.data_folder: 
    images_folder=FLAGS.data_folder 
    list_of_images = os.listdir(images_folder) 
    else: 
    raise ValueError("Please specify image folder") 

    with open("feature_data.csv", "wb") as f: 
    feature_writer = csv.writer(f, delimiter='|') 

    for image in list_of_images: 
     print(image) 
     current_features = run_inference_on_image(images_folder+"/"+image) 
     feature_writer.writerow([image]+current_features) 

それは約21イメージのためうまく働いたが、その後、次のエラーでクラッシュした:私は、以前の画像データは次のようになりrun_inference_on_image(images_folder+"/"+image)メソッドを呼び出すことで考え

File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1912, in as_graph_def 
    raise ValueError("GraphDef cannot be larger than 2GB.") 
ValueError: GraphDef cannot be larger than 2GB. 

ここに私がいることをやった方法です新しい画像データのみを上書きするように上書きされますが、そうではないようです。この問題を解決するには?

答えて

17

ここで問題となるのは、run_inference_on_image()の呼び出しでは、ノードが同じグラフに追加され、最終的に最大サイズを超えてしまうことです。この問題を解決するには、少なくとも2つの方法があります。

  1. 簡単ですが、遅い方法はrun_inference_on_image()にコールごとに異なるデフォルトのグラフを使用することです:

    for image in list_of_images: 
        # ... 
        with tf.Graph().as_default(): 
        current_features = run_inference_on_image(images_folder+"/"+image) 
        # ... 
    
  2. より複雑けどより効率的な方法は、run_inference_on_image()を複数の画像で実行するように変更することです。 forループをthis sess.run() callを囲むように再配置すると、各呼び出しでモデル全体を再構築する必要がなくなり、各画像の処理が大幅に高速化されます。

+2

私は2番目のオプションを使用しました。アイデアありがとう! – MedAli

+0

しかし、sess.runの予測部分に1つだけではなく、画像の配列を渡す方法があります。 '' 'predictions = sess.run(pool_3_tensor、 {'DecodeJpeg/contents:0':image_data }) '' ' – MedAli

+1

私は、特定のフィードポイントは単一の画像上でしか動作しないと思います。グラフを変更してイメージのバッチを取得することは可能ですが、イメージをバッチに結合するためにプリフェッチスレッドを作成する必要があります(たとえば、 'tf.train.batch()'を使用します)。すべて同じサイズです)、ネットワークの少し後のポイントにフィードします。入力として使用されるテンソルを変更するには、 'tf.import_graph_def()'に 'input_map'引数を使用する必要があります。その特定のグラフの構造は文書化されていないので、難しいかもしれませんが... – mrry

2

あなたは(ファイルをループ)どこか前にこのループfor image in list_of_images:create_graph()を移動することができます。

同じグラフ上で推論を複数回実行しています。

+0

あなたはこれを明確にするための例を表示できますか?ありがとうございました。 – Moondra

0

最も簡単な方法は、create_graph()を最初のメイン機能に置きます。 それでは、グラフを作成するだけです

関連する問題