示例#1
0
    def save_model(self, path: str):
        """
        Serializes the model into path.

        Args:
            path (str): Target destination
        """
        inputs = [('input', datatypes.Array(*self.input))]
        outputs = [('output', datatypes.Array(*self.output))]
        net_builder = NeuralNetworkBuilder(inputs, outputs)
        input = 'input'
        prev_device = next(next(self.nn.children()).parameters()).device
        try:
            for name, layer in self.nn.to('cpu').named_children():
                input = layer.serialize(name, input, net_builder)
            mlmodel = MLModel(net_builder.spec)
            mlmodel.short_description = 'kraken recognition model'
            mlmodel.user_defined_metadata['vgsl'] = '[' + ' '.join(self.named_spec) + ']'
            if self.codec:
                mlmodel.user_defined_metadata['codec'] = json.dumps(self.codec.c2l)
            if self.user_metadata:
                mlmodel.user_defined_metadata['kraken_meta'] = json.dumps(self.user_metadata)
            mlmodel.save(path)
        finally:
            self.nn.to(prev_device)
示例#2
0
    def test_nn_partial_fp16_make_updatable_fail(self):
        nn_builder = self.create_base_builder()
        model_path = os.path.join(self.model_dir, "updatable_creation.mlmodel")
        print(model_path)
        save_spec(nn_builder.spec, model_path)
        mlmodel = MLModel(model_path)

        # fails since updatable models cannot get quantized to FP16
        with self.assertRaises(Exception):
            quantization_utils.quantize_weights(mlmodel, 16, "linear")
示例#3
0
def _get_model(spec):
    """
    Utility to get the model and the data.
    """
    from . import MLModel

    if isinstance(spec, MLModel):
        return spec
    else:
        return MLModel(spec)
示例#4
0
 def test_nn_classifier_util(self):
     input_features = [("data", datatypes.Array(3))]
     output_features = [("out", datatypes.Array(3))]
     builder = NeuralNetworkBuilder(input_features,
                                    output_features,
                                    disable_rank5_shape_mapping=True)
     builder.add_activation("linear", "LINEAR", "data", "out")
     spec = builder.spec
     mlmodel = MLModel(spec, compute_units=ComputeUnit.CPU_ONLY)
     mlmodel = make_nn_classifier(
         mlmodel,
         class_labels=["a", "b", "c"],
         predicted_feature_name="out_confidence",
         predicted_probabilities_output="out",
     )
     out_dict = mlmodel.predict({"data": np.array([4.0, 5.5, 6.0])})
     self.assertEqual(out_dict["out_confidence"], "c")
     self.assertEqual(mlmodel.get_spec().WhichOneof("Type"),
                      "neuralNetworkClassifier")
示例#5
0
 def test_rename_output(self):
     rename_feature(
         self.spec,
         "output",
         "renamed_output",
         rename_inputs=False,
         rename_outputs=True,
     )
     model = MLModel(self.spec)
     preds = model.predict({"feature_1": 1.0, "feature_2": 1.0})
     self.assertIsNotNone(preds)
     self.assertEqual(preds["renamed_output"], 3.1)
     rename_feature(
         self.spec,
         "renamed_output",
         "output",
         rename_inputs=False,
         rename_outputs=True,
     )
示例#6
0
 def test_save_spec_api_model_with_no_weights(self):
     """
     save an mlprogram model with no weights, using the save SPI and an empty weights directory.
     Reload the model from disk and verify it works
     """
     spec = self.mlmodel_no_weights.get_spec()
     with tempfile.TemporaryDirectory(suffix=utils._MLPACKAGE_EXTENSION) as model_path:
         with tempfile.TemporaryDirectory() as empty_weight_dir:
             utils.save_spec(spec, model_path, weights_dir=empty_weight_dir)
             model = MLModel(model_path)
             self._test_mlmodel_correctness(model)
示例#7
0
 def test_mlmodel_to_spec_to_mlmodel(self):
     """
     convert mlmodel to spec, and then back to mlmodel and verify that it works
     """
     spec = self.mlmodel.get_spec()
     # reload the model from the spec and verify it
     weights_dir = self.mlmodel.weights_dir
     mlmodel_from_spec = MLModel(spec, weights_dir=weights_dir)
     self._test_mlmodel_correctness(mlmodel_from_spec)
     # check that the original model still works
     self._test_mlmodel_correctness(self.mlmodel)
     # check that an error is raised when MLModel is initialized without the weights
     with pytest.raises(
             Exception,
             match=
             "MLModel of type mlProgram cannot be loaded just from the model "
             "spec object. It also needs the path to the weights file. "
             "Please provide that as well, using the 'weights_dir' argument."
     ):
         MLModel(spec)
