딥러닝 소개 - 인공 신경망 소개

Page content

강의 홍보

공지

  • 본 Tutorial은 교재 핸즈온 머신러닝 2판를 활용하여 본 강사로부터 국비교육 강의를 듣는 사람들에게 자료 제공을 목적으로 제작하였습니다.

  • 강사의 주관적인 판단으로 압축해서 자료를 정리하였기 때문에, 자세하게 공부를 하고 싶은 분은 반드시 교재를 구매하실 것을 권해드립니다.

책 정말 좋습니다! 꼭 구매하세요!

개요

  • 인경 신경망은(Artificial Neural Network)을 촉발시킨 근원임
    • 뇌에 있는 생물학적 뉴런의 네트워크에서 영감을 받은 머신러닝 모델
  • 활용예제
    • 수백만개의 이미지 분류
    • 수백만개의 비디어 추천
    • 매우 복잡한 문제를 풀 때 유용한 머신러닝 모델
  • Keras API
    • 케라스는 신경망 구축, 훈련, 평가, 실행을 목적으로 설계된 API이자, 프레임워크

(1) 주요 환경 설정

  • 주요 환경 설정은 아래와 같이 정의합니다.
# 파이썬 ≥3.5 필수
import sys
assert sys.version_info >= (3, 5)

# 사이킷런 ≥0.20 필수
import sklearn
assert sklearn.__version__ >= "0.20"

# 텐서플로 ≥2.0 필수
import tensorflow as tf
assert tf.__version__ >= "2.0"
from tensorflow import keras

# 공통 모듈 임포트
import numpy as np
import pandas as pd
import os

# 노트북 실행 결과를 동일하게 유지하기 위해
np.random.seed(42)

# 깔끔한 그래프 출력을 위해
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)

# 그림을 저장할 위치
PROJECT_ROOT_DIR = "."
CHAPTER_ID = "ann"
IMAGES_PATH = os.path.join(PROJECT_ROOT_DIR, "images", CHAPTER_ID)
os.makedirs(IMAGES_PATH, exist_ok=True)

def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300):
    path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension)
    print("그림 저장:", fig_id)
    if tight_layout:
        plt.tight_layout()
    plt.savefig(path, format=fig_extension, dpi=resolution)

# 불필요한 경고를 무시합니다 (사이파이 이슈 #5998 참조)
import warnings
warnings.filterwarnings(action="ignore", message="^internal gelsd")

I. 퍼셉트론

  • 1957년, 프랑크 로젠플라트가 제안
  • 헤비사이드 계단 함수 (교재, P. 357)
    • 입력의 선형 조합을 계산해 임계값을 기준으로 이진분류 (양성, 음성)
  • 퍼셉트론은 층이 하나뿐인 TLU(Threshold Logic Unit)로 구성됨
    • 모든 뉴런이 이전 층의 모든 뉴런과 연결되어 있을 때 완전 연결 층(Fully Connected Layer) 또는 밀집 층(Dense Layer)라고 부름

(1) 사이킷런 예제

  • Perceptron 클래스 제공
  • 교재 360페이지에 있는 소스 코드보다 아래 소스 코드를 참고
  • 사이킷런 향후 버전에서 max_itertol 매개변수의 기본값이 바뀌기 때문에 경고를 피하기 위해 명시적으로 지정
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron

iris = load_iris()
X = iris.data[:, (2, 3)]  # 꽃잎 길이, 꽃잎 너비
y = (iris.target == 0).astype(np.int)

per_clf = Perceptron(max_iter=1000, tol=1e-3, random_state=42)
per_clf.fit(X, y)

y_pred = per_clf.predict([[2, 0.5]])
y_pred
array([1])

(2) 다층 퍼셉트론

  • (1969년) 마빈 민스키와 시모어 페퍼트는 퍼셉트론의 여러가지 심각한 약점 언급, 특히 간단한 문제도 풀 수 없음 확인
  • 그러나, 다층 퍼셉트론을 훈련할 방법을 찾기 위해 노력했으나 성공하지 못함

