딥러닝
- 회귀모델 : y = wx + b
- 분류모델
101 ~ 110 acc(정확도)는 1이 나올수가 없음
x_test | ouptut |
101 | [100.99708] |
102 | [100.00705] |
103 | [102.997025] |
104 | [103.99698] |
105 | [104.996965] |
106 | [105.99692] |
107 | [106.99689] |
108 | [107.99686] |
109 | [108.99683] |
110 | [109.996796] |
기존에 가지고 있던 데이터들을 이 함수에 최대한 적용시켜야 함
머신이 다음과 같은 1차 함수가 되도록 훈련할 수 있게 서포트 하여야 함
- 이렇게 모델을 유도하고, 데이터를 정제해아 하는 작업이 우리가 해야 할 일
- 얼마나 매끈한 1차 함수가 되도록 만들어주느냐, 이것이 관건
2차 함수와 같은 모양을 띈 모델과 데이터는 어떻게?
- 미분을 통하여 1차 함수로 바꿔 줌
- y = 2ax + 0
- 1차 함수로 만들었기 때문에 딥러닝 회귀분석을 실행할 수 있음
머신러닝과 딥러닝을 공부하다 보면, 통계와 수학에 대한 많은 기초가 있다면 훨씬 수월하다는 것을 알 것이다. 그러나 꼭 통계와 수학을 완벽하게 알아야 할 필요는 없다. 적당히 사용법만 알아 두는 정보면 된다. 그리고 그 전후로 필요한 수학과 통계 부분들을 공부하면 된다.
내용을 전부 숙지하기보다, 꼭 필요할 때마다 하나씩 찾아보거나 소스를 먼저 익힌 다음에 수학부분을 응용하면 훨씬 쉽게 접근할 수 있다.
- 회귀 분석은 선형이기 때문에 딱 맞아 떨어지는 것이 아니다. 그래서 결괏값 예측 분석을 하는 함수를 다른 것으로 쓰게 된다.
## 기존 소스에서 metrics 부분만 accuracy 에서 mse로 변경
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
- acc 대신 mse로 변경해 준 부분은 머신이 훈련할 때 보여주는 부분이 acc 대신 mse(mean squared error)로 표현하겠다는 뜻
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 5) 10
_________________________________________________________________
dense_1 (Dense) (None, 3) 18
_________________________________________________________________
dense_2 (Dense) (None, 1) 4
=================================================================
Total params: 32
Trainable params: 32
Non-trainable params: 0
_________________________________________________________________
Epoch 1/500
10/10 [==============================] - 0s 29ms/step - loss: 38.5000 - mse: 38.5000
- val_loss: 11138.5000 - val_mse: 11138.5000
Epoch 2/500
회귀 모델의 판별식
회귀 모델의 판별식
# RMSE 구하기
from sklearn.metrics import mean_squard_error
def RMSE(y_text, y_predict) :
return np.sqrt(mean_squared_error(y_test, y_predict))
print("RMSE : ", RMSE(y_test, y_predict))
오류가 있다면 다음과 같이 처리
- pip install --upgrade scikit-learn
(deeplearning) C:\JetBrains\python_workspace\deeplearning>pip install --upgrade scikit-learn
RMSE(평균 제곱근 오차, Root Mead Squared Error)
- 회귀 분석을 평가할 때 가장 많이 쓰는 지표
- MSE에 루트를 씌운 것이 RMSE
- 원래 데이터에서 평균을 뺀 값을 제곱하여 모두 더한 뒤 전체 개수로 나눈 값에 루트를 씌운 것
- 회귀 분석 모델을 만들 때 RMSE는 낮을 수 록 정밀도가 높음
결과
- RMSE 가 0.97 이라고 해서 97%가 아님. 그대로의 숫자로 판단.
- 6000, 7000 은 높음, 0.0000001 은 낮음
R2 (R2, R2 Score, R제곱, 설명력, 결정계수)
- 높을 수록 좋은 지표
- MAX 값은 1
- 0.73이 나왔을 경우 모델식이 R2로 계산했을 때 73%의 설명력을 가졌다고 해석
- R2가 음의 값(-1349.121212121212)이 나왔다는 것은 학습 시에 머신에 뭔가 잘못된 부분이 있을 수 있다는 의미
# R2 구하기
from sklearn.metrics import r2_score
r2_y_predict = r2_score(y_test, y_predict)
print("R2 : ", r2_y_predict)
'''
결과
RMSE : 105.53909228338095
R2 : -1349.121212121212
'''
회귀모델 추가 코딩
1) Validation 추가
훈련셋, 테스트셋, 검증셋은 분리가 되는 것이 좋은 데이터의 형태
- 훈련셋에 검증값이 들어가고 그 검증값으로 다시 테스트로 사용한다는 것은 평가에 검증값이 반영되는 문제
x_train | y_train |
x_validation | y_validation |
x_test | y_test |
검증용 데이터 추가
- model.fit(x_train, y_train, epochs=1000, batch_size=1,validation_data=(x_val, y_val))
- 1 ~ 10까지의 데이터를 훈련 시킬 때 101 ~ 105까지의 데이터를 검증용 데이터로 사용
- 11 ~ 20까지의 데이터로 테스트
- Validation을 추가했다고 더 좋은 값이 나오는 것이 눈에 확 띄지는 않지만, 데이터가 많아질 수록 train 데이터에서의 일부의 검증셋을 분리하여 훈련하는 것이 머신의 훈련에 더 좋은 효과를 발휘하게 된다.
#1. 데이터
import numpy as np
x_train = np.array([1,2,3,4,5,6,7,8,9,10])
y_train = np.array([1,2,3,4,5,6,7,8,9,10])
x_test = np.array([11,12,13,14,15,16,17,18,19,20])
y_test = np.array([11,12,13,14,15,16,17,18,19,20])
x_val = np.array([101,102,103,104,105])
y_val = np.array([101,102,103,104,105])
#2. 모델 구성
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
# model.add(Dense(5, input_dim = 1, activation ='relu'))
model.add(Dense(5, input_shape = (1, ), activation ='relu'))
model.add(Dense(3))
model.add(Dense(4))
model.add(Dense(1))
# model.summary()
#3. 훈련
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
model.fit(x_train, y_train, epochs=1000, batch_size=1,
validation_data=(x_val, y_val))
#4. 평가 예측
mse = model.evaluate(x_test, y_test, batch_size=1)
print("mse : ", mse)
y_predict = model.predict(x_test)
print(y_predict)
#RMSE 구하기
from sklearn.metrics import mean_squared_error
def RMSE(y_test, y_predict):
return np.sqrt(mean_squared_error(y_test, y_predict))
print("RMSE : ", RMSE(y_test, y_predict))
# R2 구하기
from sklearn.metrics import r2_score
r2_y_predict = r2_score(y_test, y_predict)
print("R2 : ", r2_y_predict)
결과
mse : [9.18589683485127e-12, 9.18589683485127e-12]
[[11.000001]
[12.000001]
[12.999999]
[13.999998]
[14.999998]
[15.999997]
[16.999996]
[17.999996]
[18.999994]
[19.999994]]
RMSE : 3.3582338069265383e-06
R2 : 0.999999999998633
Process finished with exit code 0
2) 데이터를 분리
1 부터 100까지의 데이터를 준비
#1. 데이터
import numpy as np
x = np.array(range(1,101))
y = np.array(range(1,101))
해당 데이터셋을 6:2:2의 비율로 Train:Val:Test셋으로 나눔
x_train = x[:60]
x_val = x[60:80]
x_test = x[80:]
y_train = y[:60]
y_val = y[60:80]
y_test = y[80:]
결과 실행
mse : [4.5823981054127216e-08, 4.5823981054127216e-08]
[[ 81.00019 ]
[ 82.00019 ]
[ 83.00019 ]
[ 84.00019 ]
[ 85.00019 ]
[ 86.0002 ]
[ 87.000206]
[ 88.000206]
[ 89.00022 ]
[ 90.00022 ]
[ 91.00021 ]
[ 92.000206]
[ 93.00021 ]
[ 94.00022 ]
[ 95.00024 ]
[ 96.00022 ]
[ 97.00025 ]
[ 98.00024 ]
[ 99.00024 ]
[100.00024 ]]
RMSE : 0.00021479828310081982
R2 : 0.9999999986123819
이 모델의 문제점
- x_test 값으로 predict
- 가급적이면 test한 값 보다는 새로운 데이터로 예측하는 것이 좋음
- x_predict = np.array(range(101,111))
- y_predict = model.predict(x_predict)
x_train | y_train |
x_validation | y_validation |
x_test | y_test |
x_predict |
#1. 데이터
import numpy as np
x = np.array(range(1,101))
y = np.array(range(1,101))
x_train = x[:60]
x_val = x[60:80]
x_test = x[80:]
x_predict = np.array(range(101,111))
y_train = y[:60]
y_val = y[60:80]
y_test = y[80:]
.....
#4. 평가 예측
mse = model.evaluate(x_test, y_test, batch_size=1)
print("mse : ", mse)
y_predict = model.predict(x_predict)
print(y_predict)
결과
mse : [4.249159357705423e-10, 4.249159357705423e-10]
[[101.00003 ]
[102.000015]
[103.00001 ]
[104.000015]
[105.00002 ]
[106.00002 ]
[107.000015]
[108.000015]
[109.00003 ]
[110.00002 ]]
3) train_test_split
데이터를 잘라주는 함수
- x, y 값
- test_size : train_size를 넣을 수 있음
- train_size=0.6 과 test_size=0.4는 같은의미 traint_size + test_size = 1 즉 100%라는 뜻
- train_size 와 test_size를 동시에 사용할 경우 train_size로 우선 잘리게 됨
- shuffle : 잘라낸 데이터를 섞을지 여부
- x = (1, 2, 3), y=(4, 5, 6) 일경우 true로 섞인다면 x = (2, 3, 1) y = (5, 6, 4) 쌍으로 섞이게 됨
- x = (2, 3, 1), y=(4, 6, 5) 처럼 x와 y 따로 무작위로 섞이지 않음
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
x,
y,
random_state=66, ##
test_size=0.4, ## test_size 가 40% 라는 의미
shuffle=false ## 잘라낸 데이터를 섞을지 여부
)
Test 데이터의 50%를 validation에 배분하게 되어 전체적으로 train:val:test의 비율이 6:2:2가 됨
#1. 데이터
import numpy as np
x = np.array(range(1,101))
y = np.array(range(1,101))
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
x, y, random_state=66, test_size=0.4, shuffle=False
)
## validation을 만들기위해 한번더 적용
x_val, x_test, y_val, y_test = train_test_split(
x_test, y_test, random_state=66, test_size=0.5, shuffle=False
)
실행결과
mse : [2.1827872842550278e-10, 2.1827872842550278e-10]
[[ 81.000015]
[ 82.00001 ]
[ 83.00001 ]
[ 84. ]
[ 85.000015]
[ 86.00001 ]
[ 87.000015]
[ 88.00001 ]
[ 89.00001 ]
[ 90.000015]
[ 91.000015]
[ 92.00003 ]
[ 93.00001 ]
[ 94.000015]
[ 95.000015]
[ 96.000015]
[ 97.00002 ]
[ 98.00001 ]
[ 99.000015]
[100.000015]]
RMSE : 1.4475758332069607e-05
R2 : 0.9999999999936978
함수형 모델
1) 1:1
케라스 딥러닝의 모델 구성 방식
- 순차형 모델
- 함수형모델
- 모델이 길어지고 앙상블등의 여러가지 기법을 사용하고자 한다면 필수
기존의 데이터는 재사용 모델 구성
- Input 레이어를 구성, 입력 shave를 구성. 1개의 컬럼이 들어가므로 input1 = Input(shape=(1,))으로 구성
- 다음 레이어 부터는 순차형의 시쿼스형처럼 구성을 하되 상위층에서 출력된 레이어의 이름을 하위층의 가장 끝부분에 명시
- dense1 = Dense(5, activation='relu')(input1)
- 이후 동일하게 연결
dense2 = Dense(3)(dense1)
dense3 = Dense(4)(dense2)
output1 = Dense(1)(dense3)
- 마지막으로 Model로 전체레이어를 엮어줌
- model = Model(inputs = input1, outputs= output1)
#2. 모델 구성
from keras.models import Sequential, Model # Model을 추가해준다.
from keras.layers import Dense, Input # Input 레이어를 추가해준다.
# model = Sequential()
input1 = Input(shape=(1,))
dense1 = Dense(5, activation='relu')(input1)
dense2 = Dense(3)(dense1)
dense3 = Dense(4)(dense2)
output1 = Dense(1)(dense3)
model = Model(inputs = input1, outputs= output1)
model.summary()
총 49개의 모델을 사용한 간단한 심층 신경망
Model: "functional_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 1)] 0
_________________________________________________________________
dense (Dense) (None, 5) 10
_________________________________________________________________
dense_1 (Dense) (None, 3) 18
_________________________________________________________________
dense_2 (Dense) (None, 4) 16
_________________________________________________________________
dense_3 (Dense) (None, 1) 5
=================================================================
Total params: 49
Trainable params: 49
Non-trainable params: 0
_________________________________________________________________
결과
mse : [3.5845358070218936e-05, 3.5845358070218936e-05]
[[80.99502 ]
[81.99491 ]
[82.994804]
[83.9947 ]
[84.99461 ]
[85.99451 ]
[86.99439 ]
[87.99429 ]
[88.9942 ]
[89.99409 ]
[90.99399 ]
[91.9939 ]
[92.99379 ]
[93.99368 ]
[94.993576]
[95.993484]
[96.99337 ]
[97.99327 ]
[98.99318 ]
[99.99307 ]]
RMSE : 0.005987267434121411
R2 : 0.9999989218835691
2) 다:다
2개 이상의 컬럼이 입력되는 경우
- 1 ~ 100까지의 정수
- 301 ~ 400까지의 정수
#1. 데이터
import numpy as np
x = np.array([range(100), range(301,401)])
y = np.array([range(100), range(301,401)])
print(x.shape)
print(y.shape)
'''
결과 2행 100열 구조
(2, 100)
(2, 100)
'''
x = np.transpose(x)
y = np.transpose(y)
print(x.shape)
print(y.shape)
'''
결과 100행 2열 구조
(100, 2)
(100, 2)
'''
train, test, val의 데이터를 6:2:2로 구성
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
x, y, random_state=66, test_size=0.4, shuffle=False
)
x_val, x_test, y_val, y_test = train_test_split(
x_test, y_test, random_state=66, test_size=0.5, shuffle=False
)
모델구성
- input_dim = 1 에서 2로 바뀜
- model.add(Dense(5, input_shape = (2, ), activation ='relu'))
- 최종 아웃풋이 1에서 2로 바뀜
- model.add(Dense(2))
#2. 모델 구성
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
# model.add(Dense(5, input_dim = 2, activation ='relu'))
model.add(Dense(5, input_shape = (2, ), activation ='relu'))
model.add(Dense(3))
model.add(Dense(4))
model.add(Dense(2))
훈련, 평가 예측은 동일
결과
mse : [1724.2828369140625, 1724.2828369140625]
RMSE : 41.52448891223674
R2 : -50.858140734510435
3) 다:1
다:다 모델에서 아웃풋만 1개인 경우를 의미
- 100개의 데이터씩 2개의 컬럼이 입력되어, 100개의 데이터 1개가 출력되는 구조
- 인풋과 아웃풋의 shape만 조절. 모델에 적합하게 reshape시켜줌
- y의 shape (100, ) (1행 100열이 아니라 벡터가 100개라는 의미) 이므로 tranport 하지 않음
#1. 데이터
import numpy as np
x = np.array([range(100), range(301,401)])
y = np.array(range(201,301))
x = np.transpose(x)
최종 아웃풋 레이어만 1로 변경
- model.add(Dense(1))
#2. 모델 구성
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(5, input_shape = (2, ), activation ='relu'))
model.add(Dense(3))
model.add(Dense(4))
model.add(Dense(1))
# model.summary()
결과
mse : [3.395858220756054e-05, 3.395858220756054e-05]
RMSE : 0.005827694921758226
R2 : 0.999998978585621
4) 1:다
1개의 컬럼이 입력되어 어러개의 컬럼으로 출력되는 경우
- 데이터 자체로 판단해서는 이상한 모델이지만 이 역시 구현 가능함
#1. 데이터
import numpy as np
x = np.array([range(100)])
y = np.array([range(201,301), range(301,401)])
x = np.transpose(x)
y = np.transpose(y)
print(x.shape)
print(y.shape)
'''
결과
(100, 1) 100행 1열
(100, 2) 100행 2열
'''
모델
- input_shape 가 1로 바뀜
- 마지막 출력의 Dense층의 아웃풋을 2로 변경
#2. 모델 구성
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
# model.add(Dense(5, input_dim = 3, activation ='relu'))
model.add(Dense(5, input_shape = (1, ), activation ='relu'))
model.add(Dense(3))
model.add(Dense(4))
model.add(Dense(2))
실행결과
- 결괏값이 좋지 않지만 1:다 모델도 가능
mse : 67784.5234375
[[444.179 630.5826 ]
[449.0547 637.5634 ]
[453.9304 644.54425]
[458.80606 651.52496]
[463.68173 658.50574]
[468.5574 665.4866 ]
[473.43304 672.46735]
[478.30878 679.4481 ]
[483.18442 686.42896]
[488.06012 693.4098 ]
[492.9358 700.3906 ]
[497.81146 707.3714 ]
[502.68713 714.35223]
[507.56284 721.333 ]
[512.4385 728.3138 ]
[517.31415 735.2946 ]
[522.1898 742.2754 ]
[527.0655 749.25616]
[531.94116 756.237 ]
[536.81683 763.2177 ]]
RMSE : 260.3546067280783
R2 : -2037.6322178806709
'책 > 딥러닝으로 걷는 시계열 예측' 카테고리의 다른 글
앙상블 (0) | 2020.11.29 |
---|---|
딥러닝 시작 (0) | 2020.11.28 |