아나콘다텐서플로우

2-3 Fashion MNIST 텐서플로우 예제 “Your first neural network” 해설

coding art 2020. 3. 1. 21:32
728x90

2020년 구글 TensorFlow 홈페이지에서 제공하는 첫 번째 예제 바로 밑에 선보이는 Fashion MNIST 코드 해설에 주목하자. 비록 MNIST 수준의 초보자를 위한 기초적인 코드 예제이긴 하지만 그래도 웬만한 입문자에게는 쉽사리 넘을 수 없는 벽이라는 느낌을 지울 수 없어 보이므로 보다 더 쉬운 해설을 추가하기로 한다.

https://www.tensorflow.org/tutorials/keras/classification


Fashion MNIST 에제를 실행해 본 바 이 예제 자체의 머신 러닝 상의 이론적인 난이도 문제도 있겠지만 이 예제 코드가 충분히 이해가 된다면 당신은 이미 인공지능 머신 러닝 코드를 깊이 다룰 수 있는 수준에 도달했다고 보인다.


Fashion MNIST 문제를 처리할 수 있도록 우선 아래와 같이 Keras가 제공하는 방식으로 데이터를 읽어야 할 필요가 있다. 읽기 명령이 MNIST 와는 다음에 유의하자. 읽어 들인 데이터는 튜플 형태로 즉 학습(train) 과 테스트(test)를 위한 복수개의 데이터 세트로 나누어진다. 머신 러닝에 사용될 오브젝트들의 분류Class 는 주로 의류와 악세사리 백 및 신발류의 10가지 Class들 구성된다. 이들 Class 각각은 One-hot 코드로 주어지며 라벨 값 출력을 통해 확인이 가능하다.



Fashion MNIST 문제의 규모를 파악하기 위한 다음의 명령들은 쥬피터 노트북이나 구글 Colaboratoty를 사용할 경우에는 셀에서 명령을 주어 실행시키고 직접 출력 결과를 관찰할 수 있다. 하지만 아나콘다 코드로 실행 시에는 에러는 아니지만 셸에 직접 출력이 되지는 않는다. 따라서 해당 명령을 셸에서 하나하나 명령으로 실행시켜야만 다음과 같이 출력 확인이 가능하다.


Fashion-MNIST 데이터를 읽은 후 Matplotlib 라이브러리 지원 하에 이미지 샘플들을 확인 차원에서 작도해 보다. train_images 의 갯수는 0번에서부터 59,999번까지 총 60,000개이다. 따라서 60,000번째 이미지 출력은 인덱스 상 그 범위를 벗어나므로 에러 메시지를 출력하게 된다. 아울러 원래 읽어 들인 데이터가 흑백이긴 하지만 imshow 명령에서 cmap=’Greys’ 조건을 부과하지 않으면 컬러로 출력된다.


입력된 학습 데이터와 테스트데이타는 0255 사이의 값을 가지므로 255로 나눠 normalization 하자. normalization 결과는 01 사이의 값을 가지게 된다. 머신 러닝 방법론상 normalization 처리 된 결과를 사용할 경우 인식률이 향상된다.


학습용 이미지 0번에서 24번까지 25개를 순서대로 작도하되 15개씩 5개열로 흑백 이미지를 작도하고 아래쪽에 학습용 이미지의 라벨 값을 읽어서 그 인덱스 정보를 사용하여 맨 처음에 설정했던 class_names Class 이름값을 텍스트로 출력하자.


다음의 코드는 Keras 데이터를 읽어 normalization 한 후 머신 러닝을 위한 Sequential{} 뉴럴 네트워크 코드의 구조이다. Simple 네트워크에 비해 784X128 은닉 층이 추가되었으며 최종적으로 Softmax 명령을 사용 Class를 밝혀 낼 확률을 계산할 수 있도록 128X10 웨이트 매트릭스를 사용하여 hypothesis of states를 계산한다. states 는 고려하는 Class 의 개수가 10개이므로 당연히 10비트 One-hot 코드로 처리된다. model.compile 까지의 단계가 TensorFlow Graph 준비에 해당하며 학습에 해당하는 model.fit 과 그 이후는 Session 실행에 해당한다.

만약에 keras.layers.Dense(128,∙∙∙)를 빼버리면 은닉층이 없는 Simple Keras 네트워크로 귀착되며 테스트 샘플에 대한 인식률을 계산해 보면 84.2% 안팎이 된다. 하지만 은닉충을 포함한 경우 인식률은 뉴럴 네트워크 효과로 88% 수준으로 상승한다. 한편 학습 단계에서의 인식률이 테스트단계의 인식률에 비해서 34% 높은 편인데 이러한 인식률의 차이는 Overfitting에 기인한다. Overfitting은 학습 데이타가 아닌 새 데이터 또는 Unseen 데이터에 대한 테스트에서 인식률이 떨어지는 원인이다.


