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)
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")
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)
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")
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, )
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)
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)
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
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()
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)
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))
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))
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 )
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)
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)
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()))
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()))
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
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()))
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)
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
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)
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"
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()))
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))
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"])
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()))
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"])