Coremltools: Cannot convert Keras model with coremltools

Created on 6 Feb 2020  路  1Comment  路  Source: apple/coremltools

I can't convert a simple Keras model to CoreML with coremltools

Trace

~/anaconda3/lib/python3.7/site-packages/coremltools/converters/keras/_keras2_converter.py in _convert(model, input_names, output_names, image_input_names, input_name_shape_dict, is_bgr, red_bias, green_bias, blue_bias, gray_bias, image_scale, class_labels, predicted_feature_name, predicted_probabilities_output, add_custom_layers, custom_conversion_functions, custom_objects, input_shapes, output_shapes, respect_trainable, use_float_arraytype)
326 # Build network graph to represent Keras model
327 graph = _topology2.NetGraph(model)
--> 328 graph.build()
329
330 # The graph should be finalized before executing this

~/anaconda3/lib/python3.7/site-packages/coremltools/converters/keras/_topology2.py in build(self, is_top_level)
738
739 # tag input layers and and output layers
--> 740 self.make_input_layers()
741 self.make_output_layers()
742

~/anaconda3/lib/python3.7/site-packages/coremltools/converters/keras/_topology2.py in make_input_layers(self)
167 for l in self.layer_list:
168 kl = self.keras_layer_map[l]
--> 169 if isinstance(kl, InputLayer) and kl.input == ts:
170 self.input_layers.append(l)
171 elif len(in_nodes) <= 1:

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py in __bool__(self)
763 TypeError.
764 """
--> 765 self._disallow_bool_casting()
766
767 def __nonzero__(self):

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py in _disallow_bool_casting(self)
532 else:
533 # Default: V1-style Graph execution.
--> 534 self._disallow_in_graph_mode("using a tf.Tensor as a Python bool")
535
536 def _disallow_iteration(self):

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py in _disallow_in_graph_mode(self, task)
521 raise errors.OperatorNotAllowedInGraphError(
522 "{} is not allowed in Graph execution. Use Eager execution or decorate"
--> 523 " this function with @tf.function.".format(task))
524
525 def _disallow_bool_casting(self):

OperatorNotAllowedInGraphError: using a tf.Tensor as a Python bool is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.

To Reproduce

    inp = keras.layers.Input(shape=(420, 420, 3))
    conv = keras.layers.Conv2D(32, 3, activation='relu')(inp)
    keras_model = keras.models.Model(inputs=[inp], outputs=conv)
    model = coremltools.converters.keras.convert(
        keras_model,
        input_name_shape_dict={
            keras_model.input.name: [None, 420, 420, 3]
        },
        input_names=[keras_model.input.name], 
        output_names=[keras_model.output.name]
    )

If I try to use tf.compat.v1.disable_eager_execution(), I get this:

~/anaconda3/lib/python3.7/site-packages/coremltools/converters/keras/_keras2_converter.py in _convert(model, input_names, output_names, image_input_names, input_name_shape_dict, is_bgr, red_bias, green_bias, blue_bias, gray_bias, image_scale, class_labels, predicted_feature_name, predicted_probabilities_output, add_custom_layers, custom_conversion_functions, custom_objects, input_shapes, output_shapes, respect_trainable, use_float_arraytype)
494 if converter_func:
495 converter_func(builder, layer, input_names, output_names,
--> 496 keras_layer, respect_trainable)
497 else:
498 if _is_activation_layer(keras_layer):

~/anaconda3/lib/python3.7/site-packages/coremltools/converters/keras/_layers2.py in convert_convolution(builder, layer, input_names, output_names, keras_layer, respect_train)
357
358 # Get the weights from _keras.
--> 359 weightList = keras_layer.get_weights()
360
361 # Dimensions and weights

~/anaconda3/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py in eager_fn_wrapper(args, *kwargs)
103 _SYMBOLIC_SCOPE.value = False
104 with context.eager_mode():
--> 105 out = func(args, *kwargs)
106 finally:
107 _SYMBOLIC_SCOPE.value = prev_value

~/anaconda3/lib/python3.7/site-packages/keras/engine/base_layer.py in get_weights(self)
1136 """
1137 params = self.weights
-> 1138 return K.batch_get_value(params)
1139
1140 def get_config(self):

