본문 바로가기
Naver Clould with BitCamp/Aartificial Intelligence

Ensemble Model

by HJ0216 2023. 1. 31.

기본 환경: IDE: VS code, Language: Python

 

Model ensemble: 모델들의 앙상블, 즉 여러 모델들을 함께 사용하여 기존보다 성능을 더 올리는 방법

3가지 Model 들을 ensemble 하여 보다 더 좋은 예측력을 가지는 모델을 만듦

 

# ensemble_model1.py

import numpy as np

x1_datasets = np.array([range(100), range(301, 401)]).transpose() # .transpose() = .T
print(x1_datasets.shape) # (100, 2)
print(x1_datasets)
'''
[[  0 301]
 [  1 302]
 [  2 303]
 ...
  [ 98 399]
 [ 99 400]]
'''

x2_datasets = np.array([range(101, 201), range(411, 511), range(150, 250)]).transpose()
print(x2_datasets.shape) # (100, 3)

y = np.array(range(2001, 2101)) # (100,)

from sklearn.model_selection import train_test_split
x1_train, x1_test, x2_train, x2_test, y_train, y_test = train_test_split(
    x1_datasets, x2_datasets, y, train_size=0.7, random_state=1234
)

print(x1_train.shape, x2_train.shape, y_train.shape) # (70, 2) (70, 3) (70,)
print(x1_test.shape, x2_test.shape, y_test.shape) # (30, 2) (30, 3) (30,)


# 2. Model Construction
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input

# 2-1. Model_1
input1 = Input(shape=(2,))
dense1 = Dense(11, activation='relu', name='ds11')(input1) # name: summary에서 별칭
dense2 = Dense(12, activation='relu', name='ds12')(dense1)
dense3 = Dense(13, activation='relu', name='ds13')(dense2)
output1 = Dense(11, activation='relu', name='ds14')(dense3)

# 2-2. Model_2
input2 = Input(shape=(3,))
dense21 = Dense(21, activation='linear', name='ds21')(input2)
dense22 = Dense(22, activation='linear', name='ds22')(dense21)
output2 = Dense(23, activation='linear', name='ds23')(dense22)

# 2-3. Model_merge
from tensorflow.keras.layers import concatenate
merge1 = concatenate([output1, output2], name='mg1')
# merge1 = Concatenate()([output1, output2], name='mg1')
merge2 = Dense(12, activation='relu', name='mg2')(merge1)
merge3 = Dense(13, name='mg3')(merge2)
last_output = Dense(1, name='last')(merge3)

model = Model(inputs=[input1, input2], outputs=last_output)

model.summary()
'''
Model: "model"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_1 (InputLayer)           [(None, 2)]          0           []

 ds11 (Dense)                   (None, 11)           33          ['input_1[0][0]']
__________________________________________________________________________________________________

 input_2 (InputLayer)           [(None, 3)]          0           []

 ds12 (Dense)                   (None, 12)           144         ['ds11[0][0]']
__________________________________________________________________________________________________

 ds21 (Dense)                   (None, 21)           84          ['input_2[0][0]']
__________________________________________________________________________________________________

 ds13 (Dense)                   (None, 13)           169         ['ds12[0][0]']
__________________________________________________________________________________________________

 ds22 (Dense)                   (None, 22)           484         ['ds21[0][0]']
__________________________________________________________________________________________________

 ds14 (Dense)                   (None, 11)           154         ['ds13[0][0]']
__________________________________________________________________________________________________

 ds23 (Dense)                   (None, 23)           529         ['ds22[0][0]']
__________________________________________________________________________________________________

 mg1 (Concatenate)              (None, 34)           0           ['ds14[0][0]',
                                                                  'ds23[0][0]']

 mg2 (Dense)                    (None, 12)           420         ['mg1[0][0]']

 mg3 (Dense)                    (None, 13)           169         ['mg2[0][0]']

 last (Dense)                   (None, 1)            14          ['mg3[0][0]']

==================================================================================================
Total params: 2,200
Trainable params: 2,200
Non-trainable params: 0
__________________________________________________________________________________________________
'''


# 3. compile and train
model.compile(loss='mse', optimizer='adam')
model.fit([x1_train, x2_train], y_train, epochs=10, batch_size=8)
# 모델 2개를 훈련시켜야하므로 훈련의 입력값도 2개 필요


# 4. evaluate and predict
loss = model.evaluate([x1_test, x2_test], y_test)
# 모델 2개를 훈련시켰으므로 평가의 입력값도 2개 필요
print("Loss: ", loss)



'''
Result
Loss:  15543.3212890625

'''
# ensemble_model2.py

import numpy as np

from sklearn.model_selection import train_test_split

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input


# 1. Data
x_datasets = np.array([range(100), range(301, 401)]).transpose()

y1 = np.array(range(2001, 2101)) # (100,)
y2 = np.array(range(201, 301)) # (100,)

x_train, x_test = train_test_split(
    x_datasets, train_size=0.7, random_state=1234
)

y1_train, y1_test, y2_train, y2_test = train_test_split(
    y1, y2, train_size=0.7, random_state=1234
)

print(x_train.shape, y1_train.shape, y2_train.shape) # (70, 2) (70,) (70,)
print(x_test.shape, y1_test.shape, y2_test.shape) # (30, 2) (30,) (30,)


# 2. Model Construction
# 2-1. Model_1
input1 = Input(shape=(2,))
dense1 = Dense(11, activation='relu', name='ds11')(input1)
dense2 = Dense(12, activation='relu', name='ds12')(dense1)
dense3 = Dense(13, activation='relu', name='ds13')(dense2)
output = Dense(14, activation='relu', name='ds14')(dense3)

# 2-2. Model_branch1
dense21 = Dense(11, activation='relu', name='ds21')(output)
# input 변수 선언없이, last_output Dense Layer Branch Model에서 직접 받기
dense22 = Dense(12, activation='relu', name='ds22')(dense21)
dense23 = Dense(13, activation='relu', name='ds23')(dense22)
output_b1 = Dense(14, activation='relu', name='ds24')(dense23)

# 2-3. Model_branch2
dense31 = Dense(11, activation='relu', name='ds31')(output)
dense32 = Dense(12, activation='relu', name='ds32')(dense31)
dense33 = Dense(13, activation='relu', name='ds33')(dense32)
output_b2 = Dense(14, activation='relu', name='ds34')(dense33)

model = Model(inputs=[input1], outputs=[output_b1, output_b2])
model.summary()


# 3. compile and train
model.compile(loss='mse', optimizer='adam', metrics=['mae'])
model.fit(x_train, [y1_train, y2_train], epochs=128, batch_size=8)


# 4. evaluate and predict
loss = model.evaluate(x_test, [y1_test, y2_test])
print("Loss: ", loss)



'''
Result
loss: 3059665.2500 / ds24_loss: 3034864.0000 / ds34_loss: 24801.2871
-> model n개 출력: 각 model의 loss 및 loss의 합계도 출력(n+1개)

ds24_mae: 1481.5680 / ds34_mae: 104.1349
-> model n개 출력: 각 model의 mae 출력(합계는 loss 부분만 출력)

'''

 

 

 

소스 코드

🔗 HJ0216/TIL

 

참고 자료

📑 앙상블 학습(ensemble learning)으로 알고리즘 성능 개선하기(1) - Voting