티스토리 뷰

반응형

저는 파이썬을 조금 했고 처음시작하고 있습니다. 공식문서를 통해 공부하면서 처음보시는 분들도 이해할 수 있게 구글링을 통해 찾아가면서 코드를 하나씩 하나씩 풀이 해 놓겠습니다. 완벽하기 보다는 흐름따라서 쭉 읽으시면 됩니다. 참고 홈페이지는

 

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

 

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

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

www.tensorflow.org

이미지를 분류하는 신경망 모델에 대해 알아보자. 쭉 읽어보면된다. 

 

기본이미지 분류하는 코드가 아래라고 한다.

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

print(tf.__version__)


fashion_mnist = keras.datasets.fashion_mnist

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


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

 

코드 해석

위 코드를 하나씩 보자,
from future import absolute_import, division, print_function, unicode_literals, unicode_literals

이부분은 사실 아직 멀 가져 오는지 몰라도 된다. 넘어가자!

 

import tensorflow as tf

tensorflow를 불러오고 지금부터는 tensorflow를 tf라고 쓰겠다.
from tensorflow import keras

keras는 tensorflow를 쉽게 쓰려고 만든 것이라고 생각하자. (텐서플로 모델을 만들고 훈련할 수 있는 고수준 API인 tf.keras를 사용한다.)


import numpy as np

Numerical Pyrhon의 줄임말이고, 벡터 및 행렬 연산에 있어서 매우 편리한 기능을 제공한다. 또한 데이터 분석 시 사용되는 라이브러리인 pandas와 matplotlib의 기반으로 사용된다.

 

import matplotlib.pyplot as plt

Matplotlib은 파이썬에서 data를 차트나 Plot으로 그려주는 라이브러리 패키지로 가장 많이 사용되는 Data Visualization(데이타 시각화) 패키지 이다. 사용법은 위와 같이 matplotlib.pyplot를 import하면된다.

ex)

from matplotlib import pyplit as plt
plt.plot([1, 2, 4], [10, 11, 9])
plt.show()

위와 같이 하면 (1, 10), (2, 11), (4, 9)를 꼭지점으로 하나씩 직선으로 연결된 그래프가 나온다

 

print(tf.version)

tensorflow의 버전을 확인할 수 있다.

 

fashion_mnist = keras.datasets.fashion_mnist

keras안의 datasets 안의 fashion_mnist를 fashion_mnist라는 변수에 담았군

 

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

load_data() 함수를 호출하면 네 개의 NumPy 배열이 반환된다고 한다. 이때 앞의 train_image랑 train_labels배열은 모델학습에 사용되는 훈련 세트라고 한다. 뒤의 test_images와 test_labels는 테스트에 사용되는 테스트라고 한다. 먼말인지 모르겠지만 일단 쭉쭉 읽어보자. 여기서 나오는 4가지에 대해서는 밑의 데이터 탐색에서 알아보자.

 

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

기본적으로 우리가 분석할 이미지는 28x28 크기의 넘파이 배열이고 픽셀 값은 0과 255 사이이다. label은 0에서 9까지의 정수 배열이다. label 0은 T-shirt/top, 1은 Trouser... 이런식으로 인덱스에 따른 옷의 클래스가 정해져있다. 각 이미지는 위의 label중 하나에 mapping 되어있다. 그런데 데이터 자체에 숫자만 들어가있고 클래스 이름은 들어가 있지 않기 때문에 별도의 리스트로 만들어 class_names라는 변수에 저장한거다. 나중에 이미지 출력 시 숫자가 아닌 class_names[1]이라고 하면 문자로 출력 가능하다.

 

데이터 탐색(train_images, train_labels, test_images, test_labels)

모델을 훈련하기 전에 load_data 함수에나 나온 4가지 NumPy 배열에 대해 알아보자. 

 

> train_images.shape

< (6000, 28, 28)

훈련 세트가 60,000개가 있고 각 이미지는 28x28이라는 것을 알 수 있다. shape는 numpy를 거친 array의 형태(크기)를 확인할 수 있다. 쉽게 말해서 shape 값이 6000, 28, 28이라는 것은 3차원 행렬이고 6000*28*28 크기를 가진 array이다. 

 

> len(train_labels)

< 60000

훈련 set에는 60,000개의 label이 있다.

 

