지난 포스트에서 작성한 코드들을 간략히 정리해보고, 본격적으로 학습 및 결과 평가를 해보자.
학습 목표
- 분석가가 알고 있는 패턴$f(x) = x + 10$에 대한 데이터를 생성하고, 그 패턴을 찾아내는 모델을 만들어보자.
- Input은 Node 1개, Output도 Node 1개인 연속형 데이터를 생성한다.
1. 지난 코드 정리
# Import Module
import pandas as pd
import numpy as np
from tensorflow import keras
from tensorflow.keras.layers import Dense
# Dataset Setting
def f(x):
return x + 10
# Data set 생성
np.random.seed(1234) # 동일한 난수가 나오도록 Seed를 고정한다.
X_train = np.random.randint(0, 100, (100, 1))
X_test = np.random.randint(100, 200, (20, 1))
# Label 생성
y_train = f(X_train)
y_test = f(X_test)
# Model Setting
model = keras.Sequential()
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='linear'))
# Compile: 학습 셋팅
opt = keras.optimizers.Adam(learning_rate=0.01)
model.compile(optimizer=opt, loss = 'mse')
2. 학습 시작
>>> model.fit(X_train, y_train, epochs = 100)
- model.fit(): model에 대해 학습을 시작한다.
- fit() 안에는 train dataset, train data label, validation dataset 등이 들어갈 수 있다.
- validation dataset은 성능 향상에 도움이 되나, 꼭 필요한 것은 아니다.
- epochs은 전체 train set을 몇 번 학습할 것인가를 의미한다.
- 해당 코드를 실행하면 다음과 같은 문자들이 출력된다.
Epoch 1/100
4/4 [==============================] - 0s 2ms/step - loss: 955.4686
Epoch 2/100
4/4 [==============================] - 0s 998us/step - loss: 342.0951
Epoch 3/100
4/4 [==============================] - 0s 2ms/step - loss: 51.7757
Epoch 4/100
4/4 [==============================] - 0s 1ms/step - loss: 43.6929
Epoch 5/100
4/4 [==============================] - 0s 2ms/step - loss: 95.3333
Epoch 6/100
4/4 [==============================] - 0s 2ms/step - loss: 76.1808
Epoch 7/100
4/4 [==============================] - 0s 1ms/step - loss: 29.2552
Epoch 8/100
4/4 [==============================] - 0s 2ms/step - loss: 21.1532
...
Epoch 94/100
4/4 [==============================] - 0s 2ms/step - loss: 4.9562
Epoch 95/100
4/4 [==============================] - 0s 1ms/step - loss: 5.3142
Epoch 96/100
4/4 [==============================] - 0s 996us/step - loss: 5.0884
Epoch 97/100
4/4 [==============================] - 0s 2ms/step - loss: 4.9754
Epoch 98/100
4/4 [==============================] - 0s 2ms/step - loss: 5.3013
Epoch 99/100
4/4 [==============================] - 0s 1ms/step - loss: 5.0656
Epoch 100/100
4/4 [==============================] - 0s 1ms/step - loss: 4.4677
<tensorflow.python.keras.callbacks.History at 0x12fe8f0f520>
- 위 내용을 history라고 하며, 따로 history를 지정하지 않아도 출력된다.
- loss는 손실 값을 의미하며, 해당 값이 최소화되는 위치를 찾는 것이 목적이다.
- 일반적으로 loss가 0에 근사 해지는 것을 목적으로 한다.
- 만약 loss가 0에서 지나치게 먼 값에서 수렴한다면, 모델에 들어간 인자들(HyperParameter)이 잘못 들어간 것일 가능성이 매우 높으므로, 모델을 수정하길 바란다.
- loss가 지금처럼 0에 가깝게 내려 가긴 했으나, 그 정도가 0에 미치지 못한 경우 단순하게 epoch를 늘려보자.
>>> model.fit(X_train, y_train, epochs = 500)
Epoch 1/500
4/4 [==============================] - 1s 2ms/step - loss: 9528.2801
Epoch 2/500
4/4 [==============================] - 0s 2ms/step - loss: 7191.2032
Epoch 3/500
4/4 [==============================] - 0s 2ms/step - loss: 4662.3104
Epoch 4/500
4/4 [==============================] - 0s 1ms/step - loss: 2927.8638
Epoch 5/500
4/4 [==============================] - 0s 2ms/step - loss: 1738.3485
Epoch 6/500
4/4 [==============================] - 0s 2ms/step - loss: 877.1409
...
Epoch 495/500
4/4 [==============================] - 0s 2ms/step - loss: 0.0126
Epoch 496/500
4/4 [==============================] - 0s 1ms/step - loss: 0.0139
Epoch 497/500
4/4 [==============================] - 0s 1ms/step - loss: 0.0183
Epoch 498/500
4/4 [==============================] - 0s 1ms/step - loss: 0.0180
Epoch 499/500
4/4 [==============================] - 0s 2ms/step - loss: 0.0168
Epoch 500/500
4/4 [==============================] - 0s 2ms/step - loss: 0.0229
- Epochs를 500까지 올렸으나, loss 값이 원하는 만큼 나오지 않는 것을 볼 수 있다.
3. 결과를 확인해보자.
- 결과 확인은 상당히 단순하면서도 새로운 알고리즘을 만들어내야 할 필요성이 있는 영역이다.
>>> model.predict(X_test.reshape(X_test.shape[0]))
array([[195.04504 ],
[151.02899 ],
[111.01437 ],
[124.019135],
[113.015114],
[140.02496 ],
[122.0184 ],
[183.04066 ],
[129.02095 ],
[136.02351 ],
[206.04909 ],
[178.03883 ],
[174.03737 ],
[132.02205 ],
[166.03447 ],
[194.0447 ],
[118.01694 ],
[154.03008 ],
[134.02278 ],
[204.04832 ]], dtype=float32)
- model.predict(array): 들어간 array에 대하여 모델의 파라미터(가중치)들이 순방향으로 연산되어 나온 결과가 출력된다.
- 모델에 Input되는 데이터와 predict에 들어가는 데이터의 모양은 조금 다르다.
# 모델 Input 시
>>> X_test.shape
(20, 1)
# Predict Input 시
>>> X_test.reshape(X_test.shape[0]).shape
(20,)
- 모델 학습 시엔 데이터를 행 단위로 떨어뜨려 넣었다면, predict에선 위와 같이 넣어줘야 한다.
test set의 Label과 비교해보자.
- predict 결과와 Label 데이터인 y_test를 비교해보자.
pred = model.predict(X_test.reshape(X_test.shape[0]))
predict_DF = pd.DataFrame({"predict":pred.reshape(pred.shape[0]), "label":y_test.reshape(y_test.shape[0])})
predict_DF["gap"] = predict_DF["predict"] - predict_DF["label"]
predict_DF
- predict와 label이 어느 정도 근사하게 나오긴 하였으나, 얼마나 근사하게 나왔는지 보기가 어렵다.
- 모델을 평가하기 쉽도록, RMSE를 사용하여 Scalar값(숫자 1개)으로 바꿔주자.
>>> print("Accuracy:", np.sqrt(np.mean((pred - y_test)**2)))
Accuracy: 0.10477323661232778
- 0.1047로 나름 나쁘지 않은 결과가 나오긴 하였으나, $f(x) = x + 10$ 같이 굉장히 단순한 패턴을 만족스러운 수준으로 찾아내지 못했다.
- 게다가 패턴도 지나치게 단순한데, epochs가 500이나 사용되어, 생각보다 많은 자원이 낭비되었다.
이번 포스트에서는 널리 알려진 방식대로 학습을 시켜보았다. 그러나, 아주 단순한 패턴임에도 불구하고, 쉽게 찾아내질 못하였으며, 그 결과도 원하는 것에 미치지 못했다.
다음 포스트에서는 어디가 잘못되었는지 찾아내 이를 수정해보도록 하자.
'Machine Learning > TensorFlow' 카테고리의 다른 글
Tensorflow-1.5. 기초(6)-기초 모델 만들기(1)-변수 2개인 경우 (0) | 2021.02.08 |
---|---|
Tensorflow-1.4. 기초(5)-하이퍼 파라미터 튜닝 (0) | 2021.02.08 |
Tensorflow-1.3. 기초(4)-특성 스케일 조정 (0) | 2021.02.08 |
Tensorflow-1.1. 기초(2)-학습하기(1) (0) | 2021.02.08 |
Tensorflow-1.0. 기초(1)-데이터 셋 만들기 (0) | 2021.02.07 |