From d6749307ab470b4f455ba5228244e755d1c9d74f Mon Sep 17 00:00:00 2001 From: David Fan Date: Wed, 26 Feb 2020 11:38:44 -0800 Subject: [PATCH 1/4] Add vgg16 and nasnet to v2 application --- .../test_keras_applications_v2.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/applications/nightly_build/test_keras_applications_v2.py b/applications/nightly_build/test_keras_applications_v2.py index c6bb5259..12124f68 100644 --- a/applications/nightly_build/test_keras_applications_v2.py +++ b/applications/nightly_build/test_keras_applications_v2.py @@ -25,6 +25,12 @@ def tearDown(self): for fl in self.model_files: os.remove(fl) + def test_DenseNet121(self): + DenseNet121 = keras.applications.densenet.DenseNet121 + model = DenseNet121(include_top=True, weights='imagenet') + res = run_image(model, self.model_files, img_path, tf_v2=True) + self.assertTrue(*res) + def test_MobileNet(self): MobileNet = keras.applications.mobilenet.MobileNet model = MobileNet(weights='imagenet') @@ -39,15 +45,21 @@ def test_MobileNetV2(self): res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) + def test_NASNet(self): + NASNetMobile = keras.applications.nasnet.NASNetMobile + model = NASNetMobile(weights='imagenet') + res = run_image(model, self.model_files, img_path, tf_v2=True) + self.assertTrue(*res) + def test_ResNet50(self): ResNet50 = keras.applications.resnet_v2.ResNet50V2 model = ResNet50(include_top=True, weights='imagenet') res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) - def test_DenseNet121(self): - DenseNet121 = keras.applications.densenet.DenseNet121 - model = DenseNet121(include_top=True, weights='imagenet') + def test_VGG16(self): + VGG16 = keras.applications.vgg16.VGG16 + model = VGG16(include_top=True, weights='imagenet') res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) From c731d6fb6b7145dffc6162c24ab1adedb1d55b09 Mon Sep 17 00:00:00 2001 From: David Fan Date: Wed, 26 Feb 2020 11:38:44 -0800 Subject: [PATCH 2/4] Add vgg16 and nasnet to v2 application --- .../test_keras_applications_v2.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/applications/nightly_build/test_keras_applications_v2.py b/applications/nightly_build/test_keras_applications_v2.py index c6bb5259..b647ec09 100644 --- a/applications/nightly_build/test_keras_applications_v2.py +++ b/applications/nightly_build/test_keras_applications_v2.py @@ -25,6 +25,12 @@ def tearDown(self): for fl in self.model_files: os.remove(fl) + def test_DenseNet121(self): + DenseNet121 = keras.applications.densenet.DenseNet121 + model = DenseNet121(include_top=True, weights='imagenet') + res = run_image(model, self.model_files, img_path, tf_v2=True) + self.assertTrue(*res) + def test_MobileNet(self): MobileNet = keras.applications.mobilenet.MobileNet model = MobileNet(weights='imagenet') @@ -39,15 +45,21 @@ def test_MobileNetV2(self): res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) + def test_NASNetMobile(self): + NASNetMobile = keras.applications.nasnet.NASNetMobile + model = NASNetMobile(weights='imagenet') + res = run_image(model, self.model_files, img_path, tf_v2=True) + self.assertTrue(*res) + def test_ResNet50(self): ResNet50 = keras.applications.resnet_v2.ResNet50V2 model = ResNet50(include_top=True, weights='imagenet') res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) - def test_DenseNet121(self): - DenseNet121 = keras.applications.densenet.DenseNet121 - model = DenseNet121(include_top=True, weights='imagenet') + def test_VGG16(self): + VGG16 = keras.applications.vgg16.VGG16 + model = VGG16(include_top=True, weights='imagenet') res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) From 4dd886978f0c23863076590c29149df00bf50657 Mon Sep 17 00:00:00 2001 From: Wenbing Li Date: Tue, 25 Feb 2020 13:24:46 -0800 Subject: [PATCH 3/4] Add DepthwiseConv2d to subclassed model and efficient-net test cases (#394) * Efficient-net test cases. * Add DepthwiseConv2d to subclassed model. * disable efficient net test cases. --- .../linux-CI-keras-applications-nightly.yml | 1 + .../win32-CI-keras-applications-nightly.yml | 1 + applications/nightly_build/test_efn.py | 46 +++++++++++++++++++ applications/nightly_build/test_gan.py | 1 - .../test_keras_applications_v2.py | 10 ++-- keras2onnx/_parse_tf.py | 5 +- keras2onnx/ke2onnx/layer_spec.py | 5 ++ 7 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 applications/nightly_build/test_efn.py diff --git a/.azure-pipelines/linux-CI-keras-applications-nightly.yml b/.azure-pipelines/linux-CI-keras-applications-nightly.yml index c913be3f..724ae48b 100644 --- a/.azure-pipelines/linux-CI-keras-applications-nightly.yml +++ b/.azure-pipelines/linux-CI-keras-applications-nightly.yml @@ -105,6 +105,7 @@ jobs: pip install git+https://www.github.com/keras-team/keras-contrib.git pip install keras-tcn==2.8.3 $(UNINSTALL_KERAS) + pip install git+https://github.com/qubvel/efficientnet displayName: 'Install dependencies' - script: | diff --git a/.azure-pipelines/win32-CI-keras-applications-nightly.yml b/.azure-pipelines/win32-CI-keras-applications-nightly.yml index 2458c7bc..61e47c00 100644 --- a/.azure-pipelines/win32-CI-keras-applications-nightly.yml +++ b/.azure-pipelines/win32-CI-keras-applications-nightly.yml @@ -103,6 +103,7 @@ jobs: pip install git+https://www.github.com/keras-team/keras-contrib.git pip install keras-tcn==2.8.3 %UNINSTALL_KERAS% + pip install git+https://github.com/qubvel/efficientnet displayName: 'Install dependencies' - script: | diff --git a/applications/nightly_build/test_efn.py b/applications/nightly_build/test_efn.py new file mode 100644 index 00000000..63b01de0 --- /dev/null +++ b/applications/nightly_build/test_efn.py @@ -0,0 +1,46 @@ +############################################################################### +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +############################################################################### +import os +import sys +import unittest +from os.path import dirname, abspath +from keras2onnx.proto import keras, is_keras_older_than + +sys.path.insert(0, os.path.join(dirname(abspath(__file__)), '../../tests/')) +from test_utils import run_image + +img_path = os.path.join(os.path.dirname(__file__), '../data', 'street.jpg') + + +# @unittest.skipIf(is_keras_older_than('2.2.0'), "efficientnet needs keras >= 2.2.0") +@unittest.skip("Minor discrepancy on the model output.") +class TestEfn(unittest.TestCase): + + def setUp(self): + self.model_files = [] + + def tearDown(self): + for fl in self.model_files: + os.remove(fl) + + def test_custom(self): + from efficientnet import keras as efn + keras.backend.set_learning_phase(0) + base_model = efn.EfficientNetB0(input_shape=(600, 600, 3), weights=None) + backbone = keras.Model(base_model.input, base_model.get_layer("top_activation").output) + res = run_image(backbone, self.model_files, img_path, target_size=(600, 600), rtol=1e-1) + self.assertTrue(*res) + + def test_efn(self): + from efficientnet import keras as efn + keras.backend.set_learning_phase(0) + model = efn.EfficientNetB7(weights='imagenet') + res = run_image(model, self.model_files, img_path, target_size=(600, 600), rtol=1e-1) + self.assertTrue(*res) + + +if __name__ == "__main__": + unittest.main() diff --git a/applications/nightly_build/test_gan.py b/applications/nightly_build/test_gan.py index b67b512e..d750e601 100644 --- a/applications/nightly_build/test_gan.py +++ b/applications/nightly_build/test_gan.py @@ -7,7 +7,6 @@ import sys import unittest import keras2onnx -import onnx import numpy as np from keras2onnx.proto import keras from os.path import dirname, abspath diff --git a/applications/nightly_build/test_keras_applications_v2.py b/applications/nightly_build/test_keras_applications_v2.py index c6bb5259..57762878 100644 --- a/applications/nightly_build/test_keras_applications_v2.py +++ b/applications/nightly_build/test_keras_applications_v2.py @@ -27,7 +27,7 @@ def tearDown(self): def test_MobileNet(self): MobileNet = keras.applications.mobilenet.MobileNet - model = MobileNet(weights='imagenet') + model = MobileNet(weights=None) res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) @@ -35,25 +35,25 @@ def test_MobileNet(self): "Test mobilenet_v2 in tf2.") def test_MobileNetV2(self): MobileNetV2 = keras.applications.mobilenet_v2.MobileNetV2 - model = MobileNetV2(weights='imagenet') + model = MobileNetV2(weights=None) res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) def test_ResNet50(self): ResNet50 = keras.applications.resnet_v2.ResNet50V2 - model = ResNet50(include_top=True, weights='imagenet') + model = ResNet50(include_top=True, weights=None) res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) def test_DenseNet121(self): DenseNet121 = keras.applications.densenet.DenseNet121 - model = DenseNet121(include_top=True, weights='imagenet') + model = DenseNet121(include_top=True, weights=None) res = run_image(model, self.model_files, img_path, tf_v2=True) self.assertTrue(*res) def test_Xception(self): Xception = keras.applications.xception.Xception - model = Xception(include_top=True, weights='imagenet') + model = Xception(include_top=True, weights=None) res = run_image(model, self.model_files, img_path, atol=5e-3, target_size=299, tf_v2=True) self.assertTrue(*res) diff --git a/keras2onnx/_parse_tf.py b/keras2onnx/_parse_tf.py index 1bcec656..36cf410b 100644 --- a/keras2onnx/_parse_tf.py +++ b/keras2onnx/_parse_tf.py @@ -186,7 +186,10 @@ def build_layer_outputs(model, graph, outputs): output_dict[op_.name] = layer_dict[ln_] else: # fx_[1] is output node redirect function. - output_dict[fx_list[1](lobj, op_)] = layer_dict[ln_] + output_tensor = fx_list[1](lobj, op_) + assert graph.get_operation_by_name(output_tensor) is not None, "Parsing layer({}) failed.".format( + lobj) + output_dict[output_tensor] = layer_dict[ln_] return output_dict diff --git a/keras2onnx/ke2onnx/layer_spec.py b/keras2onnx/ke2onnx/layer_spec.py index 39fb0a00..44c194f8 100644 --- a/keras2onnx/ke2onnx/layer_spec.py +++ b/keras2onnx/ke2onnx/layer_spec.py @@ -27,6 +27,10 @@ def _simple_layer_name_extractor(fstr_list, node_name): def _conv_layer_spec_outputs(layer, node): + if type(layer) == _layer.DepthwiseConv2D: + ri = node.name.rindex('/') + return node.name[:ri + 1] + 'BiasAdd' + activation_map = { keras.activations.linear: '', tf.nn.sigmoid: 'Sigmoid', @@ -58,6 +62,7 @@ def _relu_like_spec_outputs(layer, node): _layer.AveragePooling2D: (["{}/AvgPool"], [_default_layer_name_extractor]), _layer.AveragePooling3D: (["{}/AvgPool"], [_default_layer_name_extractor]), _layer.Conv2DTranspose: (["{}/conv2d_transpose"], [_simple_layer_name_extractor, _conv_layer_spec_outputs]), + _layer.DepthwiseConv2D: (["{}/depthwise"], [_simple_layer_name_extractor, _conv_layer_spec_outputs]), _layer.LeakyReLU: (["{}/LeakyRelu"], [_default_layer_name_extractor]), _adv_activations.PReLU: (["{}/Relu"], [_simple_layer_name_extractor, _relu_like_spec_outputs]) } From 853ea6db69ce299b40f8f5a4c7467081b51bf513 Mon Sep 17 00:00:00 2001 From: David Fan Date: Fri, 27 Mar 2020 19:16:35 -0700 Subject: [PATCH 4/4] Ping keras-segmentation==0.2.0 --- .azure-pipelines/linux-CI-keras-applications-nightly.yml | 2 +- .azure-pipelines/win32-CI-keras-applications-nightly.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/linux-CI-keras-applications-nightly.yml b/.azure-pipelines/linux-CI-keras-applications-nightly.yml index 724ae48b..160afc8b 100644 --- a/.azure-pipelines/linux-CI-keras-applications-nightly.yml +++ b/.azure-pipelines/linux-CI-keras-applications-nightly.yml @@ -93,7 +93,7 @@ jobs: $(INSTALL_ORT) pip install opencv-python pip install tqdm - pip install keras-segmentation + pip install keras-segmentation==0.2.0 git clone https://github.com/matterport/Mask_RCNN cd Mask_RCNN pip install -r requirements.txt diff --git a/.azure-pipelines/win32-CI-keras-applications-nightly.yml b/.azure-pipelines/win32-CI-keras-applications-nightly.yml index 61e47c00..6d7b5237 100644 --- a/.azure-pipelines/win32-CI-keras-applications-nightly.yml +++ b/.azure-pipelines/win32-CI-keras-applications-nightly.yml @@ -96,7 +96,7 @@ jobs: %INSTALL_ORT% pip install opencv-python pip install tqdm - pip install keras-segmentation + pip install keras-segmentation==0.2.0 pip install matplotlib git clone https://github.com/qqwweee/keras-yolo3 %INSTALL_KERAS_RESNET%