示例#8
0
    def load_model(cls, path: str):
        """
        Deserializes a VGSL model from a CoreML file.

        Args:
            path (str): CoreML file
        """
        mlmodel = MLModel(path)
        if 'vgsl' not in mlmodel.user_defined_metadata:
            raise ValueError('No VGSL spec in model metadata')
        vgsl_spec = mlmodel.user_defined_metadata['vgsl']
        nn = cls(vgsl_spec)
        for name, layer in nn.nn.named_children():
            layer.deserialize(name, mlmodel.get_spec())

        if 'codec' in mlmodel.user_defined_metadata:
            nn.add_codec(
                PytorchCodec(json.loads(
                    mlmodel.user_defined_metadata['codec'])))
        return nn
示例#9
0
    def load_model(cls, path: str):
        """
        Deserializes a VGSL model from a CoreML file.

        Args:
            path (str): CoreML file
        """
        mlmodel = MLModel(path)
        if 'vgsl' not in mlmodel.user_defined_metadata:
            raise ValueError('No VGSL spec in model metadata')
        vgsl_spec = mlmodel.user_defined_metadata['vgsl']
        nn = cls(vgsl_spec)
        for name, layer in nn.nn.named_children():
            layer.deserialize(name, mlmodel.get_spec())

        if 'codec' in mlmodel.user_defined_metadata:
            nn.add_codec(PytorchCodec(json.loads(mlmodel.user_defined_metadata['codec'])))
        if 'kraken_meta' in mlmodel.user_defined_metadata:
            nn.user_metadata = json.loads(mlmodel.user_defined_metadata['kraken_meta'])
        return nn
 def get_spec(self):
     """
     Return the Core ML spec
     """
     if _mac_ver() >= (10, 14):
         return self.vggish_model.get_spec()
     else:
         vggish_model_file = VGGish()
         coreml_model_path = vggish_model_file.get_model_path(
             format='coreml')
         return MLModel(coreml_model_path).get_spec()
示例#11
0
    def test_simple_branch(self):
        """ Test a simple if-else branch network
        """
        input_features = [("data", datatypes.Array(3)), ("cond", datatypes.Array(1))]
        output_features = [("output", None)]

        builder_top = NeuralNetworkBuilder(
            input_features, output_features, disable_rank5_shape_mapping=True
        )
        layer = builder_top.add_branch("branch_layer", "cond")

        builder_ifbranch = NeuralNetworkBuilder(
            input_features=None,
            output_features=None,
            spec=None,
            nn_spec=layer.branch.ifBranch,
        )
        builder_ifbranch.add_elementwise(
            "mult_layer",
            input_names=["data"],
            output_name="output",
            mode="MULTIPLY",
            alpha=10,
        )
        builder_elsebranch = NeuralNetworkBuilder(
            input_features=None,
            output_features=None,
            spec=None,
            nn_spec=layer.branch.elseBranch,
        )
        builder_elsebranch.add_elementwise(
            "add_layer",
            input_names=["data"],
            output_name="output",
            mode="ADD",
            alpha=10,
        )
        coremltools.models.utils.save_spec(
            builder_top.spec, "/tmp/simple_branch.mlmodel"
        )
        mlmodel = MLModel(builder_top.spec)

        # True branch case
        input_dict = {
            "data": np.array(range(1, 4), dtype="float"),
            "cond": np.array([1], dtype="float"),
        }
        output_ref = {"output": input_dict["data"] * 10}
        self._test_model(mlmodel, input_dict, output_ref)

        # False branch case
        input_dict["cond"] = np.array([0], dtype="float")
        output_ref["output"] = input_dict["data"] + 10
        self._test_model(mlmodel, input_dict, output_ref)
示例#12
0
 def test_undefined_shape_single_output(self):
     W = np.ones((3, 3))
     input_features = [("data", datatypes.Array(3))]
     output_features = [("probs", None)]
     builder = NeuralNetworkBuilder(input_features, output_features)
     builder.add_inner_product(
         name="ip1",
         W=W,
         b=None,
         input_channels=3,
         output_channels=3,
         has_bias=False,
         input_name="data",
         output_name="probs",
     )
     mlmodel = MLModel(builder.spec)
     data = np.ones((3,))
     data_dict = {"data": data}
     probs = mlmodel.predict(data_dict)["probs"]
     self.assertTrue(np.allclose(probs, np.ones(3) * 3))
