add evaluation framework and imagenet evaluation (#69)
Browse files- README.md +12 -0
- mobilenet_v1.py +20 -8
- mobilenet_v2.py +20 -8
README.md
CHANGED
@@ -4,6 +4,17 @@ MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applicatio
|
|
4 |
|
5 |
MobileNetV2: Inverted Residuals and Linear Bottlenecks
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
## Demo
|
8 |
|
9 |
Run the following command to try the demo:
|
@@ -24,3 +35,4 @@ All files in this directory are licensed under [Apache 2.0 License](./LICENSE).
|
|
24 |
- MobileNet V2: https://arxiv.org/abs/1801.04381
|
25 |
- MobileNet V1 weight and scripts for training: https://github.com/wjc852456/pytorch-mobilenet-v1
|
26 |
- MobileNet V2 weight: https://github.com/onnx/models/tree/main/vision/classification/mobilenet
|
|
|
|
4 |
|
5 |
MobileNetV2: Inverted Residuals and Linear Bottlenecks
|
6 |
|
7 |
+
Results of accuracy evaluation with [tools/eval](../../tools/eval).
|
8 |
+
|
9 |
+
| Models | Top-1 Accuracy | Top-5 Accuracy |
|
10 |
+
| ------ | -------------- | -------------- |
|
11 |
+
| MobileNet V1 | 67.64 | 87.97 |
|
12 |
+
| MobileNet V1 quant | 55.53 | 78.74 |
|
13 |
+
| MobileNet V2 | 69.44 | 89.23 |
|
14 |
+
| MobileNet V2 quant | 68.37 | 88.56 |
|
15 |
+
|
16 |
+
\*: 'quant' stands for 'quantized'.
|
17 |
+
|
18 |
## Demo
|
19 |
|
20 |
Run the following command to try the demo:
|
|
|
35 |
- MobileNet V2: https://arxiv.org/abs/1801.04381
|
36 |
- MobileNet V1 weight and scripts for training: https://github.com/wjc852456/pytorch-mobilenet-v1
|
37 |
- MobileNet V2 weight: https://github.com/onnx/models/tree/main/vision/classification/mobilenet
|
38 |
+
|
mobilenet_v1.py
CHANGED
@@ -2,9 +2,11 @@ import numpy as np
|
|
2 |
import cv2 as cv
|
3 |
|
4 |
class MobileNetV1:
|
5 |
-
def __init__(self, modelPath, labelPath, backendId=0, targetId=0):
|
6 |
self.model_path = modelPath
|
7 |
self.label_path = labelPath
|
|
|
|
|
8 |
self.backend_id = backendId
|
9 |
self.target_id = targetId
|
10 |
|
@@ -23,9 +25,10 @@ class MobileNetV1:
|
|
23 |
|
24 |
def _load_labels(self):
|
25 |
labels = []
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
29 |
return labels
|
30 |
|
31 |
@property
|
@@ -61,9 +64,18 @@ class MobileNetV1:
|
|
61 |
return results
|
62 |
|
63 |
def _postprocess(self, output_blob):
|
64 |
-
|
65 |
for o in output_blob:
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
|
|
2 |
import cv2 as cv
|
3 |
|
4 |
class MobileNetV1:
|
5 |
+
def __init__(self, modelPath, labelPath=None, topK=1, backendId=0, targetId=0):
|
6 |
self.model_path = modelPath
|
7 |
self.label_path = labelPath
|
8 |
+
assert topK >= 1
|
9 |
+
self.top_k = topK
|
10 |
self.backend_id = backendId
|
11 |
self.target_id = targetId
|
12 |
|
|
|
25 |
|
26 |
def _load_labels(self):
|
27 |
labels = []
|
28 |
+
if self.label_path is not None:
|
29 |
+
with open(self.label_path, 'r') as f:
|
30 |
+
for line in f:
|
31 |
+
labels.append(line.strip())
|
32 |
return labels
|
33 |
|
34 |
@property
|
|
|
64 |
return results
|
65 |
|
66 |
def _postprocess(self, output_blob):
|
67 |
+
batched_class_id_list = []
|
68 |
for o in output_blob:
|
69 |
+
class_id_list = o.argsort()[::-1][:self.top_k]
|
70 |
+
batched_class_id_list.append(class_id_list)
|
71 |
+
if len(self.labels) > 0:
|
72 |
+
batched_predicted_labels = []
|
73 |
+
for class_id_list in batched_class_id_list:
|
74 |
+
predicted_labels = []
|
75 |
+
for class_id in class_id_list:
|
76 |
+
predicted_labels.append(self._labels[class_id])
|
77 |
+
batched_predicted_labels.append(predicted_labels)
|
78 |
+
return batched_predicted_labels
|
79 |
+
else:
|
80 |
+
return batched_class_id_list
|
81 |
|
mobilenet_v2.py
CHANGED
@@ -2,9 +2,11 @@ import numpy as np
|
|
2 |
import cv2 as cv
|
3 |
|
4 |
class MobileNetV2:
|
5 |
-
def __init__(self, modelPath, labelPath, backendId=0, targetId=0):
|
6 |
self.model_path = modelPath
|
7 |
self.label_path = labelPath
|
|
|
|
|
8 |
self.backend_id = backendId
|
9 |
self.target_id = targetId
|
10 |
|
@@ -23,9 +25,10 @@ class MobileNetV2:
|
|
23 |
|
24 |
def _load_labels(self):
|
25 |
labels = []
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
29 |
return labels
|
30 |
|
31 |
@property
|
@@ -61,9 +64,18 @@ class MobileNetV2:
|
|
61 |
return results
|
62 |
|
63 |
def _postprocess(self, output_blob):
|
64 |
-
|
65 |
for o in output_blob:
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
|
|
2 |
import cv2 as cv
|
3 |
|
4 |
class MobileNetV2:
|
5 |
+
def __init__(self, modelPath, labelPath=None, topK=1, backendId=0, targetId=0):
|
6 |
self.model_path = modelPath
|
7 |
self.label_path = labelPath
|
8 |
+
assert topK >= 1
|
9 |
+
self.top_k = topK
|
10 |
self.backend_id = backendId
|
11 |
self.target_id = targetId
|
12 |
|
|
|
25 |
|
26 |
def _load_labels(self):
|
27 |
labels = []
|
28 |
+
if self.label_path is not None:
|
29 |
+
with open(self.label_path, 'r') as f:
|
30 |
+
for line in f:
|
31 |
+
labels.append(line.strip())
|
32 |
return labels
|
33 |
|
34 |
@property
|
|
|
64 |
return results
|
65 |
|
66 |
def _postprocess(self, output_blob):
|
67 |
+
batched_class_id_list = []
|
68 |
for o in output_blob:
|
69 |
+
class_id_list = o.argsort()[::-1][:self.top_k]
|
70 |
+
batched_class_id_list.append(class_id_list)
|
71 |
+
if len(self.labels) > 0:
|
72 |
+
batched_predicted_labels = []
|
73 |
+
for class_id_list in batched_class_id_list:
|
74 |
+
predicted_labels = []
|
75 |
+
for class_id in class_id_list:
|
76 |
+
predicted_labels.append(self._labels[class_id])
|
77 |
+
batched_predicted_labels.append(predicted_labels)
|
78 |
+
return batched_predicted_labels
|
79 |
+
else:
|
80 |
+
return batched_class_id_list
|
81 |
|