(3) 역전파

  • 교재 361페이지 참조
    • 다층 퍼셉트론은 크게 입력-은닉-출력층으로 구성됨
    • 은닉층을 여러개 쌓아 올린 인공 신경망을 심층 신경망(DNN)이라고 부름
  • 딥러닝은 여러개를 쌓아 올리는 심층 신경망을 연구하는 분야임
  • 1986년, 역전파 훈련 알고리즘 소개하는 논문 공개(by 데이비드 루멜하트, 제프리 힌턴, 로날드 윌리엄스)
    • 그레이디언트를 자동으로 계산(자동 미분)하는 경사 하강법
    • 네트워크를 두번 통과함 (정방향, 역방향)
    • 목적은 오차를 감소시키기 위해 각 연결 가중치와 편향값이 어떻게 바뀌어야 할지 알 수 있음

(4) 활성화 함수

  • 경사 하강법이 잘 작동할 수 있도록 다층 퍼셉트론 구조에 중요한 변화를 주는데, 이를 활성화 함수라 함
  • 활성화 함수의 주 목적은, 문제 해결을 위해 도입된 것
    • 선형 변환을 해도 비선형 문제는 해결하지 못함, (예: 선형회귀와 로지스틱회귀의 차이점)
    • 선형변환에 비선형을 주는 것이 활성화 함수이며, 다만 어떻게 줄 것인지에 따라 종류가 나눠짐
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def relu(z):
    return np.maximum(0, z)

def derivative(f, z, eps=0.000001):
    return (f(z + eps) - f(z - eps))/(2 * eps)
z = np.linspace(-5, 5, 200)

plt.figure(figsize=(11,4))

plt.subplot(121)
plt.plot(z, np.sign(z), "r-", linewidth=1, label="Step")
plt.plot(z, sigmoid(z), "g--", linewidth=2, label="Sigmoid")
plt.plot(z, np.tanh(z), "b-", linewidth=2, label="Tanh")
plt.plot(z, relu(z), "m-.", linewidth=2, label="ReLU")
plt.grid(True)
plt.legend(loc="center right", fontsize=14)
plt.title("Activation functions", fontsize=14)
plt.axis([-5, 5, -1.2, 1.2])

plt.subplot(122)
plt.plot(z, derivative(np.sign, z), "r-", linewidth=1, label="Step")
plt.plot(0, 0, "ro", markersize=5)
plt.plot(0, 0, "rx", markersize=10)
plt.plot(z, derivative(sigmoid, z), "g--", linewidth=2, label="Sigmoid")
plt.plot(z, derivative(np.tanh, z), "b-", linewidth=2, label="Tanh")
plt.plot(z, derivative(relu, z), "m-.", linewidth=2, label="ReLU")
plt.grid(True)
#plt.legend(loc="center right", fontsize=14)
plt.title("Derivatives", fontsize=14)
plt.axis([-5, 5, -0.2, 1.2])

save_fig("activation_functions_plot")
plt.show()
그림 저장: activation_functions_plot

png

  • 하이퍼폴릭 탄젠트 함수: $tanh(z)=2\sigma(2z)-1$. 로지스틱 함수와 같은 0~1 사이이고, 출력 범위는 -1~1 사이임
  • ReLU 함수: $ReLU(z)=max(0,z)$. 연속적이지만, $z=0$에서 미분 가능하지 않음. $z<0$일 경우에는 0이다. 그러나, 실제로 잘 작동하고 계산 속도가 빠르다는 장점이 있어 기본 활성화 함수가 됨.

II. 회귀를 위한 다층 퍼셉트론(MLP)

  • 회귀 모형에 적용 가능, 이 때에는 출력 뉴런이 하나만 필요함
  • 뉴런의 출력값이 예측값임.
  • 회귀 MLP의 구조는 아래와 같음