示例#13
0
    def _test_use_float_array_helper(self, use_float_arraytype):
        input_features = [("data", datatypes.Array(3))]
        output_features = [("probs", None)]
        builder = NeuralNetworkBuilder(
            input_features=input_features,
            output_features=output_features,
            use_float_arraytype=use_float_arraytype,
        )
        weights = np.ones((3, 3))
        builder.add_inner_product(
            name="ip1",
            W=weights,
            b=None,
            input_channels=3,
            output_channels=3,
            has_bias=False,
            input_name="data",
            output_name="probs",
        )
        spec = builder.spec
        array_feature_type = (
            coremltools.proto.FeatureTypes_pb2.ArrayFeatureType.FLOAT32
            if use_float_arraytype else
            coremltools.proto.FeatureTypes_pb2.ArrayFeatureType.DOUBLE)
        for input in spec.description.input:
            self.assertEqual(input.type.multiArrayType.dataType,
                             array_feature_type)
        for output in spec.description.input:
            self.assertEqual(output.type.multiArrayType.dataType,
                             array_feature_type)

        # Assert that the generated spec is functional
        mlmodel = MLModel(spec)
        data = np.ones((3, ))
        data_dict = {"data": data}
        try:
            predictions = mlmodel.predict(data_dict)
        except Exception as e:
            self.fail(e)
        self.assertTrue(np.allclose(predictions["probs"], np.ones(3) * 3))
示例#14
0
    def test_dead_layer_partial_branch(self):
        convergence_tolerance = 1e-8

        input_features = [("input", datatypes.Array(*(2,)))]
        output_features = [("out", None)]

        builder = neural_network.NeuralNetworkBuilder(
            input_features, output_features, disable_rank5_shape_mapping=True
        )
        # add condition to break from the loop, if convergence criterion is met
        builder.add_less_than("cond", ["input"], "cond", alpha=convergence_tolerance)
        branch_layer = builder.add_branch("branch_layer", "cond")
        builder_ifbranch = neural_network.NeuralNetworkBuilder(
            nn_spec=branch_layer.branch.ifBranch
        )
        builder_ifbranch.add_activation("relu1", "RELU", "input", "relu1_out")
        builder_ifbranch.add_activation("relu2_out", "RELU", "relu1_out", "relu2_out")
        builder_elsebranch = neural_network.NeuralNetworkBuilder(
            nn_spec=branch_layer.branch.elseBranch
        )
        builder_elsebranch.add_activation("linear1", "LINEAR", "input", "linear1_out")
        builder_elsebranch.add_activation(
            "linear_red_1", "LINEAR", "input", "linear_red1_out"
        )
        builder_elsebranch.add_activation(
            "linear_red_2", "LINEAR", "linear_red1_out", "linear_red2_out"
        )
        builder_elsebranch.add_activation(
            "linear2", "LINEAR", "linear1_out", "relu2_out"
        )
        builder.add_squeeze("out", "relu2_out", "out", squeeze_all=True)

        mlmodel = MLModel(builder.spec, compute_units=ComputeUnit.CPU_ONLY)

        if not _IS_MACOS:
            # Can not get predictions unless on macOS.
            return

        data = np.random.rand(2,)
        data_dict = {"input": data}
        before_pass_out = mlmodel.predict(data_dict)["out"]
        if DEBUG:
            print("\n mlmodel description before remove disconnected layers pass: \n")
            print_network_spec(builder.spec, style="coding")
        old_spec = copy.copy(builder.spec)
        remove_disconnected_layers(builder.spec)
        if DEBUG:
            print("\n mlmodel description after remove disconnected layers pass: \n")
            print_network_spec(builder.spec, style="coding")
        mlmodel = MLModel(builder.spec, compute_units=ComputeUnit.CPU_ONLY)
        after_pass_out = mlmodel.predict(data_dict)["out"]

        np.testing.assert_almost_equal(before_pass_out, after_pass_out, decimal=2)
        np.testing.assert_equal(
            len(old_spec.neuralNetwork.layers[1].branch.ifBranch.layers),
            len(builder.spec.neuralNetwork.layers[1].branch.ifBranch.layers),
        )
        np.testing.assert_equal(
            len(builder.spec.neuralNetwork.layers[1].branch.elseBranch.layers), 2
        )
