Повторное распознавание изображений с помощью MobileNet

Несколько способов переобучения MobileNet для использования с Tensorflow.js для меня не увенчались успехом. Есть ли способ использовать переобученную модель с Tensorflow.js?

Как с использованием современного учебника на основе концентраторов, так и с использованием retrain.py, похоже, не срабатывают.

а также некоторые другие открытые вопросы

Два других вопроса показывают код, который не удался в обоих случаях, и оба они не решены.

Цель состоит в том, чтобы загрузить мобильную сеть, переобучить с использованием пользовательских данных и использовать их в Tensorflow.js. Выполнение обоих руководств кажется неудачным. Можно ли это сделать внутри node.js? Есть другой способ? Где я сделал ошибки (или программа не может использовать переобученные модели)? Как это может работать?

РЕДАКТИРОВАНИЕ: последняя проблема github и еще один вопрос


person serv-inc    schedule 25.04.2019    source источник
comment
Обнаружение изображений с использованием мобильной сети для обучения передачи объясняется в этой статье   -  person edkeveked    schedule 26.04.2019
comment
@edkeveked: Похоже, в вашей статье используется мобильная сеть в качестве средства извлечения функций. Цель этого вопроса - отправить уже обученную модель, которая была переобучена.   -  person serv-inc    schedule 27.04.2019


Ответы (4)


Я столкнулся с той же проблемой, и кажется, что мы используем неправильный метод. Есть loadGraphModel для моделей, преобразованных в TF, и loadLayersModel для моделей Keras. мой комментарий к проблеме

person Mahalov Ivan    schedule 16.07.2019

Скрипт retrain.py python не создает сохраненную модель, он фактически создает модель замороженного графа. Вот почему вы не можете преобразовать его с помощью конвертера tfjs 1.x. Вам нужно использовать tfjs 0.8.5 pip для преобразования. Кроме того, имя выходного узла отличается от графа модели мобильной сети, это 'final_result' для переобученного графа.

Чтобы преобразовать его, вам нужно использовать команду tensorflowjs 0.8.5:

  • используйте virtualenv для создания пустого окружения.
  • pip install tensorflowjs == 0.8.5
  • запустить конвертер
tensorflowjs_converter \
  --input_format=tf_frozen_model \
  --output_node_names='final_result' \
  --output_json=true /tmp/output_graph.pb \ /tmp/web_model

Это должно дать вам что-то вроде следующего:

ls /tmp/web_model/
group1-shard10of21  group1-shard14of21  group1-shard18of21  group1-shard21of21  group1-shard5of21  group1-shard9of21
group1-shard11of21  group1-shard15of21  group1-shard19of21  group1-shard2of21   group1-shard6of21  model.json
group1-shard12of21  group1-shard16of21  group1-shard1of21   group1-shard3of21   group1-shard7of21
group1-shard13of21  group1-shard17of21  group1-shard20of21  group1-shard4of21   group1-shard8of21
person Ping Yu    schedule 10.05.2019
comment
Я думаю, что в сценарии retrain.py есть опция --saved_model_dir = / tmp / saved_models /, которая будет генерировать сохраненные выходные данные модели. Вы должны попробовать это и посмотреть, сможете ли вы использовать конвертер 1.x для его преобразования. Спасибо. - person Ping Yu; 16.05.2019
comment
Загрузка модели с tf.loadLayersModel("file:///tmp/web_model/model.json") завершилась неудачно с className 'и должен быть установлен config. - person serv-inc; 28.05.2019
comment
Последняя версия конвертера (1.3.2) теперь поддерживает замороженную модель. - person Ping Yu; 22.11.2019
comment
Здравствуйте, не могли бы вы взглянуть на это: stackoverflow.com/questions/64621656/ - person a125; 31.10.2020

Чтобы использовать последние версии TFjs:

python retrain.py --tfhub_module https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/2 \
    --image_dir /tmp/flower_photos --saved_model_dir /tmp/saved_retrained_model
tensorflowjs_converter --input_format=tf_saved_model \
    --output_format=tfjs_graph_model \
    --saved_model_tags=serve \
    /tmp/saved_retrained_model/ /tmp/converted_model/

