IDL/Machine Learning

IDL의 머신러닝 기능을 이용한 MNIST 필기숫자 인식 모델 테스트

이상우_IDL 2020. 9. 9. 15:46
728x90

머신러닝(Machine Leaning) 관련 기능이 IDL에 탑재된 것은 버전 8.7.1부터였습니다. 원래는 위성데이터 처리 소프트웨어 패키지인 ENVI에서 머신러닝 기능이 먼저 도입되었었고, 그 이후에 IDL에서도 지원되기 시작한 것입니다. 물론 아시는 분들은 다 아시겠지만 머신러닝 분야에서는 Python 언어가 가장 널리 사용되고 있기 때문에, 굳이 IDL에서 머신러닝 관련 작업을 하는 경우가 그리 많지는 않을 것 같습니다. 그래도 늦게나마 IDL에 머신러닝 기능이 탑재되어 조금씩 발전해나가고 있는 상황이라는데 의미를 두고 싶습니다. IDL의 머신러닝 기능에 관해서는 제가 예전에 3회에 걸쳐서 관련 게시물들을 올린 적이 있습니다. 이 게시물들을 통하여 IDL의 머신러닝 기능 개요 및 관련 예제들을 소개한 바 있습니다.

 

IDL의 머신러닝 기능 사용에 관하여 [1]

IDL의 머신러닝 기능 사용에 관하여 [2]

IDL의 머신러닝 기능 사용에 관하여 [3]

 

그런데 오늘은 머신러닝과 관련된 또 다른 예제로서, MNIST 데이터베이스를 이용한 필기숫자 인식 모델의 훈련 및 테스트를 간단히 해볼 수 있는 프로그램을 하나 소개하고자 합니다. 여기서 잠깐 이해를 돕기 위하여 간단히 언급한다면, MNIST(Modified National Institute of Standards and Technology) 데이터베이스는 머신러닝 분야에서 훈련 및 테스트용으로 널리 사용되는 데이터입니다. 그 안에는 여러 종류의 데이터들(동식물사진, 가전제품사진 등등)이 있지만 그 중에서 필기숫자 즉 사람이 손으로 쓴 0~9의 숫자들에 대한 이미지들로 구성된 데이터가 있습니다. 이 데이터는 실제로는 6만개의 훈련용(Training) 이미지들과 1만개의 평가용(Validation) 이미지들로 구성되어 있는데, 각 이미지는 28x28의 구조를 갖는 바이트스케일 이미지이며, 6만개의 훈련용 이미지들 중 몇가지만 보면 다음 그림과 같습니다.

 

 

실제로 6만개의 훈련용 이미지들 각각에 대해서는 어떤 숫자에 대응되는지에 대한 정답에 해당되는 정보도 함께 수록되어 있습니다. 즉 위 그림의 8개의 필기숫자들의 경우도 각각 0, 9, 6, 2, 1, 5, 9, 3이라는 숫자에 대응된다는 정답에 해당되는 정보 역시 데이터베이스 내에 일종의 라벨 데이터의 형태로 함께 포함되어 있습니다. 그래서 이러한 훈련용 이미지 6만개를 정답 데이터와 함께 사용하여 모델을 훈련시키는 과정은 감독 분류(Supervised Classification)의 범주에 속한다고 볼 수 있습니다. 즉 정답이 함께 제공된 상태로 모델을 훈련시키는 경우입니다. 이렇게 훈련된 모델이 완성되면 이를 이용하여 임의의 필기숫자 이미지에 대하여 실제로 어떤 숫자에 해당되는가를 판독할 수 있습니다 (물론 판독 가능한 숫자의 범위는 0~9입니다). 임의의 필기숫자 이미지는 1만개의 평가용 이미지들 중 하나를 골라서 사용합니다. 이런 식으로 모델을 시험 구동 해봄으로써 모델의 정확도와 타당성을 가늠해볼 수 있게 됩니다.

 

