-
[Keras] 튜토리얼8 - 함수형으로 모델 구축(functional API)💫 Computer Science/Python & AI Framework 2019. 12. 21. 23:39
지금까지 예제에 사용했던 모델을 설계하는 방식은 sequential API를 사용한 것 입니다.
하지만 sequential API는 여러층을 공유하거나, 다양한 종류의 입출력을 사용하는 등의 복잡한 모델을 만드는 일을 하기에는 한계가 있습니다. 이번 포스팅에서는 복잡한 모델을 생성할 수 있는 방식은 functioanl API(함수형 API)에 대해서 알아봅시다.
● Sequential API
1234from tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Densemodel=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)
1234567from tensorflow.keras.layers import Input, Densefrom tensorflow.keras.models import Modelinputs = 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)을 구현한 것입니다.
12345inputs = Input(shape=(10,))x = Dense(8, activation="relu")(inputs)x = Dense(4, activation="relu")(x)x = Dense(1, activation="linear")(x)model = Model(inputs, x)cs 이런식으로 은닉층과 출력층의 변수를 전부 x로 통일하여 사용하여도 됩니다.
이렇게 model 이라는 변수에 최종적으로 할당한 모델은 sequential api와 마찬가지로 model.compile, model.fit 등으로 컴파일하고 훈련하여 사용이 가능합니다.
2) 선형 회귀(Linear Regression)
12345678910from tensorflow.keras.layers import Input, Densefrom tensorflow.keras.models import Modelinputs = 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)
12345678910from tensorflow.keras.layers import Input, Densefrom tensorflow.keras.models import Modelinputs = 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.001logistic_model.fit(x=dat_train, y=y_classifier_train, epochs = 5, validation_data = (dat_test, y_classifier_test))cs 로지스틱 회귀 : 직선 대신, S자 곡선을 이용하여 분류에 정확도를 향상
4) 다중 입력을 받는 모델(multiple inputs model)
12345678910111213141516171819202122232425262728from tensorflow.keras.layers import Input, Dense, concatenatefrom tensorflow.keras.models import Model# 두 개의 입력층을 정의inputA = Input(shape=(64,))inputB = Input(shape=(128,))# 첫번째 입력층으로부터 분기되어 진행되는 인공 신경망을 정의x = Dense(16, activation="relu")(inputA)x = Dense(8, activation="relu")(x)x = Model(inputs=inputA, outputs=x)# 두번째 입력층으로부터 분기되어 진행되는 인공 신경망을 정의y = Dense(64, activation="relu")(inputB)y = Dense(32, activation="relu")(y)y = Dense(8, activation="relu")(y)y = Model(inputs=inputB, outputs=y)# 두개의 인공 신경망의 출력을 연결(concatenate)result = concatenate([x.output, y.output])# 연결된 값을 입력으로 받는 밀집층을 추가(Dense layer)z = Dense(2, activation="relu")(result)# 선형 회귀를 위해 activation=linear를 설정z = Dense(1, activation="linear")(z)# 결과적으로 이 모델은 두 개의 입력층으로부터 분기되어 진행된 후 마지막에는 하나의 출력을 예측하는 모델이 됨.model = Model(inputs=[x.input, y.input], outputs=z)cs 5) RNN(Recurrence Neural Network) 은닉층 사용하기
1234567from tensorflow.keras.layers import Input, Dense, LSTMfrom tensorflow.keras.models import Modelinputs = Input(shape=(50,1))lstm_layer = LSTM(10)(inputs) # RNN의 일종인 LSTM을 사용x = Dense(10, activation='relu')(lstm_layer)output = Dense(1, activation='sigmoid')(x)model = Model(inputs=inputs, outputs=output)cs 하나의 피처(feature)에 50개의 시점(time-step)을 입력으로 받는 모델 설계 예시 코드입니다.
RNN 대한 구체적인 사항은 따로 포스팅하도록 하겠습니다.
- 구현해보기
위와 같은 그림의 모델을 구현한다고 하면,
먼저 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를 사용한다고 생각하면 될 것 같습니다.
'💫 Computer Science > Python & AI Framework' 카테고리의 다른 글
[Keras] 튜토리얼9 - MLP(MultiLayer Perceptron) 구현하기 (0) 2019.12.30 [Anaconda] 개발환경 설치 및 WIN32 응용프로그램 오류 (3) 2019.12.27 [Keras] 튜토리얼7 - 데이터 자르기(train_test_split) (1) 2019.12.20 [Keras] 튜토리얼6 - train, test, validation DATA (0) 2019.12.19 [Keras] 튜토리얼5 - summery()로 모델 구조 확인 (1) 2019.12.18