두달 동안 yolox-darknet53, yolox-X 모델까지 조건을 다르게해서 30번정도 훈련을 완료했다.
yolox 알고리즘의 jetson xavier 보드 포팅 및 tensorrt 추론, 성능평가 방법, Nvidia Deepstream 포팅과정은
포스팅에 다루지 않고, 결과만 정리할 예정이다.
직접해보지 않으면 알 수 없는 정보들 중 몇가지만 기록해두고자 한다.
1) 학습전략
yolox 훈련전 전체 epoch은 200~400으로 설정 하고 데이터 셋에 따라 aug 파라미터를 조정 필요.
최종 epoch에서 no_aug_epoch 후 ~7epoch 이내로 max mAP에 수렴. 이후로는 오버피팅의 경향이 있다.(똑같은 이미지를 반복 학습하기 때문)
가벼운 모델일 수록 aug 강도를 적게.
lr 스케쥴링은 'yoloxwarmcos'를 이용하는것이 좋다.
강력한 이미지 증강으로 pre-train을 사용하지 않고 scratch로 학습해도 결과에는 큰차이가 없다. mAP커브는 scratch 방식이 더 안정적임.
multiscale 훈련은 작은 obj 검출에 효과가 있음. 단, multiscale+scale aug+rotation이 동시에 적용되어 너무 작은 obj가 발생할 수 있음.
(학습 시 small obj label fillter 기능 추가가 필요해 보인다.)
2) 처리속도
처리속도 및 성능 Nvidia Jetson Xavier NX[16GB] 개발자 Kit을 기준으로 평가한다.
Xavier NX 스펙 및 라이브러리 버전은 위 그림과 같다.
Jetson Jetpack 4.6.2 버전에 맞는 jetson 전용 pyTorch 1.10.0 프리빌드를 설치했다.
(설치방법은 jetson 개발 포스팅 참조)
* Jetson Xavier NX[16GB]
- model : yolox-darknet53-640x640_FP16
- inference time : model.inference time + NMS
- Test Env : pyTorch(python), TensorRT(c++), DeepStream(c++)
위 조건으로 테스트시한 결과.
pyTorch : 74ms
TensorRT : 40ms
DeepStream : 19.6ms
처리속도가 pyTorch > TensorRT > DeepStream 적용함에 따라 매우 빨라지는 것을 알 수 있다.
신기한 점은 동일한 tensorrt engine을 사용해도 TensorRT보다 DeepStream이 훨씬 빠르다는 것.
여러가지 이유가 있지만. DeepStream에서는 모든 처리를 GPU로, 최적화된 코드로 병렬처리 되기 때문인 것 같다.
위 실험에서는 단순 infer+NMS 시간만 계산했지만 전처리, tensor 변환, gpu 메모리 적재, 후처리, Encode/Decodem, Record, Streaming, Multi-batch-inference 등등 어플리케이션의 다양한 프로세스에서 소요되는 시간까지 감안하면 DeepStream의 장점은 더욱 강력해 진다.
결과적으로 최종 모델은 DeepStream yolox-d53/yolox-X 모델을 선정했으며, 기존 모델인 custom tiny yolov2, yolov5-X 모델의 성능을 크게 앞서는 결과를 얻을 수 있었다.
yolox는 다양한 아이디어를 조합하여 성능을 끌어올리는 yolo의 철학이 잘 녹아든 것 같다. paper에서 제안하는 기법들이 어렵지않고 설명 및 소스코드가 쉽게 구현되어있어서 이해하기 어렵지 않았다.
스터디 목적으로 SimOTA와 multi-pasitive를 제외하면 특별히 소스코드를 분석할 것이 없었다.
yolox의 c++ 후처리 속도를 개선할 수 있는 아이디어가 제안되었다.
Static grid_and_strides
현재 후처리에서 decode_outputs에 대한 모든 호출에서 gird & stride를 반복계산하는데, 많은 시간이 사용된다고 한다.(직접 측정해보지는 않았음)
tensorrt 데모 및 deepstream의 nvdsinfer_custom_impl_yolov7 라이브러리에 적용해볼 필요가 있겠다.