# Pytorch & Fast API & Huggingface #### 0. DETR에 대해서 - 논문 링크: https://arxiv.org/pdf/2005.12872.pdf - 논문 해석(한글): https://www.youtube.com/watch?v=hCWUTvVrG7E - Baseline: - DETR R50: https://dl.fbaipublicfiles.com/detr/detr-r50-e632da11.pth - DETR R101: https://dl.fbaipublicfiles.com/detr/detr-r101-2c7b67e5.pth - 성능 비교 ![](https://i.imgur.com/H14q8DP.png) #### 1. Torch Hub - Dependency ``` pip install torch pip install scipy ``` - Load Pretrained State for transfer learning ``` import torch state = torch.hub.load_state_dict_from_url('https://dl.fbaipublicfiles.com/detr/detr-r50-e632da11.pth', map_location='cpu', check_hash=True) model = custom_class.load_state_dict(state) # 직접 만든 모델 레이어에 state load ``` - Load Pretrained Model ``` import torch model = torch.hub.load('facebookresearch/detr:main', 'detr_resnet50', pretrained=True) ``` #### 2. Hugging Face ##### 1. Code Lab에서 Pretrained 된 모델 로드 - Dependency ``` !pip install transformers !pip install timm ``` - Load Pretrained Model ``` from transformers import DetrFeatureExtractor, DetrForObjectDetection feature_extractor = DetrFeatureExtractor.from_pretrained('facebook/detr-resnet-50') model = DetrForObjectDetection.from_pretrained('facebook/detr-resnet-50') ``` - Load Sample Image ``` from PIL import Image import requests url = 'https://drive.google.com/uc?export=download&id=1satnK-pt3PzOOKypkPd9MDUUXbkjs5ra' image = Image.open(requests.get(url, stream=True).raw) ``` - Feature Extraction ``` inputs = feature_extractor(images=image, return_tensors="pt") outputs = model(**inputs) # model predicts bounding boxes and corresponding COCO classes logits = outputs.logits bboxes = outputs.pred_boxes ``` - Softmax ``` import torch # keep only predictions of queries with 0.9+ confidence (excluding no-object class) probas = outputs.logits.softmax(-1)[0, :, :-1] keep = probas.max(-1).values > 0.9 # rescale bounding boxes target_sizes = torch.tensor(image.size[::-1]).unsqueeze(0) postprocessed_outputs = feature_extractor.post_process(outputs, target_sizes) bboxes_scaled = postprocessed_outputs[0]['boxes'][keep] bboxes_scaled.shape[0] # Box 갯수 ``` - Count Object ``` def count_object(object_category): count = 0 for p in probas[keep]: cl = p.argmax() if model.config.id2label[cl.item()] == object_category: count = count + 1 print(count) count_object('car') # detect된 object 중 car 갯수 ``` - Plot ``` import matplotlib.pyplot as plt # colors for visualization COLORS = [[0.000, 0.447, 0.741], [0.850, 0.325, 0.098], [0.929, 0.694, 0.125], [0.494, 0.184, 0.556], [0.466, 0.674, 0.188], [0.301, 0.745, 0.933]] def plot_results(pil_img, prob, boxes): plt.figure(figsize=(16,10)) plt.imshow(pil_img) ax = plt.gca() colors = COLORS * 100 for p, (xmin, ymin, xmax, ymax), c in zip(prob, boxes.tolist(), colors): ax.add_patch(plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, fill=False, color=c, linewidth=3)) cl = p.argmax() text = f'{model.config.id2label[cl.item()]}: {p[cl]:0.2f}' ax.text(xmin, ymin, text, fontsize=15, bbox=dict(facecolor='yellow', alpha=0.5)) plt.axis('off') plt.show() plot_results(image, probas[keep], bboxes_scaled) ``` 일산 주차장1 ![](https://i.imgur.com/068pYs1.png) 일산 주차장2 ![](https://i.imgur.com/uDjr8Rn.png) ##### 2 PyCharm Local 머신에서 Pretrained 된 모델 로드 - Dependency - Transformer 기반 모델을 사용하기 위한 필수 dependency ``` pip install transformers --file requirements.txt pip install timm --file requirements.txt ``` - 원하는 Torch 버전 선택 [PyTorch Site](https://pytorch.org/get-started/locally/) ``` # 위에서 생성된 스크립트로 pytorch 설치 conda install pytorch torchvision torchaudio -c pytorch --file requirements.txt ``` - Environment 셋팅 - 프로젝트 생성시 Interpreter 설정 ![](https://i.imgur.com/anaA888.png) - 위에서 생성한 conda python을 Interpreter로 적용 ![](https://i.imgur.com/3RG08km.png) - Code - Class 선언 ``` from transformers import DetrFeatureExtractor, DetrForObjectDetection from PIL import Image import requests import torch class CarCounterModel: def __init__(self): self.feature_extractor = DetrFeatureExtractor.from_pretrained('facebook/detr-resnet-50') self.model = DetrForObjectDetection.from_pretrained('facebook/detr-resnet-50') print('model loaded') @staticmethod def load_image(url): image = Image.open(requests.get(url=url, stream=True).raw) print('image size: ', image.size) return image def feature_extraction(self, image): inputs = self.feature_extractor(images=image, return_tensors="pt") return self.model(**inputs) def softmax(self, image, outputs): probas = outputs.logits.softmax(-1)[0, :, :-1] keep = probas.max(-1).values > 0.9 target_sizes = torch.tensor(image.size[::-1]).unsqueeze(0) postprocessed_outputs = self.feature_extractor.post_process(outputs, target_sizes) bboxes_scaled = postprocessed_outputs[0]['boxes'][keep] print('total detected object count: ', bboxes_scaled.shape[0]) return probas, keep, bboxes_scaled def count_object(self, probas_keep, category='car'): count = 0 for p in probas_keep: cl = p.argmax() if self.model.config.id2label[cl.item()] == category: count = count + 1 print('total ', category, ' count: ', count) ``` - 실행 ``` model = CarCounterModel() url = 'https://drive.google.com/uc?export=download&id=1eC2ENVGBSyi04b_UAIryU6X8iTMdgzEh' loaded_image = model.load_image(url) features = model.feature_extraction(loaded_image) probas, keep, bboxes = model.softmax(loaded_image, features) model.count_object(probas[keep]) ``` - 결과 ``` model loaded image size: (4032, 3024) total detected object count: 4 total car count: 4 ``` #### 2. Fast API 적용 - Dependency ``` pip install "fastapi[all] --file requirements.tst" conda install -c conda-forge config --file requirements.txt ``` - 실행 ``` uvicorn app:app --reload ``` - Code ``` from fastapi import FastAPI, File, UploadFile from interface.image_url_interface import ImageUrlInterface from model import CarCounterModel app = FastAPI() model = CarCounterModel() @app.get("/health") async def health_check(): return { 'status': 'ok' } @app.post("/url") async def detect_from_image_link(request_body: ImageUrlInterface): if len(request_body.url) == 0: return 'invalid url' loaded_image = model.load_image(request_body.url) features = model.feature_extraction(loaded_image) probas, keep, bboxes = model.softmax(loaded_image, features) count = model.count_object(probas[keep], 'car') return { 'total object count': bboxes.shape[0], 'car count': count } @app.post("/file") async def detect_from_image_file(file: UploadFile = File()): loaded_image = await model.load_image_file(file) features = model.feature_extraction(loaded_image) probas, keep, bboxes = model.softmax(loaded_image, features) count = model.count_object(probas[keep], 'car') return { 'total object count': bboxes.shape[0], 'car count': count } ``` ![](https://i.imgur.com/0qbAdgw.png)