создает model.json файл. Команда описана в https://github.com/tensorflow/tfjs-converter#step-1-converting-a-savedmodel-keras-h5-tfkeras-savedmodel-or-tensorflow-hub-module-to-a-web-friendly-format.

Тем не менее, загрузка модели с tf.loadLayersModel("file:///tmp/web_model/model.json") не удалась с

'className' и 'config' должны быть установлены.

person serv-inc    schedule 28.05.2019
comment
Здравствуйте, не могли бы вы взглянуть на это: stackoverflow.com/questions/64621656/ - person a125; 31.10.2020
comment
Здравствуйте, где определяется application_mobilenet? - person serv-inc; 02.11.2020
comment
Я взял этот фрагмент из документации kera keras.io/api/applications/mobilenet - person a125; 02.11.2020

Может быть, кто-нибудь может изменить keep.py для поддержки использования mobileV2 по-моему. Исходная ссылка на retrain.py . Эта ссылка представляет собой код Google GitHub, а не мою ссылку.

Я изменил retrain.py, ниже мой git diff:

diff --git a/scripts/retrain.py b/scripts/retrain.py
index 5fa9b0f..02a4f9a 100644
--- a/scripts/retrain.py
+++ b/scripts/retrain.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -112,6 +114,13 @@ from tensorflow.python.framework import graph_util
 from tensorflow.python.framework import tensor_shape
 from tensorflow.python.platform import gfile
 from tensorflow.python.util import compat
+from tensorflow import saved_model as sm
+from tensorflow.python.saved_model import builder as saved_model_builder
+from tensorflow.python.saved_model import signature_constants
+from tensorflow.python.saved_model import signature_def_utils
+from tensorflow.python.saved_model import tag_constants
+from tensorflow.python.saved_model import utils as saved_model_utils
+

 FLAGS = None

