머신러닝

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

coding art 2021. 7. 6. 21:37
728x90

2020년 구글 TensorFlow 홈페이지에서 제공하는 첫 번째 예제 바로 밑에 선보이는 Fashion MNIST 코드 해설에 주목하자. 비록 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 즉 첫 번째 테스트 이미지 처리 결과로서 이미 앞서 정의 된 함수 def plot_image(∙∙∙) def plot _value_array(∙∙∙) 루틴을 사용하여 그래픽 처리 하는 사례이다. 바그래프 확률 처리는 해당 test_labels 즉 이상적인 one hot code를 작도한 사례이다. 이어서 i = 12 에 해당하는 예제를 한번 더 보여 주고 있음을 참조하자.