물론 모델을 훈련시키는 과정에 있어서 적용 가능한 기법들에는 여러가지 종류가 있고 각 기법 내에서도 세부적으로 다양한 설정이 가능하기 때문에, 모델을 훈련시키는 방법의 종류는 엄청나게 많습니다. 그래서 어떤 기법을 어떤 방식으로 적용할지에 대한 결정이 필요합니다. 그리고 훈련에 사용할 MNIST 데이터베이스 역시 해당 자료를 따로 받아야 합니다. 이와 같이 머신러닝 기반의 모델을 제대로 완성하려면 여러가지 과정들을 거쳐야 하는데요. 이 모든 과정을 하나에 담은 프로그램이 IDL에 탑재되어 있습니다. 바로 classify_digits라는 프로그램입니다. 이 프로그램은 IDL 8.8 및 8.7.3 버전에는 이미 포함되어 있습니다 (8.7 초창기 버전에는 포함되지 않았던 것 같습니다). 그래서 이러한 버전의 IDL에서는 그냥 커맨드 프롬프트에서 classify_digits를 입력하고 엔터키를 누르면 이 프로그램이 실행됩니다. 그런데 제가 이 프로그램을 테스트해본 바로는 몇가지 개선이 필요한 부분들이 보여서, 제 나름대로 약간의 수정을 해보았습니다. 그렇게 만든 프로그램이 classify_digits_lsw입니다. 이 프로그램 파일을 여기 첨부합니다.

 

classify_digits_lsw.pro
0.01MB

 

여러분들은 이 파일을 받아서 컴파일 및 실행을 해보시면 됩니다. 프로그램 파일이 어떤 디렉토리에 위치해도 상관이 없습니다. 다만 이 프로그램은 실행과 동시에 자동으로 MNIST 데이터베이스를 다운로드받도록 코딩되어 있기 때문에, 네트워크 연결 상태에서 실행되어야 한다는 점 그리고 IDL 8.7.1 또는 그 이후 버전에서만 실행이 가능하다는 점만 유의하시면 됩니다. 어쨌든 이 프로그램을 실행하면 다음과 같은 GUI 형태의 어플리케이션이 뜹니다.

 

 

참고로 위 그림은 제가 Mac OS용 IDL 8.8에서 프로그램을 실행한 모습입니다. 윈도우즈용 IDL에서 실행할 경우에도 그림 내부의 폰트 크기나 위치 등이 살짝 다르게 보일 수 있지만 거의 동일한 모습으로 보이게 됩니다. 그리고 이 프로그램은 시작과 동시에 MNIST 데이터베이스 파일들을 자동으로 다운로드하도록 코딩되어 있습니다. 따라서 앞서 이미 언급했듯이, 정상적인 실행을 위해서는 네트워크 연결이 반드시 필요합니다. 실제로 이 프로그램이 데이터 다운로드를 위하여 접속하는 곳은 IDL Git 허브에 있는 mnist-data라는 디렉토리이며 링크는 아래와 같습니다. 어차피 이 프로그램이 실행되면 자동적으로 이 링크로 연결하여 필요한 파일들을 다운로드할 것이므로, 여러분들이 직접 이 링크로 굳이 가실 필요는 없습니다. 다만 이 링크에 어떤 파일들이 있는지 궁금하시다면 한번 가서 보시는 것도 괜찮습니다.

 

https://github.com/interactive-data-language/mnist-data

 

그러면 먼저 UI 상에서 우측 하단에 있는 슬라이드바를 조정해봅시다. 이 슬라이드바는 1~10000의 범위를 갖습니다. 즉 MNIST 데이터에 수록된 1만개의 평가용 이미지들을 하나씩 화면상에서 볼 수 있도록 해주는 역할을 합니다. 예를 들어 번호가 6512가 되도록 슬라이드바를 조정한 모습은 다음 그림과 같습니다.

 

 

이와 같이 6512번째 평가용 이미지의 모습을 볼 수 있는데, 아마도 숫자 3을 필기로 쓴 모습인 것 같습니다. 물론 아직 모델을 훈련시키기 전이기 때문에 모델에 의한 판독 결과는 나오지 않은 상태입니다. 그래서 평가용 이미지 바로 우측에 위치한 결과창에서는 ?로만 표시되어 있습니다. 잠시 후 훈련이 끝난 후에는 이 ?가 모델의 판독 결과로 바뀌게 될 것입니다. 앞서 훈련용 이미지 6만개에 대해서는 정답 숫자 데이터가 함께 제공된다고 언급했지만, 평가용 이미지 1만개에 대해서는 정답 데이터가 존재하지 않습니다. 즉 훈련된 모델을 이용하여 결과를 산출해야하고, 그렇기 때문에 이와 같이 결과가 모두 ?로 표시된 상태입니다. 따라서 이제부터는 본격적인 모델 훈련의 단계로 들어가야 합니다.

 