示例#15
0
    def test_dead_layer_remove_branch(self):
        convergence_tolerance = 1e-8

        input_features = [('input', datatypes.Array(*(2,)))]
        output_features = [('out', None)]

        builder = neural_network.NeuralNetworkBuilder(input_features, output_features, disable_rank5_shape_mapping=True)
        # add condition to break from the loop, if convergence criterion is met
        builder.add_less_than('cond', ['input'], 'cond', alpha=convergence_tolerance)
        branch_layer = builder.add_branch('branch_layer', 'cond')
        builder_ifbranch = neural_network.NeuralNetworkBuilder(nn_spec=branch_layer.branch.ifBranch)
        builder_ifbranch.add_activation('relu1', 'RELU', 'input', 'relu1_out')
        builder_ifbranch.add_activation('relu2_out', 'RELU', 'relu1_out', 'relu2_out')
        builder_elsebranch = neural_network.NeuralNetworkBuilder(nn_spec=branch_layer.branch.elseBranch)
        builder_elsebranch.add_activation('linear1', 'LINEAR', 'input', 'linear1_out')
        builder_elsebranch.add_activation('linear2', 'LINEAR', 'linear1_out', 'relu2_out')
        builder.add_squeeze('out', 'input', 'out', squeeze_all=True)

        mlmodel = MLModel(builder.spec)
        data = np.random.rand(2,)
        data_dict = {'input': data}
        before_pass_out = mlmodel.predict(data_dict)['out']
        if DEBUG:
            print('\n mlmodel description before remove disconnected layers pass: \n')
            print_network_spec(builder.spec, style='coding')
        remove_disconnected_layers(builder.spec)
        if DEBUG:
            print('\n mlmodel description after remove disconnected layers pass: \n')
            print_network_spec(builder.spec, style='coding')
        mlmodel = MLModel(builder.spec)
        after_pass_out = mlmodel.predict(data_dict)['out']

        np.testing.assert_almost_equal(before_pass_out, after_pass_out, decimal=4)
        np.testing.assert_equal(len(builder.spec.neuralNetwork.layers), 1)
示例#16
0
    def test_convert_nn_spec_to_half_precision(self):
        # simple network with quantization layer
        input_features = [('data', datatypes.Array(3))]
        output_features = [('out', datatypes.Array(3))]
        builder = NeuralNetworkBuilder(input_features, output_features)
        weights = np.random.uniform(-0.5, 0.5, (3, 3))
        builder.add_inner_product(name='inner_product',
                                  W=weights,
                                  b=None,
                                  input_channels=3,
                                  output_channels=3,
                                  has_bias=False,
                                  input_name='data',
                                  output_name='out')
        model = MLModel(builder.spec)
        spec = convert_neural_network_spec_weights_to_fp16(model.get_spec())
        self.assertIsNotNone(spec)

        # simple network without quantization layer
        input_features = [('data', datatypes.Array(3))]
        output_features = [('out', datatypes.Array(3))]
        builder = NeuralNetworkBuilder(input_features, output_features)
        builder.add_lrn(name='lrn',
                        input_name='data',
                        output_name='out',
                        alpha=2,
                        beta=3,
                        local_size=1,
                        k=8)
        model = MLModel(builder.spec)
        spec = convert_neural_network_spec_weights_to_fp16(model.get_spec())
        self.assertIsNotNone(spec)
示例#17
0
    def test_linear_quant_embedding_7bit(self):
        embed_size = 2
        vocab_size = 3
        W = np.zeros((embed_size, vocab_size), dtype=np.uint8)
        W[:, 0] = [100, 127]
        W[:, 1] = [20, 40]
        W[:, 2] = [90, 1]
        quant_scale = np.reshape(np.array([10.0, 2.0]), (2, 1))
        quant_bias = np.reshape(np.array([-2.0, -10.0]), (2, 1))
        W_unquantized = np.broadcast_to(quant_scale, (2, 3)) * W + np.broadcast_to(quant_bias, (2, 3))
        bias = np.reshape(np.array([1.0, 2.0]), (2, 1))
        W_unquantized = W_unquantized + np.broadcast_to(bias, (2, 3))

        input_features = [('data', datatypes.Array(4,1,1,1))]
        output_features = [('out', None)]
        builder = NeuralNetworkBuilder(input_features, output_features, disable_rank5_shape_mapping=True)
        builder.add_embedding(name='embed',
                              W = _convert_array_to_nbit_quantized_bytes(W.flatten(), 7).tobytes(),
                              b = bias,
                              input_dim = vocab_size,
                              output_channels = embed_size,
                              has_bias = True,
                              input_name = 'data', output_name = 'out',
                              is_quantized_weight= True,
                              quantization_type='linear',
                              nbits = 7,
                              quant_scale = quant_scale,
                              quant_bias = quant_bias)

        mlmodel = MLModel(builder.spec)
        data = np.reshape(np.array([2.0, 2.0, 1.0, 0.0]), (4, 1, 1, 1))
        data_dict = {'data': data}
        out = mlmodel.predict(data_dict, useCPUOnly=True)['out']
        self.assertTrue(out.shape == (4, embed_size, 1, 1))
        expected_out = np.zeros((4, embed_size), dtype=np.float32)
        expected_out[0, :] =  W_unquantized[:, 2].flatten()
        expected_out[1, :] = W_unquantized[:, 2].flatten()
        expected_out[2, :] = W_unquantized[:, 1].flatten()
        expected_out[3, :] = W_unquantized[:, 0].flatten()
        self.assertTrue(np.allclose(out.flatten(), expected_out.flatten()))
