Example #1
0
    def test_dense(self):
        """
        Test the conversion of Dense layer.
        """
        from keras.layers import Dense

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output), len(output_names))
        six.assertCountEqual(self, output_names,
                             [x.name for x in spec.description.output])

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.innerProduct)
Example #2
0
    def test_permute(self):
        """
        Test the conversion of pooling layer.
        """
        from keras.layers.core import Permute
        # Create a simple Keras model
        model = Sequential()
        model.add(Permute((3, 2, 1), input_shape=(10, 64, 3)))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output), len(output_names))
        six.assertCountEqual(self, output_names,
                             [x.name for x in spec.description.output])

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.permute)
Example #3
0
    def test_dropout(self):
        """
        Test the conversion for a Dense + Dropout
        """
        from keras.layers import Dense, Dropout

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Dropout(0.5))
        model.add(Dense(32, input_dim=16))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertItemsEqual(input_names,
                              map(lambda x: x.name, spec.description.input))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertItemsEqual(output_names,
                              map(lambda x: x.name, spec.description.output))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.innerProduct)
        self.assertEquals(len(layers), 2)
    def test_classifier_no_name(self):
        np.random.seed(1988)

        input_dim = 5
        num_hidden = 12
        num_classes = 6
        input_length = 3

        model = Sequential()
        model.add(
            LSTM(num_hidden,
                 input_dim=input_dim,
                 input_length=input_length,
                 return_sequences=False))
        model.add(Dense(num_classes, activation='softmax'))

        model.set_weights(
            [np.random.rand(*w.shape) for w in model.get_weights()])

        input_names = ['input']
        output_names = ['zzzz']
        class_labels = ['a', 'b', 'c', 'd', 'e', 'f']
        predicted_feature_name = 'pf'
        coremlmodel = keras_converter.convert(
            model,
            input_names,
            output_names,
            class_labels=class_labels,
            predicted_feature_name=predicted_feature_name)

        if is_macos() and macos_version() >= (10, 13):
            inputs = np.random.rand(input_dim)
            outputs = coremlmodel.predict({'input': inputs})
            # this checks that the dictionary got the right name and type
            self.assertEquals(type(outputs[output_names[0]]), type({'a': 0.5}))
Example #5
0
    def test_activation_softmax(self):
        """
        Test the conversion for a Dense + Activation('softmax')
        """
        from keras.layers import Dense, Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation("softmax"))

        input_names = ["input"]
        output_names = ["output"]
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField("neuralNetwork"))

        # Test the inputs and outputs
        self.assertEqual(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEqual(len(spec.description.output), len(output_names))
        six.assertCountEqual(self, output_names,
                             [x.name for x in spec.description.output])

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.innerProduct)
        layer_1 = layers[1]
        self.assertIsNotNone(layer_1.softmax)
Example #6
0
def convert_model(architecture):
    root = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))

    labels_path = os.path.join(root, 'model/labels.json')
    with open(labels_path, 'r') as fp:
        labels = json.load(fp)

    if architecture == 'mobilenets':
        model_path = os.path.join(root, 'model/mobilenets.h5')
        model = keras.models.load_model(model_path,
                                        custom_objects={'relu6': relu6})
    elif architecture == 'inception':
        model_path = os.path.join(root, 'model/inception.h5')
        model = keras.models.load_model(model_path)
    else:
        raise ValueError('architecture must be inception or mobilenets.')

    coreml_model = convert(
        model,
        input_names='image',
        image_input_names='image',
        class_labels=labels,
        image_scale=2. / 255,
        red_bias=-1,
        green_bias=-1,
        blue_bias=-1,
    )

    coreml_model.save("model/%s.mlmodel" % architecture)
