이번 프로젝트는 코드스테이츠 AI 부트캠프에서 진행한 프로젝트 입니다.
코드스테이츠에서 진행한 프로젝트
데이터분석 → 머신러닝 → 파이썬 활용 → 딥러닝 → 생성모델 → 기업협업
부트캠프 기간 6번의 프로젝트 중 네 번째로 진행한 1인 프로젝트로
이미지 분류 모델을 만들어보고, 나아가 YOLO를 활용해 Object Detection을 진행하였습니다.
프로젝트 기획부터 발표까지의 진행 기간은 5일이었습니다.
1. 문제 정의
"인공지능이 탑재된 캡슐 내시경을 만들어보자"
의료 인공지능에 관심이 많은 저는 캡슐내시경 활용도를 높이기 위해
내시경 이미지를 분류하고 Detection 하는 모델을 만들고자 했습니다.
캡슐내시경은 일반 내시경 시술과 달리 많은 장점을 가지고 있습니다.
마취제나 수면제의 투여가 필요 없고, 일상생활을 하며 진행이 가능합니다.
일반 내시경으로 힘든 소장 검진이 가능하다는 장점도 있습니다.
자세한 내용은 아래 링크에서 확인하시기 바랍니다.
단점은 가격입니다. 현재 100만원 정도의 검사 비용이 필요한 것으로 알고 있습니다.
그 외 체내 잔류 가능성(1.4%) 등으로 아직까지는 제한적으로 이루어지는 진단 기법입니다.
배터리, 메모리, 카메라 등 하드웨어는 점점 작아지고 값이 내려갔지만, 캡슐 내시경은 여전히 비쌌는데
이는 수천장의 사진을 의사가 직접 보고 판단해야 하기 때문인 것으로 판단하였습니다.
그래서 저는 AI가 선제적으로 판단하는 캡슐 내시경을 만들고자 하였고
이미지를 구간에 따라 분류하고, 장 내의 폴립(용종)을 찾는 모델을 만들게 되었습니다.
이를 통해 의사와 같은 정확한 진단은 어렵더라도, 진단키트와 같이 선제적 검사 도구로,
나아가 의료 인력이 부족한 국가에의 적용 가능성을 생각해보았습니다.
언젠가 많은 데이터로 좋은 모델을 만든다면 인간을 뛰어넘는 성능도 가능하지 않을까요?
YOLO는 Object Detection 분야에서 많이 알려진 모델입니다.
1-stage detector 방식을 처음으로 고안해서 실시간 객체 검출을 가능하게 한 모델로,
YOLO(You Only Look Once)라는 이름에서 이를 잘 나타내고 있습니다.
YOLO는 v5까지 오면서 실시간 성능은 더 빠르고 모델은 가벼워졌습니다. YOLOv5를 선택한 이유입니다.
캡슐 내시경은 초당 몇 장에서 수 십장의 사진을 찍고 이를 허리에 찬 기기에 전송해 저장합니다.
저는 앞으로 내시경 이미지 분석 모델을 탑재하여 캡슐 스스로 실시간 분석을 하게 되고
향후 스스로 행동할 수 있는 상상 속의 로봇 내시경을 기대하고 있습니다.
2. 데이터 준비
프로젝트 진행에 앞서 가장 어려운 관문은 좋은 데이터셋을 구하는 것입니다.
의료 데이터를 구하는 것은 쉽지 않은 일인데, 다행히 내시경 이미지에 대한 공개 데이터가 있었습니다.
Kvasir 내시경 이미지 데이터셋은 노르웨이의 Bærum 병원 위장병학 부서에서 수집된 데이터셋입니다.
경험 많은 내시경 전문의에 의해 라벨링되고 검증된 이미지로 구성되어 있습니다.
총 2.3GB의 데이터셋으로 식도염 대장염 폴립(용종) 등의 사진을 포함합니다.
720x576 ~ 1920x1072 픽셀까지 다양한 해상도의 이미지로 구성되어 있습니다.
우선 기관 및 증상에 따라 6가지로 분류하는 Image Classification 모델을 만들기 위해
이미지를 분류하고 크기 등을 통일하기 위한 전처리를 진행하였습니다.
물론 정확한 해부학적 지식 없이 분류하고 명명하였기 때문에
용어에 잘못된 부분이 있거나 잘못된 분류가 있을 수 있다는 점 양해 부탁드립니다.
그리고 폴립(용종)에 대한 Object Detection을 위해 LabelIMG라는 프로그램을 활용,
폴립이 포함된 500장에 대하여 직접 Bounding Box를 이미지로부터 만들었습니다.
LabelIMG를 사용하는 방법은 간단합니다.
'pip install labelimg'로 설치하고, 'labelimg' 명령어로 실행하면 됩니다.
그리고 이미지 파일들을 불러와 바운딩 박스를 만들면 됩니다.
바운딩 박스를 만들게 되면 위와 같은 좌표값을 저장한 ' 이미지파일이름.txt ' 파일이 만들어집니다.
박스당 네 개의 좌표값에 대한 데이터를 얻을 수 있으며
한 이미지에 여러개의 박스 좌표를 저장할 수 있습니다.
LabelImg에 대한 자세한 내용은 아래 깃허브를 통해 확인하시기 바랍니다.
3. 모델 훈련
이미지 분류 모델의 경우 많은 자료들이 있을 것 같아
Object Detection에 대한 학습 과정을 설명드리고자 합니다.
실습은 따라하기 쉽게 Google colab에서 진행하였습니다. 우선 필요한 모듈을 임포트 합니다.
import random
import matplotlib.pyplot as plt
import skimage.io
import numpy as np
import os
from keras import *
from keras.models import *
from keras.layers import Input, Dense
from keras.preprocessing import image
from matplotlib.patches import Rectangle
import keras
입력 데이터의 사이즈와 스텝을 먼저 설정해주었습니다.
WINDOW_SIZES = [120] # using only one size for the sliding window
window_sizes=WINDOW_SIZES
step=10 # step of sliding on the input image (how to divide the original image)
학습시킬 데이터를 /content/drive/project/endoscopy-dataset/polyps/ 경로에 업로드하였습니다.
이 중 하나의 이미지를 불러와 출력해봅니다.
img = skimage.io.imread('/content/drive/project/endoscopy-dataset/polyps/001.pg')
print('Input image size=',img.shape[0],img.shape[1])
plt.figure()
plt.imshow(img)
이미지를 잘 불러왔다면 YOLO를 설치하고 사용해보겠습니다.
/content 폴더에 yolov5 깃허브로부터 clone을 진행하고
%cd /content
!git clone https://github.com/ultralytics/yolov5.git
/content/yolov5 의 requirements로부터 필요한 패키지를 설치해줍니다.
%cd /content/yolov5/
!pip install -r requirements.txt
/project 폴더의 data.yaml 을 실행해 train, val 경로를 확인하고 수정해줍니다.
%cat /content/drive/project/data.yaml
이미지를 저장해둔 폴더를 가져와 데이터가 몇개인지 확인해봅니다.
%cd /
from glob import glob
img_list = glob('/content/drive/project/export/images/*.jpg')
print(len(img_list))
저는 500장을 준비하여 train/val 세트를 400, 100으로 나누어주었습니다.
from sklearn.model_selection import train_test_split
train_img_list, val_img_list = train_test_split(img_list, test_size=0.2, random_state=2000)
print(len(train_img_list), len(val_img_list))
댓글