示例#18
0
    def test_lut_quant_embedding_nd_2bit(self):
        embed_size = 2
        vocab_size = 3
        W = np.zeros((embed_size, vocab_size), dtype=np.uint8)
        W[:, 0] = [1, 0]
        W[:, 1] = [0, 1]
        W[:, 2] = [3, 2]
        bias = np.array([1.0, 2.0])
        quant_lut = np.array([34.0, 12.0, -6.0, 6.0])

        input_features = [("data", datatypes.Array(4, 1))]
        output_features = [("out", None)]
        builder = NeuralNetworkBuilder(
            input_features, output_features, disable_rank5_shape_mapping=True
        )
        builder.add_embedding_nd(
            name="embedding_nd",
            input_name="data",
            output_name="out",
            vocab_size=vocab_size,
            embedding_size=embed_size,
            W=_convert_array_to_nbit_quantized_bytes(W.flatten(), 2).tobytes(),
            b=bias,
            is_quantized_weight=True,
            quantization_type="lut",
            nbits=2,
            quant_lut=quant_lut,
        )

        mlmodel = MLModel(builder.spec)
        data = np.reshape(np.array([2.0, 2.0, 1.0, 0.0]), (4, 1))
        data_dict = {"data": data}
        out = mlmodel.predict(data_dict, useCPUOnly=True)["out"]
        expected_out = np.zeros((4, embed_size), dtype=np.float32)
        expected_out[0, :] = [quant_lut[W[0, 2]], quant_lut[W[1, 2]]] + bias
        expected_out[1, :] = [quant_lut[W[0, 2]], quant_lut[W[1, 2]]] + bias
        expected_out[2, :] = [quant_lut[W[0, 1]], quant_lut[W[1, 1]]] + bias
        expected_out[3, :] = [quant_lut[W[0, 0]], quant_lut[W[1, 0]]] + bias
        self.assertTrue(out.shape == expected_out.shape)
        self.assertTrue(np.allclose(out.flatten(), expected_out.flatten()))
示例#19
0
        def get_coreml_model_depthwise(X, params, w):
            eval = True
            mlmodel = None
            try:
                input_dim = X.shape[2:]
                input_features = [("data", datatypes.Array(*input_dim))]
                output_features = [("output", None)]
                builder = neural_network.NeuralNetworkBuilder(
                    input_features, output_features)
                # tranlate weights : (Kh, Kw, kernel_channels, output_channels) == (Kh, Kw, Cin/g, Cout) == (Kh, Kw, 1, channel_multiplier * Cin)
                w_e = np.reshape(
                    w,
                    (
                        params["kernel_size"],
                        params["kernel_size"],
                        params["multiplier"] * params["C"],
                        1,
                    ),
                )
                w_e = np.transpose(w_e, [0, 1, 3, 2])
                if params["padding"] == "SAME":
                    pad_mode = "same"
                else:
                    pad_mode = "valid"
                builder.add_convolution(
                    "conv",
                    kernel_channels=1,
                    output_channels=params["multiplier"] * params["C"],
                    height=params["kernel_size"],
                    width=params["kernel_size"],
                    stride_height=params["stride"],
                    stride_width=params["stride"],
                    border_mode=pad_mode,
                    groups=params["C"],
                    W=w_e,
                    b=None,
                    has_bias=0,
                    is_deconv=0,
                    output_shape=None,
                    input_name="data",
                    output_name="output",
                )

                if cpu_only:
                    compute_unit = ComputeUnit.CPU_ONLY
                else:
                    compute_unit = ComputeUnit.ALL
                mlmodel = MLModel(builder.spec, compute_units=compute_unit)
            except RuntimeError as e:
                print(e)
                eval = False
            return mlmodel, eval