하이퍼파라미터일반적인 값
입력 뉴런 수특성마다 하나
은닉층 수문제에 따라 다름 (1~5)
은닉층의 뉴런 수문제에 따라 다름 (10~100)
출력 뉴런 수예측 차원마다 하나
은닉층의 활성화 함수주로 ReLU
출력층의 활성화 함수없음. 또는 출력이 양수일 때, ReLU/softplus
손실 함수MSE
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

housing = fetch_california_housing()

X_train_full, X_test, y_train_full, y_test = train_test_split(housing.data, housing.target, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, random_state=42)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_valid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
np.random.seed(42)
tf.random.set_seed(42)
model = keras.models.Sequential([
    keras.layers.Dense(30, activation="relu", input_shape=X_train.shape[1:]),
    keras.layers.Dense(1)
])
model.compile(loss="mean_squared_error", optimizer=keras.optimizers.SGD(lr=1e-3))
history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid))
mse_test = model.evaluate(X_test, y_test)
X_new = X_test[:3]
y_pred = model.predict(X_new)
Epoch 1/20
363/363 [==============================] - 1s 2ms/step - loss: 1.6419 - val_loss: 0.8560
Epoch 2/20
363/363 [==============================] - 1s 2ms/step - loss: 0.7047 - val_loss: 0.6531
Epoch 3/20
363/363 [==============================] - 1s 2ms/step - loss: 0.6345 - val_loss: 0.6099
Epoch 4/20
363/363 [==============================] - 1s 2ms/step - loss: 0.5977 - val_loss: 0.5658
Epoch 5/20
363/363 [==============================] - 1s 2ms/step - loss: 0.5706 - val_loss: 0.5355
Epoch 6/20
363/363 [==============================] - 1s 2ms/step - loss: 0.5472 - val_loss: 0.5173
Epoch 7/20
363/363 [==============================] - 1s 2ms/step - loss: 0.5288 - val_loss: 0.5081
Epoch 8/20
363/363 [==============================] - 1s 2ms/step - loss: 0.5130 - val_loss: 0.4799
Epoch 9/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4992 - val_loss: 0.4690
Epoch 10/20
363/363 [==============================] - 1s 1ms/step - loss: 0.4875 - val_loss: 0.4656
Epoch 11/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4777 - val_loss: 0.4482
Epoch 12/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4688 - val_loss: 0.4479
Epoch 13/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4615 - val_loss: 0.4296
Epoch 14/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4547 - val_loss: 0.4233
Epoch 15/20
363/363 [==============================] - 1s 1ms/step - loss: 0.4488 - val_loss: 0.4176
Epoch 16/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4435 - val_loss: 0.4123
Epoch 17/20
363/363 [==============================] - 1s 1ms/step - loss: 0.4389 - val_loss: 0.4071
Epoch 18/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4347 - val_loss: 0.4037
Epoch 19/20
363/363 [==============================] - 1s 2ms/step - loss: 0.4306 - val_loss: 0.4000
Epoch 20/20
363/363 [==============================] - 1s 1ms/step - loss: 0.4273 - val_loss: 0.3969
162/162 [==============================] - 0s 964us/step - loss: 0.4212
  • 모형의 그래프를 그려본다.
plt.plot(pd.DataFrame(history.history))
plt.grid(True)
plt.gca().set_ylim(0, 1)
plt.show()

png

  • 마지막으로 예측값을 적용한다.
y_pred
array([[0.38856643],
       [1.6792021 ],
       [3.1022794 ]], dtype=float32)

III. 분류를 위한 다층 퍼셉트론(MLP)

  • 이진 분류 문제는 로지스틱 활성화 함수를 가진 하나의 출력 뉴런만 필요
  • 다층 퍼셉트론은 다중 레이블 이진 분류 문제를 쉽게 처리할 수 있도록 함
    • 이 때, 두개의 출력 뉴런이 필요
    • 만약, 다중분류이면, 다중분류의 숫자만큼 출력 뉴런이 필요함
  • 분류 MLP의 전형적인 구조는 다음과 같다.
