ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Keras] 튜토리얼8 - 함수형으로 모델 구축(functional API)
    💫 Computer Science/Python & AI Framework 2019. 12. 21. 23:39

    지금까지 예제에 사용했던 모델을 설계하는 방식은 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를 사용한다고 생각하면 될 것 같습니다.

    댓글

Designed by Tistory.