示例#20
0
    def test_linear_quant_batchedmatmul_5bit(self):
        W = np.zeros((2, 3), dtype=np.uint8)
        W[0, :] = [31, 20, 11]
        W[1, :] = [1, 0, 8]
        quant_scale = np.reshape(np.array([10.0, 2.0, 3.0]), (1, 3))
        quant_bias = np.reshape(np.array([-2.0, -10.0, 6.0]), (1, 3))
        W_unquantized = np.broadcast_to(quant_scale, (2, 3)) * W + np.broadcast_to(
            quant_bias, (2, 3)
        )
        bias = np.array([1.0, 2.0, 3.0])

        input_features = [("data", datatypes.Array(2, 2))]
        output_features = [("out", None)]
        builder = NeuralNetworkBuilder(
            input_features, output_features, disable_rank5_shape_mapping=True
        )
        builder.add_batched_mat_mul(
            name="batched_matmul",
            input_names=["data"],
            output_name="out",
            weight_matrix_rows=2,
            weight_matrix_columns=3,
            W=_convert_array_to_nbit_quantized_bytes(W.flatten(), 5).tobytes(),
            bias=bias,
            is_quantized_weight=True,
            quantization_type="linear",
            nbits=5,
            quant_scale=quant_scale.flatten(),
            quant_bias=quant_bias.flatten(),
        )
        mlmodel = MLModel(builder.spec)
        data = np.zeros((2, 2), dtype=np.float32)
        data[0, :] = [5, 6]
        data[1, :] = [10, 12]
        data_dict = {"data": data}
        out = mlmodel.predict(data_dict, useCPUOnly=True)["out"]
        expected_out = np.matmul(data, W_unquantized) + bias
        self.assertTrue(out.shape == expected_out.shape)
        self.assertTrue(np.allclose(out.flatten(), expected_out.flatten()))
示例#21
0
    def test_mlmodel_to_spec_to_mlmodel_with_no_weights_model(self):
        """
        convert mlmodel to spec, and then back to mlmodel and verify that it works
        """
        spec = self.mlmodel_no_weights.get_spec()
        # if no weights_dir is passed, error will be raised
        with pytest.raises(Exception, match="MLModel of type mlProgram cannot be loaded just from the model "
                                             "spec object. It also needs the path to the weights file. "
                                             "Please provide that as well, using the 'weights_dir' argument."):
            MLModel(spec)

        # weights_dir will still exist, even though the model has no weights,
        # with a weights file that only has header and no data
        weights_dir = self.mlmodel_no_weights.weights_dir
        assert weights_dir is not None
        mlmodel_from_spec = MLModel(spec, weights_dir=weights_dir)
        self._test_mlmodel_correctness(mlmodel_from_spec)

        # load mlmodel from spec using an empty weights_dir
        with tempfile.TemporaryDirectory() as empty_weight_dir:
            mlmodel_from_spec = MLModel(spec, weights_dir=weights_dir)
            self._test_mlmodel_correctness(mlmodel_from_spec)
示例#22
0
 def _test_mlmodel_correctness(self, mlmodel):
     """
     :param mlmodel: coremltools.models.MLModel
     Test the following:
     - calling .predict on mlmodel works correctly
     - calling .save on mlmodel works correctly
     """
     # construct input dictionary
     spec = mlmodel.get_spec()
     inputs = spec.description.input
     input_dict = {}
     for input in inputs:
         input_dict[input.name] = np.random.rand(*tuple(input.type.multiArrayType.shape))
     # check prediction
     preds = mlmodel.predict(input_dict)
     assert preds is not None
     # save, load and predict again to check that the saving and loading worked correctly
     with tempfile.TemporaryDirectory(suffix=utils._MLPACKAGE_EXTENSION) as temp_path:
         mlmodel.save(temp_path)
         mlmodel_reloaded = MLModel(temp_path)
         preds = mlmodel_reloaded.predict(input_dict)
         assert preds is not None