모델의 훈련을 시작하기 위해서는 UI상의 좌측상단에 있는 ‘Train Classifier’라는 버튼을 누르면 됩니다. 이 버튼을 누르면 모델의 훈련 과정이 실행되는데, 훈련이 완료되기까지는 컴퓨터의 사양에 따라 다를 수도 있겠지만 아마도 대략 수십 초 정도 소요될 수 있습니다.

 

 

이러한 훈련을 통하여 우리가 얻게 되는 모델은 결국 임의의 필기 숫자에 대하여 0~9 범위의 총 10가지 숫자들 중 하나로 판별하게 됩니다. 즉 분류(Classification) 목적의 모델을 구축하는 셈입니다. 그리고 이러한 분류형 모델을 구축하는데 있어서는 원래 여러가지 세부 기법들이 존재하는데, IDL의 머신러닝 기능에서는 SVM(Support Vector Machine), SoftMax, FFNN(Feed Forward Neural Network) 등 세가지만 지원됩니다. 지금의 예제 프로그램은 내부적으로 SoftMax 기법이 적용되도록 코딩되어 있습니다. 그리고 세부적인 훈련의 방식도 모델마다 다른데, 한번의 런에 의하여 훈련이 종료되는 SVM과는 달리 SoftMax의 경우는 일정 횟수의 반복(Iteration)을 거쳐야 하도록 되어 있습니다. 이 프로그램에서는 내부적으로 반복 횟수가 20회로 설정된 상태입니다. 그리고 각 회차별 학습률(Learning Rate)라는 인자도 존재하는데 이 프로그램 내부적으로는 0.9로 설정된 상태입니다. 그리고 이러한 인자값들을 설정할 수 있도록 하기 위하여, ‘Train Classifier’ 버튼의 위쪽에 훈련과정의 반복 횟수를 결정하는 Iterations, 그리고 학습률을 결정하는 Learning Rate라는 이름의 텍스트창들이 지원됩니다. 따라서 이 항목들의 값은 여러분이 직접 수정할 수 있는데, 일단 여기서는 이미 수록되어 있는 디폴트 값인 20과 0.9를 그대로 사용하기로 합니다. 이 상태에서 Train Classifier 버튼을 누르면 훈련과정이 실행되며, 종료되기까지는 약 수십여 초 정도의 시간이 소요될 수 있습니다. 그리고 이 과정에서는 별도의 팝업 그래픽창이 뜨면서 다음과 같은 그림이 보이게 될 것입니다.

 

 

이 그림은 Confusion Matrix라는 일종의 적중률 데이터에 해당되는 결과를 도식적으로 보여줍니다. 실제로 이 예제 프로그램 내의 훈련과정을 보면, 6만개의 훈련용 데이터 중에서 90%인 5만4천개가 훈련용(Training)으로 사용되고 10%인 6천개는 검증용(Test)으로 사용되도록 코딩되어 있습니다. 즉 90%의 데이터를 SoftMax 기법으로 훈련시켜서 분류형 모델을 구축한 다음, 이 모델을 10%의 검증용 데이터에 적용해서 0~9 각 숫자별로 정답 적중률을 나타낸 것이 Confusion Matrix라고 보시면 됩니다. 그래서 0->0, 1->1, 2->2 등에 해당되는 셀들이 적중률이 높은 것을 볼 수 있습니다. 그래서 원래는 0~9 각 숫자마다의 적중률이 모두 계산되지만 이 모든 것을 종합한 적중률에 해당되는 정확도(Accuracy)라는 값도 존재합니다. 훈련의 과정에서 반복 횟수가 늘어날수록 이러한 정확도가 점점 증가하게 되며(잘 훈련되는 경우), 이 그림의 상단에서 Accuracy라고 표시된 값이 이에 해당됩니다. 이 그림에서는 정확도가 91.16%라고 표시되었지만, 이 값은 훈련을 할 때마다 달라질 수 있습니다. 그리고 여러분이 실행할 때에도 다르게 나올 것입니다 (어차피 머신러닝의 훈련이라는 작업은 할 때마다 조금씩 결과는 다르게 나옵니다). 이제 훈련이 모두 종료된 후에 메인 UI를 보면 그 모습은 다음과 같을 것입니다.

 

 

