tensorflow keras save error: Failed to add concrete function
tensorflow keras save error: Failed to add concrete function
问题:
我在 colab 上有一个成功的 运行 最近邻张量流模型,名为 top_classify。但是在保存时,收到以下错误消息:
KeyError: "Failed to add concrete function
'b'__inference_model_layer_call_fn_158405'' to object-based SavedModel as it captures
tensor <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>> which is
unsupported or not reachable from root. One reason could be that a stateful object or
a variable that the function depends on is not assigned to an attribute of the
serialized trackable object (see SaveTest.test_captures_unreachable_variable)."
详情:
感兴趣的最近邻模型正在使用已训练模型 (embedding_network) 的输出。并将输入的输出与训练数据集的输出(最近距离)进行比较。我的意思是我们不是直接比较图像,比较它们的输出。通常我不会费心在 tensorflow 上编写 NN 代码,因为模型不是迭代的,但我需要一个 tflite 模型才能在 android 应用程序上使用。所以,我没有太多选择。
首先,我训练了 embedding_network 模型(通过迁移学习和 siamese),输出大小为 (None, 27)。 xc 是整个训练集(752 个样本,大小为 (752, 27) )的恒定输出矩阵,yc 是训练集的正确标签。两者都是 tf 常量。下面的示例是最佳匹配 (1NN)。也可以修改代码以适用于任意数量的所需匹配项 (KNN)。
xc = tf.constant(embedding_network(x_train))
yc = tf.constant(y_train)
inputs = keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = embedding_network(inputs, training=False)
distance = tf.reduce_sum(tf.abs(tf.add(xc, tf.negative(x0))), axis=1)
findKClosestTrImages = tf.argsort(distance, direction='ASCENDING')
closest0 = tf.gather(yc, findKClosestTrImages[0])
out=tf.one_hot(closest0, DEPTH)
top_classify = keras.Model(inputs=inputs, outputs=out)
top_classify.summary()
如您所见,我没有对模型进行任何训练,没有损失函数,也没有编译和拟合。因为我只会在推理时使用它。
这里是新近邻模型的总结,top_classify:
Model: "model_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_6 (InputLayer) [(None, 224, 224, 3)] 0
model (Functional) (None, 27) 2292571
tf.math.negative_1 (TFOpLam (None, 27) 0
bda)
tf.math.add_1 (TFOpLambda) (752, 27) 0
tf.math.abs_1 (TFOpLambda) (752, 27) 0
tf.math.reduce_sum_1 (TFOpL (752,) 0
ambda)
tf.argsort_1 (TFOpLambda) (752,) 0
tf.__operators__.getitem_1 () 0
(SlicingOpLambda)
tf.compat.v1.gather_1 (TFOp () 0
Lambda)
tf.one_hot_1 (TFOpLambda) (27,) 0
=================================================================
Total params: 2,292,571
Trainable params: 0
Non-trainable params: 2,292,571
_________________________________________________________________
无论如何,模型在 colab 上很有用。我得到了非常好的结果。但我无法保存模型,无论我使用 tf.saved_model.save 还是 top_classify.save
错误如果尝试tf.saved_model.save
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/function_serialization.py in serialize_concrete_function(concrete_function, node_ids, coder)
64 for capture in concrete_function.captured_inputs:
---> 65 bound_inputs.append(node_ids[capture])
66 except KeyError:
7 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/object_identity.py in __getitem__(self, key)
138 def __getitem__(self, key):
--> 139 return self._storage[self._wrap_key(key)]
140
KeyError: <_ObjectIdentityWrapper wrapping <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>>>
During handling of the above exception, another exception occurred:
KeyError Traceback (most recent call last)
<ipython-input-33-13ced446758f> in <module>()
15 TOP_CLASSIFY_SAVE_LOC = "/content/top_classify"
16 #top_classify.save("/content/top_classify")
---> 17 tf.saved_model.save(top_classify, TOP_CLASSIFY_SAVE_LOC)
18 #top_classify.save("/content/top_classify", save_format='h5')
19 # Convert the model
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in save(obj, export_dir, signatures, options)
1278 # pylint: enable=line-too-long
1279 metrics.IncrementWriteApi(_SAVE_V2_LABEL)
-> 1280 save_and_return_nodes(obj, export_dir, signatures, options)
1281 metrics.IncrementWrite(write_version="2")
1282
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in save_and_return_nodes(obj, export_dir, signatures, options, experimental_skip_checkpoint)
1313
1314 _, exported_graph, object_saver, asset_info, saved_nodes, node_paths = (
-> 1315 _build_meta_graph(obj, signatures, options, meta_graph_def))
1316 saved_model.saved_model_schema_version = (
1317 constants.SAVED_MODEL_SCHEMA_VERSION)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _build_meta_graph(obj, signatures, options, meta_graph_def)
1485
1486 with save_context.save_context(options):
-> 1487 return _build_meta_graph_impl(obj, signatures, options, meta_graph_def)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _build_meta_graph_impl(obj, signatures, options, meta_graph_def)
1449
1450 object_graph_proto = _serialize_object_graph(
-> 1451 saveable_view, asset_info.asset_index)
1452 meta_graph_def.object_graph_def.CopyFrom(object_graph_proto)
1453
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _serialize_object_graph(saveable_view, asset_file_def_index)
1015 name = saveable_view.function_name_map.get(name, name)
1016 serialized = function_serialization.serialize_concrete_function(
-> 1017 concrete_function, saveable_view.captured_tensor_node_ids, coder)
1018 if serialized is not None:
1019 proto.concrete_functions[name].CopyFrom(serialized)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/function_serialization.py in serialize_concrete_function(concrete_function, node_ids, coder)
66 except KeyError:
67 raise KeyError(
---> 68 f"Failed to add concrete function '{concrete_function.name}' to object-"
69 f"based SavedModel as it captures tensor {capture!r} which is unsupported"
70 " or not reachable from root. "
KeyError: "Failed to add concrete function
'b'__inference_model_layer_call_fn_158405'' to object-based SavedModel as it captures
tensor <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>> which is
unsupported or not reachable from root. One reason could be that a stateful object or
a variable that the function depends on is not assigned to an attribute of the
serialized trackable object (see SaveTest.test_captures_unreachable_variable)."
错误如果尝试 top_classify.save:
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
/usr/local/lib/python3.7/dist-packages/keras/engine/functional.py:1410: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument.
layer_config = serialize_layer_fn(layer)
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-34-7275f8fa7bba> in <module>()
18 top_classify.save("/content/top_classify", save_format='h5')
19 # Convert the model
---> 20 converter = tf.lite.TFLiteConverter.from_saved_model(TOP_CLASSIFY_SAVE_LOC) # path to the SavedModel directory
21 tflite_model = converter.convert()
22
4 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/lite/python/lite.py in from_saved_model(cls, saved_model_dir, signature_keys, tags)
1603
1604 with context.eager_mode():
-> 1605 saved_model = _load(saved_model_dir, tags)
1606 if not signature_keys:
1607 signature_keys = saved_model.signatures
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/load.py in load(export_dir, tags, options)
898 ValueError: If `tags` don't match a MetaGraph in the SavedModel.
899 """
--> 900 result = load_internal(export_dir, tags, options)["root"]
901 return result
902
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/load.py in load_internal(export_dir, tags, options, loader_cls, filters)
911 tags = nest.flatten(tags)
912 saved_model_proto, debug_info = (
--> 913 loader_impl.parse_saved_model_with_debug_info(export_dir))
914
915 if (len(saved_model_proto.meta_graphs) == 1 and
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/loader_impl.py in parse_saved_model_with_debug_info(export_dir)
58 parsed. Missing graph debug info file is fine.
59 """
---> 60 saved_model = _parse_saved_model(export_dir)
61
62 debug_info_path = file_io.join(
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/loader_impl.py in parse_saved_model(export_dir)
117 else:
118 raise IOError(
--> 119 f"SavedModel file does not exist at: {export_dir}{os.path.sep}"
120 f"{{{constants.SAVED_MODEL_FILENAME_PBTXT}|"
121 f"{constants.SAVED_MODEL_FILENAME_PB}}}")
OSError: SavedModel file does not exist at: /content/top_classify/{saved_model.pbtxt|saved_model.pb}
如果您能提出解决方案或建议,我们将不胜感激。泰
经过多次详细的搜索和尝试,我找到了这个论坛post:
https://github.com/keras-team/keras/issues/15699
(在 Tensorflow 2.7 上使用数据增强层保存模型时出错
#15699)。其中指出,数据扩充可能会产生一些保存问题。
问题中没有说明,但这里是 embedding_network 的详细信息,在我的 tf 代码中:
inputs = tf.keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = rescale(inputs)
x0 = data_augmentation(x0)
x0 = base_model(x0, training=False)
x0 = tf.keras.layers.GlobalAveragePooling2D()(x0)
x0 = tf.keras.layers.Dropout(DROPOUT_VAL)(x0)
outputs = tf.keras.layers.Dense(NUM_CLASSES)(x0)
embedding_network = tf.keras.Model(inputs, outputs)
如您所见,它有一个增强层,它阻止了保存。所以我创建了一个非常相似的模型,称为 embedding_network_cleany,没有增强。
inputs = tf.keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = rescale(inputs)
x2 = base_model(x0, training=False)
x3 = tf.keras.layers.GlobalAveragePooling2D()(x2)
x4 = tf.keras.layers.Dropout(DROPOUT_VAL)(x3)
outputs = tf.keras.layers.Dense(NUM_CLASSES)(x4)
embedding_network_cleany = tf.keras.Model(inputs, outputs)
用 embedding_network.save_weights 复制了 embedding_network 的权重,然后加载到 embedding_network_cleany。现在我可以同时保存 top_classify 和 embedding_network_cleany 模型。也可以转换为 tflite
一个新的解决方案:
可能 AloneTogether 在 link 中给出了更好的解决方案
“解决方法是简单地使用较旧的 Keras H5 格式保存模型 model.save("test", save_format='h5')"
问题:
我在 colab 上有一个成功的 运行 最近邻张量流模型,名为 top_classify。但是在保存时,收到以下错误消息:
KeyError: "Failed to add concrete function
'b'__inference_model_layer_call_fn_158405'' to object-based SavedModel as it captures
tensor <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>> which is
unsupported or not reachable from root. One reason could be that a stateful object or
a variable that the function depends on is not assigned to an attribute of the
serialized trackable object (see SaveTest.test_captures_unreachable_variable)."
详情:
感兴趣的最近邻模型正在使用已训练模型 (embedding_network) 的输出。并将输入的输出与训练数据集的输出(最近距离)进行比较。我的意思是我们不是直接比较图像,比较它们的输出。通常我不会费心在 tensorflow 上编写 NN 代码,因为模型不是迭代的,但我需要一个 tflite 模型才能在 android 应用程序上使用。所以,我没有太多选择。
首先,我训练了 embedding_network 模型(通过迁移学习和 siamese),输出大小为 (None, 27)。 xc 是整个训练集(752 个样本,大小为 (752, 27) )的恒定输出矩阵,yc 是训练集的正确标签。两者都是 tf 常量。下面的示例是最佳匹配 (1NN)。也可以修改代码以适用于任意数量的所需匹配项 (KNN)。
xc = tf.constant(embedding_network(x_train))
yc = tf.constant(y_train)
inputs = keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = embedding_network(inputs, training=False)
distance = tf.reduce_sum(tf.abs(tf.add(xc, tf.negative(x0))), axis=1)
findKClosestTrImages = tf.argsort(distance, direction='ASCENDING')
closest0 = tf.gather(yc, findKClosestTrImages[0])
out=tf.one_hot(closest0, DEPTH)
top_classify = keras.Model(inputs=inputs, outputs=out)
top_classify.summary()
如您所见,我没有对模型进行任何训练,没有损失函数,也没有编译和拟合。因为我只会在推理时使用它。
这里是新近邻模型的总结,top_classify:
Model: "model_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_6 (InputLayer) [(None, 224, 224, 3)] 0
model (Functional) (None, 27) 2292571
tf.math.negative_1 (TFOpLam (None, 27) 0
bda)
tf.math.add_1 (TFOpLambda) (752, 27) 0
tf.math.abs_1 (TFOpLambda) (752, 27) 0
tf.math.reduce_sum_1 (TFOpL (752,) 0
ambda)
tf.argsort_1 (TFOpLambda) (752,) 0
tf.__operators__.getitem_1 () 0
(SlicingOpLambda)
tf.compat.v1.gather_1 (TFOp () 0
Lambda)
tf.one_hot_1 (TFOpLambda) (27,) 0
=================================================================
Total params: 2,292,571
Trainable params: 0
Non-trainable params: 2,292,571
_________________________________________________________________
无论如何,模型在 colab 上很有用。我得到了非常好的结果。但我无法保存模型,无论我使用 tf.saved_model.save 还是 top_classify.save
错误如果尝试tf.saved_model.save
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/function_serialization.py in serialize_concrete_function(concrete_function, node_ids, coder)
64 for capture in concrete_function.captured_inputs:
---> 65 bound_inputs.append(node_ids[capture])
66 except KeyError:
7 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/object_identity.py in __getitem__(self, key)
138 def __getitem__(self, key):
--> 139 return self._storage[self._wrap_key(key)]
140
KeyError: <_ObjectIdentityWrapper wrapping <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>>>
During handling of the above exception, another exception occurred:
KeyError Traceback (most recent call last)
<ipython-input-33-13ced446758f> in <module>()
15 TOP_CLASSIFY_SAVE_LOC = "/content/top_classify"
16 #top_classify.save("/content/top_classify")
---> 17 tf.saved_model.save(top_classify, TOP_CLASSIFY_SAVE_LOC)
18 #top_classify.save("/content/top_classify", save_format='h5')
19 # Convert the model
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in save(obj, export_dir, signatures, options)
1278 # pylint: enable=line-too-long
1279 metrics.IncrementWriteApi(_SAVE_V2_LABEL)
-> 1280 save_and_return_nodes(obj, export_dir, signatures, options)
1281 metrics.IncrementWrite(write_version="2")
1282
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in save_and_return_nodes(obj, export_dir, signatures, options, experimental_skip_checkpoint)
1313
1314 _, exported_graph, object_saver, asset_info, saved_nodes, node_paths = (
-> 1315 _build_meta_graph(obj, signatures, options, meta_graph_def))
1316 saved_model.saved_model_schema_version = (
1317 constants.SAVED_MODEL_SCHEMA_VERSION)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _build_meta_graph(obj, signatures, options, meta_graph_def)
1485
1486 with save_context.save_context(options):
-> 1487 return _build_meta_graph_impl(obj, signatures, options, meta_graph_def)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _build_meta_graph_impl(obj, signatures, options, meta_graph_def)
1449
1450 object_graph_proto = _serialize_object_graph(
-> 1451 saveable_view, asset_info.asset_index)
1452 meta_graph_def.object_graph_def.CopyFrom(object_graph_proto)
1453
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/save.py in _serialize_object_graph(saveable_view, asset_file_def_index)
1015 name = saveable_view.function_name_map.get(name, name)
1016 serialized = function_serialization.serialize_concrete_function(
-> 1017 concrete_function, saveable_view.captured_tensor_node_ids, coder)
1018 if serialized is not None:
1019 proto.concrete_functions[name].CopyFrom(serialized)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/function_serialization.py in serialize_concrete_function(concrete_function, node_ids, coder)
66 except KeyError:
67 raise KeyError(
---> 68 f"Failed to add concrete function '{concrete_function.name}' to object-"
69 f"based SavedModel as it captures tensor {capture!r} which is unsupported"
70 " or not reachable from root. "
KeyError: "Failed to add concrete function
'b'__inference_model_layer_call_fn_158405'' to object-based SavedModel as it captures
tensor <tf.Tensor: shape=(), dtype=resource, value=<Resource Tensor>> which is
unsupported or not reachable from root. One reason could be that a stateful object or
a variable that the function depends on is not assigned to an attribute of the
serialized trackable object (see SaveTest.test_captures_unreachable_variable)."
错误如果尝试 top_classify.save:
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
/usr/local/lib/python3.7/dist-packages/keras/engine/functional.py:1410: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument.
layer_config = serialize_layer_fn(layer)
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-34-7275f8fa7bba> in <module>()
18 top_classify.save("/content/top_classify", save_format='h5')
19 # Convert the model
---> 20 converter = tf.lite.TFLiteConverter.from_saved_model(TOP_CLASSIFY_SAVE_LOC) # path to the SavedModel directory
21 tflite_model = converter.convert()
22
4 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/lite/python/lite.py in from_saved_model(cls, saved_model_dir, signature_keys, tags)
1603
1604 with context.eager_mode():
-> 1605 saved_model = _load(saved_model_dir, tags)
1606 if not signature_keys:
1607 signature_keys = saved_model.signatures
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/load.py in load(export_dir, tags, options)
898 ValueError: If `tags` don't match a MetaGraph in the SavedModel.
899 """
--> 900 result = load_internal(export_dir, tags, options)["root"]
901 return result
902
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/load.py in load_internal(export_dir, tags, options, loader_cls, filters)
911 tags = nest.flatten(tags)
912 saved_model_proto, debug_info = (
--> 913 loader_impl.parse_saved_model_with_debug_info(export_dir))
914
915 if (len(saved_model_proto.meta_graphs) == 1 and
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/loader_impl.py in parse_saved_model_with_debug_info(export_dir)
58 parsed. Missing graph debug info file is fine.
59 """
---> 60 saved_model = _parse_saved_model(export_dir)
61
62 debug_info_path = file_io.join(
/usr/local/lib/python3.7/dist-packages/tensorflow/python/saved_model/loader_impl.py in parse_saved_model(export_dir)
117 else:
118 raise IOError(
--> 119 f"SavedModel file does not exist at: {export_dir}{os.path.sep}"
120 f"{{{constants.SAVED_MODEL_FILENAME_PBTXT}|"
121 f"{constants.SAVED_MODEL_FILENAME_PB}}}")
OSError: SavedModel file does not exist at: /content/top_classify/{saved_model.pbtxt|saved_model.pb}
如果您能提出解决方案或建议,我们将不胜感激。泰
经过多次详细的搜索和尝试,我找到了这个论坛post:
https://github.com/keras-team/keras/issues/15699 (在 Tensorflow 2.7 上使用数据增强层保存模型时出错 #15699)。其中指出,数据扩充可能会产生一些保存问题。
问题中没有说明,但这里是 embedding_network 的详细信息,在我的 tf 代码中:
inputs = tf.keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = rescale(inputs)
x0 = data_augmentation(x0)
x0 = base_model(x0, training=False)
x0 = tf.keras.layers.GlobalAveragePooling2D()(x0)
x0 = tf.keras.layers.Dropout(DROPOUT_VAL)(x0)
outputs = tf.keras.layers.Dense(NUM_CLASSES)(x0)
embedding_network = tf.keras.Model(inputs, outputs)
如您所见,它有一个增强层,它阻止了保存。所以我创建了一个非常相似的模型,称为 embedding_network_cleany,没有增强。
inputs = tf.keras.Input(shape=(TARGET_SIZE, TARGET_SIZE, 3))
x0 = rescale(inputs)
x2 = base_model(x0, training=False)
x3 = tf.keras.layers.GlobalAveragePooling2D()(x2)
x4 = tf.keras.layers.Dropout(DROPOUT_VAL)(x3)
outputs = tf.keras.layers.Dense(NUM_CLASSES)(x4)
embedding_network_cleany = tf.keras.Model(inputs, outputs)
用 embedding_network.save_weights 复制了 embedding_network 的权重,然后加载到 embedding_network_cleany。现在我可以同时保存 top_classify 和 embedding_network_cleany 模型。也可以转换为 tflite
一个新的解决方案:
可能 AloneTogether 在 link 中给出了更好的解决方案
“解决方法是简单地使用较旧的 Keras H5 格式保存模型 model.save("test", save_format='h5')"