Преобразование сохраненной модели TF 2 в замороженный график — без атрибута model.inputs[0]

Я создал/обучил модель через TF 2.4 (с CUDA 11.0, Python 3.7) /models/research/object_detection учебник. Ошибок нет, вроде 25 000 шагов прошел нормально. Все выглядело нормально, Tensorboard показал общие потери <0,5. Он создал файл save_model.pb в соответствии с учебником. Теперь я хочу преобразовать в замороженный график для выводов.

Кажется, он загружается нормально (этот код был запущен в блокноте Jupyter):

!ls {model_path} -l
model = tf.compat.v2.saved_model.load(export_dir=model_path)
print (type(model))

выход:

total 13232
drwxr-xr-x 2 jay jay     4096 Dec 21 10:41 assets
-rw-r--r-- 1 jay jay 13538598 Dec 21 10:41 saved_model.pb
drwxr-xr-x 2 jay jay     4096 Dec 21 10:41 variables
<class 'tensorflow.python.saved_model.load.Loader._recreate_base_user_object.<locals>._UserObject'>

однако, когда я начинаю его конвертировать, я получаю сообщение об ошибке

full_model = tf.function(lambda x: model(x))
full_model = full_model.get_concrete_function(
    tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))

выход:

AttributeError                            Traceback (most recent call last)
<ipython-input-73-50e1947f8357> in <module>
      2 full_model = tf.function(lambda x: model(x))
      3 full_model = full_model.get_concrete_function(
----> 4     tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))

AttributeError: '_UserObject' object has no attribute 'inputs'

кроме того, модель cli, похоже, работает:

!saved_model_cli show --dir {model_path} --all

сокращенный вывод:

2020-12-22 11:38:23.453843: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['__saved_model_init_op']:
  The given SavedModel SignatureDef contains the following input(s):
  The given SavedModel SignatureDef contains the following output(s):
    outputs['__saved_model_init_op'] tensor_info:
        dtype: DT_INVALID
        shape: unknown_rank
        name: NoOp
  Method name is: 

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['input_tensor'] tensor_info:
        dtype: DT_UINT8
        shape: (1, -1, -1, 3)
        name: serving_default_input_tensor:0

<content removed for brevity>

Defined Functions:
  Function Name: '__call__'
    Option #1
      Callable with:
        Argument #1
          input_tensor: TensorSpec(shape=(1, None, None, 3), dtype=tf.uint8, name='input_tensor')

Моя модель плохая или я что-то не так делаю? Должен ли я использовать tf.keras для загрузки модели?

tf.keras.models.load_model(model_path, custom_objects=None, compile=True, options=None)

когда я использовал tf.keras, я получил ошибку при загрузке:

~/anaconda3/envs/tf24/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py in infer_inputs_from_restored_call_function(fn)
    980     return tensor_spec.TensorSpec(defun.common_shape(x.shape, y.shape),
    981                                   x.dtype, x.name)
--> 982   spec = fn.concrete_functions[0].structured_input_signature[0][0]
    983   for concrete in fn.concrete_functions[1:]:
    984     spec2 = concrete.structured_input_signature[0][0]

IndexError: list index out of range
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
1 564
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

  1. используйте tf.keras.models.load_model()
  2. но (по состоянию на 20201226 год) это не работает

https://github.com/tensorflow/tensorflow/issues/43527

если вы пытаетесь преобразовать save_graph.pb в замороженный график для выводов — вам нужно следовать проблеме № 43527.

Ответ принят как подходящий

Вы можете использовать Keras, чтобы получить замороженный график, но (по состоянию на 2021.01.04) это не работает, и вы столкнетесь с проблемой 43527, как уже отмечалось.

Есть обходной путь - не использовать Keras. Пройдите уроки colab: тензорный поток/модели/исследования/object_detection/colab_tutorials/

В частности, пройдите через: inference_from_saved_model_tf2_colab.ipynb С небольшими правками это будет работать локально — вам не нужно запускать в colab. Это хорошо работает и покажет вам шаблон использования вашей модели без проблем с Keras.

Вы можете изменить

full_model = full_model.get_concrete_function(
    tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))

к

full_model = full_model.get_concrete_function(
    tf.TensorSpec(model.signatures['serving_default'].inputs[0].shape.as_list(), model.signatures['serving_default'].inputs[0].dtype.name))

. Подробнее см. https://github.com/tensorflow/models/issues/8966#issuecomment-1017052562.

Другие вопросы по теме