하이퍼파라미터이진분류다중 레이블 분류다중 분류
입력층과 은닉층회귀와 동일회귀와 동일회귀와 동일
출력 뉴런 수1개레이블마다 1개클래스마다 1개
출력층의 활성화 함수로지스틱 함수로지스틱 함수소프트맥스 함수
손실함수크로스 엔트로피크로스 엔트로피크로스 엔트로피

(1) 모듈 불러오기

  • 모듈을 불러옵니다.
import tensorflow as tf
from tensorflow import keras

print(tf.__version__)
print(keras.__version__)
2.2.0
2.3.0-tf

(2) 데이터 불러오기

  • Fashion MNIST를 불러옵니다.
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
  • 이미지의 크기는 28 x 28크기의 배열이다.
  • 또한 픽셀 강도가 실수(0.0에서 255.0까지)가 아니라 정수(0에서 255까지)로 표현되어 있다.
print(X_train_full.shape)
print(X_train_full.dtype)
(60000, 28, 28)
uint8

(3) 데이터셋 분리

  • 훈련데이터와 테스트 데이터로 분리합니다.
  • 간편하게 픽셀 강도를 255.0으로 나누너 0~1 사이 범위로 조정함.
X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test / 255.
  • 이제 예측하려는 레이블을 확인해보자.
y_train
array([4, 0, 7, ..., 3, 0, 5], dtype=uint8)
  • 각 단계별 레이블 이름을 다음과 같이 정의한다.
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
               "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
  • 훈련 세트에 있는 첫번째 이미지 이름은 코트이다.
class_names[y_train[0]]
'Coat'
  • 모형 학습 전, 데이터세트의 크기가 동일한지 확인한다.
print(X_valid.shape)
print(X_test.shape)
(5000, 28, 28)
(10000, 28, 28)
  • 28, 28이 다르면 모형 예측이 되지 않는다.

(4) 데이터 시각화

  • 시각화를 통해, 실제 이미지가 어떻게 생겼는지 확인해본다.
plt.imshow(X_train[0], cmap="binary")
plt.axis('off')
plt.show()

png

  • 조금 더 자세하게 데이터를 출력해보자.
n_rows = 4
n_cols = 10
plt.figure(figsize=(n_cols * 1.2, n_rows * 1.2))
for row in range(n_rows):
    for col in range(n_cols):
        index = n_cols * row + col
        plt.subplot(n_rows, n_cols, index + 1)
        plt.imshow(X_train[index], cmap="binary", interpolation="nearest")
        plt.axis('off')
        plt.title(class_names[y_train[index]], fontsize=12)
plt.subplots_adjust(wspace=0.2, hspace=0.5)
save_fig('fashion_mnist_plot', tight_layout=False)
plt.show()
그림 저장: fashion_mnist_plot

png

(5) 모형 만들기

  • 이제 신경망 모형을 만든다.
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
  • 위 모형에 대한 구체적인 설명은 교재 373 페이지를 확인한다.
keras.backend.clear_session()
np.random.seed(42)
tf.random.set_seed(42)
  • 코드는 일종의 실험 재현성을 위한 코드이다.
model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dense(300, activation="relu"),
    keras.layers.Dense(100, activation="relu"),
    keras.layers.Dense(10, activation="softmax")
])
  • summary()메서드는 모델에 있는 모든 층을 출력함
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0         
_________________________________________________________________
dense (Dense)                (None, 300)               235500    
_________________________________________________________________
dense_1 (Dense)              (None, 100)               30100     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                1010      
=================================================================
Total params: 266,610
Trainable params: 266,610
Non-trainable params: 0
_________________________________________________________________
  • 모형이 만들어가지는 과정을 출력할 수 있다.
keras.utils.plot_model(model, "my_fashion_mnist_model.png", show_shapes=True)

png

(6) 모델 컴파일

  • 모델을 만들고 나서 compile() 메서드를 호출하여 사용할 손실 함수와 옵티마이저(optimizer)를 지정한다.