Example #7
0
    def test_make_updatable_with_bilstm(self):
        from keras.models import Sequential
        from keras.layers import Dense, LSTM
        from coremltools.converters import keras as keras_converter
        from keras.layers.wrappers import Bidirectional
        import numpy as np

        num_classes = 6
        model = Sequential()
        model.add(
            Bidirectional(LSTM(32, input_shape=(10, 32)),
                          input_shape=(10, 32)))
        model.add(Dense(num_classes, activation="softmax"))
        model.set_weights(
            [np.random.rand(*w.shape) for w in model.get_weights()])

        input_names = ["input"]
        output_names = ["zzzz"]
        class_labels = ["a", "b", "c", "d", "e", "f"]
        predicted_feature_name = "pf"
        coremlmodel = keras_converter.convert(
            model,
            input_names,
            output_names,
            class_labels=class_labels,
            predicted_feature_name=predicted_feature_name,
            predicted_probabilities_output=output_names[0],
        )
        spec = coremlmodel.get_spec()
        builder = NeuralNetworkBuilder(spec=spec)
        # we could be able to make "dense_1" updatable without any issue
        builder.make_updatable([spec.neuralNetworkClassifier.layers[1].name])
Example #8
0
    def test_activation_softmax(self):
        """
        Test the conversion for a Dense + Activation('softmax')
        """
        from keras.layers import Dense, Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation('softmax'))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
               sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertEqual(sorted(output_names),
               sorted(map(lambda x: x.name, spec.description.output)))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.innerProduct)
        layer_1 = layers[1]
        self.assertIsNotNone(layer_1.softmax)
Example #9
0
    def test_merge_multiply(self):
        """
        Test the following Keras model
               |- dense-|
        dense -|        |- merge - dense
               |- dense-|
        """
        input_tensor = Input(shape=(3, ))
        x1 = Dense(4)(input_tensor)
        x2 = Dense(5)(x1)
        x3 = Dense(5)(x1)
        x4 = merge([x2, x3], mode='mul')
        x5 = Dense(7)(x4)

        model = Model(input=[input_tensor], output=[x5])
        input_names = ['data']
        output_names = ['output']

        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEqual(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
                         sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEqual(len(spec.description.output), len(output_names))
        self.assertEqual(
            sorted(output_names),
            sorted(map(lambda x: x.name, spec.description.output)))
Example #10
0
    def test_pooling(self):
        """
        Test the conversion of pooling layer.
        """
        from keras.layers import Conv2D, MaxPooling2D

        # Create a simple Keras model
        model = Sequential()
        model.add(Conv2D(input_shape=(64, 64, 3),
                                filters=32, kernel_size=(5,5), strides=(1,1), activation=None, 
                                padding='valid', use_bias=True))
        model.add(MaxPooling2D(pool_size=(2,2)))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
               sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertEqual(sorted(output_names),
               sorted(map(lambda x: x.name, spec.description.output)))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        self.assertIsNotNone(layers[1].pooling)
Example #11
0
    def test_batchnorm(self):
        """
        Test the conversion for a Convoultion2D + Batchnorm layer
        """
        from keras.layers import Conv2D
        from keras.layers.normalization import BatchNormalization

        # Create a simple Keras model
        model = Sequential()
        model.add(Conv2D(input_shape=(64, 64, 3),
                               filters=32, kernel_size=(5,5), strides=(1,1), activation=None, 
                               padding='valid', use_bias=True))
        # epsilon in CoreML is currently fixed at 1e-5
        model.add(BatchNormalization(epsilon=1e-5))
        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
              sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertEqual(sorted(output_names),
              sorted(map(lambda x: x.name, spec.description.output)))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        self.assertIsNotNone(layers[0].convolution)
        self.assertIsNotNone(layers[1].batchnorm)
Example #12
0
    def test_upsample(self):
        """
        Test the conversion of 2D convolutional layer + upsample
        """
        from keras.layers import Conv2D, UpSampling2D

        # Create a simple Keras model
        model = Sequential()
        model.add(
            Conv2D(input_shape=(64, 64, 3), filters=32, kernel_size=(5, 5)))
        model.add(UpSampling2D(size=(2, 2)))
        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
                         sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertEqual(
            sorted(output_names),
            sorted(map(lambda x: x.name, spec.description.output)))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.convolution)
        layer_1 = layers[1]
        self.assertIsNotNone(layer_1.upsample)