> train_labels

< arr([9, 0, 0, ..., 3, 0, 5], dtype=uint8)

배열안에 0과 9사이의 label이 있군.

 

> test_images.shape

< (10000, 28, 28)

10000개의 이미지와 28x28 픽셀로 표현된다.

 

> len(test_labels)

< 10000

 

 

데이터 전처리

import matplotlib.pyplot as plt 를 사용한다.

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

 

코드분석

figure 생성

import numpy as np
import matplitlib.pyplot as plt
fig = plt.figure()
plt.show()

plt.figure()는 새로운 figure를 생성해 준다.

plt.show()는 생성된 모든 figure를 보여준다.

이 상태에서는 figure를 생성하기만 하고 아무것도 추가하지 않았기 때문에 회색 창만 뜬다.

fig = plt.figure(figsize=(9,9))

최초 창의 크기를 가로 세로 9인치로 설정하는 코드다. 물론 일반적인 프로그램 창처럼 창 구석에 마우스 를 가져다 대어 크기르 조절해도 된다.

 

inshow() 매서드는 이미지를 출력하는 매서드다. 즉, 위의 코드에서는 train_images중 첫번째 이미지를 출력 할 수 있다.

 

colorbar는 inshow()를 통해 발생된 axesImage들을 연결해 주는 클래스다.

 

 

그리드(grid)의 작성

pyplot에서는 그래프에 그리드를 그릴 수 있도록 관련 함수를 제공한다.

grid(b=None, which='major', axis='both', **kwargs)
  • b - bool, None - grid를 작성할지 안 할지 결정해 주는 입력인자이다. 만약 **kwargs가 입력되어 있다면 b인자는 자동으로 True이다
  • which - str - major와 minor 틱에 대해 그리드 라인을 그리는 것을 결정하는 인자이다.
    • 'major'는 메이저 틱에 대한 그리드를 그리도록 설정
    • 'minor는 마이너 틱에 대한 그리드를 그리도록 설정
    • 'both'는 메이저 마이너 두 틱 모두 그리드를 그리도록 설정
  • axis - str - 그리드를 그릴 축을 설정하는 입력인자이다.
    • 'both'는 두 축 모두에 그리드를 그리도록 설정한다.
    • 'x'는 x 축에만 그리드를 그리도록 설정한다.
    • 'y'는 y축에만 그리드를 그리도록 설정한다.
  • **kwargs -  2D 선의 속성을 설정한다.

 

 

신경망 모델에 주입하기 전에 이 값의 범위를 0~1 사이로 조정한다. 훈련 세트와 테스트 세트를 동일한 방식으로 전처리 하는 것이 중요하다.

train_images = train_images /255.0
test_image = test_images /255.0

 

모델 구성(Build the model)

심경망 모델을 만들기위해 모델의 layer를 구성한 후 모델을 컴파일 한다.

 

layer(층) 설정

신경망의 기본구성 요소는 층(layer)이다. layer는 layer에 공급된 데이터로부터 표현을 추출하고, 그 표현은 당면한 문제에 의미가 있다. 대부분의 딥러닝은 간단한 layer들을 연결하는 것으로 구성된다. 'tk.keras.layers.Dense'와 같은 대부분의 layers는 훈련 동안 배워지는 변수들을 가진다.

 

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

코드설명

'tf.keras.layers.Flatten'는 이 network의 첫번째 레이아웃이다. 이 layer는 이미지의 형태를 이차원 배열(28 by 28 pixels)에서 일차원 배열(28*28=784 pixels)로 변환시키다. 이 layer는 학습할 변수를 가지지 않고 단지, 데이터만 reformats 한다.

픽셀들의 패턴화 이후에, network는 2개의 'tf.keras.layers.Dense' layers를 구성한다. 이건 밀접하고 왖너하게 연결된 신경 layers이다. 첫번째 Dense layer는 128개의 노드를 가지고, 2번째 layer는 길이가 10인 logit 배열을 반환한다. 각 노드에는 현재 이미지가 10개의 클래스 중 하나에 속한다는 것을 나타내는 점수가 포함된다.

 

모델 컴파일하기

모델을 훈련 시키기 전에 몇사지의 설정이 필요하다. 이러한 설정은 컴파일 단계에서 추가된다.

