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 |
|