def _test_one_to_one_operator_coreml(self, keras_model, x): # Verify Keras-to-CoreML-to-ONNX path coreml_model = None try: coreml_model = coremltools.converters.keras.convert(keras_model) except (AttributeError, ImportError) as e: warnings.warn( "Unable to test due to an error in coremltools '{0}'".format( e)) onnx_model = None if coreml_model is None else onnxmltools.convert_coreml( coreml_model) self.assertTrue(onnx_model or coreml_model is None) if self._no_available_inference_engine(): return y_reference = keras_model.predict(x) y_produced = evaluate_deep_model(onnx_model, x) self.assertTrue(np.allclose(y_reference, y_produced)) # Verify Keras-to-ONNX path onnx_model = onnxmltools.convert_keras(keras_model) y_produced = evaluate_deep_model(onnx_model, x) self.assertTrue(np.allclose(y_reference, y_produced))
def _test_one_to_one_operator_coreml_channels_last(self, keras_model, x): ''' There are two test paths. One is Keras-->CoreML-->ONNX and the other one is Keras-->ONNX. Keras-->CoreML-->ONNX: Keras computation path: [N, C, H, W] ---> numpy transpose ---> [N, H, W, C] ---> keras convolution ---> [N, H, W, C] ---> numpy transpose ---> [N, C, H, W] ONNX computation path: [N, C, H, W] ---> ONNX convolution ---> [N, C, H, W] The reason for having extra transpose's in the Keras path is that CoreMLTools doesn't not handle channels_last flag properly. Precisely, oreMLTools always converts Conv2D under channels_first mode. Keras-->ONNX Keras computation path: [N, C, H, W] ---> numpy transpose ---> [N, H, W, C] ---> keras convolution ---> [N, H, W, C] ONNX computation path: [N, C, H, W] ---> numpy transpose ---> [N, H, W, C] ---> ONNX convolution ---> [N, H, W, C] ''' # Verify Keras-to-CoreML-to-ONNX path coreml_model = None try: coreml_model = coremltools.converters.keras.convert(keras_model) except (AttributeError, ImportError) as e: warnings.warn( "Unable to test due to an error in coremltools '{0}'.".format( e)) onnx_model_p1 = None if coreml_model is None else onnxmltools.convert_coreml( coreml_model) onnx_model_p2 = onnxmltools.convert_keras(keras_model) self.assertTrue(onnx_model_p1 or coreml_model is None) self.assertTrue(onnx_model_p2) if self._no_available_inference_engine(): return if isinstance(x, list): x_t = [np.transpose(_, [0, 2, 3, 1]) for _ in x] else: x_t = np.transpose(x, [0, 2, 3, 1]) y_reference = np.transpose(keras_model.predict(x_t), [0, 3, 1, 2]) y_produced = evaluate_deep_model(onnx_model_p1, x) self.assertTrue(np.allclose(y_reference, y_produced)) # Verify Keras-to-ONNX path y_reference = np.transpose(y_reference, [0, 2, 3, 1]) y_produced = evaluate_deep_model(onnx_model_p2, x_t) self.assertTrue(np.allclose(y_reference, y_produced, atol=1e-6))
def test_recursive_model(self): N, C, D = 2, 3, 3 x = create_tensor(N, C) sub_input1 = Input(shape=(C, )) sub_mapped1 = Dense(D)(sub_input1) sub_model1 = Model(inputs=sub_input1, outputs=sub_mapped1) sub_input2 = Input(shape=(C, )) sub_mapped2 = Dense(D)(sub_input2) sub_model2 = Model(inputs=sub_input2, outputs=sub_mapped2) input1 = Input(shape=(D, )) input2 = Input(shape=(D, )) mapped1_2 = sub_model1(input1) mapped2_2 = sub_model2(input2) sub_sum = Add()([mapped1_2, mapped2_2]) keras_model = Model(inputs=[input1, input2], output=sub_sum) try: coreml_model = coremltools.converters.keras.convert(keras_model) except (AttributeError, ImportError) as e: warnings.warn( "Unable to test due to an error in coremltools '{0}'".format( e)) return onnx_model = onnxmltools.convert_coreml(coreml_model) x = [x, 2 * x] y_reference = keras_model.predict(x) y_produced = evaluate_deep_model(onnx_model, x).reshape(N, D)
def _test_one_to_one_operator_core_keras(self, keras_model, x): y_reference = keras_model.predict(x) onnx_model = onnxmltools.convert_keras(keras_model) if find_keras_backend(): y_produced = evaluate_deep_model(onnx_model, x) self.assertTrue(np.allclose(y_reference, y_produced)) else: warnings.warn("cntk or caffe2 are not available")
def _test_one_to_one_operator_keras(self, keras_model, x): y_reference = keras_model.predict(x) onnx_model = onnxmltools.convert_keras(keras_model) if not self._no_available_inference_engine(): y_produced = evaluate_deep_model(onnx_model, x) self.assertTrue(np.allclose(y_reference, y_produced)) else: self.assertIsNotNone(onnx_model) warnings.warn("None of onnx inference engine is available.") if self._no_available_inference_engine(): return
def test_flatten(self): N, C, H, W, D = 2, 3, 1, 2, 2 x = create_tensor(N, C, H, W) keras_model = Sequential() keras_model.add(Flatten(input_shape=(H, W, C))) keras_model.add(Dense(D)) keras_model.compile(optimizer='adagrad', loss='mse') try: coreml_model = coremltools.converters.keras.convert(keras_model) except ImportError: warnings.warn("Issue in coremltools.") return onnx_model = onnxmltools.convert_coreml(coreml_model) y_reference = keras_model.predict(np.transpose(x, [0, 2, 3, 1])) y_produced = evaluate_deep_model(onnx_model, x).reshape(N, D) self.assertTrue(np.allclose(y_reference, y_produced))
def test_dense(self): N, C, D = 2, 3, 2 x = create_tensor(N, C) input = Input(shape=(C, )) result = Dense(D)(input) keras_model = Model(inputs=input, outputs=result) keras_model.compile(optimizer='adagrad', loss='mse') try: coreml_model = coremltools.converters.keras.convert(keras_model) except (AttributeError, ImportError) as e: warnings.warn( "Unable to test due to an error in coremltools '{0}'.".format( e)) return onnx_model = onnxmltools.convert_coreml(coreml_model) y_reference = keras_model.predict(x) y_produced = evaluate_deep_model(onnx_model, x).reshape(N, D) self.assertTrue(np.allclose(y_reference, y_produced))