Batch 시 calibrator.collect_data 에러

안녕하세요.

해당 코드는 기본 예제 코드를 이용하였으며,
예제에서 배치 1로 export한 onnx모델에 대하여 input_ 하나씩 calibrator.collect_data[[input_]] 넣어주면 정상작동하는 코드를

배치 8로 onnx 모델을 추출하고, calibrator.collect_data()에 이미지를 넣어줄 때 에러가 발생했습니다.

기존처럼 1개씩 넣어주면, 인풋 크기가 안맞다고 에러가 뜨고 [1,3,640,640] → [8,3,640,640]
8개씩 배치로 넣어주면, expected input은 1이라고 에러가 뜹니다.

사진 개수 제한 때문에 오류는 글로 대체하겠습니다.

  1. self._calibrator.collect_data(calibration_dataset) / ValueError: a tensor of shape [1, 3, 640, 640] (float32) is invalid for input of shape [8, 3, 640, 640] (float32)

  2. self._calibrator.collect_data(calibration_dataset) / ValueError: expected 1 input(s) but got 8

도움주시면 감사하겠습니다.

안녕하세요, 혹시 전처리 함수를 아래와 같이 변경한다음에

from typing import Any, Dict, List, Tuple

import cv2
import numpy as np


def letterbox(
    img: np.ndarray,
    new_shape: Tuple[int, int],
    color=(114, 114, 114),
    auto=True,
    scaleup=True,
    stride=32,
):
    h, w = img.shape[:2]
    ratio = min(new_shape[0] / h, new_shape[1] / w)
    if not scaleup:
        ratio = min(ratio, 1.0)
    new_unpad = int(round(ratio * w)), int(round(ratio * h))
    dw, dh = (new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1])
    dw /= 2
    dh /= 2

    if ratio != 1.0:
        interpolation = cv2.INTER_LINEAR if ratio > 1 else cv2.INTER_AREA
        img = cv2.resize(img, new_unpad, interpolation=interpolation)

    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    img = cv2.copyMakeBorder(
        img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color
    )
    return img, ratio, (dw, dh)


class YOLOPreProcessor:
    def __init__(self):
        self.contexts = []

    @staticmethod
    def __call__(
        images, new_shape: Tuple[int,int] = (640, 640), tensor_type = "uint8", with_scaling: bool = False
    ):
        imgs = []
        contexts = []

        for img in images:
            img, ratio, (padw, padh) = letterbox(img, new_shape)
            imgs.append(img)
            contexts.append({"ratio": ratio, "pad": (padw, padh)})
        
        imgs = np.stack(imgs)
        imgs = imgs[..., ::-1].transpose((0, 3, 1, 2))
        if tensor_type == "uint8":
            input_ = np.ascontiguousarray(imgs, dtype=np.uint8)
        else:
            input_ = np.ascontiguousarray(imgs, dtype=np.float32) / 255.0

        return input_, contexts

양자화 코드를 이런식으로 작성하고 테스트 진행가능하실까요?

#for data in tqdm(calib_data, desc="calibration"):
    for idx in tqdm(range(0, len(calib_data), bs)):
        imgs = []
        for b in range(bs):
            if idx + b >= len(calib_data):
                break
            data = calib_data[idx+b]
            if not (data.endswith(".png") or data.endswith(".jpg")):
                continue
            imgs.append(cv2.imread(data))
        if len(imgs) != bs:
            continue
        input_, _ = preprocess(imgs, new_shape=(int(input_shape[2:][0]),int(input_shape[2:][1])), tensor_type = "float32")
        calibrator.collect_data([[input_]])
1 Like