Example #13
0
    def test_embedding(self):
        from keras.layers import Embedding

        model = Sequential()
        num_inputs = 10
        num_outputs = 3
        model.add(Embedding(num_inputs, num_outputs, input_length=5))

        input_names = ['input']
        output_names = ['output']

        spec = keras.convert(model, input_names, output_names).get_spec()

        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.embedding)

        self.assertEquals(layer_0.embedding.inputDim, num_inputs)
        self.assertEquals(layer_0.embedding.outputChannels, num_outputs)

        self.assertEquals(len(layer_0.embedding.weights.floatValue),
                          num_inputs * num_outputs)
Example #14
0
    def test_conv1d_lstm(self):
        from keras.layers import Convolution1D, LSTM, Dense
        model = Sequential()
        # input_shape = (time_step, dimensions)
        model.add(Convolution1D(32, 3, border_mode='same',
                                input_shape=(10, 8)))
        # conv1d output shape = (None, 10, 32)
        model.add(LSTM(24))
        model.add(Dense(1, activation='sigmoid'))
        print('model.layers[1].output_shape=', model.layers[1].output_shape)

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()

        self.assertIsNotNone(spec)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output), len(output_names))
        six.assertCountEqual(self, output_names,
                             [x.name for x in spec.description.output])

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        self.assertIsNotNone(layers[0].convolution)
        self.assertIsNotNone(layers[1].simpleRecurrent)
        self.assertIsNotNone(layers[2].innerProduct)
Example #15
0
    def test_default_interface_names(self):
        from keras.layers import Dense
        from keras.layers import Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation('softmax'))

        expected_input_names = ['input1']
        expected_output_names = ['output1']
        spec = keras.convert(model).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input),
                          len(expected_input_names))
        six.assertCountEqual(self, expected_input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          [x.name for x in spec.description.output])
Example #16
0
    def test_pooling(self):
        """
        Test the conversion of pooling layer.
        """
        from keras.layers import Convolution2D, MaxPooling2D

        # Create a simple Keras model
        model = Sequential()
        model.add(Convolution2D(input_shape=(64, 64, 3),
                                nb_filter=32, nb_row=5, nb_col=5,
                                init='glorot_uniform', activation=None, weights=None,
                                border_mode='valid', subsample=(1, 1), bias=True))
        model.add(MaxPooling2D(pool_size=(2,2)))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertItemsEqual(input_names,
               map(lambda x: x.name, spec.description.input))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertItemsEqual(output_names,
               map(lambda x: x.name, spec.description.output))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.convolution)
Example #17
0
    def test_classifier_integer_classes(self):
        from keras.layers import Dense
        from keras.layers import Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation("softmax"))
        classes = list(range(32))

        input_names = ["input"]
        output_names = ["prob_output"]
        expected_output_names = ["prob_output", "classLabel"]
        spec = keras.convert(model,
                             input_names,
                             output_names,
                             class_labels=classes).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField("neuralNetworkClassifier"))
        self.assertFalse(spec.HasField("neuralNetwork"))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          [x.name for x in spec.description.output])

        # Check the types
        self.assertEquals(spec.description.output[0].type.WhichOneof("Type"),
                          "dictionaryType")
        self.assertEquals(
            spec.description.output[0].type.dictionaryType.WhichOneof(
                "KeyType"),
            "int64KeyType",
        )
        self.assertEquals(spec.description.output[1].type.WhichOneof("Type"),
                          "int64Type")
        self.assertTrue(spec.description.predictedFeatureName, "classLabel")
        self.assertTrue(spec.description.predictedProbabilitiesName,
                        "prob_output")

        # Test the class parameters
        self.assertEqual(
            spec.WhichOneof("Type"),
            "neuralNetworkClassifier",
            "Expected a NN classifier model",
        )
        self.assertEqual(
            spec.neuralNetworkClassifier.WhichOneof("ClassLabels"),
            "int64ClassLabels")
        class_from_proto = list(
            spec.neuralNetworkClassifier.int64ClassLabels.vector)
        six.assertCountEqual(self, classes, class_from_proto)
