[Anaconda+python] 미리 훈련된 ResNet50으로 이미지 분류하기

프로그래밍/python|2020. 3. 14. 12:34

오늘은 거대한 데이터셋인 이미지넷에서 미리 훈련된 ResNet50을 이용해서 이미지 분류를 시행해보도록 하겠습니다. ResNet은 2015년 이미지넷경진 대회에서 우승을 차지한 이미지 분류 모델입니다. ResNet50은 ResNet 중에서 50개의 층을 갖는 하나의 모델입니다. 

 

이미지넷과 같이 아주 큰 데이터셋을 이용해서 직접 이미지 분류기를 훈련시키는 것은 쉽지 않습니다. 상당히 많은 시간이 소요되기 때문입니다. 공대생들이 소장하고 있는 고성능의 랩탑이나 데스트탑을 이용한다고 해도 보름 이상은 걸릴 일입니다. 그래서 보통은 이미지넷에 훈련된 모델을 가지고 와서, 그것을 각자의 목적에 맞게 업그레이드시켜서 사용합니다. 좀 더 자세히 말한다면, 훈련된 가중치들을 가지고 와서 그 가중치들을 목적에 맞게 새롭게 fine-tuning 해주는 것이죠.

 

오늘은 이미지넷을 이용해서 훈련된 ResNet50의 성능을 한 번 살펴보도록 하겠습니다. 이미지넷에 훈련되었기 때문에 1000개의 객체를 분류해낼 수 있습니다. 이미 훈련된 ResNet50에게 아래 이미지가 무엇에 관한 것인지 물어보도록 하겠습니다.

 

ResNet50아, 얘네들 뭐야?

 

우선 새라고 분류해낼지, 또한 이 새의 정확한 이름을 알려줄 수 있을지 관심을 갖고 지켜보시면 되겠습니다. 필요한 파이썬 코드는 다음과 같습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions
from tensorflow.keras.preprocessing.image import load_img, img_to_array
 
# imagenet에 미리 훈련된 ResNet50 모델 불러오기
model = ResNet50(weights='imagenet')
model.summary()
 
# 테스트할 이미지 불러오기
img_path = 'test1.bmp'
img = load_img(img_path, target_size=(224224)) 
 
# ResNet에 입력하기 전에 이미지 전처리
= img_to_array(img)
= np.expand_dims(x, axis=0)
= preprocess_input(x)
 
# 이미지 분류
preds = model.predict(x)
print('Predicted:', decode_predictions(preds, top=3)[0])
cs

 

실행에 앞서 준비해야할 패키지들이 있습니다. 우선 tensorflow를 이용하기 때문에, tensorflow를 먼저 설치해주셔야 합니다. 

 

>> conda install tensorflow

 

그리고 혹시 다음과 같은 에러가 뜨신다면, 

 

 

Pillow 패키지도 설치해주셔야 합니다.

 

>> conda install Pillow

 

그럼 이미지 분류를 잘 해내는지 테스트해보겠습니다. 위 파이썬 코드를 실행한 결과, 위 이미지를 다음과 같이 분류했습니다.

 

 

저는 가장 높은 확률을 가지는 3개의 결과가 나오도록 했습니다. 가장 큰 확률인 0.994385로 macaw(금강앵무)라고 분류했고, 두번째로 큰 확률인 0.0021338847로 lorikeet(청해앵무속), 세번째로 큰 확률인 0.0010255446로 bee_eater(벌잡이새류)라고 분류했습니다. 해당 이미지가 macaw일 확률이 절대적으로 크다고 ResNet50은 봤습니다. 

 

위키피디아에서 macaw가 뭔지 찾아봤습니다.

 

https://en.wikipedia.org/wiki/Macaw

 

아주 정확히 분류한 것 같죠? ㅎㅎ 

 

재미삼아 하나의 이미지를 더 테스트해보겠습니다. 피아노가 주 피사체인 사진입니다. 

 

ResNet50아, 이것은 뭐야? 

 

위 파이썬 코드에서 img_path 부분만 이 이미지 파일의 이름으로 봐꿔주고 실행했습니다. 저는 이 결과가 상당히 놀라웠습니다. 

 

 

여기서 upright가 바로 다음과 같이 생긴 피아노를 의미하는 것이더라구요.

 

구글에서 upright piano를 검색했을때 나오는 결과

 

grand_piano(그랜드 피아노)는 다들 어떻게 생긴 피아노인지 아실 것이고. ResNet50이 업라이트 피아노와 그랜드 피아노도 구분할 수 있는 능력을 가지고 있다는 것이 놀랍습니다. 

 

오늘은 이미 훈련된 ResNet50을 이용해서 이미지를 분류해봤습니다. ResNet50말고도 VGG16, InxeptionV3, MobileNet, DenseNet 등의 다른 이미지 분류 모델들을 불러와서 사용할 수도 있습니다. 한 두줄의 코드만 바꿔주면 됩니다. 

 

질문과 지적은 항상 환영입니다. 빠르게 답변드리도록 노력하고 있으니 댓글 남겨주세요.^^  

 

 

<참고자료>

[1] https://keras.io/applications/, Keras Documentation, "Applications"