반응형

0-0. Tensorflow란?

TensorFlow는 머신러닝을 위한 엔드 투 엔드 오픈소스 플랫폼이다. 도구, 라이브러리, 커뮤니티 리소스로 구성된 포괄적이고 유연한 생태계를 통해 연구원들은 ML에서 첨단 기술을 구현할 수 있고 개발자들은 ML이 접목된 애플리케이션을 손쉽게 빌드 및 배포할 수 있다. (출처: tensorflow 홈페이지)

한마디로 파이썬 같은 건데, 머신러닝 돌릴 때 굉장히 간단한 코드로 모든 것을 할 수 있다.

Tensorflow 자체는 코드가 조금 어려웠으나, 그 위에 Keras라는 API를 얹어 코드가 매우 간단해졌다.

이번 포스팅에서는 Tensorflow 홈페이지 튜토리얼에서 제공하는 Keras가 적용된 Basic classification을 작성해보았다.

0-1. Tensorflow with Keras

이 튜토리얼에서는 운동화나 셔츠 같은 옷 이미지를 분류하는 신경망 모델을 train한다.

완전한 텐서플로(TensorFlow) 프로그램을 빠르게 살펴 보고, 자세한 내용은 앞으로 배우면서 더 설명한다. 텐서플로 모델을 만들고 훈련(train)할 수 있는 고수준 API인 tf.keras를 사용한다.

from __future__ import absolute_import, division, print_function, unicode_literals, unicode_literals

# tensorflow와 tf.keras를 임포트합니다

import tensorflow as tf from tensorflow import keras

# 헬퍼(helper) 라이브러리를 임포트합니다

import numpy as np import matplotlib.pyplot as plt # tensorflow version print(tf.__version__)

 

 

1. 패션 MNIST 데이터셋 임포트하기

10개의 범주(category)와 70,000개의 흑백 이미지로 구성된 패션 MNIST 데이터셋을 사용한다. 이미지는 해상도(28x28 픽셀)가 낮은 개별 옷 품목을 나타낸다:

- 패션 MNIST

컴퓨터 비전 분야의 "Hello, World" 프로그램격인 고전 MNIST 데이터셋을 대신해서 자주 사용된다. MNIST 데이터셋은 손글씨 숫자(0, 1, 2 등)의 이미지로 이루어져 있으며, 여기서 사용하려는 옷 이미지와 동일한 포맷이다.

패션 MNIST는 일반적인 MNIST 보다 조금 더 어려운 문제이고 다양한 예제를 만들기 위해 선택했다. 두 데이터셋은 비교적 작기 때문에 알고리즘의 작동 여부를 확인하기 위해 사용되곤 한다. 코드를 테스트하고 디버깅하는 용도로 좋다.

네트워크를 훈련하는데 60,000개의 이미지를 사용한다. 그다음 네트워크가 얼마나 정확하게 이미지를 분류하는지 10,000개의 이미지로 평가하겠다. 패션 MNIST 데이터셋은 텐서플로에서 바로 임포트하여 적재할 수 있다:

패션 MNIST 샘플 (Zalando, MIT License)

fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

load_data() 함수를 호출하면 네 개의 넘파이(NumPy) 배열이 반환된다:

- train_images, train_labels 배열: 모델 학습에 사용되는 train set.

- test_images, test_labels 배열: 모델 테스트에 사용되는 test set.

 

이미지는 28x28 크기의 넘파이 배열이고 픽셀 값은 0과 255 사이.

레이블(label)은 0에서 9까지의 정수 배열이며, 이 값은 이미지에 있는 옷의 클래스(class)를 나타낸다:

 

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 1s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step

 

Label Class

0 T-shirt/top

1 Trouser

2 Pullover

3 Dress

4 Coat

5 Sandal

6 Shirt

7 Sneaker

8 Bag

9 Ankle boot

각 이미지는 하나의 레이블에 매핑되어 있다. dataset에 클래스 이름이 들어있지 않기 때문에 나중에 이미지를 출력할 때 사용하기 위해 별도의 변수를 만들어 저장한다:

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

2. 데이터 탐색 (Explore the data)

모델을 훈련하기 전에 데이터셋 구조를 살펴본다. 다음 코드는 훈련 세트에 60,000개의 이미지가 있다는 것을 보여준다. 각 이미지는 28x28 픽셀로 표현된다:

train_images.shape len(train_labels) train_labels test_images.shape len(test_labels)

(60000, 28, 28) # train_images엔 60,000개의 이미지가 있음. 28x28 픽셀 60000 array([9, 0, 0, ..., 3, 0, 5], dtype=uint8) # 각 레이블은 0~9사이의 정수 (10000, 28, 28) # test_images엔 10,000개의 이미지가 있음. 28x28 픽셀 10000

3. 데이터 전처리 (Preprocess the data)