Loss function (손실) - 훈련이 얼마나 정확한지를 평가한다. 모델이 옳바른 방향으로 가기 위해 이 기능을 최소화 해야한다. 즉, 적은 값이 나와야 좋은거다.

Optimizer - 보는 데이터와 loss function을 바탕으로 모델을 최신화 시키는 방법이다.

Metrics (지표) - 테스트하고 훈련하는 단계를 감시한다. 

아래의 예는 정확하게 분류 된 이미지의 일부인 정확도를 활용한다.

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

 

모델 훈련

the neural network model 훈련은 다음 스텝이 필요하다.

  1. training data를 모델에 넣자. 여기서의 training data는 train_images와 train_labels 배열이다.
  2. 모델은 이미지와 레이블을 관련짓는 방법을 학습한다.
  3. 모델에 테스트 셋(test_images)에 대한 예측을 요청한다.
  4. 예측이 test_labels 배열의 레이블과 일치하는지 확인하자.

 

모델에 데이터 넣기

훈련을 시작하기 위해서 `model.fit` 메소드를 호출하자. 이 메소드는 모델을 training data에 적합하게 한다.

model.fit(train_images, train_labels, epochs=10)
Epoch 1/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.4967 - accuracy: 0.8257
Epoch 2/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3764 - accuracy: 0.8641
Epoch 3/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3400 - accuracy: 0.8762
Epoch 4/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3156 - accuracy: 0.8841
Epoch 5/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2954 - accuracy: 0.8913
Epoch 6/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2804 - accuracy: 0.8964
Epoch 7/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2672 - accuracy: 0.9015
Epoch 8/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2569 - accuracy: 0.9040
Epoch 9/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2478 - accuracy: 0.9087
Epoch 10/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2402 - accuracy: 0.9110

<tensorflow.python.keras.callbacks.History at 0x7f979c4540b8>

결과를 보면 모델을 훈련하면서 생성하는 loss와 accutacy metrics를 보여준다. 이 모델을 보면 약 0.91(91%)정확도에 도달한다.

 

 

정확성 평가

이제 모델이 test dataset을 얼마나 잘 수행하는지 비교해 보자.

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
313/313 - 0s - loss: 0.3361 - accuracy: 0.8819
Test accuracy: 0.8819000124931335

 test dataset의 정확도는 training dataset의 정확도 보다 약간 낮다. 이러한 차이를 overfitting이라고 할 수 있다. overfitting은 머신러닝 모델에 훈련 데이터와 비교해 볼 때, 이전에 볼수 없었던 input값이 들어오는 경우에 발생한다.

 

 

예측

모델을 훈련하면 우리는 이미지에 대해 예측을 할 수 있다. 모델의 선형 출력, 로직을 확률로 변환하기 위해 softmax 를 사용하면 해석하기가 더 쉽다.

probability_model = tf.keras.Sequential([model, 
                                         tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)

여기서 모델은 테스트 세트의 각 이미지에 대한 리이블을 예측했다.

 

 

predictions[0]
array([3.7470576e-07, 2.1464190e-09, 8.1236013e-09, 6.0691945e-09,
       1.5032628e-09, 4.2749266e-03, 6.4576420e-09, 1.3718357e-02,
       2.8398659e-07, 9.8200607e-01], dtype=float32)

첫번째 예측한 것을 보자. 10개의 벼열이 보이는데, 이건 모델의 신뢰도를 나타낸 것이다 이 이미지는 10개의 서로 다른 옷들의 각각과 일치한다. 이걸 보면 layer 중 가장 높은 신뢰도 값을 확인 할 수 있다.

 

np.argmax(predictions[0])
9

9번은 위에서 ankle boot(class_names[9])다. 즉, 이 이미지는 ankle boot라고 가장 확신하고 있는 것이다.

 

 

test_labels[0]
9

테스트 레이블을 살펴보면 이 부류가 올바르다는 것을 알 수 있다.

 

10개의 클래스 예츨의 전체 세트를 보기위해 그래프로 표시해 보자.

def plot_image(i, predictions_array, true_label, img):
  predictions_array, true_label, img = predictions_array, 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, true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  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[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

 

이제 여러 이미지를 그려보자. 확률이 높아도 모델을 잘 못 찾을 수 도 있다.

# Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and incorrect predictions in red.
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[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함