728x90
반응형

 지난 포스트에서 작성한 코드들을 간략히 정리해보고, 본격적으로 학습 및 결과 평가를 해보자.

 

 

학습 목표

  • 분석가가 알고 있는 패턴$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이나 사용되어, 생각보다 많은 자원이 낭비되었다.

 

 

 

 이번 포스트에서는 널리 알려진 방식대로 학습을 시켜보았다. 그러나, 아주 단순한 패턴임에도 불구하고, 쉽게 찾아내질 못하였으며, 그 결과도 원하는 것에 미치지 못했다.

 다음 포스트에서는 어디가 잘못되었는지 찾아내 이를 수정해보도록 하자.

728x90
반응형

+ Recent posts