새소식

AI 개발

[Keras] 튜토리얼8 - 함수형으로 모델 구축(functional API)

  • -

지금까지 예제에 사용했던 모델을 설계하는 방식은 sequential API를 사용한 것 입니다.

하지만 sequential API는 여러층을 공유하거나, 다양한 종류의 입출력을 사용하는 등의 복잡한 모델을 만드는 일을 하기에는 한계가 있습니다. 이번 포스팅에서는 복잡한 모델을 생성할 수 있는 방식은 functioanl API(함수형 API)에 대해서 알아봅시다.

 

 

● Sequential API

1
2
3
4
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model=Sequential()
model.add(Dense(3, input_dim=4, activation='softmax'))
cs

 

sequential api를 이용한 방식은 직관적이고 편리하지만 단순히 층을 쌓는 것만으로는 구현할 수 없는 복잡한 Neural Network를 구현할 수 없습니다.

 

 

 

 

● Functional API

- Sequential API와 Functional API 차이점

  • functional api에서는 입력 데이터의 크기(shape)을 Input() 함수의 인자로 입력층을 정의해주어야 합니다.
  • 이전층을 다음층 함수의 입력으로 사용하고, 변수에 할당합니다.
  • Model() 함수에 입력과 출력을 정의합니다.

 

여기서 shape = (1,) 엄밀히 말하면 vector가 한개라는 뜻이됩니다. 데이터.shape이 (5,1)일 경우 5행1열을 가진 데이터라는 뜻이 되는데요. 여기서 행은 무시하고 열!만 shape으로 입력을 해주는 것 입니다. 데이터는 계속 추가 될 수 있으므로 열(feature)만 중요하기 때문입니다.

 

 

1) 전결합 피드 포워드 신경망(Fully-connected FFNN)

1
2
3
4
5
6
7
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
inputs = Input(shape=(10,))
hidden1 = Dense(64, activation='relu')(inputs)
hidden2 = Dense(64, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=inputs, outputs=output)
cs

이 예제는 입력의 차원이 1인 전결합 피드 포워드신경망(Fully-connected FFNN)을 구현한 것입니다.

 

1
2
3
4
5
inputs = Input(shape=(10,))
= Dense(8, activation="relu")(inputs)
= Dense(4, activation="relu")(x)
= Dense(1, activation="linear")(x)
model = Model(inputs, x)
cs

이런식으로 은닉층과 출력층의 변수를 전부 x로 통일하여 사용하여도 됩니다.

 

이렇게 model 이라는 변수에 최종적으로 할당한 모델은 sequential api와 마찬가지로 model.compile, model.fit 등으로 컴파일하고 훈련하여 사용이 가능합니다.

 

 

2) 선형 회귀(Linear Regression)

1
2
3
4
5
6
7
8
9
10
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
 
inputs = Input(shape=(3,))
output = Dense(1, activation='linear')(inputs)
linear_model = Model(inputs, output)
 
linear_model.compile(optimizer='sgd', loss='mse')
linear_model.fit(x=dat_test, y=y_cts_test, epochs=50, verbose=0)
linear_model.fit(x=dat_test, y=y_cts_test, epochs=1, verbose=1)
cs

선형 회귀 : 1차원 방정식의 기울기(함수식)을 구하는 것

 

 

3) 로지스틱 회귀(Logistic Regression)

1
2
3
4
5
6
7
8
9
10
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
 
inputs = Input(shape=(3,))
output = Dense(1, activation='sigmoid')(inputs)
logistic_model = Model(inputs, output)
 
logistic_model.compile(optimizer='sgd', loss = 'binary_crossentropy', metrics=['accuracy'])
logistic_model.optimizer.lr = 0.001
logistic_model.fit(x=dat_train, y=y_classifier_train, epochs = 5, validation_data = (dat_test, y_classifier_test))
cs

로지스틱 회귀 : 직선 대신, S자 곡선을 이용하여 분류에 정확도를 향상

 

 

4) 다중 입력을 받는 모델(multiple inputs model)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from tensorflow.keras.layers import Input, Dense, concatenate
from tensorflow.keras.models import Model
 
# 두 개의 입력층을 정의
inputA = Input(shape=(64,))
inputB = Input(shape=(128,))
 
# 첫번째 입력층으로부터 분기되어 진행되는 인공 신경망을 정의
= Dense(16, activation="relu")(inputA)
= Dense(8, activation="relu")(x)
= Model(inputs=inputA, outputs=x)
 
# 두번째 입력층으로부터 분기되어 진행되는 인공 신경망을 정의
= Dense(64, activation="relu")(inputB)
= Dense(32, activation="relu")(y)
= Dense(8, activation="relu")(y)
= Model(inputs=inputB, outputs=y)
 
# 두개의 인공 신경망의 출력을 연결(concatenate)
result = concatenate([x.output, y.output])
 
# 연결된 값을 입력으로 받는 밀집층을 추가(Dense layer)
= Dense(2, activation="relu")(result)
# 선형 회귀를 위해 activation=linear를 설정
= Dense(1, activation="linear")(z)
 
# 결과적으로 이 모델은 두 개의 입력층으로부터 분기되어 진행된 후 마지막에는 하나의 출력을 예측하는 모델이 됨.
model = Model(inputs=[x.input, y.input], outputs=z)
cs

 

5) RNN(Recurrence Neural Network) 은닉층 사용하기

1
2
3
4
5
6
7
from tensorflow.keras.layers import Input, Dense, LSTM
from tensorflow.keras.models import Model
inputs = Input(shape=(50,1))
lstm_layer = LSTM(10)(inputs) # RNN의 일종인 LSTM을 사용
= Dense(10, activation='relu')(lstm_layer)
output = Dense(1, activation='sigmoid')(x)
model = Model(inputs=inputs, outputs=output)
cs

하나의 피처(feature)에 50개의 시점(time-step)을 입력으로 받는 모델 설계 예시 코드입니다.

RNN 대한 구체적인 사항은 따로 포스팅하도록 하겠습니다.

 

 

 

 

- 구현해보기

 

 

3개의 레이어를 가진 모델

위와 같은 그림의 모델을 구현한다고 하면,

 

먼저 Sequential API로 구현하였을 경우

model = Sequential()
model.add(Dense(5, input_dim=1, activation='relu'))
model.add(Dense(3))
model.add(Dense(1))

 

Funtional API로 구현하였을 경우

input1 = Input(shape=(1,)) # 최초의 input 명시, 컬럼 1개
dense1 = Dense(5, activation='relu')(input1) # 앞 -> 꽁무니
dense2 = Dense(3)(dense1) # input 5, output 3
output1 = Dense(1)(dense2)

model = Model(inputs=input1, outputs=output1) # 이Model은 inpt1~output1이다 명시

 

위처럼 복잡한 구조를 만들지 않을 때는 Input에서 shape 정의, 앞의 레이어 정의, model()에 입출력 정의를 하는 것 외에는 두 가지 방법을 사용하는 것은 비슷합니다. 간단한 구조를 만들때는 Sequential API을 이용해서 직관적이고 빠르게 모델을 만들고 복잡한 구조의 모델을 만들때는 주로 Functial API를 사용한다고 생각하면 될 것 같습니다.

 

 

https://wikidocs.net/book/9214

https://keras.io/api/

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.