[인공지능] 케라스 기초 - 모델 구성 방법

참조


모델 구성 방법

  • Sequential()
  • 서브클래싱(Subclassing)
  • 함수형 API

Sequential()

  • 모델이 순차적으로 진행할 때 사용
  • 간단한 방법
    • Sequential 객체 생성 후, add를 통한 방법
    • Sequential 인자에 한번에 추가
  • 다중 입력 및 출력이 존재하는 등의 복잡한 모델을 구성할 수 없음
from tensorflow.keras.layers import Dense, Input, Flatten
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.utils import plot_model

model = Sequential()
model.add(Input(shape=(28,28))) 
model.add(Dense(300, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(10, activation='softmax'))

# 모델 구조 확인
# model 객체의 summary() 이용
model.summary()

model = Sequential([Input(shape=(28,28), name='Input'),
                    Dense(300, activation='relu', name='Dense1'),
                    Dense(100, activation='relu', name='Dense2'),
                    Dense(10, activation='softmax', name='Output')])

model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense (Dense)               (None, 28, 300)           8700      

 dense_1 (Dense)             (None, 28, 100)           30100     

 dense_2 (Dense)             (None, 28, 10)            1010      

=================================================================
Total params: 39,810
Trainable params: 39,810
Non-trainable params: 0
_________________________________________________________________
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #
=================================================================
 Dense1 (Dense)              (None, 28, 300)           8700

 Dense2 (Dense)              (None, 28, 100)           30100

 Output (Dense)              (None, 28, 10)            1010

=================================================================
Total params: 39,810
Trainable params: 39,810
Non-trainable params: 0

함수형 API

  • 가장 권장되는 방법
  • 모델을 복잡하고, 유연하게 구성 가능
  • 다중 입출력을 다룰 수 있음
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense, Concatenate

inputs = Input(shape=(28, 28, 1))

x = Flatten(input_shape=(28,28,1))(inputs)
x = Dense(300, activation='relu')(x)
x = Dense(100, activation='relu')(x)
x = Dense(10, activation='softmax')(x)

model = Model(inputs=inputs, outputs=x)

model.summary()

input_layer = Input(shape=(28,28))
hidden1 = Dense(100, activation='relu')(input_layer)
hidden2 = Dense(30, activation='relu')(hidden1)
concat = Concatenate()([input_layer, hidden2])
output = Dense(1)(concat)

model = Model(inputs=[input_layer], outputs=[output])
model.summary()

input_1 = Input(shape=(10,10), name='input_1')
input_2 = Input(shape=(10,28), name='input_2')

hidden1 = Dense(100, activation='relu')(input_2)
hidden2 = Dense(10, activation='relu')(hidden1)
concat = Concatenate()([input_1, hidden2])
output = Dense(1, activation='sigmoid', name='output')(concat)

model = Model(inputs=[input_1, input_2], outputs = [output])

model.summary()

# 다중 출력
input_ = Input(shape=(10,10), name='input_')

hidden1 = Dense(100, activation='relu')(input_)
hidden2 = Dense(10, activation='relu')(hidden1)

output = Dense(1, activation='sigmoid', name='main_output')(hidden2)
sub_out = Dense(1, name='sum_output')(hidden2)

model = Model(inputs=[input_], outputs=[output, sub_out])

model.summary()

## 입력 다중, 출력 다중
input_1 = Input(shape=(10,10), name='input_1')
input_2 = Input(shape=(10,28), name='input_2')

hidden1 = Dense(100, activation='relu')(input_2)
hidden2 = Dense(10, activation='relu')(hidden1)
concat = Concatenate()([input_1, hidden2])
output = Dense(1, activation='sigmoid', name='main_output')(concat)
sub_out = Dense(1, name='sum_output')(hidden2)

model = Model(inputs=[input_1, input_2], outputs=[output, sub_out])

model.summary()
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #
=================================================================
 input_1 (InputLayer)        [(None, 28, 28, 1)]       0

 flatten (Flatten)           (None, 784)               0

 dense (Dense)               (None, 300)               235500

 dense_1 (Dense)             (None, 100)               30100

 dense_2 (Dense)             (None, 10)                1010

=================================================================
Total params: 266,610
Trainable params: 266,610
Non-trainable params: 0
_________________________________________________________________
Model: "model_1"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_2 (InputLayer)           [(None, 28, 28)]     0           []

 dense_3 (Dense)                (None, 28, 100)      2900        ['input_2[0][0]']

 dense_4 (Dense)                (None, 28, 30)       3030        ['dense_3[0][0]']

 concatenate (Concatenate)      (None, 28, 58)       0           ['input_2[0][0]',
                                                                  'dense_4[0][0]']

 dense_5 (Dense)                (None, 28, 1)        59          ['concatenate[0][0]']

==================================================================================================
Total params: 5,989
Trainable params: 5,989
Non-trainable params: 0
__________________________________________________________________________________________________
Model: "model_2"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_2 (InputLayer)           [(None, 10, 28)]     0           []

 dense_6 (Dense)                (None, 10, 100)      2900        ['input_2[0][0]']

 input_1 (InputLayer)           [(None, 10, 10)]     0           []

 dense_7 (Dense)                (None, 10, 10)       1010        ['dense_6[0][0]']

 concatenate_1 (Concatenate)    (None, 10, 20)       0           ['input_1[0][0]',
                                                                  'dense_7[0][0]']

 output (Dense)                 (None, 10, 1)        21          ['concatenate_1[0][0]']

==================================================================================================
Total params: 3,931
Trainable params: 3,931
Non-trainable params: 0
__________________________________________________________________________________________________
Model: "model_3"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_ (InputLayer)            [(None, 10, 10)]     0           []

 dense_8 (Dense)                (None, 10, 100)      1100        ['input_[0][0]']

 dense_9 (Dense)                (None, 10, 10)       1010        ['dense_8[0][0]']

 main_output (Dense)            (None, 10, 1)        11          ['dense_9[0][0]']

 sum_output (Dense)             (None, 10, 1)        11          ['dense_9[0][0]']

==================================================================================================
Total params: 2,132
Trainable params: 2,132
Non-trainable params: 0
__________________________________________________________________________________________________
Model: "model_4"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_2 (InputLayer)           [(None, 10, 28)]     0           []

 dense_10 (Dense)               (None, 10, 100)      2900        ['input_2[0][0]']

 input_1 (InputLayer)           [(None, 10, 10)]     0           []

 dense_11 (Dense)               (None, 10, 10)       1010        ['dense_10[0][0]']

 concatenate_2 (Concatenate)    (None, 10, 20)       0           ['input_1[0][0]',
                                                                  'dense_11[0][0]']

 main_output (Dense)            (None, 10, 1)        21          ['concatenate_2[0][0]']

 sum_output (Dense)             (None, 10, 1)        11          ['dense_11[0][0]']

==================================================================================================
Total params: 3,942
Trainable params: 3,942
Non-trainable params: 0

서브클래싱(Subclassing)

  • 커스터마이징에 최적화된 방법
  • Model 클래스를 상속받아 Model이 포함하는 기능을 사용할 수 있음
    • fit(), evaluate(), predict()
    • save(), load()
  • 주로 call() 메서드안에서 원하는 계산 가능
    • for, if, 저수준 연산 등
  • 권장되는 방법은 아니지만 어떤 모델의 구현 코드를 참고할 때 해석할 수 있어야 함
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense

# MyModel 클래스 
class MyModel(Model):
    def __init__(self, units=30, activation='relu', **kwargs):
        super(MyModel, self).__init__(**kwargs)

        self.dense_layer1 = Dense(300, activation=activation)
        self.dense_layer2 = Dense(100, activation=activation)
        self.dense_layer3 = Dense(units, activation=activation)

        self.output_layer = Dense(10, activation='softmax')

    def call(self, inputs):
        x = self.dense_layer1(inputs)
        x = self.dense_layer2(x)
        x = self.dense_layer3(x)
        x = self.output_layer(x)
        return x

언제 서브 클래싱 API를 사용해야 할까?

  • Sequential API는 간단한 모델을 구현하기에 적합합니다.
  • Functional API로는 Sequential API로 구현할 수 없는 복잡한 모델들을 구현 가능합니다.
  • 그런데 Subclassing API로는 Functional API가 구현할 수 없는 모델들조차 구현할 수 있는 경우가 있습니다.
  • Function API는 기본적으로 딥 러닝 모델을 DAG(directed acyclic graph)로 취급합니다.
  • 실제로 대부분의 딥 러닝 모델이 이에 속하기는 하지만, 항상 그러지는 않습니다.
  • 예를 들어 재귀 네트워크나 트리 RNN은 이 가정을 따르지 않으며 Functional API에서 구현할 수 없습니다.
  • 이를 반대로 해석하면 대부분의 딥 러닝 모델은 Functional API 수준에서도 전부 구현이 가능하다는 의미이기도 합니다.
  • 그래서 Subclassing API 는 밑바닥부터 새로운 수준의 아키텍처를 구현해야 하는 실험적 연구를 하는 연구자들에게 적합합니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY