TensorFlow画像分類モデルinception_リサーチv 2モデルのエクスポート、凍結と使用

16852 ワード

1.背景
新しい学習の深さとして、プロジェクトは突然画像分類モデルを使用して分類する必要があります.そのため、TensorFlowのモデルライブラリを見つけました.そのフレームを使って訓練と後続の操作を行います.プロジェクトアドレス:https://github.com/tensorflow/models/tree/master/research/slim.
本当のデータセットを使う前に、まず使ったのはflowersのデータセットです.使うモデルはinceptionです.リサーチv 2,top-5 Accuuracyが高いからです.
そしてflowersのディレクトリ構造をインストールして、私のデータを類似の構造に従って組織します.
downloadを真似するand_convert_.flowerss.pyは自分のデータ処理ファイルを追加しました.ノルマ.data.py;
データセットをまねてファイルを読み込みます.flowers.pyは自分のファイルnormal.pyを増加しました.
そしてプロジェクトの教程を使って、一歩ずつfine-tuningを行います.正確率は90%以上になります.訓練を中止します.
しかし、この時はモデルをエクスポートする時にピットに遭遇しました.
 
2.Inference Graphをエクスポートする
実際に教程は簡単に書いてあります.モデルの枠組みを先に導き出すことです.
Saves out a GraphDef containing the architecture of the model.
その後、トレーニングしたcheckpointsをフレームにgraphに書く.
If you then want to use the resulting model with your own or pretraned checkpoints as parts of a mobile model,you can run freeze_graph to get a graph def with the variables inlind
それが出した教程はこうです.
$ python export_inference_graph.py \
  --alsologtostderr \
  --model_name=inception_v3 \
  --output_file=/tmp/inception_v3_inf_graph.pb
このフォーマットをインストールして、モデルをinception_に変えます.リサーチv 2、そしてcheckpointを案内して、いつも報告します.
tenssor flow.python.fram ework.errors_impl.InvalidArgmentErrror:Asign requires shops of both tens to match.lhs shpe=[1001]rhs shpe=[2][{node save/Asignu 916]]
グループを探して聞いてみましたが、モデルの最後の層の出力の数は変わっていないということで、もう一度考えを整理して、exportを見に行きました.inference_graphh.pyのソースコードは、中にnum_があることを発見しました.clasesのパラメータは最後の出力層の数を決定するために使用されます.最後に導出パラメータを追加しました.最後のコマンドは以下の通りです.
python export_inference_graph.py \
  --alsologtostderr \
  --model_name=${MODEL_NAME} \
  --dataset_name=normal \
  --dataset_dir=${DATASET_DIR} \
  --output_file=/you/path/to/sava/${MODEL_NAME}_inf_graph.pb
最後に私のgraphh.pbを獲得しました.
 
3.Graphを凍結する
凍結は大きな穴です.なぜですか?公式の教程はbazelを使って先にfreezeをコンパイルします.graphを使用してモデルを凍結します.お手数をおかけしましたが、まずUbuntu 18.04はapptを使ってインストールできませんので、振り回すと、それが放出したinstallスクリプトを使ってインストールしました.
そして、git clone TensorFlowのソースコードをコンパイルする必要があります.このコンパイルの間に多くのエラーが報告されました.コンパイルに失敗した後、conda環境のTensorFlow GPUバージョンはまだ使えません.
最後に、condaやgitを使ってTensorFlowをインストールしたら、そのまま使うことができます.
find / -name freeze_graph.py
このpythonファイルの位置を見つければいいです.最後にコマンドを使います.
python tensorflow/python/tools/freeze_graph.py \
  --input_graph=/you/path/to/sava/${MODEL_NAME}_inf_graph.pb \
  --input_checkpoint=/you/trained/checkpoints/model.ckpt-10000 \
  --input_binary=true \
  --output_node_names=InceptionResnetV2/Logits/Predictions \
  --output_graph=/your/path/to/save/frozen_graph.pb
最後にモデルを導出した.
4.モデルを使って予測する
主に博文を参考にしました.
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
 
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
 
import argparse
import os.path
import re
import sys
import tarfile
 