Example #18
0
def _keras_2_mlmodel_image():
    """
    Converts a Keras h5 model into ML Model for image data and saves it on 
    disk.

    NOTE: Image configuration must be specified from Explora. 

    NOTE: Currently, only categorical cross entropy loss is supported.
    """
    model = get_keras_model()
    ios_config = state.state["ios_config"]
    class_labels = ios_config["class_labels"]
    mlmodel = keras_converter.convert(model, input_names=['image'],
                                output_names=['output'],
                                class_labels=class_labels,
                                predicted_feature_name='label')
    mlmodel.save(state.state["mlmodel_path"])

    image_config = ios_config["image_config"]
    spec = coremltools.utils.load_spec(state.state["mlmodel_path"])
    builder = coremltools.models.neural_network.NeuralNetworkBuilder(spec=spec)

    dims = image_config["dims"]
    spec.description.input[0].type.imageType.width = dims[0]
    spec.description.input[0].type.imageType.height = dims[1]

    cs = _FeatureTypes_pb2.ImageFeatureType.ColorSpace.Value(image_config["color_space"])
    spec.description.input[0].type.imageType.colorSpace = cs

    trainable_layer_names = [layer.name for layer in model.layers if layer.get_weights()]
    builder.make_updatable(trainable_layer_names)

    builder.set_categorical_cross_entropy_loss(name='loss', input='output')

    if isinstance(model.optimizer, SGD):
        params = SgdParams(
            lr=K.eval(model.optimizer.lr), 
            batch=state.state["hyperparams"]["batch_size"],
        )
        builder.set_sgd_optimizer(params)
    elif isinstance(model.optimizer, Adam):
        params = AdamParams(
            lr=K.eval(model.optimizer.lr), 
            batch_size=state.state["hyperparams"]["batch_size"],
            beta1=model.optimizer.beta1,
            beta2=model.optimizer.beta2,
            eps=model.optimizer.eps,    
        )
        builder.set_adam_optimizer(params)
    else:
        raise Exception("iOS optimizer must be SGD or Adam!")

    builder.set_epochs(UNLIMITED_EPOCHS)
    builder.set_shuffle(state.state["hyperparams"]["shuffle"])  

    mlmodel_updatable = MLModel(spec)
    mlmodel_updatable.save(state.state["mlmodel_path"])

    K.clear_session()
def _get_coreml_model(model, input_names, output_names):
    """
    Get the coreml model from the Keras model.
    """
    # Convert the model
    from coremltools.converters import keras as keras_converter
    model = keras_converter.convert(model, input_names, output_names)
    return model
Example #20
0
    def test_classifier_custom_class_name(self):
        from keras.layers import Dense
        from keras.layers import Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_shape=(16, )))
        model.add(Activation('softmax'))
        classes = ['c%s' % i for i in range(32)]

        input_names = ['input']
        output_names = ['prob_output']
        expected_output_names = ['prob_output', 'my_foo_bar_class_output']
        spec = keras.convert(
            model,
            input_names,
            output_names,
            class_labels=classes,
            predicted_feature_name='my_foo_bar_class_output').get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetworkClassifier'))
        self.assertFalse(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
                         sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          list(map(lambda x: x.name, spec.description.output)))

        # Check the types
        self.assertEquals(spec.description.output[0].type.WhichOneof('Type'),
                          'dictionaryType')
        self.assertEquals(
            spec.description.output[0].type.dictionaryType.WhichOneof(
                'KeyType'), 'stringKeyType')
        self.assertEquals(spec.description.output[1].type.WhichOneof('Type'),
                          'stringType')
        self.assertTrue(spec.description.predictedFeatureName,
                        'my_foo_bar_class_output')
        self.assertTrue(spec.description.predictedProbabilitiesName,
                        'prob_output')

        # Test the class parameters
        self.assertEqual(spec.WhichOneof('Type'), 'neuralNetworkClassifier',
                         "Expected a NN classifier model")
        self.assertEqual(
            spec.neuralNetworkClassifier.WhichOneof('ClassLabels'),
            'stringClassLabels')
        class_from_proto = list(
            spec.neuralNetworkClassifier.stringClassLabels.vector)
        self.assertEqual(sorted(classes), sorted(class_from_proto))
