본문 바로가기

Information/구글 텐서플로우 자격증 따기

[코세라 강좌] 2주차 - 실습(1/2)

반응형

Fashion-MNIST 데이터에 대한 Classification 프로그램 실습

 

Fashion-MNIST 데이터

핸드 라이팅한 9종의 그레이스케일 의상 사진 7만장을 모아 놓은 것 (https://github.com/zalandoresearch/fashion-mnist)

 

참조 그림들

 

 

 

 

 

 

9종 레이블

 

Label Description
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot

 

테스트 코드

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

np.set_printoptions(linewidth=200)
plt.imshow(training_images[0])

print(training_labels[0])
print(training_images[0])

#normalize to 0~1
training_images  = training_images / 255.0
test_images = test_images / 255.0

#modeling
# Flatten: make to 1 dimensional set
# relu: X if X>0 else 0
# softmax: picks the biggest one,
#           for example, [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05] ->  [0,0,0,0,1,0,0,0,0]
model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),
                                    tf.keras.layers.Dense(128, activation=tf.nn.relu),
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])

model.compile(optimizer = tf.optimizers.Adam(),
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)

#evaluation
model.evaluate(test_images, test_labels)

#classifications
classifications = model.predict(test_images)
print(classifications[0]) # print 10 probability number. the last one is biggest
print(test_labels[0])     # print 9

 

코드 설명

Fashion-MNIST 데이터 가져오기

mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

 

'https://storage.googleapis.com/tensorflow/tf-keras-datasets/'에 있는 4개의 압축파일을 다운로드하고, 거기에서 패션 이미지를 추출해냄.

 

mnist.load_data는,

Returns:
      Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.

      **x_train, x_test**: uint8 arrays of grayscale image data with shape
        (num_samples, 28, 28).

      **y_train, y_test**: uint8 arrays of labels (integers in range 0-9)
        with shape (num_samples,).

 

Normalization(정규화)

#normalize to 0~1
training_images  = training_images / 255.0
test_images = test_images / 255.0

[0,255] 사이의 값을 [0.0, 1.0] 사이 값으로 변환

 

정규화하는 이유는,

  • 데이터의 종류가 여러 개일 경우는 각 데이터의 단위를 비슷한 범위를 가지도록 정규화를 하는게 필수.
    예를들어, 어떤 값 예측을 하는데 있어 변수가 2개(A, B), A의 범위는 [0.0, 1.0], B의 범위는 [0, 10000]이라면, 정규화 하지 않고 A,B에 의한 예측을 하면 B의 변동성에 묻혀서 A의 변동성은 사라져 버림. 따라서 B의 범위도 A와 동일하게 되도록 정규화 해줘야 함
  • 데이터가 1개(위의 칼라 값 0~255) 인데도 정규화를 하는 이유는, 적은 epoch 횟수에도 학습이 가능하도록 하기 위함임.
     
    위 예제에서 정규화를 하지 않고 epochs=5로 그대로 놔두고 돌리면, 주어지 테스트 데이터에 대해 답이 9라는 것을 찾긴 하는데, 그 확률이 52.9% 정도로 떨어짐.  (정규화를 한 경우는 95%) (정규화를 안하고 95% 정도에 도달하려면 epochs=9로 해야함)

    즉, 큰 값에 대해서 에러를 보정해가면 목표값에 찾아가기보다는, 적은 값에 대해서 목표값에 도달하는 것이 더 쉽다는 것. (물론 에러 보정 값보다도 더 작은 값이면 목표값을 지나쳐 버리는 문제가 있겠지만)
위 정규화하는 이유에 대한 참고 사이트는 https://medium.com/@urvashilluniya/why-data-normalization-is-necessary-for-machine-learning-models-681b65a05029

 

모델링

#modeling
# Flatten: make to 1 dimensional set
# relu: X if X>0 else 0
# softmax: picks the biggest one,
#           for example, [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05] ->  [0,0,0,0,1,0,0,0,0]
model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),
                                    tf.keras.layers.Dense(128, activation=tf.nn.relu),
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])

model.compile(optimizer = tf.optimizers.Adam(),
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)

 

  • Flatten: 입력 이미지 데이터 형태가 (28 x 28)의 2차원 배열이어서, 이를 1차원 배열로 바꾸는 것
  • Dense(128, ...): 히든 레이어의 수를 128로 한 것. 바꿔가며 테스트할 수 있음. 복잡한 이미지도 아니고 칼라도 아니기에 더 늘려도 그닥 효과를 보지는 못함
  • relu: 0보다 큰 값은 X, 0 이하인 값은 0으로 처리하는 함수  (Rectified Linear Unit)

  • softmax: 배열중에서 가장 큰 값을 1로하고 나머지를 0으로 만듦
  • Adam: 경사하강법 대신에 요즘 많이 쓰이고 있는 최적화 함수

 

실행

파이참에서 돌려보면 아래와 같은 결과 보임

[1.3193754e-04 3.8016094e-07 4.9900282e-06 4.0231498e-07 2.3794528e-06 3.4480866e-02 1.9938405e-05 3.7106015e-02 4.3960899e-04 9.2781341e-01]
9

 

-끝-

반응형