본문 바로가기
스터디/딥러닝

핸즈온 머신러닝(Hands-On Machine Learning) 10장 - 케라스를 사용한 인공 신경망 (2)-1

by ag_zero 2021. 10. 27.
728x90

10.2 케라스로 다층 퍼셉트론 구현하기

 

10.2.2 시퀀셜 API를 사용하여 이미지 분류기 만들기

 

import tensorflow as tf
from tensorflow import keras

 

 

먼저 MNIST 데이터셋을 로드

케라스는 keras.datasets에 널리 사용하는 데이터셋을 로드하기 위한 함수를 제공한다.

이 데이터셋은 이미 훈련 세트와 테스트 세트로 나누어져 있어 훈련 세트를 더 나누어 검증 세트를 만드는 것이 좋다.

fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()

 

전체 훈련 세트를 검증 세트와 (조금 더 작은) 훈련 세트로 나누어 보죠. 또한 픽셀 강도를 255로 나누어 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.
plt.imshow(X_train[0], cmap="binary")
plt.axis('off')
plt.show()

출력 결과

 

레이블은 0에서 9까지 (uint8로 표현된) 클래스 아이디이다.

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"]

 

 

샘플 이미지 출력

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()

 

신경망 생성

두개의 은닉층으로 이루어진 분류용 다층 퍼셉트론

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"))

아래와 같이 Sequential 모델을 만들 때 층의 리스트를 전달할 수도 있다.

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")
])

1. Sequential 모델 생성

- 가장 간단한 케라스의 신경망 모델로, 순서대로 연결된 층을 일렬로 쌓아서 구성

 

2. 첫 번째 층을 만들고 모델에 추가

- Flatten층은 이미지를 1차원 배열로 변환해준다.

  • 이 층은 어떤 모델 파라미터도 가지지 않고 간단한 전처리만 수행

3. 뉴런 300개를 가진 Dense 은닉층 추가

- ReLU활성화 함수 사용

- 층의 뉴런과 입력 사이의 모든 연결 가중치가 포함되어있다.

- 완전 연결 층의 출력 계산 식을 계산

 

4. 뉴런 100개를 가진 두 번째 Dense 은닉층 추가

- ReLU활성화 함수 사용

 

5. 마지막으로 클래스마다 하나씩 뉴런 10개를 가진 Dense출력층 추가

- 소프트맥스 활성화 함수 사용

 

모델 Layer 확인

model.summary()

- Dense층은 많은 파라미터를 가진다.

784*300개의 연결 가중치 + 300개 편향 = 235500

 

keras.utils.plot_model(model, "my_fashion_mnist_model.png", show_shapes=True)

모델 컴파일

model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd",
              metrics=["accuracy"])

- 레이블이 정수 하나로 이루어져 있다

- 클래스가 배타적이므로 sparse_categorical_crossentropy 손실 사용

  • 만약 원-핫 벡터라면 categorical_crossentropy 손실을 사용해야한다.
  • 이진 분류나 다중 레이블 이진 분류를 수행한다면 출력층에 softmax 대신 sigmoid함수 사용, binary_corssentropy 손실 사용해야한다.

- 옵디마이저 sgd : 확률적 경사 하강법을 사용해 모델을 훈련

- 분류기 이므로 정확도 측정을 위해 accuracy로 지정 

 

모델  훈련과 평가

history = model.fit(X_train, y_train, epochs=30,
                    validation_data=(X_valid, y_valid))

.

.

.

 

- epoch가 끝날 때 마다 검증 세트를 사용해 손실과 추가적인 측정 지표 계산.

- 훈련 세트 성능이 검증 세트보다 높다면 모델이 훈련 세트에 과대적합 됐을 가능성이 높다.

 

훈련 손실이 감소하고 30 epoch 이후에 정확도가 89.26에 도달했을므로 과대적합이 많이 일어나지 않은 결과를 얻었다.

 

history 객체를 사용한 학습 곡선 확인

import pandas as pd

pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1)
save_fig("ke

- 검증 곡선이 훈련 곡선과 가까움 = 크게 과대적합이 되지 않았다.

- 훈련 초기 모델이 검증 세트에서 더 좋은 성능을 나타낸 것 처럼 보이지만, 검증 손실은 epoch가 끝난 후 계산된다.

- 훈련 손실은 epoch가 진행되는 동안 계산된다.

=> 훈련 곡선은 epoch의 절반 만큼 왼쪽으로 이동 시켜서 봐야한다.

 

예측 해보기

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()

 


10.2.3 시퀀셜 API를 사용하여 회귀용 다층 퍼셉트론 만들기

캘리포니아 주택 데이터셋을 로드하여 회귀 신경망 실습