示例#23
0
def make_updatable(builder, mlmodel_url, mlmodel_updatable_path):
    """This method makes an existing non-updatable mlmodel updatable.
    mlmodel_url - the path the Core ML model is stored.
    mlmodel_updatable_path - the path the updatable Core ML model will be saved.
    """
    import coremltools
    model_spec = builder.spec

    # make_updatable method is used to make a layer updatable. It requires a list of layer names.
    # dense_1 and dense_2 are two innerProduct layer in this example and we make them updatable.
    builder.make_updatable(['dense_1', 'dense_2'])

    # Categorical Cross Entropy or Mean Squared Error can be chosen for the loss layer.
    # Categorical Cross Entropy is used on this example. CCE requires two inputs: 'name' and 'input'.
    # name must be a string and will be the name associated with the loss layer
    # input must be the output of a softmax layer in the case of CCE.
    # The loss's target will be provided automatically as a part of the model's training inputs.
    builder.set_categorical_cross_entropy_loss(name='lossLayer',
                                               input='digitProbabilities')

    # in addition of the loss layer, an optimizer must also be defined. SGD and Adam optimizers are supported.
    # SGD has been used for this example. To use SGD, one must set lr(learningRate) and batch(miniBatchSize) (momentum is an optional parameter).
    from coremltools.models.neural_network import SgdParams
    builder.set_sgd_optimizer(SgdParams(lr=0.01, batch=32))

    # Finally, the number of epochs must be set as follows.
    builder.set_epochs(10)

    # Set training inputs descriptions
    model_spec.description.trainingInput[
        0].shortDescription = 'Example image of handwritten digit'
    model_spec.description.trainingInput[
        1].shortDescription = 'Associated true label (digit) of example image'

    # save the updated spec
    from coremltools.models import MLModel
    mlmodel_updatable = MLModel(model_spec)
    mlmodel_updatable.save(mlmodel_updatable_path)
示例#24
0
 def test_weights_path_correctness(self):
     """
     test that after reloading an mlmodel from the spec, the weights path is updated
     """
     spec = self.mlmodel.get_spec()
     original_weight_dir_path = self.mlmodel.weights_dir
     assert os.path.exists(original_weight_dir_path)
     # load mlmodel from spec: this will create a new mlpackage in a temp location
     # and copy over the weights
     mlmodel_reloaded = MLModel(spec, weights_dir=original_weight_dir_path)
     assert os.path.exists(mlmodel_reloaded.weights_dir)
     assert mlmodel_reloaded.weights_dir != original_weight_dir_path
     assert mlmodel_reloaded.weights_dir == mlmodel_reloaded.package_path + "/Data/" \
                                             + _MLPACKAGE_AUTHOR_NAME + "/weights"
示例#25
0
 def test_linear_quant_inner_product_3bit(self):
     W = np.reshape(np.arange(6), (2,3)).astype(np.uint8)
     input_features = [('data', datatypes.Array(3))]
     output_features = [('probs', None)]
     builder = NeuralNetworkBuilder(input_features, output_features)
     builder.add_inner_product(name = 'ip1',
                               W = _convert_array_to_nbit_quantized_bytes(W.flatten(), 3).tobytes(),
                               b = None,
                               input_channels = 3,
                               output_channels = 2,
                               has_bias = False,
                               input_name = 'data',
                               output_name = 'probs',
                               quantization_type = 'linear',
                               nbits = 3,
                               quant_scale = [11.0, 2.0],
                               quant_bias = [-2.0, 10.0])
     mlmodel = MLModel(builder.spec)
     data = np.array([1.0, 3.0, 5.0])
     data_dict = {'data': data}
     probs = mlmodel.predict(data_dict)['probs']
     expected_out = np.array([125, 170])
     self.assertTrue(np.allclose(probs.flatten(), expected_out.flatten()))
示例#26
0
 def test_rename_image_input(self):
     input_features = [("data", datatypes.Array(3, 1, 1))]
     output_features = [("out", datatypes.Array(3, 1, 1))]
     builder = NeuralNetworkBuilder(input_features,
                                    output_features,
                                    disable_rank5_shape_mapping=True)
     builder.add_activation("linear", "LINEAR", "data", "out")
     spec = builder.spec
     # make an image input
     mlmodel = make_image_input(MLModel(spec),
                                "data",
                                image_format="NCHW",
                                scale=2.0)
     # rename the input
     spec = mlmodel.get_spec()
     rename_feature(spec, "data", "new_input_name")
     mlmodel = MLModel(spec)
     # test
     x = np.array([4, 5, 6], dtype=np.uint8).reshape(1, 1, 3)
     pil_img = PIL.Image.fromarray(x)
     out = mlmodel.predict({"new_input_name": pil_img},
                           useCPUOnly=True)['out']
     np.testing.assert_equal(out,
                             np.array([8.0, 10.0, 12.0]).reshape(3, 1, 1))
