Source code for anomalib.utils.sweep.helpers.inference
"""Utils to help compute inference statistics."""# Copyright (C) 2020 Intel Corporation## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions# and limitations under the License.importtimefrompathlibimportPathfromtypingimportDict,Iterable,List,Tuple,UnionimportnumpyasnpimporttorchfromomegaconfimportDictConfig,ListConfigfromtorch.utils.dataimportDataLoaderfromanomalib.deployimportOpenVINOInferencer,TorchInferencerfromanomalib.models.componentsimportAnomalyModule
[docs]classMockImageLoader:"""Create mock images for inference on CPU based on the specifics of the original torch test dataset. Uses yield so as to avoid storing everything in the memory. Args: image_size (List[int]): Size of input image total_count (int): Total images in the test dataset """def__init__(self,image_size:List[int],total_count:int):self.total_count=total_countself.image_size=image_sizeself.image=np.ones((*self.image_size,3)).astype(np.uint8)
[docs]def__len__(self):"""Get total count of images."""returnself.total_count
[docs]def__call__(self)->Iterable[np.ndarray]:"""Yield batch of generated images. Args: idx (int): Unused """for_inrange(self.total_count):yieldself.image
[docs]defget_meta_data(model:AnomalyModule,input_size:Tuple[int,int])->Dict:"""Get meta data for inference. Args: model (AnomalyModule): Trained model from which the metadata is extracted. input_size (Tuple[int, int]): Input size used to resize the pixel level mean and std. Returns: (Dict): Metadata as dictionary. """meta_data={"image_threshold":model.image_threshold.value.cpu().numpy(),"pixel_threshold":model.pixel_threshold.value.cpu().numpy(),"min":model.min_max.min.cpu().numpy(),"max":model.min_max.max.cpu().numpy(),"stats":{},}image_mean=model.training_distribution.image_mean.cpu().numpy()ifimage_mean.size>0:meta_data["stats"]["image_mean"]=image_meanimage_std=model.training_distribution.image_std.cpu().numpy()ifimage_std.size>0:meta_data["stats"]["image_std"]=image_stdpixel_mean=model.training_distribution.pixel_mean.cpu().numpy()ifpixel_mean.size>0:meta_data["stats"]["pixel_mean"]=pixel_mean.reshape(input_size)pixel_std=model.training_distribution.pixel_std.cpu().numpy()ifpixel_std.size>0:meta_data["stats"]["pixel_std"]=pixel_std.reshape(input_size)returnmeta_data
[docs]defget_torch_throughput(config:Union[DictConfig,ListConfig],model:AnomalyModule,test_dataset:DataLoader,meta_data:Dict)->float:"""Tests the model on dummy data. Images are passed sequentially to make the comparision with OpenVINO model fair. Args: config (Union[DictConfig, ListConfig]): Model config. model (Path): Model on which inference is called. test_dataset (DataLoader): The test dataset used as a reference for the mock dataset. meta_data (Dict): Metadata used for normalization. Returns: float: Inference throughput """torch.set_grad_enabled(False)model.eval()inferencer=TorchInferencer(config,model)torch_dataloader=MockImageLoader(config.dataset.image_size,len(test_dataset))start_time=time.time()# Since we don't care about performance metrics and just the throughput, use mock data.forimageintorch_dataloader():inferencer.predict(image,superimpose=False,meta_data=meta_data)# get throughputinference_time=time.time()-start_timethroughput=len(test_dataset)/inference_timetorch.set_grad_enabled(True)returnthroughput
[docs]defget_openvino_throughput(config:Union[DictConfig,ListConfig],model_path:Path,test_dataset:DataLoader,meta_data:Dict)->float:"""Runs the generated OpenVINO model on a dummy dataset to get throughput. Args: config (Union[DictConfig, ListConfig]): Model config. model_path (Path): Path to folder containing the OpenVINO models. It then searches `model.xml` in the folder. test_dataset (DataLoader): The test dataset used as a reference for the mock dataset. meta_data (Dict): Metadata used for normalization. Returns: float: Inference throughput """inferencer=OpenVINOInferencer(config,model_path/"model.xml")openvino_dataloader=MockImageLoader(config.dataset.image_size,total_count=len(test_dataset))start_time=time.time()# Create test images on CPU. Since we don't care about performance metrics and just the throughput, use mock data.forimageinopenvino_dataloader():inferencer.predict(image,superimpose=False,meta_data=meta_data)# get throughputinference_time=time.time()-start_timethroughput=len(test_dataset)/inference_timereturnthroughput