~/anaconda3/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py in batch_get_value(ops)
2937 A list of Numpy arrays.
2938 """
-> 2939 return tf_keras_backend.batch_get_value(ops)
2940
2941

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/backend.py in batch_get_value(tensors)
3294 """
3295 if context.executing_eagerly():
-> 3296 return [x.numpy() for x in tensors]
3297 elif ops.inside_function(): # pylint: disable=protected-access
3298 raise RuntimeError('Cannot get value inside Tensorflow graph function.')

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/backend.py in (.0)
3294 """
3295 if context.executing_eagerly():
-> 3296 return [x.numpy() for x in tensors]
3297 elif ops.inside_function(): # pylint: disable=protected-access
3298 raise RuntimeError('Cannot get value inside Tensorflow graph function.')

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/resource_variable_ops.py in numpy(self)
575 def numpy(self):
576 if context.executing_eagerly():
--> 577 return self.read_value().numpy()
578 raise NotImplementedError(
579 "numpy() is only available when eager execution is enabled.")

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/resource_variable_ops.py in read_value(self)
628 # Ensure we read the variable in the same device as the handle.
629 with ops.device(self._handle.device):
--> 630 value = self._read_variable_op()
631 # Return an identity so it can get placed on whatever device the context
632 # specifies instead of the device where the variable is.

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/resource_variable_ops.py in _read_variable_op(self)
606 variable_accessed(self)
607 result = gen_resource_variable_ops.read_variable_op(self._handle,
--> 608 self._dtype)
609 _maybe_set_handle_data(self._dtype, self._handle, result)
610

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/gen_resource_variable_ops.py in read_variable_op(resource, dtype, name)
573 try:
574 return read_variable_op_eager_fallback(
--> 575 resource, dtype=dtype, name=name, ctx=_ctx)
576 except _core._SymbolicException:
577 pass # Add nodes to the TensorFlow graph.

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/gen_resource_variable_ops.py in read_variable_op_eager_fallback(resource, dtype, name, ctx)
611 _attrs = ("dtype", dtype)
612 _result = _execute.execute(b"ReadVariableOp", 1, inputs=_inputs_flat,
--> 613 attrs=_attrs, ctx=_ctx, name=name)
614 _execute.record_gradient(
615 "ReadVariableOp", _inputs_flat, _attrs, _result, name)

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
74 "Inputs to eager execution function cannot be Keras symbolic "
75 "tensors, but found {}".format(keras_symbolic_tensors))
---> 76 raise e
77 # pylint: enable=protected-access
78 return tensors

~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
59 tensors = pywrap_tensorflow.TFE_Py_Execute(ctx._handle, device_name,
60 op_name, inputs, attrs,
---> 61 num_outputs)
62 except core._NotOkStatusException as e:
63 if name is not None:

TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
@tf.function
def has_init_scope():
my_constant = tf.constant(1.)
with tf.init_scope():
added = my_constant * 2
The graph tensor has name: conv2d_1/kernel:0

System environment (please complete the following information):

  • coremltools version (e.g., 3.0b5): 3.2
  • OS (e.g., MacOS, Linux): Ubuntu 18
  • How you install python (anaconda, virtualenv, system): conda
  • python version (e.g. 3.7): 3.7.3
  • Keras version: '2.3.1'
  • TF: 2.0 (not using tf.keras though; just vanilla keras)
bug

>All comments

This appears to be a TF2.0 native issue. If TF1.x (e.g. 1.14) is used instead, the code appears to run fine. (Although this is pretty inconvenient and definitely not a good long term solution for version compatibility with other libraries)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xternalz picture xternalz  路  3Comments

wschin picture wschin  路  4Comments

G-mel picture G-mel  路  5Comments

HussainHaris picture HussainHaris  路  5Comments

tucan9389 picture tucan9389  路  4Comments