model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd",
              metrics=["accuracy"])
  • 위 모형에 대한 구체적인 설명은 교재 377페이지를 참고한다.

(7) 모델 훈련

  • 케라스는 에포크 횟수를 전달함
  • 에포크가 끝날 때 마다 ���증 세트를 사용해 손실과 추가적인 측정 지표를 계산
history = model.fit(X_train, y_train, epochs=30,
                    validation_data=(X_valid, y_valid))
Epoch 1/30
1719/1719 [==============================] - 7s 4ms/step - loss: 0.7237 - accuracy: 0.7643 - val_loss: 0.5213 - val_accuracy: 0.8226
Epoch 2/30
1719/1719 [==============================] - 8s 4ms/step - loss: 0.4842 - accuracy: 0.8318 - val_loss: 0.4353 - val_accuracy: 0.8526
Epoch 3/30
1719/1719 [==============================] - 8s 5ms/step - loss: 0.4391 - accuracy: 0.8458 - val_loss: 0.5304 - val_accuracy: 0.7996
Epoch 4/30
1719/1719 [==============================] - 8s 5ms/step - loss: 0.4123 - accuracy: 0.8566 - val_loss: 0.3916 - val_accuracy: 0.8650
Epoch 5/30
1719/1719 [==============================] - 7s 4ms/step - loss: 0.3939 - accuracy: 0.8622 - val_loss: 0.3745 - val_accuracy: 0.8690
Epoch 6/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3752 - accuracy: 0.8675 - val_loss: 0.3718 - val_accuracy: 0.8724
Epoch 7/30
1719/1719 [==============================] - 7s 4ms/step - loss: 0.3631 - accuracy: 0.8716 - val_loss: 0.3616 - val_accuracy: 0.8736
Epoch 8/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3514 - accuracy: 0.8747 - val_loss: 0.3853 - val_accuracy: 0.8608
Epoch 9/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3412 - accuracy: 0.8793 - val_loss: 0.3573 - val_accuracy: 0.8718
Epoch 10/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3317 - accuracy: 0.8821 - val_loss: 0.3420 - val_accuracy: 0.8786
Epoch 11/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3238 - accuracy: 0.8839 - val_loss: 0.3450 - val_accuracy: 0.8770
Epoch 12/30
1719/1719 [==============================] - 6s 3ms/step - loss: 0.3147 - accuracy: 0.8865 - val_loss: 0.3306 - val_accuracy: 0.8832
Epoch 13/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3077 - accuracy: 0.8896 - val_loss: 0.3274 - val_accuracy: 0.8868
Epoch 14/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.3019 - accuracy: 0.8917 - val_loss: 0.3420 - val_accuracy: 0.8772
Epoch 15/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2943 - accuracy: 0.8940 - val_loss: 0.3222 - val_accuracy: 0.8842
Epoch 16/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2889 - accuracy: 0.8971 - val_loss: 0.3090 - val_accuracy: 0.8906
Epoch 17/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2835 - accuracy: 0.8979 - val_loss: 0.3546 - val_accuracy: 0.8736
Epoch 18/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2775 - accuracy: 0.9006 - val_loss: 0.3136 - val_accuracy: 0.8902
Epoch 19/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2726 - accuracy: 0.9024 - val_loss: 0.3110 - val_accuracy: 0.8904
Epoch 20/30
1719/1719 [==============================] - 8s 4ms/step - loss: 0.2671 - accuracy: 0.9036 - val_loss: 0.3271 - val_accuracy: 0.8818
Epoch 21/30
1719/1719 [==============================] - 6s 3ms/step - loss: 0.2621 - accuracy: 0.9056 - val_loss: 0.3066 - val_accuracy: 0.8926
Epoch 22/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2576 - accuracy: 0.9071 - val_loss: 0.2968 - val_accuracy: 0.8972
Epoch 23/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2533 - accuracy: 0.9086 - val_loss: 0.2997 - val_accuracy: 0.8936
Epoch 24/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2484 - accuracy: 0.9104 - val_loss: 0.3079 - val_accuracy: 0.8890
Epoch 25/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2442 - accuracy: 0.9127 - val_loss: 0.2977 - val_accuracy: 0.8948
Epoch 26/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2404 - accuracy: 0.9138 - val_loss: 0.3069 - val_accuracy: 0.8906
Epoch 27/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2360 - accuracy: 0.9155 - val_loss: 0.3040 - val_accuracy: 0.8940
Epoch 28/30
1719/1719 [==============================] - 6s 4ms/step - loss: 0.2327 - accuracy: 0.9166 - val_loss: 0.3003 - val_accuracy: 0.8934
Epoch 29/30
1719/1719 [==============================] - 6s 3ms/step - loss: 0.2284 - accuracy: 0.9181 - val_loss: 0.3050 - val_accuracy: 0.8908
Epoch 30/30
1719/1719 [==============================] - 6s 3ms/step - loss: 0.2248 - accuracy: 0.9203 - val_loss: 0.3055 - val_accuracy: 0.8934
  • 모형을 만들고 훈련 시키는 것은 위 과정이 전부이다.
  • 그러나, 초보자들이 흔히 하는 실수는 훈련 데이터와 검증 데이터의 크기가 맞지 않을 때 예외가 발생한다.