Example #21
0
    def test_activations(self):
        """
        Test the conversion for a Dense + Activation('something')
        """
        from keras.layers import Dense, Activation

        # Create a simple Keras model
        keras_activation_options = [
            "tanh",
            "softplus",
            "softsign",
            "relu",
            "sigmoid",
            "hard_sigmoid",
            "linear",
        ]
        coreml_activation_options = [
            "tanh",
            "softplus",
            "softsign",
            "ReLU",
            "sigmoid",
            "sigmoidHard",
            "linear",
        ]

        for i, k_act in enumerate(keras_activation_options):
            c_act = coreml_activation_options[i]
            model = Sequential()
            model.add(Dense(32, input_dim=16))
            model.add(Activation(k_act))

            input_names = ["input"]
            output_names = ["output"]
            spec = keras.convert(model, input_names, output_names).get_spec()
            self.assertIsNotNone(spec)

            # Test the model class
            self.assertIsNotNone(spec.description)
            self.assertTrue(spec.HasField("neuralNetwork"))

            # Test the inputs and outputs
            self.assertEqual(len(spec.description.input), len(input_names))
            self.assertCountEqual(
                self, input_names, [x.name for x in spec.description.input]
            )
            self.assertEqual(len(spec.description.output), len(output_names))
            self.assertCountEqual(
                self, output_names, [x.name for x in spec.description.output]
            )

            # Test the layer parameters.
            layers = spec.neuralNetwork.layers
            self.assertIsNotNone(layers[0].innerProduct)
            self.assertIsNotNone(layers[1].activation)
            self.assertTrue(layers[1].activation.HasField(c_act))
Example #22
0
    def test_bidir(self):
        """
        Test the conversion of a bidirectional layer
        """
        from keras.layers import LSTM
        from keras.layers.wrappers import Bidirectional

        # Create a simple Keras model
        model = Sequential()
        model.add(
            Bidirectional(LSTM(32, input_dim=32, input_length=10),
                          input_shape=(10, 32)))

        input_names = ["input"]
        output_names = ["output"]
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField("neuralNetwork"))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names) + 4)
        self.assertEquals(input_names[0], spec.description.input[0].name)

        self.assertEquals(
            32, spec.description.input[1].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.input[2].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.input[3].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.input[4].type.multiArrayType.shape[0])

        self.assertEquals(len(spec.description.output), len(output_names) + 4)
        self.assertEquals(output_names[0], spec.description.output[0].name)
        self.assertEquals(
            64, spec.description.output[0].type.multiArrayType.shape[0])

        self.assertEquals(
            32, spec.description.output[1].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.output[2].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.output[3].type.multiArrayType.shape[0])
        self.assertEquals(
            32, spec.description.output[4].type.multiArrayType.shape[0])

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_0 = layers[0]
        self.assertIsNotNone(layer_0.biDirectionalLSTM)
        self.assertEquals(len(layer_0.input), 5)
        self.assertEquals(len(layer_0.output), 5)