Compile 다음 단계는 model.fit 이다. model Compile 작업이 완료되았으면 학습용 이미지 데이터(train_images)와 학습용 라벨 값 데이터(train_labels)를 사용하여 epoch 값을 설정하여 학습(training)을 시키도록 하자. fit은 수치해석에서 흔히 사용하는 interpolation 개념이다. 어떤 주어진 함수 형상이나 숫자 값을 나타낼 수 있도록 경사하강법을 적용하여 웨이트 매트릭스의 최종 웨이트 값들을 찾아내는 과정에 해당한다. 학습에 의해 웨이트 값들이 결정된 후 테스트용 이미지 데이터와 라벨 값을 사용하면 인식률 계산이 가능하다. Fashion MNIST 문제에서 epoch 설정 기준은 MNIST와 유사하다. MNIST문제에서는 batch_size=100을 흔히 사용하며, 학습 데이터 갯수를 batch_size 로 나누면 각 epoch별 반복학습계산 횟수가 계산된다. 반면에 Kerasmodel.fit에서 Default batch_size 값은 32 이지만 batch_size epoch 값을 각각 지정할 수 있다.



아래의 모신 러닝 계산 결과를 참조해 보자 학습 인식률과 테스트 인식률 차이가 약 3% 수준이다.


이와 같이 학습을 통해 웨이트 값들이 얻어졌으면 이를 이용하여 다시 테스트 이미지 데이터를 사용하여 예측(Prediction)작업을 실행해 보자. 이 단계까지 인식률 계산은 이루어졌으나 학습용 이미지 데이터나 테스트용 이미지 데이터 각각에 대해서 확률적 계산이 완료된 것은 아니다. 따라서 tf.keras.Sequential 명령에서 이미 학습이 완료된 model tf.keras.layers.Softmax()를 사용하여 각 Class 별 확률의 합이 1.0이 되도록 probability_modelParent로 정의하고 predict에 상속하여 전체 테스트 이미지 각각에 대해서 확률 계산을 실행하고 출력한다. 확률 계산 출력 코드들은 셸(Shell)에서 실행시켜 줘야할 필요가 있다.


그 다음에 연속되는 함수 정의들 def plot_image(∙∙∙) def plot _value_array(∙∙∙)을 사용하여 테스트 결과를 그래픽 처리하자. 다음은 def plot_image(∙∙∙) 함수 루틴에 의한 테스트 이미지 그래픽 처리 방식이다.


다음은 def plot _value_array(∙∙∙) 함수 루틴에 의한 테스트 이미지의 one hot code 확률분포 계산 결과의 그래픽 처리 방식이다.


다음의 결과는 i = 0 즉 첫 번째 테스트 이미지 처리 결과로서 인시률이 100%dlek. 이미 앞서 정의 된 함수 def plot_image(∙∙∙) def plot _value_array(∙∙∙) 루틴을 사용하여 확률분포를 바그래프로 그래픽 처리한 사례이다



이어서 i = 12 에 해당하는 인식률이 74%인 예제를 한 번 더 보여 주고 있음을 참조하자. 8번째에 해당하는 바가 최대 확률 값 0.74이므로 테스트 이미지는 Class에서부터 ‘Sneaker’ 즉 운동화임을 알 수 있다.




총 테스트 이미지 15세트를 그래픽 처리하자. 세트는 테스트 오브젝트의 Class 그림과 인식률 및 확률분포로 구성된다.


다음은 5X3 세트 그래픽 실제 출력 사례이다.


마지막으로 확률 그래프 작성 방향을 바꾸어 가로축 상에 10개의 Class를 순차적으로 설정 후 테스트 결과 얻어진 최대 확률분포 값을 출력해 보자.



이상 해설 내용 중에서 keras 학습 및 테스트 과정까지가 머신 러닝이며 그 이후의 matplotlib를 이용한 그래픽은 초보자가 더욱 흥미를 느낄 수 있도록 가시화하여 보여 주는 과정이다. 머신 러닝에 비해 그래픽 부분 내용이 좀 길기는 하지만 keras tensorflow 학습 및 테스트 결과를 아주 효율적으로 보여주며 사용자 필요에 따라서 복사 붙여넣기하여 사용하기 편리한 오픈소스이다.