@@ -319,6 +328,7 @@ def maybe_download_and_extract(data_url):
   Args:
     data_url: Web location of the tar file containing the pretrained model.
   """
+  print(FLAGS.model_dir)
   dest_directory = FLAGS.model_dir
   if not os.path.exists(dest_directory):
     os.makedirs(dest_directory)
@@ -827,6 +837,7 @@ def save_graph_to_file(sess, graph, graph_file_name):
       sess, graph.as_graph_def(), [FLAGS.final_tensor_name])
   with gfile.FastGFile(graph_file_name, 'wb') as f:
     f.write(output_graph_def.SerializeToString())
+
   return


@@ -971,6 +982,7 @@ def main(_):

   # Prepare necessary directories  that can be used during training
   prepare_file_system()
+  sigs = {}

   # Gather information about the model architecture we'll be using.
   model_info = create_model_info(FLAGS.architecture)
@@ -1002,6 +1014,9 @@ def main(_):
       FLAGS.random_brightness)

   with tf.Session(graph=graph) as sess:
+    serialized_tf_example = tf.placeholder(tf.string, name='tf_example')
+    feature_configs = {'x': tf.FixedLenFeature(shape=[784], dtype=tf.float32),}
+    tf_example = tf.parse_example(serialized_tf_example, feature_configs)
     # Set up the image decoding sub-graph.
     jpeg_data_tensor, decoded_image_tensor = add_jpeg_decoding(
         model_info['input_width'], model_info['input_height'],
@@ -1133,6 +1148,73 @@ def main(_):
                           (test_filename,
                            list(image_lists.keys())[predictions[i]]))

+    """
+    # analyze SignatureDef protobuf
+    SignatureDef_d = graph.signature_def
+    SignatureDef = SignatureDef_d[sm.signature_constants.CLASSIFY_INPUTS]
+
+    # three TensorInfo protobuf
+    X_TensorInfo = SignatureDef.inputs['input_1']
+    scale_TensorInfo = SignatureDef.inputs['input_2']
+    y_TensorInfo = SignatureDef.outputs['output']
+
+    # Tensor details
+    # .get_tensor_from_tensor_info() to get default graph 
+    X = sm.utils.get_tensor_from_tensor_info(X_TensorInfo, sess.graph)
+    scale = sm.utils.get_tensor_from_tensor_info(scale_TensorInfo, sess.graph)
+    y = sm.utils.get_tensor_from_tensor_info(y_TensorInfo, sess.graph)
+    """
+
+    """
+    output_graph_def = graph_util.convert_variables_to_constants(
+      sess, graph.as_graph_def(), [FLAGS.final_tensor_name])
+
+    X_TensorInfo = sm.utils.build_tensor_info(bottleneck_input)
+    scale_TensorInfo = sm.utils.build_tensor_info(ground_truth_input)
+    y_TensorInfo = sm.utils.build_tensor_info(output_graph_def)
+
+    # build SignatureDef protobuf
+    SignatureDef = sm.signature_def_utils.build_signature_def(
+                                inputs={'input_1': X_TensorInfo, 'input_2': scale_TensorInfo},
+                                outputs={'output': y_TensorInfo},
+                                method_name='what'
+    )
+    """
+
+    #graph = tf.get_default_graph()
+    tensors_per_node = [node.values() for node in graph.get_operations()]
+    tensor_names = [tensor.name for tensors in tensors_per_node for tensor in tensors]
+    print(tensor_names)
+
+    export_dir = './tf_files/savemode'
+    builder = saved_model_builder.SavedModelBuilder(export_dir)
+
+    # name="" is important to ensure we don't get spurious prefixing
+    graph_def = tf.GraphDef()
+    tf.import_graph_def(graph_def, name="")
+    g = tf.get_default_graph()
+    inp1 = g.get_tensor_by_name("input:0")
+    inp2 = g.get_tensor_by_name("input_1/BottleneckInputPlaceholder:0")
+    inp3 = g.get_tensor_by_name("input_1/GroundTruthInput:0")
+    out = g.get_tensor_by_name("accuracy_1:0")
+
+    sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
+        tf.saved_model.signature_def_utils.predict_signature_def(
+            {'input_1': inp1, 'input_2': inp3}, {"output": out})
+
+    builder.add_meta_graph_and_variables(sess,
+                                         tags=[tag_constants.SERVING],
+                                         signature_def_map=sigs)
+
+    """
+    builder.add_meta_graph_and_variables(
+            sess=sess,
+            tags=[tag_constants.SERVING],
+            signature_def_map={sm.signature_constants.CLASSIFY_INPUTS: SignatureDef})
+    """
+
+    builder.save()
+
     # Write out the trained graph and labels with the weights stored as
     # constants.
     save_graph_to_file(sess, graph, FLAGS.output_graph)

Используя свой diff, я могу сгенерировать модель, обслуживаемую Tensorflow. Затем я использую команду для преобразования модели, обслуживаемой TensorFlow, в модель Tfjs.

tensorflowjs_converter \
    --input_format=tf_saved_model \
    --output_format=tfjs_graph_model \
    ./tf_files/savemode \
    ./tf_files/js_model

Все еще не поддерживается Ops для последней версии Tensorflow JS.

Я просто делаю видео здесь, чтобы объяснить, почему мы не можем преобразовать замороженную модель Tensorflow в Модель Tensorflow JS рассказывает, как найти входной тензор и выходной тензор. Наконец, выполняемые шаги и результат указывают на неподдерживаемый Ops ScalarSummary и причину.

Теперь, когда я не могу изменить модель Mobilenet на модель Tensorflow JS, я использую тензорный поток Python и библиотеку флаконов на стороне сервера, пользователь загружает изображение на сервер и затем возвращает результат.

person Yucheng Wang    schedule 11.08.2019
comment
Спасибо за помощь пользователям StackOverflow. Несмотря на то, что вы потратили время на создание видео, ответы здесь должны быть независимыми, замкнутыми объяснениями и не зависеть от внешних источников для понимания. Вы можете сохранить ссылку на видео, если добавите достаточно пояснений в свой ответ, так что просмотр ссылки на видео не требуется для получения ответа. - person Léa Gris; 11.08.2019
comment
Вы пытались сделать как предложил @MahalovIvan? - person serv-inc; 12.08.2019
comment
@ serv-inc Я уже пробовал, но до сих пор не могу получить нужный результат. - person Yucheng Wang; 12.08.2019
comment
@ LéaGris Спасибо, я добавлю больше пояснений к этому ответу. - person Yucheng Wang; 12.08.2019