Example #23
0
    def test_8bit_symmetric_and_skips(self):
        from keras.models import Sequential
        from keras.layers import Conv2D

        def stable_rel_error(x, ref):
            err = x - ref
            denom = np.maximum(np.abs(ref), np.ones_like(ref))
            return np.abs(err) / denom

        np.random.seed(1988)
        input_dim = 16
        num_kernels, kernel_height, kernel_width, input_channels = 64, 3, 3, 32

        # Define a model
        model = Sequential()
        model.add(
            Conv2D(input_shape=(input_dim, input_dim, input_channels),
                   filters=num_kernels,
                   kernel_size=(kernel_height, kernel_width)))

        # Set some random weights
        weight, bias = model.layers[0].get_weights()
        num_filters = weight.shape[-1]
        filter_shape = weight.shape[:-1]

        new_weight = np.stack([
            4.0 * np.random.rand(*filter_shape) - 2 for i in range(num_filters)
        ],
                              axis=-1)
        model.layers[0].set_weights([new_weight, bias])

        mlmodel = keras_converter.convert(model, ['data'], ['output_0'])
        selector = quantization_utils.AdvancedQuantizedLayerSelector(
            skip_layer_types=['batchnorm', 'bias', 'depthwiseConv'],
            minimum_conv_kernel_channels=4,
            minimum_conv_weight_count=4096)

        q_mlmodel = quantization_utils.quantize_weights(mlmodel,
                                                        8,
                                                        selector=selector)

        input_shape = (1, 1, input_channels, input_dim, input_dim)
        input_val = 2 * np.random.rand(*input_shape) - 1

        coreml_input = {'data': input_val}
        coreml_output = mlmodel.predict(coreml_input)
        q_coreml_output = q_mlmodel.predict(coreml_input)

        val = coreml_output['output_0']
        q_val = q_coreml_output['output_0']
        rel_err = stable_rel_error(q_val, val)
        max_rel_err, mean_rel_err = np.max(rel_err), np.mean(rel_err)
        self.assertTrue(max_rel_err < 0.25)
        self.assertTrue(max_rel_err > 0.01)
        self.assertTrue(mean_rel_err < 0.02)
Example #24
0
    def test_classifier_integer_classes(self):
        from keras.layers import Dense
        from keras.layers import Activation

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation('softmax'))
        classes = range(32)

        input_names = ['input']
        output_names = ['prob_output']
        expected_output_names = ['prob_output', 'classLabel']
        spec = keras.convert(model,
                             input_names,
                             output_names,
                             class_labels=classes).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetworkClassifier'))
        self.assertFalse(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertItemsEqual(input_names,
                              map(lambda x: x.name, spec.description.input))
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          map(lambda x: x.name, spec.description.output))

        # Check the types
        self.assertEquals(spec.description.output[0].type.WhichOneof('Type'),
                          'dictionaryType')
        self.assertEquals(
            spec.description.output[0].type.dictionaryType.WhichOneof(
                'KeyType'), 'int64KeyType')
        self.assertEquals(spec.description.output[1].type.WhichOneof('Type'),
                          'int64Type')
        self.assertTrue(spec.description.predictedFeatureName, 'classLabel')
        self.assertTrue(spec.description.predictedProbabilitiesName,
                        'prob_output')

        # Test the class parameters
        self.assertEqual(spec.WhichOneof('Type'), 'neuralNetworkClassifier',
                         "Expected a NN classifier model")
        self.assertEqual(
            spec.neuralNetworkClassifier.WhichOneof('ClassLabels'),
            'int64ClassLabels')
        class_from_proto = list(
            spec.neuralNetworkClassifier.int64ClassLabels.vector)
        self.assertItemsEqual(classes, class_from_proto)
Example #25
0
    def test_classifier_file(self):
        from keras.layers import Dense
        from keras.layers import Activation
        import os
        import tempfile

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_dim=16))
        model.add(Activation("softmax"))
        classes = ["c%s" % i for i in range(32)]
        classes_file = tempfile.mktemp()
        with open(classes_file, "w") as f:
            f.write("\n".join(classes))

        input_names = ["input"]
        output_names = ["prob_output"]
        expected_output_names = ["prob_output", "classLabel"]
        spec = keras.convert(model,
                             input_names,
                             output_names,
                             class_labels=classes).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField("neuralNetworkClassifier"))
        self.assertFalse(spec.HasField("neuralNetwork"))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        six.assertCountEqual(self, input_names,
                             [x.name for x in spec.description.input])
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          [x.name for x in spec.description.output])

        # Check the types
        self.assertEquals(spec.description.output[0].type.WhichOneof("Type"),
                          "dictionaryType")
        self.assertEquals(
            spec.description.output[0].type.dictionaryType.WhichOneof(
                "KeyType"),
            "stringKeyType",
        )
        self.assertEquals(spec.description.output[1].type.WhichOneof("Type"),
                          "stringType")
        self.assertTrue(spec.description.predictedFeatureName, "classLabel")
        self.assertTrue(spec.description.predictedProbabilitiesName,
                        "prob_output")

        # cleanup
        os.remove(classes_file)