네트워크를 훈련하기 전에 데이터를 전처리해야 한다. train set에 있는 첫 번째 이미지를 보면 픽셀 값의 범위가 0~255 사이라는 것을 알 수 있다.

plt.figure() plt.imshow(train_images[0]) plt.colorbar() plt.grid(False) plt.show()

신경망 모델에 주입하기 전에 이 값의 범위를 0~1 사이로 조정한다. 이렇게 하려면 255로 나누어야 하는데, train set과 test set을 동일한 방식으로 전처리하는 것이 중요하다.

train_images = train_images / 255.0 test_images = test_images / 255.0

train set에서 처음 25개 이미지와 그 아래 클래스 이름을 출력해본다. 데이터 포맷이 올바른지 확인하고 네트워크 구성과 train할 준비를 마친다.

plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(train_images[i], cmap=plt.cm.binary) plt.xlabel(class_names[train_labels[i]]) plt.show()

4. 모델 구성 (Build the model)

신경망 모델을 만들려면 모델의 layer를 구성한 다음 모델을 컴파일한다.

- layer 설정(Set up the layers)

신경망의 기본 구성 요소는 (layer)으로, 층은 주입된 데이터에서 표현을 추출한다. 아마도 문제를 해결하는데 더 의미있는 표현이 추출될 것이다. 대부분 딥러닝은 간단한 층을 연결하여 구성된다.

tf.keras.layers.Dense와 같은 층들의 가중치(parameter)는 훈련하는 동안 학습된다.

model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(10, activation='softmax') ])

tf.keras.layers.Flatten: 네트워크의 1st layer로 2차원 배열(28 x 28 픽셀)의 이미지 포맷을 28 * 28 = 784 픽셀의 1차원 배열로 변환한다. 이 층은 이미지에 있는 픽셀의 행을 펼쳐서 일렬로 늘린다. 이 층에는 학습되는 가중치가 없고 데이터를 변환하기만 한다.

tf.keras.layers.Dense: 픽셀을 펼친 후에는 두 개의 층이 연속되어 연결된다. 이 층을 밀집 연결(densely-connected) 또는 완전 연결(fully-connected) 층이라고 부른다.

- 첫 번째 Dense layer: 128개의 노드(또는 뉴런)를 가지며, 두 번째 (마지막) layer는 10개 노드의 소프트맥스(softmax) 층이다. 이 layer은 10개의 확률을 반환하고 반환된 값의 전체 합은 1이다. 각 노드는 현재 이미지가 10개 클래스 중 하나에 속할 확률을 출력한다.

5. 모델 컴파일(Compile the model)

모델을 훈련하기 전에 필요한 몇 가지 설정이 모델 컴파일 단계에서 추가된다:

- 손실 함수(Loss function): 훈련 하는 동안 모델의 오차 측정. 모델의 학습이 올바른 방향으로 향하도록 이 함수를 최소화해야 한다.

- 옵티마이저(Optimizer): 데이터와 손실 함수를 바탕으로 모델의 업데이트 방법을 결정.

- 지표(Metrics): 훈련 단계와 테스트 단계를 모니터링하기 위해 사용한다. 다음 예에서는 올바르게 분류된 이미지의 비율인 정확도를 사용합니다.

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

6. 모델 훈련 (Train the model)

신경망 모델을 훈련하는 단계는 다음과 같다:

훈련 데이터를 모델에 주입-이 예에서는 train_imagestrain_labels 배열.

모델이 이미지와 레이블을 매핑하는 방법을 배운다.

테스트 세트에 대한 모델의 예측을 만듦-이 예에서는 test_images 배열. 이 예측이 test_labels 배열의 레이블과 맞는지 확인.

훈련을 시작하기 위해 model.fit 메서드를 호출하면 모델이 훈련 데이터를 학습:

model.fit(train_images, train_labels, epochs=5)

Train on 60000 samples Epoch 1/5 60000/60000 [==============================] - 4s 74us/sample - loss: 0.4948 - accuracy: 0.8255 Epoch 2/5 60000/60000 [==============================] - 4s 62us/sample - loss: 0.3725 - accuracy: 0.8664 Epoch 3/5 60000/60000 [==============================] - 4s 61us/sample - loss: 0.3349 - accuracy: 0.8774 Epoch 4/5 60000/60000 [==============================] - 4s 62us/sample - loss: 0.3115 - accuracy: 0.8860 Epoch 5/5 60000/60000 [==============================] - 4s 61us/sample - loss: 0.2946 - accuracy: 0.8930 <tensorflow.python.keras.callbacks.History at 0x7f1d480e31d0>

모델이 훈련되면서 손실과 정확도 지표가 출력된다. 이 모델은 훈련 세트에서 약 0.88(88%) 정도의 정확도를 달성한다.

7. 정확도 평가(Evaluate accuracy)

그다음 test set에서 모델의 성능을 비교한다:

