본 포스팅은 선형 회귀 기반 심층신경망 학습의 예제입니다.
보스턴 주택 가격 데이터세트를 이용하여 모델을 학습하고, 이를 이용하여 데이터를 예측 해보겠습니다.
코드는 아래와 같습니다.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import math
from tensorflow.keras.datasets import boston_housing
# 4.11 데이터 불러오기
(train_X, train_Y), (test_X, test_Y) = boston_housing.load_data()
print(len(train_X), len(test_X))
print(train_X[0])
print(train_Y[0])
# 4.12 데이터 전처리(정규화)
x_mean = train_X.mean(axis=0)
x_std = train_X.std(axis=0)
train_X -= x_mean
train_X /= x_std
test_X -= x_mean
test_X /= x_std
y_mean = train_Y.mean(axis=0)
y_std = train_Y.std(axis=0)
train_Y -= y_mean
train_Y /= y_std
test_Y -= y_mean
test_Y /= y_std
print(train_X[0])
print(train_Y[0])
# 4.13 Boston Housing Dataset 회귀 모델 생성
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=52, activation='relu', input_shape=(13,)),
tf.keras.layers.Dense(units=39, activation='relu'),
tf.keras.layers.Dense(units=26, activation='relu'),
tf.keras.layers.Dense(units=1)
])
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.07), loss='mse')
model.summary()
# 활성화함수 비교 시각화
def sigmoid(x):
return 1 / (1 + math.exp(-x))
x = np.arange(-5, 5, 0.01)
sigmoid_x = [sigmoid(z) for z in x]
tanh_x = [math.tanh(z) for z in x]
relu = [0 if z < 0 else z for z in x]
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.plot(x, sigmoid_x, 'b-', label='sigmoid')
plt.plot(x, tanh_x, 'r--', label='tanh')
plt.plot(x, relu, 'g.', label='relu')
plt.legend()
plt.show()
# 4.14 회귀 모델 학습
history = model.fit(train_X, train_Y, epochs=25, batch_size=32, validation_split=0.25)
# 4.15 회귀 모델 학습 결과 시각화
plt.plot(history.history['loss'], 'b-', label='loss')
plt.plot(history.history['val_loss'], 'r--', label='val_loss')
plt.xlabel('Epoch')
plt.legend()
plt.show()
# 4.16 회귀 모델 평가
model.evaluate(test_X, test_Y)
# 4.17 실제 주택 가격과 예측 주택 가격 시각화
import matplotlib.pyplot as plt
pred_Y = model.predict(test_X)
plt.figure(figsize=(5, 5))
plt.plot(test_Y, pred_Y, 'b.')
plt.axis([min(test_Y), max(test_Y), min(test_Y), max(test_Y)])
# y=x에 해당하는 대각선
plt.plot([min(test_Y), max(test_Y)], [min(test_Y), max(test_Y)], ls="--", c=".3")
plt.xlabel('test_Y')
plt.ylabel('pred_Y')
plt.show()
# 4.18 모델 재정의 및 학습
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=52, activation='relu', input_shape=(13,)),
tf.keras.layers.Dense(units=39, activation='relu'),
tf.keras.layers.Dense(units=26, activation='relu'),
tf.keras.layers.Dense(units=1)
])
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.07), loss='mse')
history = model.fit(train_X, train_Y, epochs=25, batch_size=32, validation_split=0.25,
callbacks=[tf.keras.callbacks.EarlyStopping(patience=3, monitor='val_loss')])
# 4.19 회귀 모델 학습 결과 시각화
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], 'b-', label='loss')
plt.plot(history.history['val_loss'], 'r--', label='val_loss')
plt.xlabel('Epoch')
plt.legend()
plt.show()
# 4.20 회귀 모델 평가
model.evaluate(test_X, test_Y)
# 4.21 실제 주택 가격과 예측 주택 가격 시각화
import matplotlib.pyplot as plt
pred_Y = model.predict(test_X)
plt.figure(figsize=(5, 5))
plt.plot(test_Y, pred_Y, 'b.')
plt.axis([min(test_Y), max(test_Y), min(test_Y), max(test_Y)])
plt.plot([min(test_Y), max(test_Y)], [min(test_Y), max(test_Y)], ls="--", c=".3")
plt.xlabel('test_Y')
plt.ylabel('pred_Y')
plt.show()
코드를 분석해보면,
load_data()를 이용하여 데이터 세트를 훈련 데이터와 테스트 데이터로 분리하여 가져오고 있습니다.
훈련 데이터는 학습 과정에 사용되는 데이터이고, 테스트 데이터는 학습 결과를 평가하기 위한 데이터입니다.
훈련 데이터로 학습할 때는 일부 데이터를 떼어내서 검증 데이터로 만들 수 있습니다.
이것은 학습이 잘 되고 있는지 검증하는 용도로 쓰이며, 검증 데이터의 성적이 좋지 않을 때 학습을 중단할 수 있도록 합니다.
딥러닝 네트워크에서 가중치에 영향을 주는 데이터는 훈련 데이터뿐입니다.
훈련 데이터과 테스트 데이터는 80:20 비율이 이상적입니다.
훈련 데이터 중 검증 데이터를 만드는데 보통 20%정도를 사용합니다.
최종적으로 훈련, 검증, 테스트 데이터의 이상적인 비율은 약 60:20:20입니다.
훈련 데이터는 모두 실수형이지만, 각 데이터의 단위는 모두 다릅니다.
효율적인 학습을 위해 데이터를 전처리해서 정규화(Standardization) 해야 합니다. (관련 내용)
데이터를 정규화하려면 각 데이터에서 평균값을 뺀 다음 표준편차로 나눠주면 됩니다.
이 작업은 데이터의 분포를 정규분포로 옮기는 역할을 수행합니다.
훈련 데이터를 정규화하고 테스트 데이터도 훈련 데이터의 평균값과 표준편차를 이용해 정규화합니다.
테스트 데이터는 실제 데이터라고 생각해야 하기 때문입니다.
Sequential()을 이용하여 순차적인 인공신경망 모델을 만들고, Dense()를 이용하여 모델을 완전 연결층으로 만들어줍니다.
from : https://hyjykelly.tistory.com/60
코드를 기준으로, 13개의 입력과 1개의 출력을 가지며 3개의 은닉층을 이루고 있고 각 은닉층의 뉴런 개수는
52, 39, 26 입니다.
compile()을 이용하여 learning rate를 0.07, 최적화는 Adam, 손실 함수는 평균 제곱 오차(MSE)로 설정합니다.
summary()를 이용하여 신경망의 정보를 파악합니다.
param의 값은 아래와 같습니다.
param = ((노드의 수) * (input 차원)) + 노드의 수
fit()을 이용하여 batch_size를 32, epoch를 25, 훈련 데이터로의 25%를 검증 데이터로 설정(validation_split=0.25)합니다.
evaluate()를 이용하여 테스트 데이터를 입력으로 모델을 평가해봅니다.
테스트 데이터를 입력으로 predict()를 이용하여 예측 값을 얻고, 이를 비교해봅니다.
검증 데이터와 테스트 데이터에 대해 모두 좋은 예측 성적을 내려면 val_loss가 높아지지 않도록,
즉 딥러닝 네트워크가 훈련 데이터에 과적합되지 않도록 학습 도중에 멈춰야 합니다.
학습 도중에 끼어들기 위해서는 콜백(callback) 함수를 사용합니다.
콜백 함수는 모델을 학습할 때 epoch가 끝날 때마다 호출됩니다.
fit()을 호출할 때 매개변수로 callbacks=[tf.keras.callbacks.EarlyStopping(patience=3, monitor='val loss')] 를
넘겨 학습을 일찍 멈추도록 할 수 있습니다.
여기서 patience는 몇 번의 epoch를 기준으로 삼을 것인지, monitor는 어떤 값을 감시할 것인지에 대한 매개변수 입니다.
여기서는 3회의 epoch를 수행하는 동안 최고 기록을 갱신하지 못하면 학습을 멈추게 됩니다.
다시 fit()을 이용하여 학습을 진행하고 evaluate()를 이용하여 모델을 평가해봅니다.
다시 테스트 데이터를 입력으로 predict()를 이용하여 예측 값을 얻고, 이를 비교해봅니다.
그림 5를 보면 그림 3과 달리 손실 값이 줄어들었고, 25 epoch를 수행하기 전에 학습이 종료 되었습니다.
그림 6은 그림 4와 달리 결과값의 분산이 좁아졌고 예측값이 대각선에 가까워졌습니다.
이렇게 콜백 함수로 Early Stopping을 이용하면 딥러닝 네트워크가 과적합되지 않도록 도중에 학습을 중단할 수 있습니다.
위 코드 내용은 아래 구글 코랩에서 실행해 볼 수 있습니다.
colab.research.google.com/drive/15BsABExpgF8dG8zVWg7D54-w--wiafrl?usp=sharing
'AI > TensorFlow & PyTorch' 카테고리의 다른 글
[TensorFlow] 텐서플로우(TensorFlow 2.x) 와인 데이터 다항 분류 (0) | 2021.03.05 |
---|---|
[TensorFlow] 텐서플로우(TensorFlow 2.x) 와인 데이터 이항 분류 (0) | 2021.03.05 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 로지스틱 회귀 예제 (0) | 2021.03.05 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 선형 회귀 예제 (0) | 2021.02.26 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 개발 환경 구축 (Windows) (1) | 2021.02.22 |