Example #26
0
    def test_separable_convolution(self,
                                   with_dilations=False,
                                   activation=None):
        """
        Test the conversion of 2D depthwise separable convolutional layer.
        """
        from keras.layers import SeparableConv2D

        dilation_rate = [1, 1]
        if with_dilations:
            dilation_rate = [2, 2]

        # Create a simple Keras model
        model = Sequential()
        model.add(
            SeparableConv2D(input_shape=(64, 64, 3),
                            filters=32,
                            kernel_size=(5, 5),
                            activation=activation,
                            padding='valid',
                            strides=(1, 1),
                            use_bias=True,
                            dilation_rate=dilation_rate))

        input_names = ['input']
        output_names = ['output']
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
                         sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output), len(output_names))
        self.assertEqual(
            sorted(output_names),
            sorted(map(lambda x: x.name, spec.description.output)))

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        layer_depthwise, layer_pointwise = layers[0], layers[1]

        self.assertIsNotNone(layer_depthwise.convolution)
        self.assertIsNotNone(layer_pointwise.convolution)
        self.assertEqual(layer_depthwise.convolution.dilationFactor,
                         dilation_rate)
        if activation is not None:
            self.assertIsNotNone(layers[2].activation)
            self.assertTrue(layers[2].activation.HasField('ELU'))
Example #27
0
    def test_classifier_file(self):
        from keras.layers import Dense
        from keras.layers import Activation
        import os
        import tempfile

        # Create a simple Keras model
        model = Sequential()
        model.add(Dense(32, input_shape=(16, )))
        model.add(Activation('softmax'))
        classes = ['c%s' % i for i in range(32)]
        classes_file = tempfile.mktemp()
        with open(classes_file, 'w') as f:
            f.write('\n'.join(classes))

        input_names = ['input']
        output_names = ['prob_output']
        expected_output_names = ['prob_output', 'classLabel']
        spec = keras.convert(model,
                             input_names,
                             output_names,
                             class_labels=classes).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField('neuralNetworkClassifier'))
        self.assertFalse(spec.HasField('neuralNetwork'))

        # Test the inputs and outputs
        self.assertEquals(len(spec.description.input), len(input_names))
        self.assertEqual(sorted(input_names),
                         sorted(map(lambda x: x.name, spec.description.input)))
        self.assertEquals(len(spec.description.output),
                          len(expected_output_names))
        self.assertEquals(expected_output_names,
                          list(map(lambda x: x.name, spec.description.output)))

        # Check the types
        self.assertEquals(spec.description.output[0].type.WhichOneof('Type'),
                          'dictionaryType')
        self.assertEquals(
            spec.description.output[0].type.dictionaryType.WhichOneof(
                'KeyType'), 'stringKeyType')
        self.assertEquals(spec.description.output[1].type.WhichOneof('Type'),
                          'stringType')
        self.assertTrue(spec.description.predictedFeatureName, 'classLabel')
        self.assertTrue(spec.description.predictedProbabilitiesName,
                        'prob_output')

        # cleanup
        os.remove(classes_file)