import numpy as np
from six.moves import urllib
import tensorflow as tf
 
FLAGS = None
 
class NodeLookup(object):
  def __init__(self, label_lookup_path=None):
    self.node_lookup = self.load(label_lookup_path)
 
  def load(self, label_lookup_path):
    node_id_to_name = {}
    with open(label_lookup_path) as f:
      for line in f:
        line_list = line.strip().split(":")
        node_id_to_name[int(line_list[0])] = line_list[1]
    return node_id_to_name
 
  def id_to_string(self, node_id):
    if node_id not in self.node_lookup:
      return ''
    return self.node_lookup[node_id]
 
 
def create_graph():
  """Creates a graph from saved GraphDef file and returns a saver."""
  # Creates graph from saved graph_def.pb.
  with tf.gfile.FastGFile(FLAGS.model_path, 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')
 
def preprocess_for_eval(image, height, width,
                        central_fraction=0.875, scope=None):
  with tf.name_scope(scope, 'eval_image', [image, height, width]):
    if image.dtype != tf.float32:
      image = tf.image.convert_image_dtype(image, dtype=tf.float32)
    # Crop the central region of the image with an area containing 87.5% of
    # the original image.
    if central_fraction:
      image = tf.image.central_crop(image, central_fraction=central_fraction)
 
    if height and width:
      # Resize the image to the specified height and width.
      image = tf.expand_dims(image, 0)
      image = tf.image.resize_bilinear(image, [height, width],
                                       align_corners=False)
      image = tf.squeeze(image, [0])
    image = tf.subtract(image, 0.5)
    image = tf.multiply(image, 2.0)
    return image
 
def run_inference_on_image(image):
  """Runs inference on an image.
  Args:
    image: Image file name.
  Returns:
    Nothing
  """
  with tf.Graph().as_default():
    image_data = tf.gfile.FastGFile(image, 'rb').read()
    image_data = tf.image.decode_jpeg(image_data)
    image_data = preprocess_for_eval(image_data, 299, 299)
    image_data = tf.expand_dims(image_data, 0)
    with tf.Session() as sess:
      image_data = sess.run(image_data)
 
  # Creates graph from saved GraphDef.
  create_graph()
 
  with tf.Session() as sess:
    softmax_tensor = sess.graph.get_tensor_by_name('InceptionResnetV2/Logits/Predictions:0')
    predictions = sess.run(softmax_tensor,
                           {'input:0': image_data})
    predictions = np.squeeze(predictions)
 
    # Creates node ID --> English string lookup.
    node_lookup = NodeLookup(FLAGS.label_path)
 
    top_k = predictions.argsort()[-FLAGS.num_top_predictions:][::-1]
    for node_id in top_k:
      human_string = node_lookup.id_to_string(node_id)
      score = predictions[node_id]
      print('%s (score = %.5f)' % (human_string, score))
 
 
def main(_):
  image = FLAGS.image_file
  run_inference_on_image(image)
 
 
if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--model_path',
      type=str,
  )
  parser.add_argument(
      '--label_path',
      type=str,
  )
  parser.add_argument(
      '--image_file',
      type=str,
      default='',
      help='Absolute path to image file.'
  )
  parser.add_argument(
      '--num_top_predictions',
      type=int,
      default=5,
      help='Display this many predictions.'
  )
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
最後に一枚の写真を使ってテストします.
python classify_image_inception_resnet_v2.py \
  --model_path /your/saved/path/frozen_graph.pb \
  --label_path /your/path/labels.txt \
  --image_file /your/path/test.jpg
最後の出力:
unsuited(score=0.94713)suited(スコア=0.05287)
ちょっと嬉しいですが、ふと振り返ってみたら、やはり心が疲れました.そして今はcondaのTensorFlow GPUバージョンが膝をついています.修復が必要です.
 
5.参考
(1)【深さ学習-モデルeval+モデル導出】Tensorflow Slimを用いてトレーニングのモデルを評価+導出するモデル
(2)【Tensorflowシリーズ】Inception_を使用するリサーチv 2は自分のデータセットを訓練してTensorboardで監視します.
(終わり)