示例#27
0
def mlCreateAndSaveModel():
    model = globalModel['model']
    features = globalModel['features']
    target = globalModel['target']
    if globalModel['converter'] == Converters.sklearn:
        coreml_model = coremltools.converters.sklearn.convert(
            model, features, target)
    else:
        coreml_model = coremltools.converters.xgboost.convert(
            model, features, target)

    coreml_model.save(globalModel['name'] + '.mlmodel')
    loaded_model = MLModel(globalModel['name'] + '.mlmodel')

    return True
    def test_can_init_and_save_model_from_builder_with_updated_spec(self):
        builder = KNearestNeighborsClassifierBuilder(
            input_name='input',
            output_name='output',
            number_of_dimensions=10,
            default_class_label='defaultLabel',
            k=3,
            weighting_scheme='inverse_distance',
            index_type='kd_tree',
            leaf_size=50)
        builder.author = 'CoreML Team'
        builder.license = 'MIT'
        builder.description = 'test_builder_with_validation'

        # Save the updated spec
        coreml_model = MLModel(builder.spec)
        self.assertIsNotNone(coreml_model)
        coreml_model_path = '/tmp/__test_builder_with_validation.mlmodel'

        try:
            coreml_model.save(coreml_model_path)
            self.assertTrue(os.path.isfile(coreml_model_path))
        finally:
            self._delete_mlmodel_and_mlmodelc(coreml_model_path)
    def test_nn_fp16_make_updatable_fail(self):
        nn_builder = self.create_base_builder(is_updatable=False)
        model_path = os.path.join(self.model_dir, "updatable_creation.mlmodel")
        print(model_path)
        save_spec(nn_builder.spec, model_path)
        mlmodel = MLModel(model_path)

        quantized_model = quantization_utils.quantize_weights(
            mlmodel, 16, "linear")

        q_nn_builder = NeuralNetworkBuilder(spec=quantized_model._spec)

        # fails since an FP16 model cannot be marked updatable
        with self.assertRaises(ValueError):
            q_nn_builder.make_updatable(["ip1", "ip2"])
示例#30
0
 def test_lut_quant_inner_product_1bit(self):
     W = np.zeros((2,3), dtype=np.uint8)
     W[0,:] = [0,1,1]
     W[1,:] = [1,0,0]
     input_features = [('data', datatypes.Array(3))]
     output_features = [('probs', None)]
     builder = NeuralNetworkBuilder(input_features, output_features)
     builder.add_inner_product(name = 'ip1',
                               W = _convert_array_to_nbit_quantized_bytes(W.flatten(), 1).tobytes(),
                               b = None,
                               input_channels = 3,
                               output_channels = 2,
                               has_bias = False,
                               input_name = 'data',
                               output_name = 'probs',
                               quantization_type = 'lut',
                               nbits = 1,
                               quant_lut = [5.0, -3.0])
     mlmodel = MLModel(builder.spec)
     data = np.array([1.0, 3.0, 5.0])
     data_dict = {'data': data}
     probs = mlmodel.predict(data_dict)['probs']
     expected_out = np.array([-19, 37])
     self.assertTrue(np.allclose(probs.flatten(), expected_out.flatten()))
示例#31
0
        def get_coreml_model_reorganize(X, params):
            eval = True
            mlmodel = None
            try:
                input_dim = X.shape[2:]
                input_features = [('data', datatypes.Array(*input_dim))]
                output_features = [('output', None)]
                builder = neural_network.NeuralNetworkBuilder(input_features, output_features)
                builder.add_reorganize_data('reorg', 'data', 'output', mode=params["mode"],
                                            block_size=params["block_size"])
                mlmodel = MLModel(builder.spec)
            except RuntimeError as e:
                print(e)
                eval = False

            return mlmodel, eval
    def test_nn_partial_fp16_make_updatable_quantized_layer_fail(self):
        nn_builder = self.create_base_builder(is_updatable=False)
        model_path = os.path.join(self.model_dir, "updatable_creation.mlmodel")
        print(model_path)
        save_spec(nn_builder.spec, model_path)
        mlmodel = MLModel(model_path)

        selector = LayerSelector(layer_name='ip2')
        quantized_model = quantization_utils.quantize_weights(
            mlmodel, 16, "linear", selector=selector)

        q_nn_builder = NeuralNetworkBuilder(spec=quantized_model._spec)

        # fails since model has a layer with FP16 bias
        with self.assertRaises(ValueError):
            q_nn_builder.make_updatable(["ip2"])