MXNet 시작하기 (5) – VGG16 및 ResNet-152 학습 모델 사용하기

4편에서는 사전 학습된 Inception v3 모델을 사용하여, 이미지 내 분류를 검색하는 것이 얼마나 쉬운지 확인했습니다. 이 글에서는 두 개의 유명한 합성곱 신경망(Convolutional neural network, CNN)인 VGG19와 ResNet-152을 사용해 보고, Inception v3 모델과 비교해 보겠습니다.

CNN이라는 어려운 단어가 나왔지만, 과정은 크게 다르지 않습니다. 레이어를 더 많이 늘린 것입니다.


Architecture of a CNN (Source: Nvidia)

VGG16

2014 년에 발표된 VGG16은 16 개의 레이어로 구성된 모델입니다 (연구 논문). 객체 분류에서 7.4 %의 오류율을 달성하여 2014 년 ImageNet Challenge에서 우승했습니다.

ResNet-152

2015 년에 발표된 ResNet-152는 152 개의 레이어 (연구 논문)로 구성된 모델입니다. 이미지 내 객체 탐지에 대한 오류율 3.57 %를 달성함으로써 2015 ImageNet Challenge에서 우승했습니다.  이건 진짜 놀라운 결과인데, 인간이 대체적으로 5 %의 오류율을 가지는데 (100개를 보면 5개를 긴가민가하게 생각하는) 사람 보다 더 똑똑하다고 볼 수 있겠죠.

모델 다운로드 하기

MXNet zoo를 다시 방문 할 시간입니다! Inception v3와 마찬가지로 모델 정의와 매개 변수를 다운로드해야합니다. 세 모델 모두 동일한 카테고리에 대해 교육을 받았으므로 synset.txt 파일을 다시 사용할 수 있습니다.

$ wget http://data.dmlc.ml/models/imagenet/vgg/vgg16-symbol.json
$ wget http://data.dmlc.ml/models/imagenet/vgg/vgg16-0000.params
$ wget http://data.dmlc.ml/models/imagenet/resnet/152-layers/resnet-152-symbol.json
$ wget http://data.dmlc.ml/models/imagenet/resnet/152-layers/resnet-152-0000.params

모델 로딩하기

세 가지 모델은 224 X 224의 전형적인 이미지 크기의 ImageNet 데이터 셋을 기반으로 학습하기 때문에 우리가 이전에 사용한 코드를 재사용 할 수 있습니다.

우리가 바꾸어야하는 것은 모델 이름입니다 : loadModel()과 init() 함수에 매개 변수를 추가합니다.

def loadModel(modelname):
        sym, arg_params, aux_params = mx.model.load_checkpoint(modelname, 0)
        mod = mx.mod.Module(symbol=sym)
        mod.bind(for_training=False, data_shapes=[('data', (1,3,224,224))])
        mod.set_params(arg_params, aux_params)
        return mod

def init(modelname):
        model = loadModel(modelname)
        cats = loadCategories()
        return model, cats

모델별 예측 비교하기
이전에 사용한 샘플 이미지를 기반으로 이번 두 가지 모델을 비교해 보겠습니다.

*** VGG16
[(0.58786136, 'n03272010 electric guitar'), (0.29260877, 'n04296562 stage'), (0.013744719, 'n04487394 trombone'), (0.013494448, 'n04141076 sax, saxophone'), (0.00988709, 'n02231487 walking stick, walkingstick, stick insect')]

상위 2개 카테고리는 잘 맞는데, 나머지 3개는 잘못되었습니다. 마이크 받침대의 수직 모양에서 혼란스러워하네요.

*** ResNet-152
[(0.91063803, 'n04296562 stage'), (0.039011702, 'n03272010 electric guitar'), (0.031426914, 'n03759954 microphone, mike'), (0.011822623, 'n04286575 spotlight, spot'), (0.0020199812, 'n02676566 acoustic guitar')]

상위 카테고리에서 매우 높습니다. 나머지 4 개 모두 의미가 있습니다.

*** Inception v3
[(0.58039135, 'n03272010 electric guitar'), (0.27168664, 'n04296562 stage'), (0.090769522, 'n04456115 torch'), (0.023762707, 'n04286575 spotlight, spot'), (0.0081428187, 'n03250847 drumstick')]

