왜 디버깅하면서 이미지를 봐야하지?
제가 예전에 담당했던 업무중에 사람 얼굴의 특징점 (눈, 코, 입 등이라고생각하면 편하다) 가지고 기능을 짜야했던 적이 있었습니다. 지금도 그렇지만 그때는 텐서감수성이 떨어질 때라서, 현재 짜고 있는 코드가 맞게 동작하는지 잘 이해가 안가는 경우가 굉장히 많았습니다. 🙂
이미지 출처: https://towardsdatascience.com/facial-keypoints-detection-deep-learning-737547f73515?gi=529af36da233
특히, 이게 단순 산술연산이 아니라 이미지상에서 어느 부분을 짜르거나, 어느 부분을 기준으로 뭔짓을 가해야하는 종류라면 정말 디버깅에 많은 시간이 걸립니다. (예를 들면 얼굴 부분만 자르기!)
짜도 그 이미지에 알맞게 적용됐는지, 머리속으로 상상은 해도 실제로 그렇게 짜졌는지 실행하기 전까지 불안에 떨어야 했죠.
따라서 디버깅 하면서 이미지를 보는 건 디버깅 시에 확실히 이점이 있습니다. 보면서 실수를 그때 그때 잡을 수 있으니까요. 특히 저 같은 뉴비 머신러닝러는 더더더더더더욱 그렇습니다.
이처럼 머신러닝, 특히 비전관련한 테스크를 하다보면 디버깅을 할 때 이미지 파일을 보면서 할 때 더편한 경우가 왕왕 있습니다.
대안들
중간중간 이미지를 보는 작업은 생각보다 편하지만, 단순하게 이미지를 로그처럼 찍는 방법은 생각보다 불편합니다. 이렇게 할 경우 폴더를 열어서 이미지를 켜봐야 하고, 코드에 삽입해서 작성함으로 그때 그때 모델을 실행해야하죠.
특히 후처리를 해야할 경우 매 실행마다 모델을 로드해야하기 때문에 더 오랜 시간이 걸리게 됩니다. 이것 때문에 코드하나 고치고 다시 재시작하고, 모델을 로드하는데 많은 시간을 소모하게 됩니다. 😢
다른 방법으로는 plt.show() 같은 짓을 코드에 삽입하는 겁니다. 그러면 scientific mode로 pycharm을 사용하면 되죠. 하지만 전 이 scientific mode를 좋아하지 않습니다. 솔직히 창도 번거롭게 많아지고 생각보다 기능이 불편했습니다. 제가 잘 사용하지 못하는걸까요.
플러그인
그래서 저는 주로 pycharm의 디버거를 사용하는데, 이 디버거에서 사용하기 매우 좋은 플로그인을 소개하고자 합니다.
바로 디버깅 중에 이미지를 보여주는 플러그인입니다.
https://plugins.jetbrains.com/plugin/14371-opencv-image-viewer
여기 들어가서 pycharm에 추가하면 파이참에서 dialog가 뜨는데 수락을하면 바로 pycharm에서 이 플러그인을 사용할 수 있습니다.
사용법
플러그인이 정상적으로 설치됐다면 디버깅을 원하는 지점에 break point를 등록 후 디버깅 모드로 실행합니다.
Watch에 등록된 image 형태의 numpy 배열을 우클릭했을 때, View as Image 라는 메뉴가 등록됐을 거에요.
image 형태의 numpy 배열이란 H x W x 1, H x W x 3 (BGR), H x W x 4 (BGRA) 형태의 배열입니다. $256 \times 256 \times 3$ 형태가 되겠죠.
근데 이 메뉴를 디버깅때마다 클릭하는 것은 좀 귀찮으니까 전 주로 단축키 alt+i 를 사용해서 디버깅합니다.
그러면 이렇게 창이 뜨면서 디버깅중에 이미지를 볼 수 있습니다! 이렇게 이미지를 보면 그때 그때 이미지에 조작을 가하면서 프로그램이 정상동작하는지 볼 수 있습니다. 프로그램을 다시실행하지 않고도요!
기타 꿀팁
Color 변환
그런데 프레임워크별로 color format이 다릅니다. 예를들자면 matplotlib와 pillow의 경우, RGBA 형태로 로드하게됩니다. (PNG의 경우)
그러니까 이걸 그냥 그대로 보면 이렇게 원본 얼굴과 전혀 다른 형태로 이미지가 나오게 됩니다. pytorch도 RGB 형태로 BGR 형태로 바꿔줘야 올바른 색으로 볼 수 있죠.
즉 이런 경우 color foramt을 변경해줘야 하는데, cv2.cvtColor로 한줄코딩해주면 쉽게 변경해줄 수 있습니다.
matplotlib 으로 load한 경우
cv2.cvtColor(mat_image, cv2.COLOR_RGBA2BGRA) # matplotlib로 load한 경우
cv2 모듈의 색형식 변환 함수인 cvtColor를 통해서 변환해준 것입니다.
만약 Alpha channel이 필요없다면 cv2의 색형식 상수에서 A들을 빼주시면 됩니다.
pillow 로 load한 경우
cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGBA2BGRA) # pillow로 load한 경우
pillow가 return하는 image의 경우 numpy 형태가 아닙니다.
따라서 np.array로 변환해줘야 정상적으로 보입니다.
그리고 색변환을 수행해줘야하죠.
마무리
이게 뭐라고 상당히 글이 길어졌네요.
도움이 되셨으면 좋겠습니다.
다른 꿀팁이 있다면 공유해주시면 감사하겠습니다!
'ML > 기타 팁들' 카테고리의 다른 글
gradio를 이용한 머신러닝 모델 공개 배포하기 (0) | 2023.02.15 |
---|---|
ML task 별 SOTA 논문, 성능 비교, 지표, 데이터셋 등을 한눈에 보는 곳 (0) | 2021.04.07 |