(8) 모델 평가

  • 이제 모델을 평가합니다. 모델을 평가할 때는 보통 시각화를 통해서 확인합니다.
  • 그리고, evaluate() 함수를 사용합니다.
import pandas as pd

pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1)
save_fig("keras_learning_curves_plot")
plt.show()
그림 저장: keras_learning_curves_plot

png

  • 훈련 손실과 검증 손실은 감소하며, 또한 검증 곡선이 훈련 곡선과 가까우면, 과대적합하지 않았다는 증거가 된다.
model.evaluate(X_test, y_test)
313/313 [==============================] - 1s 3ms/step - loss: 0.3382 - accuracy: 0.8822





[0.3381877839565277, 0.8822000026702881]

(9) 모델 예측

  • 이제 predict() 함수를 사용해 새로운 샘플에 대해 예측을 만든다.
  • 새로운 샘플은 존재하지 않기 때문에 처음 3개의 샘플만 사용한다.
X_new = X_test[:3]
y_proba = model.predict(X_new)
print(y_proba.round(2))
y_pred = model.predict_classes(X_new)
print(y_pred)
print(np.array(class_names)[y_pred])
[[0.   0.   0.   0.   0.   0.01 0.   0.03 0.   0.96]
 [0.   0.   0.99 0.   0.01 0.   0.   0.   0.   0.  ]
 [0.   1.   0.   0.   0.   0.   0.   0.   0.   0.  ]]
[9 2 1]
['Ankle boot' 'Pullover' 'Trouser']
  • 가장 높은 확률을 가진 클래스에만 관심이 있다면, predict_classes() 사용한다.
y_new = y_test[:3]
y_new
array([9, 2, 1], dtype=uint8)
  • 실제 학습한 코드가 제대로 분류 되었는지 실제 이미지를 확인하는 차원에서의 코드를 다음과 같이 구현한다.
plt.figure(figsize=(7.2, 2.4))
for index, image in enumerate(X_new):
    plt.subplot(1, 3, index + 1)
    plt.imshow(image, cmap="binary", interpolation="nearest")
    plt.axis('off')
    plt.title(class_names[y_test[index]], fontsize=12)
plt.subplots_adjust(wspace=0.2, hspace=0.5)
save_fig('fashion_mnist_images_plot', tight_layout=False)
plt.show()
그림 저장: fashion_mnist_images_plot

png

IV. 금일 과제

  • 교재를 참조하여 아래 예제를 연습한다.
    • 함수형 API 모델 만들기
    • 모형의 저장과 복원
    • 훈련 과정에서의 Callback 사용하기

V. What’s Next

  • 다음 시간에는 심층 신경망에 대해 학습하도록 한다.