상위 2 개 카테고리의 VGG16과 매우 유사한 결과. 나머지 세 개는 역시 잘 모르겠네요.

다른 사진으로 해볼까요?

*** VGG16
[(0.96909302, 'n04536866 violin, fiddle'), (0.026661994, 'n02992211 cello, violoncello'), (0.0017284016, 'n02879718 bow'), (0.00056815811, 'n04517823 vacuum, vacuum cleaner'), (0.00024804732, 'n04090263 rifle')]

*** ResNet-152
[(0.96826887, 'n04536866 violin, fiddle'), (0.028052919, 'n02992211 cello, violoncello'), (0.0008367821, 'n02676566 acoustic guitar'), (0.00070532493, 'n02787622 banjo'), (0.00039021231, 'n02879718 bow')]

*** Inception v3
[(0.82023674, 'n04536866 violin, fiddle'), (0.15483995, 'n02992211 cello, violoncello'), (0.0044540241, 'n02676566 acoustic guitar'), (0.0020963412, 'n02879718 bow'), (0.0015099624, 'n03447721 gong, tam-tam')]

세 가지 모델 모두 상위 카테고리에서 매우 높은 점수를 받았습니다. 바이올린의 모양이 신경망에 대해 매우 모호한 패턴이라고 가정 할 수 있습니다.

몇 가지 샘플에서 사용 여부를 결정해서는 안됩니다. 사전 학습된 모델을 찾고 있다면 반드시 학습 데이터 셋을 잘 살펴보고, 자신의 데이터에 대한 테스트를 실행하고 사용할지 여부를 정해야합니다!

기술적 성능 비교
위의 연구 논문에서 많은 모델의 성능에 대한 벤치 마크 결과를 보실 수 있습니다. 개발자의 경우, 가장 중요한 두 가지 요인은 다음과 같습니다.

  • 모델에 필요한 메모리 양은 얼마인가?
  • 얼마나 빨리 예측 가능한가?

첫 번째 질문에 답하기 위해 우리는 매개 변수 파일의 크기를 보고 추측을 할 수 있습니다.

  • VGG16: 528MB (about 140 million parameters)
  • ResNet-152: 230MB (about 60 million parameters)
  • Inception v3: 43MB (about 25 million parameters)

보시다시피 더 적은 매개 변수로 더 많은 레이어로 심층 네트워크를 사용하는 것입니다. 이것은 교육 시간 단축(네트워크가 매개 변수를 덜 학습하므로)과 메모리 사용량 감소라는 두 가지 이점이 있습니다.

두 번째 질문은 조금 복잡해서 배치 크기와 같은 다양한 매개 변수에 따라 달라집니다. 예측 호출 및 실행 시간에 중점을 두고 예제를 다시 실행 해 봅시다.

t1 = time.time()
model.forward(Batch([array]))
t2 = time.time()
t = 1000*(t2-t1)
print("Predicted in %2.2f millisecond" % t)

결과는 다음과 같습니다. (몇 번 호출한 뒤 평균값입니다.)

*** VGG16
Predicted in 0.30 millisecond
*** ResNet-152
Predicted in 0.90 millisecond
*** Inception v3
Predicted in 0.40 millisecond

자! 이제 요약을 해보죠. ResNet-152는 세 가지 네트워크 중에서 가장 우수한 정확도를 가졌지만, 2-3 배 더 느립니다.
VGG16은 레이어 수가 적기 때문에 가장 빠릅니다. 그러나, 높은 메모리 사용과 최악의 정확도를 가지고 있습니다.

Inception v3은 더 빠른 정확성과 가장 보수적인 메모리 사용을 제공하는 동시에 거의 빠릅니다. 이 마지막 점은 실시간 분석과 같은 제한된 환경에서는 좋은 후보가 됩니다. 이에 대한 자세한 부분은 마지막 6편에서 다뤄 보겠습니다.

다음 글:  MXNet 시작하기 (6) – Raspberry Pi에서 실시간 객체 분석 하기

연재 순서

코드 전체 보기

여러분의 생각