딥러닝 모델을 개발하기위해 사용하는 프레임워크에는 TensorFlow와 PyTorch가 있다. TensorFlow에는 세 가지의 API를 활용해서 모델을 개발할 수 있다.
- Sequential API
- Functional API
- Subclassing API
이 API들은 각각의 장단점을 가지고있다. 이번 포스팅에서는 API들에 대해 알아보고, 이전 포스팅인 수어인식 모델 개발에서 Functional API와 Subclassing API를 각각 사용했을 때, 성능차이(학습시간, Accuracy 등)가 있는지, 왜 생기는지에 대해 알아보겠다.
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
model = Sequential()
model.add(Conv2D(kernel_size=(3, 3), filters=16, activation='relu'))
model.add(MaxPooling2D((2, 2))
model.add(Conv2D(kernel_size=(3, 3), filters=16, activation='relu'))
model.add(MaxPooling2D((2, 2))
model.add(Conv2D(kernel_size=(3, 3), filters=16, activation='relu'))
model.add(Flatten())
model.add(Dense(32, activation='relu')
model.add(Dense(10, activation='softmax')
위 코드는 총 10개의 Class를 분류하는 CNN을 Sequential API로 구현한 모델이다.
Sequential API를 활용한 모델은 아마도(?) 처음 딥러닝을 입문하는 서적이나 자료에서 가장 먼저 다루는 모델의 형태일 것이다.
- 장점으로는 매우 직관적이며, 단순히 층을 쌓음으로 쉽게 모델을 개발할 수 있다. 초심자에게 적합하다.
- 단점은 단순하게 층을 쌓음으로써, 복잡하고 깊은 모델에 대해서는 타 API에 비해 상대적으로 구현하기 힘들다는 단점이 존재한다.
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.models import Model
inputs = Input(shape=(10,))
conv1 = tf.keras.layers.Conv2D(kernel_size=(3, 3), filters=16, activation='relu')(inputs)
pool1 = tf.keras.layers.MaxPooling2D((2, 2))(conv1)
conv2 = tf.keras.layers.Conv2D(kernel_size=(3, 3), filters=32, activation='relu')(pool1)
pool2 = tf.keras.layers.MaxPooling2D((2, 2))(conv2)
conv3 = tf.keras.layers.Conv2D(kernel_size=(3, 3), filters=64, activation='relu')(pool2)
flatten = tf.keras.layers.Flatten()(conv3)
dense1 = tf.keras.layers.Dense(32, activation='relu')(flatten)
outputs = tf.keras.layers.Dense(10, activation='softmax')(dense1)
model = Model(inputs=inputs, outputs=output)
Functional API는 이름에서 알 수 있듯이, 함수(Function)로 모델을 정의한다. Functional API는 Sequential API에서는 구현하기 힘든 복잡한 Network의 구현이 가능하다.
- Input()으로 input_shape(입력 크기)를 정의하고, 모델의 Layer을 정의할 때, 이전층을 다음층의 입력으로 사용한다.
- Model()에 Input과 Output을 정의한다.
class Subclassing(tf.keras.Model):
def __init__(self):
super(Subclassing, self).__init__()
self.conv1 = tf.keras.layers.Conv2D(kernel_size=(3,3), filters=16, activation='relu')
self.conv2 = tf.keras.layers.Conv2D(kernel_size=(3,3), filters=32, activation='relu')
self.conv3 = tf.keras.layers.Conv2D(kernel_size=(3,3), filters=64, activation='relu')
self.pool = tf.keras.layers.MaxPooling2D((2, 2))
self.flatten = tf.keras.layers.Flatten()
self.d1 = tf.keras.layers.Dense(32, activation='relu')
self.d2 = tf.keras.layers.Dense(10, activation='softmax')
def call(self, x):
x = self.conv1(x)
x = self.pool(x)
x = self.conv2(x)
x = self.pool(x)
x = self.conv3(x)
x = self.flatten(x)
x = self.d1(x)
return self.d2(x)
model = Subclassing()
이전의 Functional API는 Sequential API에 비해 복잡한 Network구현이 가능했다. 하지만, Subclassing API는 Functional API보다 더 복잡한 Network의 구현이 가능하다.
- Subclassing API는 밑바닥부터 새로운 수준의 Architecture를 구현해야하는 연구자 등 연구의 목적에 적합하다.
API | Sequential API | Functional API | Subclassing API |
---|---|---|---|
장점 | 직관적 | Sequential API에서 구현이 힘든 모델 구현이 가능 | Functional API에서 구현이 힘든 모델 구현이 가능 |
단점 | 복잡한 신경망을 구현이 어려움 | 입력과 출력을 직접 정의 해줘야 함 | Oop에 익숙해야 사용하기 편하며, 사용이 까다로움 |
위 표처럼 API들은 각각의 상대적인 장단점을 가지고있으며, API마다 상대적인 모델 구현의 한계가 존재하며, 자신의 개발 프로젝트에 필요한 모델의 정도(?)에 맞추어 사용하면 좋을 것 같다.