test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2) print('\n테스트 정확도:', test_acc)

10000/1 - 1s - loss: 0.2867 - accuracy: 0.8601 테스트 정확도: 0.8601

test set의 정확도가 train set의 정확도보다 조금 낮다. train set의 정확도와 테스트 세트의 정확도 사이의 차이는 과대적합(overfitting) 때문이다

* 과대적합(overfitting)은 머신러닝 모델이 훈련 데이터보다 새로운 데이터에서 성능이 낮아지는 현상을 말한다.

8. 예측 만들기 (Evaluate accuracy)

훈련된 모델을 사용하여 이미지에 대한 예측을 만들 수 있다.

predictions = model.predict(test_images) # 여기서는 테스트 세트에 있는 각 이미지의 레이블을 예측. 첫 번째 예측을 확인: predictions[0]

array([1.6537431e-05, 8.6610027e-07, 1.9992506e-06, 9.1384734e-08, 1.2081074e-06, 1.7686512e-02, 9.6968342e-06, 1.6786481e-01, 2.6662360e-04, 8.1415164e-01], dtype=float32)

이 예측은 10개의 숫자 배열로 나타난다. 이 값은 10개의 옷 품목에 상응하는 모델의 신뢰도(confidence)를 나타낸다. 가장 높은 신뢰도를 가진 레이블을 찾아본다:

np.argmax(predictions[0]) test_labels[0]

9 # 모델은 이 이미지가 앵클 부츠(class_name[9])라고 가장 확신. # 이 값이 맞는지 테스트 레이블을 확인: 9

10개 클래스에 대한 예측을 모두 그래프로 표현:

def plot_image(i, predictions_array, true_label, img): predictions_array, true_label, img = predictions_array[i], true_label[i], img[i] plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(img, cmap=plt.cm.binary) predicted_label = np.argmax(predictions_array) if predicted_label == true_label: color = 'blue' else: color = 'red' plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label], 100*np.max(predictions_array), class_names[true_label]), color=color) def plot_value_array(i, predictions_array, true_label): predictions_array, true_label = predictions_array[i], true_label[i] plt.grid(False) plt.xticks([]) plt.yticks([]) thisplot = plt.bar(range(10), predictions_array, color="#777777") plt.ylim([0, 1]) predicted_label = np.argmax(predictions_array) thisplot[predicted_label].set_color('red') thisplot[true_label].set_color('blue')

0번째 원소의 이미지, 예측, 신뢰도 점수 배열을 확인.

i = 0 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()

i = 12 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()

몇 개의 이미지의 예측을 출력. 올바르게 예측된 레이블은 파란색이고 잘못 예측된 레이블은 빨강색. 숫자는 예측 레이블의 신뢰도 퍼센트(100점 만점)이다. 신뢰도 점수가 높을 때도 잘못 예측할 수 있다.

# 처음 X 개의 테스트 이미지와 예측 레이블, 진짜 레이블을 출력. 

# 올바른 예측은 파랑색으로 잘못된 예측은 빨강색으로 나타낸다. num_rows = 5 num_cols = 3 num_images = num_rows*num_cols plt.figure(figsize=(2*2*num_cols, 2*num_rows)) for i in range(num_images): plt.subplot(num_rows, 2*num_cols, 2*i+1) plot_image(i, predictions, test_labels, test_images) plt.subplot(num_rows, 2*num_cols, 2*i+2) plot_value_array(i, predictions, test_labels) plt.show()

마지막으로 훈련된 모델을 사용하여 한 이미지에 대한 예측을 만든다.

# 테스트 세트에서 이미지 하나를 선택 img = test_images[0] print(img.shape)

(28, 28)

# 이미지 하나만 사용할 때도 배치에 추가 img = (np.expand_dims(img,0)) print(img.shape)

(1, 28, 28)

이제 이 이미지의 예측을 만든다:

predictions_single = model.predict(img) print(predictions_single)

[[1.6537435e-05 8.6609879e-07 1.9992472e-06 9.1384756e-08 1.2081076e-06 1.7686490e-02 9.6968179e-06 1.6786472e-01 2.6662284e-04 8.1415176e-01]]

plot_value_array(0, predictions_single, test_labels) _ = plt.xticks(range(10), class_names, rotation=45)

model.predict는 2차원 넘파이 배열을 반환하므로 첫 번째 이미지의 예측을 선택합니다: np.argmax(predictions_single[0])

9

이전과 마찬가지로 모델의 예측은 레이블 9이다.

출처: 텐서플로우 공식홈페이지

- 영문판

https://www.tensorflow.org/tutorials/keras/classification?hl=en

 

첫 번째 신경망 훈련하기: 기초적인 분류 문제  |  TensorFlow Core

Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수

www.tensorflow.org

- 국문판

https://www.tensorflow.org/tutorials/keras/classification?hl=ko

반응형

+ Recent posts