Hailo Model Zoo 를 사용해 모델을 최적화(양자화)할 때, 학습 테스크에 따른 데이터 전/후처리 방법에 대한 내용
Hailo Model Zoo 데이터 처리
Version
- 아래 Hailo 버전 기준으로 작성함
- Hailo DFC: 3.27.0
- Hailo Model Zoo: 2.11.0
- 설치 참고: Hailo Dataflow Compiler 설치
Optimization
- Hailo Model Zoo에서 모델을 최적화하는 과정에서, 모델이 수행하는 테스크(detection, segmentation 등)에 따라 학습에 사용된 데이터셋을 양자화를 위한 캘리브레이션 및 사후학습이 이루어 진다.
- 이러한 양자화를 위해, 모델의 input/output 데이터를 전처리 및 후처리하는 과정을 테스크별 사전 정의가 되어있으며, 커스텀 모델을 사용하기 위해서는 이러한 전후처리 과정을 직접 정의하거나 수정해야 한다.
- Hailo Model Zoo에서 제공하는 양자화 캘리브레이션 및 사후학습 관련 스크립트는
.alls
파일을 통해 수정 가능하다.
model_optimization_config(calibration, batch_size=8, calibset_size=93)
post_quantization_optimization(finetune, policy=enabled, dataset_size=93, epochs=8, learning_rate=0.0001)
모델의 전/후처리 정보
- Hailo Model Zoo에서 사전 작성해놓은 모델 정보에 대한
.yaml
파일에서 모델에 지정된 task 및 네트워크 타입 정보를 확인할 수 있다.
...
# 전처리 관련 정보
preprocessing:
network_type: classification
meta_arch: basic_resnet
# 후처리 관련 정보
postprocessing:
meta_arch: None
device_pre_post_layers:
softmax: false
argmax: false
bilinear: false
nms: false
...
최적화 - 데이터 전처리
- Hailo Model Zoo를 통해 모델을 최적화하는 과정에서, 컴파일러(DFC)는 최적화 단계에서 모델의 명세인
.yaml
파일의 내용 중preprocessing
항목의network_type
과meta_arch
의 값을 읽어서 정의된 데이터 전처리를 수행한다. - 대표적으로 classification task에서는 center crop 등, detection task(yolo)에서는 padding 처리 등이 있다.
- 데이터 전처리 관련 python 코드는 다음 경로에 위치한다:
/hailo_model_zoo/core/preprocessing/{model_name}.py
최적화 데이터 전처리 예시
전처리 정보
- Hailo Model Zoo에서 제공하는
Resnet18
모델에 대한 최적화 데이터 전처리 과정을 살펴 본다. Resnet18
모델의 config 파일은resnet_v1_18.yaml
파일에 전처리에 대한 정보를 포함하여 작성되어 있다.
preprocessing:
network_type: classification
meta_arch: basic_resnet
전처리 코드
- 위의 전처리 정보에 해당하는 전처리 코드는
/hailo_model_zoo/core/preprocessing/classification_preprocessing.py
파일에 작성되어 있다. - 해당 코드에서
basic_resnet
아키텍처에 해당하는 전처리 내용은 아래와 같다.
...
def _resnet_base_preprocessing(image, output_height=None, output_width=None, resize_side=None, method=None):
if output_height is not None:
assert output_width is not None
assert resize_side is not None
image = _aspect_preserving_resize(image, resize_side, method=method) #비율보존 리사이즈
image = _central_crop([image], output_height, output_width)[0]
image.set_shape([output_height, output_width, 3])
image = tf.cast(image, tf.float32)
return image
@PREPROCESS_FACTORY.register(name="basic_resnet")
def resnet_v1_18_34(image, image_info=None, output_height=None, output_width=None, **kwargs):
image = _resnet_base_preprocessing(image, output_height, output_width, RESIZE_SIDE)
if image_info:
image_info['img_orig'] = tf.cast(image, tf.uint8)
return image, image_info
...
- 일반적으로 resnet18 모델을 학습할 때 사용되는 데이터 전처리 파이프라인(resize, center crop)이 미리 세팅되어 있음을 알 수 있다.
- 만약, 커스텀 모델이 해당 파이프라인을 따라 학습되지 않은 모델이라면 성능 불일치를 막기 위해 커스텀 모델의 학습 당시 데이터 전처리 파이프라인에 맞게 수정하여야 한다.
최적화 - 데이터 후처리
- 모델에서 출력되는 데이터에 대한 후처리는 모델 명세
.yaml
파일의postprocessing
항목에 명시될 수 있다. - Hailo Model Zoo에서 제공하는 대표적인 후처리 방법은 detection task의 NMS(Non Maximum Suppression)가 있다.
PPU 레이어
- Hailo 에는 PPU(pre/post processing unit) 프로세서가 존재하므로 칩셋 내부 연산을 통해 데이터 연산이 가능하다.
- 일반적으로 비신경망 처리는 호스트 프로세서(CPU)에서 수행되지만, Hailo의 소프트웨어는 일부 전처리 및 후처리 작업을 칩 자체의 전용 전/후처리 장치(PPU) 로 오프로드하는 기능도 지원한다.
- PPU 레이어에서 처리할 후처리 방법은 모델의 명세
.yaml
파일에 정의할 수 있으며, 네트워크 내부에서 처리 하지 않고 출력 데이터를 외부에서 처리하는 경우/hailo_model_zoo/core/postprocessing/{models}_postprocessing.py
파일에 후처리 관련 함수가 작성되어 있다.
최적화 데이터 후처리 예시
PPU를 이용한 네트워크 내부 후처리
- Hailo Model Zoo에서 제공하는
Resnet50
모델에 대한 최적화 데이터 전처리 과정을 살펴 본다. Resnet50
모델의 config 파일은resnet_v1_50.yaml
파일에 전처리에 대한 정보를 포함하여 작성되어 있다.
postprocessing:
device_pre_post_layers:
softmax: true
argmax: false
bilinear: false
nms: false
- Hailo Model Zoo 에서 제공하는
Resnet50
모델의 경우 네트워크의 출력 레이어 직전에softmax
레이어가 존재하며, 이softmax
레이어의 연산을 Hailo 디바이스에서 실행하도록 설정한 내용이라 할 수 있다.
네트워크 외부 후처리
- Classification에 해당하는 후처리 코드는
/hailo_model_zoo/core/postprocessing/classification_postprocessing.py
파일에 작성되어 있다. - 해당 코드에서 기본 후처리에 해당하는 내용은 아래와 같다.
def classification_postprocessing(endnodes, device_pre_post_layers=None, **kwargs):
if device_pre_post_layers is not None and device_pre_post_layers['softmax']:
probs = endnodes
else:
logits = endnodes
if not _is_logits_shape_allowed(logits.shape, kwargs['classes']):
raise PostprocessingException('Unexpected logits shape {}'.format(logits.shape))
# Verify the shape of the logits tensor has four dimensions
logits = tf.reshape(logits, [-1, 1, 1, kwargs['classes']])
probs = tf.nn.softmax(tf.squeeze(logits, axis=(1, 2)), axis=1)
return {'predictions': probs}
- 만약
device_pre_post_layers
가 주어졌고, 그 안에'softmax': True
이면, 이미 softmax 처리가 된 출력 (probs
)라고 간주하고 그대로 사용. 'softmax': True
가 아니면 네트워크 내부에서 softmax 처리를 하지 않으므로 네트워크 내부에서 softmax 함수를 적용하도록 되어 있다.