여기서 UI상의 좌측 중간쯤을 보면 Loss Profile이라는 제목의 그래프가 보입니다. 이 그래프는 훈련된 모델이 검증용 데이터와 얼마나 차이가 나는가를 나타내는 Loss라고 하는 양이 20회의 반복 과정에서 어떻게 변해갔는가를 보여줍니다. 이 Loss라는 값이 작을수록 모델이 데이터 사이의 괴리가 작다는 것입니다. 즉 모델이 얼마나 잘 훈련되었는가를 나타내는데, 20회의 반복 과정을 거치면서 그 값이 계속 감소하였음을 확인할 수 있습니다. 즉 훈련이 비교적 잘 진행되었다는 의미로 해석하면 됩니다. 그리고 위의 그림을 보면 우측에 있는 Result 창에 이제는 ? 대신 3이라는 숫자가 적혀있는 것이 보입니다. 즉 바로 왼쪽에 있는 평가용 이미지에 대하여 모델이 판단한 숫자값이 3이란 의미입니다. 이 정도면 사람이 보는 시각과 일치하는 결과라고 볼 수 있습니다. 물론 우리가 얻은 모델의 정확도가 100%는 아니기 때문에, 다음과 같이 우리의 생각과 전혀 다른 경우들도 일부 존재합니다.

 

 

훈련된 모델의 정확도는 위의 스크린샷을 보면 91.16%라고 나오는데, 훈련을 여러번 해봐도 대략 90~91% 정도가 나옵니다. 여러분들도 아마 비슷한 결과를 얻으실 것이라 예상합니다. 사실 이 정도의 정확도는 비교적 낮은 편에 속한다고 볼 수 있습니다. 정확도가 높은 모델을 얻기 위해서는 다른 방식의 훈련이 필요합니다. 즉 훈련된 모델의 정확도는 훈련의 과정에서 어떤 기법을 사용하는가, 그 기법을 세부적으로 어떤 식으로 설정하는가, 그리고 훈련용 데이터를 어떤 식으로 활용하는가 등의 여러가지 요소들에 따라 천차만별로 달라집니다. 여기서는 예제 프로그램을 통하여 그러한 예들 중 하나를 제시한 것 뿐입니다. 일단 오늘 소개한 classify_digits_lsw 프로그램 내에서 모델이 훈련된 과정을 정리해보면 다음과 같습니다.

 

1) 훈련용 데이터 6만개를 활용하는데 있어서, 실제 훈련용(Training)으로는 90%가 할당되었고 검증용(Test)으로는 10%가 할당되었다

2) 감독 분류(Supervised Classification) 형태의 모델로 훈련시키는데 있어서 SoftMax 방법이 적용되었다

3) SoftMax 방법의 세부 설정에서 반복 횟수는 20회, 회차별 학습률은 0.9로 설정되었다

 

이와 같은 과정에 의하여 훈련된 것인데, UI상에서 유저가 변경할 수 있는 부분은 반복횟수(Iteration)와 학습률(Learning Rate)입니다. 적어도 이러한 인자들에 대해서는 유저들이 다른 값을 넣어서 다양하게 실행해볼 수 있습니다. 값을 조정한 후 Train Classifier 버튼을 다시 누르면 됩니다. 예를 들면 반복횟수를 50으로 하고 학습률은 0.3 정도로 설정해서 테스트해볼 수도 있습니다. 다만 그 외의 요소들 즉 훈련용과 검증용의 비율을 조정한다든지, SoftMax 외에 다른 분류 모델을 선택한다든지 하는 여러가지 다양한 시도들은 UI상에서는 설정으로는 불가능합니다. 물론 프로그램의 소스코드가 존재하기 때문에 이러한 세세한 부분들까지도 뭐 마음만 먹는다면 변경하는 것이 불가능하지는 않지만, 작업이 좀 복잡해지게 될 것입니다.

 

일단 오늘은 classify_digits_lsw 프로그램을 간단히 사용하여 MNIST 데이터베이스 기반의 필기숫자 판독을 위한 분류형 모델을 훈련시키고 시험해보는 방법을 소개해보는 선에서 마무리하도록 하겠습니다. 그리고 마지막에 언급한 것과 같은 좀 더 유연하고 디테일한 방식의 접근을 위해서는 소스코드의 레벨에서 이것저것 뜯어보고 필요한 수정을 가하는 작업이 필요할 것 같습니다. 이와 관련해서는 제가 따로 준비를 좀 해서 소개해 볼 생각입니다. 시간이 얼마나 걸릴지는 모르겠으나 언제든 준비가 다 되면 여기서 소개하도록 하겠습니다.

LIST