Upload model_mobilenetv3_large_100.py with huggingface_hub
Browse files- model_mobilenetv3_large_100.py +226 -0
model_mobilenetv3_large_100.py
ADDED
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .configuration_mobilenetv3_large_100 import RyzenAIORTModelForImageClassificationConfig
|
2 |
+
import numpy as np
|
3 |
+
import time
|
4 |
+
import os
|
5 |
+
import torch
|
6 |
+
from typing import Optional, Union
|
7 |
+
from pathlib import Path
|
8 |
+
import onnxruntime as ort
|
9 |
+
import datasets
|
10 |
+
from transformers.image_utils import load_image
|
11 |
+
from transformers import AutoConfig, AutoModel, AutoModelForImageClassification
|
12 |
+
from transformers.modeling_utils import custom_object_save
|
13 |
+
from transformers.modeling_outputs import ModelOutput
|
14 |
+
from huggingface_hub import hf_hub_download
|
15 |
+
from huggingface_hub.utils import EntryNotFoundError
|
16 |
+
from optimum.onnxruntime import ORTModelForCustomTasks
|
17 |
+
from optimum.onnxruntime.modeling_ort import logger
|
18 |
+
from optimum.utils.save_utils import maybe_load_preprocessors
|
19 |
+
|
20 |
+
|
21 |
+
class RyzenAIORTModelForImageClassification(ORTModelForCustomTasks):
|
22 |
+
model_type = "RyzenAIORTModelForImageClassification_mobilenetv3_large_100"
|
23 |
+
config_class = AutoConfig
|
24 |
+
auto_model_class = AutoModelForImageClassification
|
25 |
+
|
26 |
+
def __init__(self,
|
27 |
+
model: ort.InferenceSession,
|
28 |
+
config: RyzenAIORTModelForImageClassificationConfig,
|
29 |
+
**kwargs):
|
30 |
+
super().__init__(model=model, config=config, **kwargs)
|
31 |
+
|
32 |
+
def _forward(self, **kwargs):
|
33 |
+
return super().forward(**kwargs)
|
34 |
+
|
35 |
+
def forward(self, **kwargs):
|
36 |
+
pixel_values = kwargs.pop("pixel_values")
|
37 |
+
kwargs["MobileNetV3::input_0"] = pixel_values
|
38 |
+
res = dict(self._forward(**kwargs))
|
39 |
+
logits = res.pop("2208")
|
40 |
+
res["logits"] = logits
|
41 |
+
res = ModelOutput(res)
|
42 |
+
return res
|
43 |
+
|
44 |
+
def infer(self, image):
|
45 |
+
image = load_image(image)
|
46 |
+
output = self.forward(**self.preprocessors[0]([image], return_tensors="np"))
|
47 |
+
top5_probabilities, top5_class_indices = torch.topk(torch.nn.functional.softmax(torch.tensor(output["logits"]), dim=-1), k=5)
|
48 |
+
return top5_probabilities, top5_class_indices
|
49 |
+
|
50 |
+
def eval_imagenet(self, dataset="imagenet-1k", split="valid"):
|
51 |
+
|
52 |
+
batch_time = AverageMeter()
|
53 |
+
top1 = AverageMeter()
|
54 |
+
top5 = AverageMeter()
|
55 |
+
end = time.time()
|
56 |
+
print_freq = 10
|
57 |
+
def transforms(examples):
|
58 |
+
images = [img.convert("RGB") for img in examples["image"]]
|
59 |
+
examples["pixel_values"] = images
|
60 |
+
return examples
|
61 |
+
dataset = datasets.load_dataset("zh-plus/tiny-imagenet", split=split)
|
62 |
+
dataset.set_transform(transforms)
|
63 |
+
for i, data in enumerate(dataset):
|
64 |
+
label = data['label']
|
65 |
+
output = self.forward(**self.preprocessors[0]([data["pixel_values"]], return_tensors="np"))
|
66 |
+
logits = output["logits"]
|
67 |
+
|
68 |
+
# measure accuracy and record loss
|
69 |
+
n = 1
|
70 |
+
prec1, prec5 = accuracy_np(logits, np.array([label]))
|
71 |
+
top1.update(prec1.item(), n)
|
72 |
+
top5.update(prec5.item(), n)
|
73 |
+
|
74 |
+
# measure elapsed time
|
75 |
+
batch_time.update(time.time() - end)
|
76 |
+
end = time.time()
|
77 |
+
if i % print_freq == 0:
|
78 |
+
print(
|
79 |
+
f'Test: [{i}/{len(dataset)}]\t'
|
80 |
+
f'Time {batch_time.val:.3f} ({batch_time.avg:.3f}, {n / batch_time.avg:.3f}/s, '
|
81 |
+
f'{100 * batch_time.avg / n:.3f} ms/sample) \t'
|
82 |
+
f'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t'
|
83 |
+
f'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'
|
84 |
+
)
|
85 |
+
|
86 |
+
print(f' * Prec@1 {top1.avg:.3f} ({100-top1.avg:.3f}) Prec@5 {top5.avg:.3f} ({100.-top5.avg:.3f})')
|
87 |
+
|
88 |
+
@classmethod
|
89 |
+
def register_for_auto_class(cls, auto_class="AutoModel"):
|
90 |
+
"""
|
91 |
+
Register this class with a given auto class. This should only be used for custom models as the ones in the
|
92 |
+
library are already mapped with an auto class.
|
93 |
+
|
94 |
+
<Tip warning={true}>
|
95 |
+
|
96 |
+
This API is experimental and may have some slight breaking changes in the next releases.
|
97 |
+
|
98 |
+
</Tip>
|
99 |
+
|
100 |
+
Args:
|
101 |
+
auto_class (`str` or `type`, *optional*, defaults to `"AutoModel"`):
|
102 |
+
The auto class to register this new model with.
|
103 |
+
"""
|
104 |
+
if not isinstance(auto_class, str):
|
105 |
+
auto_class = auto_class.__name__
|
106 |
+
|
107 |
+
import transformers.models.auto as auto_module
|
108 |
+
|
109 |
+
if not hasattr(auto_module, auto_class):
|
110 |
+
raise ValueError(f"{auto_class} is not a valid auto class.")
|
111 |
+
|
112 |
+
cls._auto_class = auto_class
|
113 |
+
|
114 |
+
def save_pretrained(
|
115 |
+
self,
|
116 |
+
save_directory: Union[str, os.PathLike],
|
117 |
+
push_to_hub: bool = False,
|
118 |
+
**kwargs,
|
119 |
+
):
|
120 |
+
"""
|
121 |
+
Saves a model and its configuration file to a directory, so that it can be re-loaded using the
|
122 |
+
[`from_pretrained`] class method.
|
123 |
+
|
124 |
+
Args:
|
125 |
+
save_directory (`Union[str, os.PathLike]`):
|
126 |
+
Directory to which to save. Will be created if it doesn't exist.
|
127 |
+
push_to_hub (`bool`, *optional*, defaults to `False`):
|
128 |
+
Whether or not to push your model to the Hugging Face model hub after saving it.
|
129 |
+
|
130 |
+
<Tip warning={true}>
|
131 |
+
|
132 |
+
Using `push_to_hub=True` will synchronize the repository you are pushing to with `save_directory`,
|
133 |
+
which requires `save_directory` to be a local clone of the repo you are pushing to if it's an existing
|
134 |
+
folder. Pass along `temp_dir=True` to use a temporary directory instead.
|
135 |
+
|
136 |
+
</Tip>
|
137 |
+
"""
|
138 |
+
if os.path.isfile(save_directory):
|
139 |
+
logger.error(f"Provided path ({save_directory}) should be a directory, not a file")
|
140 |
+
return
|
141 |
+
|
142 |
+
os.makedirs(save_directory, exist_ok=True)
|
143 |
+
|
144 |
+
for preprocessor in self.preprocessors:
|
145 |
+
preprocessor.save_pretrained(save_directory)
|
146 |
+
self._save_pretrained(save_directory)
|
147 |
+
if self._auto_class is not None:
|
148 |
+
custom_object_save(self, save_directory, config=self.config)
|
149 |
+
self._save_config(save_directory)
|
150 |
+
|
151 |
+
if push_to_hub:
|
152 |
+
return self.push_to_hub(save_directory, **kwargs)
|
153 |
+
|
154 |
+
@staticmethod
|
155 |
+
def _cached_file(
|
156 |
+
model_path: Union[Path, str],
|
157 |
+
use_auth_token: Optional[Union[bool, str]] = None,
|
158 |
+
revision: Optional[str] = None,
|
159 |
+
force_download: bool = False,
|
160 |
+
cache_dir: Optional[str] = None,
|
161 |
+
file_name: Optional[str] = None,
|
162 |
+
subfolder: str = "",
|
163 |
+
local_files_only: bool = False,
|
164 |
+
):
|
165 |
+
model_path = Path(model_path)
|
166 |
+
|
167 |
+
# locates a file in a local folder and repo, downloads and cache it if necessary.
|
168 |
+
if model_path.is_dir():
|
169 |
+
model_cache_path = model_path / file_name
|
170 |
+
preprocessors = maybe_load_preprocessors(model_path.as_posix(), trust_remote_code=True)
|
171 |
+
else:
|
172 |
+
model_cache_path = hf_hub_download(
|
173 |
+
repo_id=model_path.as_posix(),
|
174 |
+
filename=file_name,
|
175 |
+
subfolder=subfolder,
|
176 |
+
use_auth_token=use_auth_token,
|
177 |
+
revision=revision,
|
178 |
+
cache_dir=cache_dir,
|
179 |
+
force_download=force_download,
|
180 |
+
local_files_only=local_files_only,
|
181 |
+
)
|
182 |
+
# try download external data
|
183 |
+
try:
|
184 |
+
hf_hub_download(
|
185 |
+
repo_id=model_path.as_posix(),
|
186 |
+
subfolder=subfolder,
|
187 |
+
filename=file_name + "_data",
|
188 |
+
use_auth_token=use_auth_token,
|
189 |
+
revision=revision,
|
190 |
+
cache_dir=cache_dir,
|
191 |
+
force_download=force_download,
|
192 |
+
local_files_only=local_files_only,
|
193 |
+
)
|
194 |
+
except EntryNotFoundError:
|
195 |
+
# model doesn't use external data
|
196 |
+
pass
|
197 |
+
|
198 |
+
model_cache_path = Path(model_cache_path)
|
199 |
+
preprocessors = maybe_load_preprocessors(model_path.as_posix(), subfolder=subfolder, trust_remote_code=True)
|
200 |
+
|
201 |
+
return model_cache_path, preprocessors
|
202 |
+
|
203 |
+
|
204 |
+
class AverageMeter:
|
205 |
+
"""Computes and stores the average and current value"""
|
206 |
+
def __init__(self):
|
207 |
+
self.reset()
|
208 |
+
|
209 |
+
def reset(self):
|
210 |
+
self.val = 0
|
211 |
+
self.avg = 0
|
212 |
+
self.sum = 0
|
213 |
+
self.count = 0
|
214 |
+
|
215 |
+
def update(self, val, n=1):
|
216 |
+
self.val = val
|
217 |
+
self.sum += val * n
|
218 |
+
self.count += n
|
219 |
+
self.avg = self.sum / self.count
|
220 |
+
|
221 |
+
|
222 |
+
def accuracy_np(output, target):
|
223 |
+
max_indices = np.argsort(output, axis=1)[:, ::-1]
|
224 |
+
top5 = 100 * np.equal(max_indices[:, :5], target[:, np.newaxis]).sum(axis=1).mean()
|
225 |
+
top1 = 100 * np.equal(max_indices[:, 0], target).mean()
|
226 |
+
return top1, top5
|