파이썬/딥러닝

keras 인공신경망으로 기상변수 예측 모델 만들기4

이석사 중 2023. 8. 7. 20:44
728x90

이번 포스팅은 입력 변수 개수를 증가시켜서 해보겠습니다


모델에도 약간의 수정이 있습니다

 

출력층의 노드 갯수가 12개여야 하기 때문에

 

앞선 모델들의 노드 갯수에 2배를 해줬습니다

 

또 추가적으로 이전 모델들에서 학습 횟수가 30~50 정도부터 더 이상 낮아지지 않는 구간이 시작되기 때문에

 

EarlyStopping도 추가했습니다

 

Early Stopping은 학습 횟수를 전부 채우지 않았음에도 학습을 조기 종료하는 함수입니다

 

변수는 monitor, min_delta, patience, mode 이렇게 4가지를 입력 받으며 monitor와 patience 2개를 주로 사용합니다

 

monitor : 조기 종료 기준이 될 값 (loss, val_loss...)

min_delta : 모델이 손실을 줄여가는 과정에서 개선되었다고 생각하는 최소 변화량

patience : 개선을 하지 못했다고 해서 바로 종료시키지 않고 경고를 주는 횟수, 3으로 지정하면 3번 개선하지 못하면 종료

 

데이터 전처리나 정규화 과정에는 차이가 없으니 바뀐 부분만 보여드리겠습니다

df1 = pd.DataFrame({'T' : df['기온(°C)'],
                    'WS' : df['풍속(m/s)'],
                    'WD' : df['풍향(16방위)'],
                    'RH' : df['습도(%)'],
                    'SP' : df['증기압(hPa)'],
                    'P' : df['해면기압(hPa)'],
                    'VS' : df['시정(10m)'],
                    'TD' : df['이슬점온도(°C)'],
                    'SD' : df['일조(hr)'],
                    'IS' : df['일사(MJ/m2)'],
                    'LC' : df['중하층운량(10분위)'],
                    'TC' : df['전운량(10분위)']})

wfm.add(Dense(24, input_dim = 12, activation = 'tanh'))
wfm.add(Dense(24, activation = 'tanh'))
wfm.add(Dense(12, activation = 'relu'))
wfm.add(Dense(12, activation = 'relu'))
wfm.add(Dense(12, activation = 'relu'))
wfm.add(Dense(12, activation = 'relu'))
wfm.add(Dense(12, activation = 'relu'))
wfm.add(Dense(12, activation = 'relu'))

from keras.callbacks import EarlyStopping

early_stopping = EarlyStopping(monitor = 'val_loss', patience = 3)

wfm.fit(x_train, y_train, epochs = 100, batch_size = 10,
        validation_data = (x_val, y_val), callbacks=[early_stopping])

학습 과정입니다

 

23번째에서 조기 종료가 돼서 전체 다 보여드리도록 하겠습니다

Epoch 1/100
6136/6136 [==============================] - 23s 3ms/step - loss: 0.0628 - val_loss: 0.0573
Epoch 2/100
6136/6136 [==============================] - 19s 3ms/step - loss: 0.0503 - val_loss: 0.0498
Epoch 3/100
6136/6136 [==============================] - 19s 3ms/step - loss: 0.0496 - val_loss: 0.0497
Epoch 4/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0494 - val_loss: 0.0494
Epoch 5/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0493 - val_loss: 0.0491
Epoch 6/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0491 - val_loss: 0.0490
Epoch 7/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0490 - val_loss: 0.0492
Epoch 8/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0490 - val_loss: 0.0490
Epoch 9/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0215 - val_loss: 0.0099
Epoch 10/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0100 - val_loss: 0.0100
Epoch 11/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0099 - val_loss: 0.0098
Epoch 12/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0099 - val_loss: 0.0099
Epoch 13/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0099 - val_loss: 0.0098
Epoch 14/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0098 - val_loss: 0.0100
Epoch 15/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0098 - val_loss: 0.0101
Epoch 16/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0098 - val_loss: 0.0097
Epoch 17/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0097 - val_loss: 0.0097
Epoch 18/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0097 - val_loss: 0.0096
Epoch 19/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0096 - val_loss: 0.0096
Epoch 20/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0096 - val_loss: 0.0095
Epoch 21/100
6136/6136 [==============================] - 18s 3ms/step - loss: 0.0096 - val_loss: 0.0098
Epoch 22/100
6136/6136 [==============================] - 19s 3ms/step - loss: 0.0095 - val_loss: 0.0096
Epoch 23/100
6136/6136 [==============================] - 17s 3ms/step - loss: 0.0095 - val_loss: 0.0096
<keras.callbacks.History at 0x7a97179bc9d0>

 

다음은 예측값입니다

 

n = pd.DataFrame({'T' : [35.2],
                    'WS' : [0.8],
                    'WD' : [292.5],
                    'RH' : [48],
                    'SP' : [27.2],
                    'P' : [1004.3],
                    'VS' : [1963],
                    'TD' : [22.5],
                    'SD' : [1],
                    'IS' : [2.31],
                    'LC' : [0],
                    'TC' : [3]})
                    
now = (n - df1.min())/(df1.max() - df1.min())

predict(now)
1/1 [==============================] - 0s 23ms/step
1시간 뒤 기상변수 예측
기온 :  36.924744 degreeC
풍속 :  2.4615066 m/s
풍향 :  164.3516
습도 :  48.01915 %
증기압 :  26.755552 hPa
해면기압 :  998.85516 hPa
시정 :  18974.835205078125 m
이슬점 온도 :  22.611895 degreeC
일조 :  1.023409 hr
일사 :  2.2006326 MJ/m2
중하층운량 :  0.7897797 10분위
전운량 :  2.5254493 10분위

더 이상 과소적합 현상이 일어나지 않고 제대로 출력된 모습입니다

 

#실제
#기온 : 33.4
#풍속 : 2.2
#풍향 : 247.5
#습도 : 50
#증기압 : 25.6
#해면기압 : 1004.2
#시정 : 19880
#이슬점온도 : 21.5
#일조 : 0.8
#일사 : 1.28
#중하층 운량 : 3
#전운량 : 6

실제 관측값과 비교해봐도 많이 가까워진 모습입니다

 

기온은 약 3도씨, 풍속은 약 0.2m/s, 풍향은 약 80도, 습도는 약 2%, 증기압은 약 1hPa,

 

해면기압 약 6hPa, 시정은 약 1000m, 이슬점 온도는 약1도씨, 일조는 약 0.2hr, 일사는 1MJ/m2 차이가 났습니다

 

하지만 여전히 운량은 차이가 크게 나타납니다

 

운량은 이미 정해진 범위 1 ~ 10 사의 값만 나타내는 변수라 저렇게 출력이 된다고 생각합니다

 

이제 얼추 제 모델이 정확해져가고 있는 것 같습니다

 

다음 포스팅에는 모델의 복잡도를 올려서 비교해보겠습니다

728x90