You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following example converts the TensorFlow Inception V1 image classifier to a Core ML neural network classifier model that directly predicts the class label of the input image. It demonstrates the importance of setting the image preprocessing parameters correctly to get the right results.
11
+
The following example converts the TensorFlow Inception V1 image classifier to a Core ML classifier model that directly predicts the class label of the input image. It demonstrates the importance of setting the image preprocessing parameters correctly to get the right results.
12
12
13
-
## Prerequisites
13
+
## Requirements
14
14
15
-
To use TensorFlow 1 (version 1.15) for this example, you may need to change your version of Python to one that works with TensorFlow 1. For details, see the following:
16
-
17
-
- For virtual environments, see [How to manage multiple Python versions](https://www.freecodecamp.org/news/manage-multiple-python-versions-and-virtual-environments-venv-pyenv-pyvenv-a29fb00c296f/).
18
-
- For Miniconda and Anaconda environments, see [Managing Python](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-python.html).
19
-
20
-
You may also need to install [Pillow](https://pillow.readthedocs.io/en/stable/), [Requests](https://pypi.org/project/requests/), and [matplotlib](https://pypi.org/project/matplotlib/). The following commands work for a Miniconda environment:
15
+
This model requires TensorFlow 1, which is deprecated and difficult to install directly with pip. You can use the appropriate [Miniconda installer](https://docs.conda.io/en/latest/miniconda.html) for your operating system and create a Miniconda environment specifically for Python 3.7, and then use conda to install TensorFlow 1.15:
21
16
22
17
```shell
23
-
conda install python=3.7.9
18
+
conda create -n tensorflow1-env python=3.7
19
+
conda activate tensorflow1-env
24
20
conda install tensorflow==1.15
21
+
```
22
+
23
+
```{note}
24
+
For alternatives, see [How to pip install old version of library(tensorflow)](https://stackoverflow.com/questions/41937915/how-to-pip-install-old-version-of-librarytensorflow) on StackOverflow.
25
+
```
26
+
27
+
In addition, you need to install the following for this environment:
28
+
29
+
```
30
+
pip install -U coremltools
25
31
pip install pillow
26
-
conda install requests
32
+
conda install requests
27
33
conda install matplotlib
28
34
```
29
35
@@ -72,7 +78,6 @@ The following code loads the TensorFlow graph to find the input and output tenso
As shown in the following results, the output of the `Placeholder` op is the input (`input:0`), and the output of the `Softmax` op (near the end of the graph) is the output (`InceptionV1/Logits/Predictions/Softmax:0`).
99
-
100
-
```text Result
101
-
op id 0 : op type: "Placeholder"
102
-
input(s):
103
-
104
-
output(s):
105
-
name = input:0, shape: (1, 224, 224, 3),
106
-
107
-
108
-
op id 1 : op type: "Const"
109
-
input(s):
110
-
111
-
output(s):
112
-
name = InceptionV1/Conv2d_1a_7x7/weights:0, shape: (7, 7, 3, 64),
113
-
114
-
115
-
op id 2 : op type: "Identity"
116
-
input(s):
117
-
name = InceptionV1/Conv2d_1a_7x7/weights:0, shape: (7, 7, 3, 64),
118
-
119
-
output(s):
120
-
name = InceptionV1/Conv2d_1a_7x7/weights/read:0, shape: (7, 7, 3, 64),
121
-
122
-
123
-
op id 1012 : op type: "Softmax"
124
-
input(s):
125
-
name = InceptionV1/Logits/Predictions/Reshape:0, shape: (1, 1001),
126
-
127
-
output(s):
128
-
name = InceptionV1/Logits/Predictions/Softmax:0, shape: (1, 1001),
129
-
130
-
131
-
op id 1013 : op type: "Const"
132
-
input(s):
133
-
134
-
output(s):
135
-
name = InceptionV1/Logits/Predictions/Shape:0, shape: (2,),
136
-
137
-
138
-
op id 1014 : op type: "Reshape"
139
-
input(s):
140
-
name = InceptionV1/Logits/Predictions/Softmax:0, shape: (1, 1001),
141
-
name = InceptionV1/Logits/Predictions/Shape:0, shape: (2,),
142
-
143
-
output(s):
144
-
name = InceptionV1/Logits/Predictions/Reshape_1:0, shape: (1, 1001),
145
-
```
103
+
If you run the code at this point, you can see that the output of the `Placeholder` op is the input (`input:0`), and the output of the `Softmax` op (near the end of the graph) is the output (`InceptionV1/Logits/Predictions/Softmax:0`).
146
104
147
105
## Convert to Core ML
148
106
149
-
The following code sets the `image_inputs` for `inputs` and the output name (`'InceptionV1/Logits/Predictions/Softmax'`) for `outputs` in order to use them with the [`convert()`](https://apple.github.io/coremltools/source/coremltools.converters.convert.html#module-coremltools.converters._converters_entry) method. The `convert()` method produces a neural network by default:
107
+
The following code sets the `image_inputs` for `inputs` and the output name (`'InceptionV1/Logits/Predictions/Softmax'`) for `outputs` in order to use them with the [`convert()`](https://apple.github.io/coremltools/source/coremltools.converters.convert.html#module-coremltools.converters._converters_entry) method. The `convert()` method produces an ML program by default:
Converting Frontend ==> MIL Ops: 100%|██████████| 441/441 [00:00<00:00, 926.87 ops/s]
173
-
Running MIL optimization passes: 100%|██████████| 17/17 [00:00<00:00, 20.06 passes/s]
174
-
Translating MIL ==> MLModel Ops: 100%|██████████| 839/839 [00:00<00:00, 1085.04 ops/s]
127
+
```
128
+
UserWarning: Output, 'InceptionV1/Logits/Predictions/Softmax', of the source model, has been renamed to 'InceptionV1_Logits_Predictions_Softmax' in the Core ML model.
175
129
```
176
130
177
-
## Load a Test Image
178
-
179
-
To make predictions on the same image using both the original model and the converted model, the following sample code snippet loads a test image. It uses [NumPy](https://numpy.org), [Pillow](https://pillow.readthedocs.io/en/stable/), [Requests](https://pypi.org/project/requests/), and [matplotlib](https://pypi.org/project/matplotlib/):
131
+
You will use the new name when making a prediction.
180
132
181
-
```python
182
-
# Load an image
183
-
import numpy as np
184
-
importPIL
185
-
import requests
186
-
from io import BytesIO
187
-
from matplotlib.pyplot import imshow
188
-
# This is an image of a golden retriever from Wikipedia
To make predictions on the same image using both the original model and the converted model, right-click the following image and save it as `Golden_Retriever_Carlos.jpg` in the same folder as your Python project:
This image of a golden retriever is from Wikipedia.
142
+
This image of a golden retriever is from [Wikipedia](https://en.m.wikipedia.org/wiki/File:Golden_Retriever_Carlos_%2810581910556%29.jpg).
204
143
```
205
144
145
+
The following code loads the image:
146
+
147
+
```python
148
+
# Load an image
149
+
import numpy as np
150
+
fromPILimport Image
151
+
img = Image.open("Golden_Retriever_Carlos.jpg")
152
+
```
206
153
207
154
## Input the Image and Make a Prediction
208
155
209
-
The following code passes the PIL image into the Core ML model after resizing it, and uses a NumPy array of the image to make a prediction:
156
+
The following code passes the PIL image into the Core ML model after resizing it, and uses a NumPy array of the image to make a prediction. It also fixes the output name to use the renamed output (`'InceptionV1_Logits_Predictions_Softmax'`) in the Core ML model:
210
157
211
158
```python
212
-
# To get CoreML predictions directly pass in the PIL image after resizing
print("TF prediction class = {}, probability = {}".format(labels[idx],
243
194
str(tf_out[idx])))
244
-
```
245
-
246
-
The result shows that both predictions match, which ensures that the conversion is correct. However, the class labels are incorrect:
247
-
248
-
```text Result
249
-
image shape: (224, 224, 3)
250
-
first few values: [39. 33. 18. 42.] max value: 255.0
251
195
196
+
#print Core ML prediction
197
+
print('\n')
252
198
253
-
CoreML prediction class = thatch, probability = 0.5372982025146484
254
-
TF prediction class = thatch
255
-
, probability = 0.5372873
199
+
print("CoreML prediction class = {}, probability = {}".format(coreml_predicted_class_label,
200
+
str(coreml_pred_dict[0])))
256
201
```
257
202
258
-
The class labels are incorrect because the image was not preprocessed correctly before it was passed to the neural network.
203
+
The result shows that both predictions match, which ensures that the conversion is correct. However, for better results, ensure that the image is preprocessed correctly before passing it to the ML program.
259
204
260
205
## Preprocess the Image Before Converting
261
206
262
-
Preprocessing is always a crucial step when using neural networks on images. The best approach is to find the source of the pre-trained model and check for the preprocessing that the model's author used during training and evaluation.
207
+
Preprocessing is always a crucial step when using ML programs and neural networks on images. The best approach is to find the source of the pre-trained model and check for the preprocessing that the model's author used during training and evaluation.
@@ -278,54 +223,47 @@ print("TF prediction class = {}, probability = {}".format(labels[idx],
278
223
str(tf_out[idx])))
279
224
```
280
225
281
-
The TensorFlow model now predicts a dog as the highest class:
226
+
The TensorFlow model predicts an English Setter as the highest class, (with a probability of 0.301507):
282
227
283
228
```text Result
284
229
TF prediction class = English setter
285
230
, probability = 0.301507
286
231
```
287
232
288
-
Core ML automatically handles the image preprocessing when the input is of type image. However, the image biases and scale are not correct. The channel scale should be multiplied first before adding the bias. The following code converts the model again with this correction, and saves the newly converted model:
233
+
Core ML automatically handles the image preprocessing when the input is of type image. However, the image biases and scale are not correct. The channel scale should be multiplied first before adding the bias. The following code converts the model again with this correction, and saves the newly converted model. It also makes the prediction again with the newly converted Core ML model:
0 commit comments