concatenate
2개 이상의 모델 합치기
데이터 구성
- x 값 y값이 미리 유추되지 않도록 데이터 컬럼을 약간 섞음
- x 2개 : 300개씩의 데이터
- y 1개 : 100개의 데이터
#1. 데이터
import numpy as np
x1 = np.array([range(100), range(311,411), range(100)])
x2 = np.array([range(101,201), range(311,411), range(101,201)])
y = np.array([range(501,601)]) #, range(711,811), range(100)]
- 현재의 shape는 (3, 100) 이므로 (100,3)으로 reshape
x1 = np.transpose(x1)
y = np.transpose(y)
x2 = np.transpose(x2)
- train, test, validation으로 분리
from sklearn.model_selection import train_test_split
x1_train, x1_test, y_train, y_test = train_test_split(
x1, y, random_state=66, test_size=0.4, shuffle=False
)
x1_val, x1_test, y_val, y_test = train_test_split(
x1_test, y_test, random_state=66, test_size=0.5, shuffle=False
)
x2_train, x2_test = train_test_split(
x2, random_state=66, test_size=0.4, shuffle=False
)
x2_val, x2_test= train_test_split(
x2_test, random_state=66, test_size=0.5, shuffle = False
)
모델 구성
2개의 모델을 만든 뒤 2개의 모델을 병합 - 앙상블 모델 이용
Sequantial을 주석 처리 후 Input 레이어를 이용 레이어를 만듦 이후 input1의 함수형 모델을 만듦
#2. 모델 구성
from keras.models import Sequential, Model
from keras.layers import Dense, Input
# model = Sequential()
input1 = Input(shape=(3,))
dense1 = Dense(100, activation='relu')(input1)
dense1_2 = Dense(30)(dense1)
dense1_3 = Dense(7)(dense1_2)
input2 함수형 모델을 만듦
input2 = Input(shape=(3,))
dense2 = Dense(50, activation='relu')(input2)
dense2_2 = Dense(7)(dense2)
다음 그림과 같이 머지
concatenate 함수로 머지
from keras.layers.merge import concatenate
merge1 = concatenate([dense1_3, dense2_2])
또는 Concatenate 클래스로 머지
from keras.layers.merge import Concatenate
merge1 = Concatenate()([dense1_3, dense2_2])
모델이 병합된 이후 레이어를 엮어줌
model1 = Dense(10)(merge1)
model2 = Dense(5)(model1)
output = Dense(1)(model2)
아웃풋 레이어가 준비되면 다음과 같이 모델을 정의
model = Model(inputs = [input1, input2], outputs = output)
model.summary()
summary() 의 출력
- 다섯 번째 dense 와 여섯 번째 dense 사이에 concatenate가 이루어진 것을 확인
Model: "functional_1"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 3)] 0
__________________________________________________________________________________________________
dense (Dense) (None, 100) 400 input_1[0][0]
__________________________________________________________________________________________________
input_2 (InputLayer) [(None, 3)] 0
__________________________________________________________________________________________________
dense_1 (Dense) (None, 30) 3030 dense[0][0]
__________________________________________________________________________________________________
dense_3 (Dense) (None, 50) 200 input_2[0][0]
__________________________________________________________________________________________________
dense_2 (Dense) (None, 7) 217 dense_1[0][0]
__________________________________________________________________________________________________
dense_4 (Dense) (None, 7) 357 dense_3[0][0]
__________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 14) 0 dense_2[0][0]
dense_4[0][0]
__________________________________________________________________________________________________
dense_5 (Dense) (None, 10) 150 concatenate_1[0][0]
__________________________________________________________________________________________________
dense_6 (Dense) (None, 5) 55 dense_5[0][0]
__________________________________________________________________________________________________
dense_7 (Dense) (None, 1) 6 dense_6[0][0]
==================================================================================================
Total params: 4,415
Trainable params: 4,415
Non-trainable params: 0
__________________________________________________________________________________________________
훈련
- x의 입력 데이터가 2개이므로 list 형태임을 주의
- validation 역시 list 형태임을 주의
#3. 훈련
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
model.fit([x1_train, x2_train],
y_train,
epochs=100,
batch_size=1,
validation_data=([x1_val, x2_val] , y_val))
평가
#4. 평가 예측
mse = model.evaluate([x1_test, x2_test],
y_test, batch_size=1)
print("mse : ", mse)
평가 시에도 x의 입력 데이터가 2개 이므로 list 형태로 입력
y_predict = model.predict([x1_test, x2_test])
for i in range(len(y_predict)):
print(y_test[i], y_predict[i])
결과
mse : [99.28654479980469, 99.28654479980469]
[581] [587.13806]
[582] [588.51447]
[583] [589.8908]
[584] [591.2672]
[585] [592.64343]
[586] [594.01996]
[587] [595.39624]
[588] [596.77454]
[589] [598.153]
[590] [599.5315]
[591] [600.91003]
[592] [602.28845]
[593] [603.667]
[594] [605.0454]
[595] [606.4239]
[596] [607.8025]
[597] [609.1809]
[598] [610.5593]
[599] [611.938]
[600] [613.3164]
Merge Layer
concatenate는 단순히 2개의 모델을 엮어 주는 역할을 함
- (10, 3) , (10, 3) ==> (10, 6) 행태로 엮이는 것뿐
- 합쳐지는 레이어 부분에서 노드들이 단순하게 더하기 형태로 합쳐짐
데이터 상에서 컴럼을 합쳐서 단일 모델로 구성해도 되지 않을까?
1) Add - keras.layers.Add()
layer 끼리의 단순한 더하기.
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서(동일한 모양)
#1. ADD
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
# equivalent to added = keras.layers.add([x1, x2])
added = keras.layers.Add()([x1, x2])
out = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
2) Substract - kereas.layers.Subtract()
layer끼리의 단순한 뺄셈.
- 입력 : 동일한 모양의 크기 2인 텐서 목록
- 반환 : 동일한 모양의 단일 텐서(입력[0] - 입력[1])
#2. Subtract
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
# Equivalent to subtracted = keras.layers.subtract([x1, x2])
subtracted = keras.layers.Subtract()([x1, x2])
out = keras.layers.Dense(4)(subtracted)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
3) Multiply
layer 끼리의 입력 목록을 (요소 별로) 곱하는 레이어.
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서
4) Average
인풋 리스트의 평균을 내는 레이어
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서
5) Maximum
입력 목록의 최대(요소별로)를 계산하는 레이어
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서
6) Minimum
입력 목록의 최소(요소별로)를 계산하는 레이어
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서
7) Concatenate
입력 목록을 연결하는 계층
- 연결축 : 디폴트는 axis= -1
- 입력 : 동일한 모양의 텐서 목록
- 반환 : 하나의 텐서
8) Dot
두 텐서에서 샘플간 내적을 계산하는 레이어
- 2개의 텐서 a 와 b의 모양(batch_size, n) 목록에 적용되는 경우
- 출력 : 모양의 텐서(batch_size, n). 여기서 각 항목 i는 a[i] 와 b[i]사이의 내적
9) add
Add와 같은 기능이지만 사용법이 다름
#9. add
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
added = keras.layers.add([x1, x2])
out = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
10) subtract
Substract 와 같은 기능이지만 사용법이 다름
#10. subtract
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
subtracted = keras.layers.subtract([x1, x2])
out = keras.layers.Dense(4)(subtracted)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
11) multiply
12) average
13) maximum
14) minimum
15) concatenate
16) dot
'책 > 딥러닝으로 걷는 시계열 예측' 카테고리의 다른 글
회귀모델 (0) | 2020.11.29 |
---|---|
딥러닝 시작 (0) | 2020.11.28 |