• 카테고리

    질문 & 답변
  • 세부 분야

    컴퓨터 비전

  • 해결 여부

    미해결

클래스 메서드 call을 __call__로 하면 왜 오류가 날까요?

21.04.23 10:56 작성 조회수 655

0

파이썬 클래스의  'call' 메서드를 정의할때

' __call__'을 사용하는 것으로 알고 있는데, 

    def __call__:

            --code--

캐글 강의코드에서 __call__로 바꾸면 오류가 안나고

call을 하면 정상작동하는데 왜 이런건지 이런지 궁금합니다.

답변 1

답변을 작성해보세요.

1

안녕하십니까

1. 캐글 강의코드에서 __call__로 바꾸면 오류가 안나고

call을 하면 정상작동하는데 왜 이런건지 이런지 궁금합니다.

=> keras Layer의 call()과 __call__()은 거의 유사하게 동작합니다.

keras Layer를 Callbable 객체로 만들면 보다 정확하게는 __call__()이 내부적으로 호출이 됩니다. 이 __call__()은 부모 Layer에 감춰져 있기에 작성해줄 필요가 없으며, __call__()이 해주는 것은 build()를 호출한 뒤에 call()을 호출하는 역할을 합니다.

Custom layer에 call()을 사용하지 않고 __call__()을 바로 적용할 수도 있습니다. 하지만 그렇게 하기 위해서는 build()에서 사용된 weight와 bias의 초기화를 한 뒤에 matrix 연산을 적용하고 tensor로 반환하는 로직을 만들어 줘야 합니다.

class CustomDense(tf.keras.layers.Layer):
    # CustomDense 객체 생성시 입력되는 초기화 parameter 처리
    def __init__(self, units=32):
        super(CustomDense, self).__init__()
        self.units = units

    
    def __call__(self, inputs):
        self.w = self.add_weight(
            shape=(inputs.shape[-1], self.units),
            initializer="random_normal",
            trainable=True,
        )
        self.b = self.add_weight(
            shape=(self.units,), initializer="random_normal", trainable=True
        )
        return tf.matmul(inputs, self.w) + self.b

# input 값을 4개의 원소를 가지는 1차원으로 생성.
inputs = Input((4,))
# 10개의 unit을 가지는 CustomDense 객체를 생성 후 callable로 inputs값 입력
outputs = CustomDense(10)(inputs)

# inputs와 outputs로 model 생성.
model = Model(inputs, outputs)
model.summary()