def export_coreml(config, frozen_graph_path, enable_saliency_maps=False): checkpoint_dir = config['checkpoint_path'] model_name = config['model_name'] output_mlmodel_path = os.path.join(checkpoint_dir, 'plant.mlmodel') model_extra_kwargs_dict = { 'resnet_v2_50': { 'red_bias': -123.68, 'green_bias': -116.78, 'blue_bias': -103.94, }, 'mobilenet_v1': { 'red_bias': -1.0, 'green_bias': -1.0, 'blue_bias': -1.0, 'image_scale': 2.0 / 255., } } tfcoreml.convert(tf_model_path=frozen_graph_path, mlmodel_path=output_mlmodel_path, output_feature_names=[ '{}:0'.format( get_node_names( model_name, enable_saliency_maps=enable_saliency_maps)) ], image_input_names=['input:0'], input_name_shape_dict={'input:0': [1, 224, 224, 3]}, **model_extra_kwargs_dict.get(model_name, {}))
def pb2coreml(pb_path='./frozen_graph.pb', save_path='./model.mlmodel', input_tensor_shapes={'x': [1, 640, 640, 3]}, image_scale=1.0 / 255.0, output_tensor_names=['Identity'], ios_version='13'): import tfcoreml """ example pb_path = './frozen_graph.pb' input_tensor_shapes = {"x:0": [1, 32, 32, 9]} # Output CoreML model path save_path = './model.mlmodel' output_tensor_name = ['Identity:0'] """ tfcoreml.convert(tf_model_path=pb_path, mlmodel_path=save_path, input_name_shape_dict=input_tensor_shapes, output_feature_names=output_tensor_names, image_scale=image_scale, minimum_ios_deployment_target=ios_version) print("converted!")
def convert_and_export(self): ckpt_path = self._import_model_dir + self._ckptfile_name export_pb_path = self._import_model_dir + self._pb_name export_frozenpb_path = self._export_model_dir + self._frozen_pb_name export_tflite_path = self._export_model_dir + self._tflite_name export_mlmodel_path = self._export_model_dir + self._mlmodel_name # check_variable_name = 'model/reception/reception/reception_conv7x7_out/weights' # chkp.print_tensors_in_checkpoint_file(ckpt_path, # tensor_name=check_variable_name, # all_tensors= False) with tf.Session(graph=self._input_graph) as sess: tf.logging.info('------------------------------------------') # sess.run(self._init_op) self._saver.restore(sess,ckpt_path) # export pb tf.train.write_graph(graph_or_graph_def=sess.graph_def, logdir=self._import_model_dir, name=self._pb_name, as_text=False) tf.logging.info('[ConvertorToMobileFormat] pb is generated.') self._graph_def = sess.graph_def # # check collect loading # sample_of_restored_var = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, # scope=check_variable_name) # np_restored_var = sample_of_restored_var[0].eval() # tflite generation toco = tf.contrib.lite.TocoConverter.from_session(sess=sess, input_tensors=[self._model_in], output_tensors=[self._model_out]) tflite_model = toco.convert() # frozen pb generation for coreml self._frozen_graph_def = tf.graph_util.convert_variables_to_constants( sess=sess, input_graph_def=sess.graph_def, output_node_names=self._output_node_name.replace(" ","").split(",")) with tf.gfile.GFile(export_frozenpb_path,'wb') as f: f.write(self._frozen_graph_def.SerializeToString()) tf.logging.info('[ConvertorToMobileFormat] frozen pb is generated.') with tf.gfile.GFile(export_tflite_path,'wb') as f: f.write(tflite_model) tf.logging.info('[ConvertorToMobileFormat] tflite is generated.') # mlmodel (coreml) generation mlmodel_converter.convert(tf_model_path=export_frozenpb_path, mlmodel_path=export_mlmodel_path, image_input_names=["%s:0" % self._input_node_name], output_feature_names=["%s:0" % self._output_node_name]) tf.logging.info('[ConvertorToMobileFormat] mlmodel is generated.')
def convert_pb_to_core_model(tf_model_path: str, mlmodel_path: str, output_feature_names: list, input_name_shape_dict: dict = None): tfcoreml.convert(tf_model_path=tf_model_path, mlmodel_path=mlmodel_path, output_feature_names=output_feature_names, input_name_shape_dict=input_name_shape_dict)
def convert_to_core_ml(exported_graph_path, model_structure, output_path): import tfcoreml if not os.path.exists('.tmp'): os.makedirs('.tmp') if os.path.exists(output_path) and os.path.isdir(output_path): shutil.rmtree(output_path) os.makedirs(output_path) if model_structure['type'] == ModelType.LOCALIZATION: convert_ssd(exported_graph_path, model_structure, output_path) else: frozen_model_file = '.tmp/tmp_frozen_graph.pb' with tf.Session(graph=tf.Graph()) as sess: saved_model_path = os.path.join(exported_graph_path, 'saved_model/') tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], saved_model_path) with gfile.GFile(frozen_model_file, 'wb') as f: output_graph_def = tf.graph_util.convert_variables_to_constants( sess, tf.get_default_graph().as_graph_def(), model_structure['output_names']) f.write(output_graph_def.SerializeToString()) output_feature_names = [ '{}:0'.format(name) for name in model_structure['output_names'] ] class_labels = None json_labels = os.path.join(exported_graph_path, 'labels.json') text_labels = os.path.join(exported_graph_path, 'labels.txt') if os.path.isfile(text_labels): with open(text_labels, 'r') as f: class_labels = f.read() class_labels = list( filter(bool, [s.strip() for s in class_labels.splitlines()])) elif os.path.isfile(json_labels): with open(json_labels) as f: class_labels = json.load(f) tfcoreml.convert( tf_model_path=frozen_model_file, mlmodel_path=os.path.join(output_path, 'Model.mlmodel'), output_feature_names=output_feature_names, class_labels=class_labels, red_bias=-1, green_bias=-1, blue_bias=-1, image_scale=1.0 / 128.0, image_input_names='{}:0'.format(model_structure['input_name']))
def export_to_coreml(model_name): import tfcoreml tfcoreml.convert( mlmodel_path='frozen/' + model_name + '.mlmodel', tf_model_path='frozen/' + model_name + '.pb', output_feature_names=[ 'output/strided_slice_4:0', 'output/strided_slice:0' ], input_name_shape_dict={"output/Placeholder:0": [1536, 1152, 3]}, image_input_names="output/Placeholder:0")
def create_coreml_model(model_dir, args): # coreml変換 tf_converter.convert(tf_model_path=os.path.join(model_dir, "original_98_frozen.pb"), mlmodel_path=os.path.join(model_dir, 'pfld.mlmodel'), input_name_shape_dict={ 'image_batch:0': [1, args.image_size, args.image_size, 3] }, output_feature_names=['fc/BiasAdd:0'], add_custom_layers=True)
def main(): parser = build_parser() opts = parser.parse_args() #check_opts(opts) tf_converter.convert( tf_model_path='../style-transfer-models/pb/' + opts.pb_output + '.pb', mlmodel_path='../style-transfer-models/mlmodel/temp.mlmodel', output_feature_names=['add_37:0'], ## Note found this after running a conversion the first time image_input_names=['img_placeholder__0'])
def generate_mlmodel(ckpt_dir, filename): tf_converter.convert(tf_model_path=ckpt_dir + '/' + filename + '.pb', mlmodel_path=ckpt_dir + '/' + filename + '.mlmodel', output_feature_names=['add_37:0'], image_input_names=['img_placeholder__0']) model = coremltools.models.MLModel(ckpt_dir + '/' + filename + '.mlmodel') spec = model.get_spec() convert_multiarray_output_to_image(spec, 'add_37__0', is_bgr=False) new_model = coremltools.models.MLModel(spec) new_model.save(ckpt_dir + '/' + filename + '_output.mlmodel') convert_flexible_coremodel(ckpt_dir + '/' + filename + '_output.mlmodel', 'img_placeholder__0', 'add_37__0')
def export(model, path, method="default"): import shutil import subprocess import sys global_path = model[0] technology = model[1] outputed_files = model[2] if technology == "tensorflow" and len(outputed_files) == 2: if method == "default" and type(path) == list: for i in range(len(outputed_files)): shutil.copy2(outputed_files[i], path[i]) elif method == "tflite": import neuron_ml.tools.subprocess_checker as valid if valid.command("toco"): command = [ "toco", "--graph_def_file", outputed_files[0], "--output_file", path, "--input_arrays", "Placeholder", "--output_arrays", "final_result" ] print(" ".join(command)) process = subprocess.Popen(command, stdout=subprocess.PIPE) for line in iter(lambda: process.stdout.read(1), b''): sys.stdout.buffer.write(line) else: raise ValueError( "[Neuron - Export] ERROR: TOCO not found. Please install TensorFlow's TOCO cli." ) return elif method == "coreml": import tfcoreml as tf_converter tf_converter.convert(tf_model_path=outputed_files[0], mlmodel_path=path, output_feature_names=['final_result:0'], image_input_names='input', class_labels=outputed_files[1], red_bias=-1, green_bias=-1, blue_bias=-1, image_scale=2.0 / 299.0) else: raise ValueError( "[Neuron - Export] ERROR: Wrong arguments. See the wiki for help." ) return elif technology == "createml" and method == "default": shutil.copy2(outputed_files[0], path) else: raise ValueError( "[Neuron - Export] ERROR: Wrong arguments. See the wiki for help.") return print("[Neuron - Export] All file where exported.")
def main(): parser = ArgumentParser() parser.add_argument("--input_graph", type=str, default="", help="TensorFlow .pbtxt file to convert.") input_graph = parser.parse_args().input_graph tf_converter.convert(tf_model_path=input_graph, mlmodel_path=replace_extension( input_graph, '.mlmodel'), output_feature_names=[ 'bbox/trimming/bbox', 'probability/score', 'probability/class_idx' ])
def test_googlenet_v1_nonslim(self): #Download model url = 'https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'tensorflow_inception_graph.pb') #Convert to coreml mlmodel_path = os.path.join(TMP_MODEL_DIR, 'googlenet_v1_nonslim.mlmodel') mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['softmax2:0'], input_name_shape_dict = {'input:0':[1,224,224,3]}, image_input_names = ['input:0'], red_bias = -1, green_bias = -1, blue_bias = -1, image_scale = 2.0/255.0) #Test predictions on an image self._test_coreml_model_image_input( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensor_name = 'input:0', output_tensor_name = 'softmax2:0', img_size = 224)
def test_inception_v3_slim(self): #Download model url = 'https://storage.googleapis.com/download.tensorflow.org/models/inception_v3_2016_08_28_frozen.pb.tar.gz' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'inception_v3_2016_08_28_frozen.pb') #Convert to coreml mlmodel_path = os.path.join(TMP_MODEL_DIR, 'inception_v3_2016_08_28.mlmodel') mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['InceptionV3/Predictions/Softmax:0'], input_name_shape_dict = {'input:0':[1,299,299,3]}, image_input_names = ['input:0'], red_bias = -1, green_bias = -1, blue_bias = -1, image_scale = 2.0/255.0) #Test predictions on an image self._test_coreml_model_image_input( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensor_name = 'input:0', output_tensor_name = 'InceptionV3/Predictions/Softmax:0', img_size = 299)
def main(args): if args.type == 'FLOAT32': if args.model_dir[-3:] != '.pb': print("Error: the model type must be .pb file") return else: coreml_model = tfcoreml.convert( tf_model_path=args.model_dir, mlmodel_path=args.output_file, input_name_shape_dict={'input': [1, 160, 160, 3]}, output_feature_names=["embeddings"], minimum_ios_deployment_target='13') return else: if args.model_dir[-8:] != '.mlmodel': print("Error: the model type must be .mlmodel") return if args.type == 'FLOAT16': model_spec = coremltools.utils.load_spec(args.model_dir) model_fp16_spec = coremltools.utils.convert_neural_network_spec_weights_to_fp16( model_spec) coremltools.utils.save_spec(model_fp16_spec, args.output_file) return else: model = coremltools.models.MLModel(args.model_dir) bit = int(args.type[-1]) print("quantization in INT" + str(bit)) quantized_model = quantization_utils.quantize_weights( model, bit, "linear") quantized_model.save(args.output_file) return print('File correctly saved in:', args.output_file)
def convert_pb_to_coreml(path_pb, path_coreml, input_shape, tensor_name): coreml_model = tfcoreml.convert(tf_model_path=path_pb, mlmodel_path=path_coreml, image_input_names='data', input_name_shape_dict=input_shape, output_feature_names=tensor_name) return coreml_model
def test_style_transfer(self): url = 'https://storage.googleapis.com/download.tensorflow.org/models/stylize_v1.zip' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'stylize_quantized.pb') mlmodel_path = os.path.join(TMP_MODEL_DIR, 'stylize_quantized.mlmodel') # ? style transfer image size and style number? mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['Squeeze:0'], input_name_shape_dict = {'input:0':[1,256,256,3], 'style_num:0':[26]}) # Test predictions on an image input_tensors = [('input:0',[1,256,256,3]), ('style_num:0',[26])] self.err_thresh = 0.5 self._test_tf_model( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensors = input_tensors, output_tensor_names = ['Squeeze:0'], data_modes = ['image', 'onehot_0'], delta = 1e-2, use_cpu_only = True, scale = 1, bias = 0, img_size = 256, sequence_inputs = {'style_num:0'})
def test_mobilenet_v1_50_160(self): url = 'https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_0.50_160_frozen.tgz' tf_model_dir = _download_file(url=url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'mobilenet_v1_0.50_160/frozen_graph.pb') mlmodel_path = os.path.join(TMP_MODEL_DIR, 'mobilenet_v1_0.50_160.mlmodel') mlmodel = tf_converter.convert( tf_model_path=tf_model_path, mlmodel_path=mlmodel_path, output_feature_names=['MobilenetV1/Predictions/Softmax:0'], input_name_shape_dict={'input:0': [1, 160, 160, 3]}, image_input_names=['input:0'], red_bias=-1, green_bias=-1, blue_bias=-1, image_scale=2.0 / 255.0) #Test predictions on an image self._test_coreml_model_image_input( tf_model_path=tf_model_path, coreml_model=mlmodel, input_tensor_name='input:0', output_tensor_name='MobilenetV1/Predictions/Softmax:0', img_size=160)
def evaluate_and_convert_model(numConvNeurons, numRegNeurons): # flatten image array, build model with arbitrary number of hidden units and 10 output units (for numbers between 0 and 9) model = create_model(numConvNeurons, numRegNeurons) # evaluate model accuracy on test data finalLoss, finalAccuracy = model.evaluate(inp_test, out_test, verbose=1) # display results print("accuracy on test data is ", finalAccuracy) model.save('finalModel.h5', save_format="h5") # get input, output node names for the TF graph from the Keras model input_name = model.inputs[0].name.split(':')[0] keras_output_node_name = model.outputs[0].name.split(':')[0] graph_output_node_name = keras_output_node_name.split('/')[-1] print(model.outputs) converted_model = tfcoreml.convert( tf_model_path='finalModel.h5', image_input_names=input_name, input_name_shape_dict={input_name: (1, 28, 28, 1)}, output_feature_names=[graph_output_node_name], minimum_ios_deployment_target='13', image_scale=1.0 / 255.0) converted_model.author = 'Sonia' converted_model.short_description = 'Handwritten Digit Recognition with MNIST dataset' converted_model.save('myDigitRecognitionModel.mlmodel')
def test_googlenet_v1_slim_with_img_format(self): url = 'https://storage.googleapis.com/download.tensorflow.org/models/inception_v1_2016_08_28_frozen.pb.tar.gz' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'inception_v1_2016_08_28_frozen.pb') mlmodel_path = os.path.join(TMP_MODEL_DIR, 'inception_v1_2016_08_28_frozen.mlmodel') mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['InceptionV1/Logits/Predictions/Softmax:0'], input_name_shape_dict = {'input:0':[1,224,224,3]}, image_input_names = ['input:0'], red_bias = -1, green_bias = -1, blue_bias = -1, image_scale = 2.0/255.0, tf_image_format='NHWC') #Test predictions on an image self._test_coreml_model_image_input( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensor_name = 'input:0', output_tensor_name = 'InceptionV1/Logits/Predictions/Softmax:0', img_size = 224)
def main(): parser = build_parser() options = parser.parse_args() ckpt_dir = options.checkpoint_dir filename = options.file_name g = tf.Graph() soft_config = tf.ConfigProto(allow_soft_placement=True) soft_config.gpu_options.allow_growth = True with g.as_default(), tf.device('/cpu:0'), tf.Session( config=soft_config) as sess: # batch_shape = (batch_size,) + img_shape img_placeholder = tf.placeholder(tf.float32, shape=(batch_size, 256, 256, 3), name='img_placeholder') preds = transform.net(img_placeholder) saver = tf.train.Saver() if os.path.isdir(ckpt_dir): ckpt = tf.train.get_checkpoint_state(ckpt_dir) if ckpt and ckpt.model_checkpoint_path: saver.restore(sess, ckpt.model_checkpoint_path) frozen_graph_def = tf.graph_util.convert_variables_to_constants( sess, sess.graph_def, ['add_37']) with open(ckpt_dir + '/' + filename + '.pb', 'wb') as f: f.write(frozen_graph_def.SerializeToString()) else: raise Exception("No checkpoint found...") else: saver.restore(sess, ckpt_dir) frozen_graph_def = tf.graph_util.convert_variables_to_constants( sess, sess.graph_def, ['add_37']) with open(ckpt_dir + '/' + filename + '.pb', 'wb') as f: f.write(frozen_graph_def.SerializeToString()) tf_converter.convert(tf_model_path=ckpt_dir + '/' + filename + '.pb', mlmodel_path=ckpt_dir + '/' + filename + '.mlmodel', output_feature_names=['add_37:0'], image_input_names=['img_placeholder__0']) model = coremltools.models.MLModel(ckpt_dir + '/' + filename + '.mlmodel') # lin_quant_model = quantize_weights(model, 8, "linear") # lin_quant_model.save(ckpt_dir + '/' + filename + '.mlmodel') spec = model.get_spec() convert_multiarray_output_to_image(spec, 'add_37__0', is_bgr=False) new_model = coremltools.models.MLModel(spec) new_model.save(ckpt_dir + '/' + filename + '_output.mlmodel') convert_flexible_coremodel(ckpt_dir + '/' + filename + '_output.mlmodel', 'img_placeholder__0', 'add_37__0')
def convert_to_core_ml(exported_graph_path, model_structure, output_path): import tfcoreml if not os.path.exists('.tmp'): os.makedirs('.tmp') if os.path.exists(output_path) and os.path.isdir(output_path): shutil.rmtree(output_path) os.makedirs(output_path) if model_structure['type'] == ModelType.LOCALIZATION: convert_ssd(exported_graph_path, model_structure, output_path) else: frozen_model_file = '.tmp/tmp_frozen_graph.pb' with tf.Session(graph=tf.Graph()) as sess: saved_model_path = os.path.join(exported_graph_path, 'saved_model/') tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], saved_model_path) with gfile.GFile(frozen_model_file, 'wb') as f: output_graph_def = tf.graph_util.convert_variables_to_constants( sess, tf.get_default_graph().as_graph_def(), model_structure['output_names']) f.write(output_graph_def.SerializeToString()) output_feature_names = ['{}:0'.format(name) for name in model_structure['output_names']] class_labels = None json_labels = os.path.join(exported_graph_path, 'labels.json') text_labels = os.path.join(exported_graph_path, 'labels.txt') if os.path.isfile(text_labels): with open(text_labels, 'r') as f: class_labels = f.read() class_labels = list(filter(bool, [s.strip() for s in class_labels.splitlines()])) elif os.path.isfile(json_labels): with open(json_labels) as f: class_labels = json.load(f) tfcoreml.convert(tf_model_path=frozen_model_file, mlmodel_path=os.path.join(output_path, 'Model.mlmodel'), output_feature_names=output_feature_names, class_labels=class_labels, red_bias=-1, green_bias=-1, blue_bias=-1, image_scale=1.0/128.0, image_input_names='{}:0'.format(model_structure['input_name']))
def _convert_to_coreml(tf_model_path, mlmodel_path, input_name_shape_dict, output_names): """ Convert and return the coreml model from the Tensorflow """ model = tf_converter.convert(tf_model_path=tf_model_path, mlmodel_path=mlmodel_path, output_feature_names=output_names, input_name_shape_dict=input_name_shape_dict) return model
def _convert_to_coreml(tf_model_path, mlmodel_path, input_name_shape_dict, output_names,add_custom_layers=False,custom_conversion_functions={}): """ Convert and return the coreml model from the Tensorflow """ model = tf_converter.convert(tf_model_path=tf_model_path, mlmodel_path=mlmodel_path, output_feature_names=output_names, input_name_shape_dict=input_name_shape_dict, add_custom_layers=add_custom_layers, custom_conversion_functions=custom_conversion_functions) return model
def convert_classification(frozen_model, labels_path, output_path): os.makedirs(output_path, exist_ok=True) tfcoreml.convert( tf_model_path=frozen_model, mlmodel_path=os.path.join(output_path, "Model.mlmodel"), input_name_shape_dict={ "Placeholder": [1, 224, 224, 3], "input/BottleneckInputPlaceholder": [-1, 1024], }, image_input_names=["Placeholder"], output_feature_names=["final_result"], class_labels=labels_path, is_bgr=False, red_bias=-1.0, green_bias=-1.0, blue_bias=-1.0, image_scale=2.0 / 255, minimum_ios_deployment_target="13", )
def convert2(model_id, model_dir=MODEL_DIR): model_ord = model_id_to_ord(model_id) cfg = load_config() print(cfg) checkpoints = cfg['checkpoints'] print(checkpoints) imageSize = cfg['imageSize'] print(imageSize) chkpoint = checkpoints[model_ord] width = imageSize height = imageSize if not os.path.exists(model_dir): os.makedirs(model_dir) # Provide these to run freeze_graph: # Graph definition file, stored as protobuf TEXT #graph_def_file = './models/model.pbtxt' # Frozen model's output name frozen_model_file = os.path.join(model_dir, "model-%s.pb" % chkpoint) coreml_model_file = os.path.join(model_dir, "model-%s.mlmodel" % chkpoint) # Output nodes. If there're multiple output ops, use comma separated string, e.g. "out1,out2". output_node_names = 'heatmap,offset_2,displacement_fwd_2,displacement_bwd_2' # output_node_names = 'Softmax' input_tensor_shapes = {"image:0": [1, imageSize, imageSize, 3]} # output_tensor_names = ['output:0'] output_tensor_names = [ 'heatmap:0', 'offset_2:0', 'displacement_fwd_2:0', 'displacement_bwd_2:0' ] coreml_model = tfcoreml.convert(tf_model_path=frozen_model_file, mlmodel_path=coreml_model_file, input_name_shape_dict=input_tensor_shapes, image_input_names=['image:0'], output_feature_names=output_tensor_names, is_bgr=False, red_bias=-1, green_bias=-1, blue_bias=-1, image_scale=2. / 255) # use_coreml_3=True,) coreml_model.author = 'joker2017' coreml_model.license = 'MIT' coreml_model.short_description = 'Ver.0.0.1' coreml_model.save(model_dir + '/posenet' + str(imageSize) + '_' + chkpoint + '.mlmodel') print("Model for CoreML saving")
def _convert_to_coreml(tf_model_path, mlmodel_path, input_name_shape_dict, output_names, add_custom_layers=False, custom_conversion_functions={}, custom_shape_functions={}, minimum_ios_deployment_target='12'): """ Convert and return the coreml model from the Tensorflow """ model = tf_converter.convert(tf_model_path=tf_model_path, mlmodel_path=mlmodel_path, output_feature_names=output_names, input_name_shape_dict=input_name_shape_dict, add_custom_layers=add_custom_layers, custom_conversion_functions=custom_conversion_functions, custom_shape_functions=custom_shape_functions, minimum_ios_deployment_target=minimum_ios_deployment_target) return model
def run_inference_by_coreml(config, image_np, coreml_file_path=None): import coremltools import tfcoreml model_name = get_model_name(config) checkpoint_dir_path = get_checkpoint_dir_path(config) frozen_model_file = '%s/frozen_graph.pb' % checkpoint_dir_path coreml_model_file = coreml_file_path or '%s/plant.mlmodel' % checkpoint_dir_path image_np = pre_process(config, image_np, coreml=True) image = Image.fromarray(image_np.astype('int8'), 'RGB') input_tensor_shapes = { "input:0": [1, image_np.shape[0], image_np.shape[1], 3] } # batch size is 1 output_tensor_name = OUTPUT_MODEL_NODE_NAMES_DICT[model_name] + ":0" coreml_model = coremltools.models.MLModel(coreml_model_file) convert_model = False # convert_model = True if convert_model: extra_args = { 'resnet_v2_50': { 'red_bias': -_R_MEAN, 'green_bias': -_G_MEAN, 'blue_bias': -_B_MEAN, }, 'mobilenet_v1': { 'red_bias': -1.0, 'green_bias': -1.0, 'blue_bias': -1.0, 'image_scale': 2.0 / 255., } }[model_name] coreml_model = tfcoreml.convert( tf_model_path=frozen_model_file, mlmodel_path=coreml_model_file.replace('.mlmodel', '_test.mlmodel'), input_name_shape_dict=input_tensor_shapes, output_feature_names=[output_tensor_name], image_input_names=['input:0'], **extra_args) coreml_inputs = {'input__0': image} coreml_output = coreml_model.predict(coreml_inputs, useCPUOnly=False) # example output: 'resnet_v2_50__predictions__Reshape_1__0' probs = coreml_output[output_tensor_name.replace('/', '__').replace( ':', '__')].flatten() return probs
def tf2coreml(frozen_model_path, coreml_model_path, input_tensor_shapes, output_tensor_names): """ Step 2: Call converter """ # Provide these inputs in addition to inputs in Step 1 # A dictionary of input tensors' name and shape (with batch) # Call the converter coreml_model = tfcoreml.convert(tf_model_path=frozen_model_path, mlmodel_path=coreml_model_path, input_name_shape_dict=input_tensor_shapes, output_feature_names=output_tensor_names) return coreml_model
def coreml_convert(input_model_file, output_file, model_image_size): if input_model_file.endswith('.h5'): if not tf.__version__.startswith('2'): raise ValueError( 'tf.keras model convert only support in TF 2.x env') # tf.keras h5 model custom_object_dict = get_custom_objects() keras_model = load_model(input_model_file, custom_objects=custom_object_dict) # get input, output node names for the TF graph from tf.keras model # assume only 1 input input_name = keras_model.inputs[0].name.split(':')[0] output_names = [ output.name.split(':')[0].split('/')[-1] for output in keras_model.outputs ] assert len( output_names ) == 1, 'h5 model convert only support YOLOv2 family with 1 prediction output.' elif input_model_file.endswith('.pb'): # NOTE: TF 1.x frozen pb graph need to specify input/output tensor name # so we need to hardcode the input/output tensor names here to get them from model input_name = 'image_input' # YOLOv2 model with 1 prediction output #output_names = ['predict_conv/BiasAdd'] # Tiny YOLOv3 model with 2 prediction outputs output_names = ['predict_conv_1/BiasAdd', 'predict_conv_2/BiasAdd'] # YOLOv3 model with 3 prediction outputs #output_names = ['predict_conv_1/BiasAdd', 'predict_conv_2/BiasAdd', 'predict_conv_3/BiasAdd'] else: raise ValueError('unsupported model type') input_name_shape_dict = {input_name: (1, ) + model_image_size + (3, )} # convert to CoreML model file model = tfcoreml.convert(tf_model_path=input_model_file, mlmodel_path=output_file, input_name_shape_dict=input_name_shape_dict, output_feature_names=output_names, minimum_ios_deployment_target='13')
def write(self) : try : output_path = os.path.splitext(self.tf_model_path)[0] + ".mlmodel" with gfile.GFile(self.frozen_model_file, "wb") as f: f.write(self.gdef.SerializeToString()) self.coreml_model = tfcoreml.convert(tf_model_path = self.frozen_model_file, mlmodel_path = output_path, output_feature_names = self.output_feature_names, input_name_shape_dict = self.input_name_shape_dict, image_input_names="Preprocessor/sub:0", image_scale=2./255., red_bias=-1.0, green_bias=-1.0, blue_bias=-1.0) finally : if os.path.exists(self.frozen_model_file) : os.unlink(self.frozen_model_file)
def write(self): try: self.save_stripped_graph() self.coreml_model = tfcoreml.convert( tf_model_path=self.frozen_model_file, mlmodel_path=self.mlmodel_file, output_feature_names=self.output_feature_names, input_name_shape_dict=self.input_name_shape_dict, image_input_names=self._get_input_image_name(), is_bgr=False, image_scale=2. / 255., red_bias=-1.0, green_bias=-1.0, blue_bias=-1.0) finally: if os.path.exists(self.frozen_model_file): os.unlink(self.frozen_model_file)
def test_mobilenet_v1_50_160(self): url = 'https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_0.50_160_frozen.tgz' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'mobilenet_v1_0.50_160/frozen_graph.pb') mlmodel_path = os.path.join(TMP_MODEL_DIR, 'mobilenet_v1_0.50_160.mlmodel') mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['MobilenetV1/Predictions/Softmax:0'], input_name_shape_dict = {'input:0':[1,160,160,3]}, image_input_names = ['input:0'], red_bias = -1, green_bias = -1, blue_bias = -1, image_scale = 2.0/255.0) #Test predictions on an image self._test_coreml_model_image_input( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensor_name = 'input:0', output_tensor_name = 'MobilenetV1/Predictions/Softmax:0', img_size = 160)
# input_tensor_name = 'input:0', # output_tensor_name = 'InceptionV3/Predictions/Softmax:0', # img_size = 299) #Download model url = 'https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip' tf_model_dir = _download_file(url = url) tf_model_path = os.path.join(TMP_MODEL_DIR, 'tensorflow_inception_graph.pb') #Convert to coreml mlmodel_path = os.path.join(TMP_MODEL_DIR, 'googlenet_v1_nonslim.mlmodel') mlmodel = tf_converter.convert( tf_model_path = tf_model_path, mlmodel_path = mlmodel_path, output_feature_names = ['softmax2:0'], input_name_shape_dict = {'input:0':[1,224,224,3]}, image_input_names = ['input:0'], red_bias = -1, green_bias = -1, blue_bias = -1, image_scale = 2.0/255.0) #Test predictions on an image _test_coreml_model_image_input( tf_model_path = tf_model_path, coreml_model = mlmodel, input_tensor_name = 'input:0', output_tensor_name = 'softmax2:0', img_size = 224) print("convert ok!")
def convert_ssd(exported_graph_path, model_structure, output_path): num_anchors = 1917 saved_model_path = os.path.join(exported_graph_path, 'saved_model') coreml_model_path = os.path.join(output_path, 'Model.mlmodel') json_labels = os.path.join(exported_graph_path, 'labels.json') with open(json_labels) as f: labels = json.load(f) # Strip the model down to something usable by Core ML. # Instead of `concat_1`, use `Postprocessor/convert_scores`, because it # applies the sigmoid to the class scores. frozen_model_path = '.tmp/tmp_frozen_graph.pb' input_node = 'Preprocessor/sub' bbox_output_node = 'concat' class_output_node = 'Postprocessor/convert_scores' graph = optimize_graph(saved_model_path, frozen_model_path, [input_node], [bbox_output_node, class_output_node]) # conversion tensors have a `:0` at the end of the name input_tensor = input_node + ':0' bbox_output_tensor = bbox_output_node + ':0' class_output_tensor = class_output_node + ':0' # Convert to Core ML model. ssd_model = tfcoreml.convert( tf_model_path=frozen_model_path, mlmodel_path=coreml_model_path, input_name_shape_dict={ input_tensor: [1, 300, 300, 3] }, image_input_names=input_tensor, output_feature_names=[bbox_output_tensor, class_output_tensor], is_bgr=False, red_bias=-1.0, green_bias=-1.0, blue_bias=-1.0, image_scale=2./255) spec = ssd_model.get_spec() # Rename the inputs and outputs to something more readable. spec.description.input[0].name = 'image' spec.description.input[0].shortDescription = 'Input image' spec.description.output[0].name = 'scores' spec.description.output[0].shortDescription = 'Predicted class scores for each bounding box' spec.description.output[1].name = 'boxes' spec.description.output[1].shortDescription = 'Predicted coordinates for each bounding box' input_mlmodel = input_tensor.replace(':', '__').replace('/', '__') class_output_mlmodel = class_output_tensor.replace(':', '__').replace('/', '__') bbox_output_mlmodel = bbox_output_tensor.replace(':', '__').replace('/', '__') for i in range(len(spec.neuralNetwork.layers)): if spec.neuralNetwork.layers[i].input[0] == input_mlmodel: spec.neuralNetwork.layers[i].input[0] = 'image' if spec.neuralNetwork.layers[i].output[0] == class_output_mlmodel: spec.neuralNetwork.layers[i].output[0] = 'scores' if spec.neuralNetwork.layers[i].output[0] == bbox_output_mlmodel: spec.neuralNetwork.layers[i].output[0] = 'boxes' spec.neuralNetwork.preprocessing[0].featureName = 'image' # For some reason the output shape of the `scores` output is not filled in. spec.description.output[0].type.multiArrayType.shape.append(len(labels) + 1) spec.description.output[0].type.multiArrayType.shape.append(num_anchors) # And the `boxes` output shape is (4, 1917, 1) so get rid of that last one. del spec.description.output[1].type.multiArrayType.shape[-1] # Convert weights to 16-bit floats to make the model smaller. spec = coremltools.utils.convert_neural_network_spec_weights_to_fp16(spec) # Create a new MLModel from the modified spec and save it. ssd_model = coremltools.models.MLModel(spec) decoder_model = build_decoder(graph, len(labels), num_anchors) nms_model = build_nms(decoder_model, labels) input_features = [ ('image', datatypes.Array(3, 300, 300)), ('iouThreshold', datatypes.Double()), ('confidenceThreshold', datatypes.Double()) ] output_features = ['confidence', 'coordinates'] pipeline = Pipeline(input_features, output_features) # We added a dimension of size 1 to the back of the inputs of the decoder # model, so we should also add this to the output of the SSD model or else # the inputs and outputs do not match and the pipeline is not valid. ssd_output = ssd_model._spec.description.output ssd_output[0].type.multiArrayType.shape[:] = [len(labels) + 1, num_anchors, 1] ssd_output[1].type.multiArrayType.shape[:] = [4, num_anchors, 1] pipeline.add_model(ssd_model) pipeline.add_model(decoder_model) pipeline.add_model(nms_model) # The `image` input should really be an image, not a multi-array. pipeline.spec.description.input[0].ParseFromString(ssd_model._spec.description.input[0].SerializeToString()) # Copy the declarations of the `confidence` and `coordinates` outputs. # The Pipeline makes these strings by default. pipeline.spec.description.output[0].ParseFromString(nms_model._spec.description.output[0].SerializeToString()) pipeline.spec.description.output[1].ParseFromString(nms_model._spec.description.output[1].SerializeToString()) # Add descriptions to the inputs and outputs. pipeline.spec.description.input[1].shortDescription = '(optional) IOU Threshold override' pipeline.spec.description.input[2].shortDescription = '(optional) Confidence Threshold override' pipeline.spec.description.output[0].shortDescription = u'Boxes \xd7 Class confidence' pipeline.spec.description.output[1].shortDescription = u'Boxes \xd7 [x, y, width, height] (relative to image size)' # Add metadata to the model. pipeline.spec.description.metadata.versionString = 'ssd_mobilenet' pipeline.spec.description.metadata.shortDescription = 'MobileNet + SSD' pipeline.spec.description.metadata.author = 'Converted to Core ML by Cloud Annotations' pipeline.spec.description.metadata.license = 'https://github.com/tensorflow/models/blob/master/research/object_detection' # Add the list of class labels and the default threshold values too. user_defined_metadata = { 'iou_threshold': str(0.5), 'confidence_threshold': str(0.5), 'classes': ','.join(labels) } pipeline.spec.description.metadata.userDefined.update(user_defined_metadata) pipeline.spec.specificationVersion = 3 final_model = coremltools.models.MLModel(pipeline.spec) final_model.save(coreml_model_path)
import tfcoreml as tf_converter tf_converter.convert(tf_model_path='tf_model_path.pb', mlmodel_path='mlmodel_path.mlmodel', output_feature_names=['softmax:0'], input_name_shape_dict={'input:0': [1, 227, 227, 3]})