세로형
Recent Posts
Recent Comments
Link
11-07 05:01
«   2024/11   »
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 29 30
Archives
Today
Total
관리 메뉴

꿈 많은 사람의 이야기

Python tensorflow 2.x error 해결 - NotImplementedError: Layer has arguments in `__init__` and therefore must override `get_config`. 본문

deep learning(딥러닝)

Python tensorflow 2.x error 해결 - NotImplementedError: Layer has arguments in `__init__` and therefore must override `get_config`.

이수진의 블로그 2020. 9. 9. 09:20
반응형
728x170

포스팅 개요

이번 포스팅은 Tensorflow 2.x 버전을 사용하면서 발견한 에러와 그 해결 방법에 대해서 정리합니다.

저의 환경은 아래와 같습니다.

  • python 3.7
  • tensorflow 2.3

포스팅 본문

포스팅 개요에서도 말씀드렸듯이 이번 포스팅은 Python의 tensorflow 2.x 버전에서 겪을 수 있는 에러에 대해 정리합니다.

제가 구성한 tensorflow 버전은 2.3이고 에러는 NotImplementedError: Layer has arguments in `__init__` and therefore must override `get_config`. 라는 에러입니다.

 

위 에러가 나오게 된 배경

저는 아래와 같은 상황에서 위 에러를 경험할 수 있었습니다.

  • Open되어 있는 Tensorflow model을 사용
    • Class로 구현되었고 케라스(keras)의 layer를 상속 받아서 만드는 모델 형식
  • Model checkpoint callback 함수를 사용해서 모델을 저장하려고 시도

이때 저장할 때 NotImplementedError: Layer has arguments in `__init__` and therefore must override `get_config`. 에러가 나오게 되었습니다.

 

에러 해결 방법

에러를 해결하는 방법은 정말 간단합니다. 

class Model(layers.Layer):
    def __init__(self, num_heads, ff_dim, rate=0.1):
        super(Model, self).__init__()
        self.A = A(num_heads)
        self.ffn = keras.Sequential(
            [layers.Dense(ff_dim, activation="relu"), layers.Dense(embed_dim),]
        )
        self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)
        self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)
        self.dropout1 = layers.Dropout(rate)
        self.dropout2 = layers.Dropout(rate)
    
    def call(self, inputs, training):
        a_output = self.A(inputs)
        a_output = self.dropout1(a_output, training=training)
        out1 = self.layernorm1(inputs + a_output)
        ffn_output = self.ffn(out1)
        ffn_output = self.dropout2(ffn_output, training=training)
        return self.layernorm2(out1 + ffn_output)

 

예를 들어서 위와 같은 코드가 있다고 했을 때 def get_config(self) 라는 함수를 추가해주면 됩니다. 이때 get_config 함수에는 update를 할 요소들을 넣어주면 됩니다. 아래와 같이 말이죠

class Model(layers.Layer):
    def __init__(self, num_heads, ff_dim, rate=0.1):
        super(Model, self).__init__()
        self.A = A(num_heads)
        self.ffn = keras.Sequential(
            [layers.Dense(ff_dim, activation="relu"), layers.Dense(embed_dim),]
        )
        self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)
        self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)
        self.dropout1 = layers.Dropout(rate)
        self.dropout2 = layers.Dropout(rate)
        
    def get_config(self):
        config = super().get_config().copy()
        config.update({
            'A': self.A,
            'ffn': self.ffn,
            'layernorm1' : self.layernorm1,
            'layernorm2' : self.layernorm2,
            'dropout1' : self.dropout1,
            'dropout2' : self.dropout2,
        })
        return config
        
    def call(self, inputs, training):
        a_output = self.A(inputs)
        a_output = self.dropout1(a_output, training=training)
        out1 = self.layernorm1(inputs + a_output)
        ffn_output = self.ffn(out1)
        ffn_output = self.dropout2(ffn_output, training=training)
        return self.layernorm2(out1 + ffn_output)

get_config는 layer를 다시 사용할 수 있게 정의를 해줍니다. 그렇게 되면 사용자가 지정한 저 클래스르 값들을 다시 사용할 수 있게 되는 것입니다. 즉, 그렇게 때문에 모델을 저장할 수 있습니다.(모델을 불러올 때 다시 사용할 수 있게 되는 구조로 생각됩니다.)

 

반응형
그리드형
Comments