@@ -167,86 +167,30 @@ ImageFeatureType* set_image_feature(
167
167
} // namespace
168
168
169
169
std::shared_ptr<MLModelWrapper> export_object_detector_model (
170
- const neural_net::model_spec& nn_spec, size_t image_width,
171
- size_t image_height, size_t num_classes, size_t num_predictions,
172
- flex_list class_labels, const std::string& input_name,
170
+ neural_net::pipeline_spec raw_pipeline, size_t num_classes,
171
+ size_t num_predictions, flex_list class_labels,
173
172
std::map<std::string, flexible_type> options) {
174
173
// Set up Pipeline
175
174
CoreML::Specification::Model model_pipeline;
176
175
model_pipeline.set_specificationversion (3 );
177
176
ModelDescription* pipeline_desc = model_pipeline.mutable_description ();
178
177
179
- // Add NeuralNetwork model to pipeline
180
- auto * model_nn = model_pipeline.mutable_pipeline ()->add_models ();
181
-
182
- // Scale pixel values 0..255 to [0,1]
183
- NeuralNetworkLayer* first_layer =
184
- model_nn->mutable_neuralnetwork ()->add_layers ();
185
- first_layer->set_name (" _divscalar0" );
186
- first_layer->add_input (input_name);
187
- first_layer->add_output (" _divscalar0" );
188
- first_layer->mutable_scale ()->add_shapescale (1 );
189
- first_layer->mutable_scale ()->mutable_scale ()->add_floatvalue (1 / 255 .f );
190
-
191
- // Copy the NeuralNetwork layers from nn_spec.
192
- // TODO: This copies ~60MB at present. Should object_detector be responsible
193
- // for _divscalar0, even though this isn't performed by the cnn_module?
194
- model_nn->mutable_neuralnetwork ()->MergeFrom (nn_spec.get_coreml_spec ());
195
- ASSERT_GT (model_nn->neuralnetwork ().layers_size (), 1 );
196
-
197
- // Set the name of preprocessing layer to input_name as well.
198
- // Since in the test case somehow the model doesn't have a preprocessing
199
- // layer, so we need to check the size first...
200
- if (model_nn->neuralnetwork ().preprocessing_size () == 1 ) {
201
- NeuralNetworkPreprocessing* preprocessing_layer =
202
- model_nn->mutable_neuralnetwork ()->mutable_preprocessing (0 );
203
- preprocessing_layer->set_featurename (input_name);
204
- }
205
-
206
- // Wire up the input layer from the copied layers to _divscalar0.
207
- // TODO: This assumes that the first copied layer is the (only) one to take
208
- // the input from "image".
209
- NeuralNetworkLayer* second_layer =
210
- model_nn->mutable_neuralnetwork ()->mutable_layers (1 );
211
- ASSERT_EQ (second_layer->input_size (), 1 );
212
-
213
- second_layer->set_input (0 , " _divscalar0" );
214
-
215
- // Write the ModelDescription.
216
- ModelDescription* model_desc = model_nn->mutable_description ();
217
-
218
- // Write FeatureDescription for the image input.
219
- set_image_feature (model_desc->add_input (), image_width, image_height,
220
- input_name);
178
+ // Adopt the model pipeline passed to us as input.
179
+ std::unique_ptr<CoreML::Specification::Pipeline> raw_pipeline_spec =
180
+ std::move (raw_pipeline).move_coreml_spec ();
181
+ model_pipeline.mutable_pipeline ()->Swap (raw_pipeline_spec.get ());
221
182
222
183
if (!options[" include_non_maximum_suppression" ].to <bool >()){
184
+ // Only support this case for models supporting spec version 1, which means
185
+ // no pipeline models.
186
+ ASSERT_EQ (model_pipeline.pipeline ().models_size (), 1 );
223
187
224
- // Write FeatureDescription for the confidence output.
225
- set_predictions_feature (model_desc->add_output (), " confidence" , num_predictions, num_classes,
226
- true , false , CONFIDENCE_STR);
227
-
228
- // Write FeatureDescription for the coordinates output.
229
- set_predictions_feature (model_desc->add_output (), " coordinates" , num_predictions, 4 , true ,
230
- false , COORDINATES_STR);
231
-
232
- // Set CoreML spec version.
233
- model_nn->set_specificationversion (1 );
234
188
auto model_wrapper = std::make_shared<MLModelWrapper>(
235
- std::make_shared<CoreML::Model>(*model_nn ));
189
+ std::make_shared<CoreML::Model>(model_pipeline. pipeline (). models ( 0 ) ));
236
190
237
191
return model_wrapper;
238
192
}
239
193
240
- model_nn->set_specificationversion (3 );
241
-
242
- // Write FeatureDescription for the raw confidence output.
243
- set_predictions_feature (model_desc->add_output (), " raw_confidence" , num_predictions, num_classes,
244
- true , true , " " );
245
-
246
- // Write FeatureDescription for the coordinates output.
247
- set_predictions_feature (model_desc->add_output (), " raw_coordinates" , num_predictions, 4 , true ,
248
- true , " " );
249
-
250
194
// Add Non Maximum Suppression model to pipeline
251
195
auto * model_nms = model_pipeline.mutable_pipeline ()->add_models ();
252
196
model_nms->set_specificationversion (3 );
@@ -294,9 +238,9 @@ std::shared_ptr<MLModelWrapper> export_object_detector_model(
294
238
first_layer_nms->set_confidenceoutputfeaturename (" confidence" );
295
239
first_layer_nms->set_coordinatesoutputfeaturename (" coordinates" );
296
240
297
- // Write FeatureDescription for the image input .
298
- set_image_feature ( pipeline_desc->add_input (), image_width, image_height,
299
- input_name, " Input image " );
241
+ // Copy input feature descriptions from the first model in the pipeline .
242
+ * pipeline_desc->mutable_input () =
243
+ model_pipeline. pipeline (). models ( 0 ). description (). input ( );
300
244
301
245
// Write FeatureDescription for the IOU Threshold input.
302
246
FeatureDescription* iou_threshold = pipeline_desc->add_input ();
0 commit comments