Keras 사용자 정의 레이어: tf.keras.layers.Layer를 활용한 맞춤형 딥러닝 레이어 구현

져닝·2025년 1월 21일

tensorflow-keras

목록 보기
3/5

사용자 정의 레이어란?

Keras는 딥러닝 모델을 빠르고 간편하게 개발할 수 있도록 다양한 기본 레이어를 제공한다. 하지만 모든 경우에 기본 레이어만으로는 원하는 모델을 구현하기 어려울 수 있다. 예를 들어, 특정 계산이 포함된 복잡한 레이어나, 데이터의 특징에 맞춘 맞춤형 레이어가 필요할 때가 있다. 이럴 때 tf.keras.layers.Layer를 상속받아 자신만의 레이어를 구현할 수 있다.

사용자 정의 레이어는 다음과 같은 경우 유용하다.
1. 특수한 계산이 필요한 경우: 기존 레이어로 구현하기 어려운 복잡한 연산을 수행할 때
2. 학습 가능한 파라미터 추가: 원하는 방식으로 학습 가능한 가중치와 편향을 정의할 수 있음
3. 재사용 가능한 컴포넌트: 여러 모델에서 사용할 수 있는 모듈형 레이어를 설계할 때
4. 연산 최적화: 특정 연산을 GPU 또는 TPU에 최적화하려는 경우

기본적으로 사용자 정의 레이어는 tf.keras.layers.Layer를 상속받아 만들며, Keras의 Functional API 또는 Sequential API와 호환된다. 사용자 정의 레이어를 설계할 때는 크게 다음 세 가지 메서드가 중요하다.
1. __init__: 초기화 메서드로, 레이어에서 사용할 주요 파라미터 정의
2. build: 입력 텐서의 크기에 따라 가중치 등 상태 초기화
3. call: 레이어의 순전파(Forward) 계산 정의


기본 구현

Keras에서 사용자 정의 레이어를 구현하려면 tf.keras.layers.Layer 클래스를 상속받아 다음 주요 메서드들을 정의해야 한다.

1. __init__ 메서드

  • 레이어의 주요 속성 초기화
  • 부모 클래스의 __init__ 메서드 호출
 import tensorflow as tf
 class CustomDenseLayer(tf.keras.layers.Layer):
 	def __init__(self, units, **kwargs):
    	super(CustomDenseLayer, self).__init__(**kwargs)
        self.units = units

2. build 메서드

  • 입력 데이터의 형태에 따라 레이어의 가중치와 학습 가능한 변수 정의
  • self.add_weight 메서드를 사용해 변수 추가
	def build(self, input_shape):
    	self.w = self.add_weight(shape=(input_shape[-1], self.units),
        						initializer="random_normal",
                                trainable=True)
        self.b = self.add_weight(shape=(self.units,),
        						initializer="zeros",
                                trainable=True)

3. call 메서드

  • 순전파 계산 정의
	def call(self, inputs):
    	return tf.matmul(inputs, self.w) + self.b

위의 내용을 바탕으로 완성된 사용자 정의 Dense 레이어는 다음과 같다.

class CustomDenseLayer(tf.keras.layers.Layer):
    def __init__(self, units, **kwargs):
        super(CustomDenseLayer, self).__init__(**kwargs)
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer="random_normal",
                                 trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                                 initializer="zeros",
                                 trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b

사용자 정의 레이어 활용

사용자 정의 레이어를 구현한 후, 이를 실제 모델에 적용하는 방법을 알아보자. Keras의 Functional API를 활용하면 더욱 유연하고 직관적인 모델 설계가 가능하다.

Functional API로 모델 설계하기

import tensorflow as tf
from tensorflow.keras import Model, Input

# 사용자 정의 레이어
class CustomDenseLayer(tf.keras.layers.Layer):
    def __init__(self, units, **kwargs):
        super(CustomDenseLayer, self).__init__(**kwargs)
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer="random_normal",
                                 trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                                 initializer="zeros",
                                 trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b
        
# 모델 설계
inputs = Input(shape=(4,))
x = CustomDenseLayer(8)(inputs)
x = tf.keras.layers.ReLU()(x)
outputs = tf.ekras.layers.Dense(1, activation='sigmoid')(x)

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

모델 컴파일 및 훈련

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10, batch_size=8)

모델 저장 및 로드

사용자 정의 레이어를 포함한 모델을 저장하고 로드하는 과정은 일반적인 Keras 모델과 크게 다르지 않다. 그러나 사용자 정의 객체를 처리하기 위해 custom_objects를 등록하거나, get_config 메서드를 구현하는 것이 중요하다. 모델 저장 시 get_config 메서드를 정의하면, 사용자 정의 레이어의 매개변수 정보가 함께 저장된다. 이를 통해 로드 시 추가적인 사용자 정의 객체 등록 없이도 레이어를 복원할 수 있다.

class CustomDenseLayer(tf.keras.layers.Layer):
    def __init__(self, units, **kwargs):
        super(CustomDenseLayer, self).__init__(**kwargs)
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer="random_normal",
                                 trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                                 initializer="zeros",
                                 trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b

    def get_config(self):
        config = super(CustomDenseLayer, self).get_config()
        config.update({"units": self.units})
        return config

# 저장 및 로드 시 get_config 활용
model.save("custom_layer_model_with_config.h5")
loaded_model = load_model("custom_layer_model_with_config.h5",
                          custom_objects={"CustomDenseLayer": CustomDenseLayer})

결론

Keras에서 사용자 정의 레이어를 구현하고 활용하는 과정은 딥러닝 모델에 있어 유연성과 확장성을 더해준다. 이를 통해 기존의 기본 레이어로는 해결하기 어려운 복잡한 연산이나 특화된 요구사항을 만족시킬 수 있다.

profile
태양물리박사 / 코드 공부 끄적끄적하는 공간 / Space weather forecasting

0개의 댓글