Example #28
0
    def test_keras_1_image_bias(self):
        # define Keras model and get prediction
        input_shape = (100, 50, 3)
        model = Sequential()
        model.add(Activation("linear", input_shape=input_shape))

        data = np.ones(input_shape)
        keras_input = np.ones(input_shape)
        data[:, :, 0] = 128.0
        data[:, :, 1] = 27.0
        data[:, :, 2] = 200.0
        red_bias = -12.0
        green_bias = -20
        blue_bias = -4
        keras_input[:, :, 0] = data[:, :, 0] + red_bias
        keras_input[:, :, 1] = data[:, :, 1] + green_bias
        keras_input[:, :, 2] = data[:, :, 2] + blue_bias

        keras_preds = model.predict(np.expand_dims(keras_input, axis=0))
        keras_preds = np.transpose(keras_preds, [0, 3, 1, 2]).flatten()

        # convert to coreml and get predictions
        model_dir = tempfile.mkdtemp()
        model_path = os.path.join(model_dir, "keras.mlmodel")
        from coremltools.converters import keras as keras_converter

        coreml_model = keras_converter.convert(
            model,
            input_names=["data"],
            output_names=["output"],
            image_input_names=["data"],
            red_bias=red_bias,
            green_bias=green_bias,
            blue_bias=blue_bias,
        )

        if _is_macos() and _macos_version() >= (10, 13):
            coreml_input_dict = dict()
            coreml_input_dict["data"] = PIL.Image.fromarray(
                data.astype(np.uint8))
            coreml_preds = coreml_model.predict(
                coreml_input_dict)["output"].flatten()

            self.assertEqual(len(keras_preds), len(coreml_preds))
            max_relative_error = compare_models(keras_preds, coreml_preds)
            self.assertAlmostEqual(max(max_relative_error, 0.001),
                                   0.001,
                                   delta=1e-6)

        if os.path.exists(model_dir):
            shutil.rmtree(model_dir)
Example #29
0
 def test_unsupported_variational_deconv(self):
     from keras.layers import Input, Lambda, Convolution2D, Flatten, Dense
     x = Input(shape=(8,8,3))
     conv_1 = Convolution2D(4, 2, 2, border_mode='same', activation='relu')(x)
     flat = Flatten()(conv_1)
     hidden = Dense(10, activation='relu')(flat)
     z_mean = Dense(10)(hidden)
     z_log_var = Dense(10)(hidden)
     def sampling(args):
         z_mean, z_log_var = args
         return z_mean + z_log_var
     z = Lambda(sampling, output_shape=(10,))([z_mean, z_log_var])
     model = Model([x], [z])
     spec = keras.convert(model, ['input'], ['output']).get_spec()
Example #30
0
    def test_batchnorm(self):
        """
        Test the conversion for a Convoultion2D + Batchnorm layer
        """
        from keras.layers import Convolution2D
        from keras.layers.normalization import BatchNormalization

        # Create a simple Keras model
        model = Sequential()
        model.add(
            Convolution2D(
                input_shape=(64, 64, 3),
                nb_filter=32,
                nb_row=5,
                nb_col=5,
                init="glorot_uniform",
                activation=None,
                weights=None,
                border_mode="valid",
                subsample=(1, 1),
                bias=True,
            )
        )
        # epsilon in CoreML is currently fixed at 1e-5
        model.add(BatchNormalization(epsilon=1e-5))
        input_names = ["input"]
        output_names = ["output"]
        spec = keras.convert(model, input_names, output_names).get_spec()
        self.assertIsNotNone(spec)

        # Test the model class
        self.assertIsNotNone(spec.description)
        self.assertTrue(spec.HasField("neuralNetwork"))

        # Test the inputs and outputs
        self.assertEqual(len(spec.description.input), len(input_names))
        self.assertCountEqual(
            self, input_names, [x.name for x in spec.description.input]
        )
        self.assertEqual(len(spec.description.output), len(output_names))
        self.assertCountEqual(
            self, output_names, [x.name for x in spec.description.output]
        )

        # Test the layer parameters.
        layers = spec.neuralNetwork.layers
        self.assertIsNotNone(layers[0].convolution)
        self.assertIsNotNone(layers[1].batchnorm)