【问题标题】:NotImplementedError: When subclassing the `Model` class, you should implement a `call` methodNotImplementedError:子类化 `Model` 类时,您应该实现 `call` 方法
【发布时间】:2021-06-07 10:53:38
【问题描述】:

我正在使用 解决这个图像分类问题。我正在尝试使用子类化API's 来做几乎所有事情。我创建了我的custom conv 块,如下所示:

class ConvBlock(keras.layers.Layer):
    def __init__(self, in_features, kernel_size=(3, 3)):
        super(ConvBlock, self).__init__()
        self.conv = keras.layers.Conv2D(in_features, kernel_size, padding="same")
        self.bn = keras.layers.BatchNormalization()
        self.relu = keras.activations.relu
        
    def call(self, x, training=False):
        x = self.conv(x)
        x = self.bn(x, training=training)
        return self.relu(x)

之后,我创建了用于测试的简单 Sequential 模型,如下所示:

seq_model = keras.Sequential([
    ConvBlock(64),
    ConvBlock(128),
    ConvBlock(64),
    keras.layers.Flatten(),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(5, activation='softmax'),
], name="seq_model")

seq_model.build((None, 96, 96, 1))
seq_model.summary()

到目前为止一切顺利,如果我在这个seq_model 上调用.compile().train().evaluate(),它就可以工作。当我尝试使用我的自定义.compile().train().evaluate() 调用.compile().train().evaluate() 时,问题就出现了。以下代码显示了我是如何创建它们的:

class Model(keras.Model):
    def __init__(self, model):
        super().__init__()
        self.model = model
        
    # .compile()
    def compile(self, loss, optimizer, metrics):
        super().compile()
        self.loss = loss
        self.optimizer = optimizer
        self.custom_metrics = metrics
        
    # .fit()
    def train_step(self, data):
        x, y = data
        with tf.GradientTape() as tape:
            pred = self.model(x, training=True)
            loss = self.loss(y, pred)
        
        gradients = tape.gradient(loss, self.trainable_variables)
        optimizer.apply_gradients(zip(gradients, self.trainable_variables))
        
        self.custom_metrics.update_state(y, pred)
        
        return {"loss": loss, "accuracy": self.custom_metrics.result()}
        
    # .evaluate()
    def test_step(self, data):
        x, y = data
        pred = self.model(x, training=False)
        loss = self.loss(y, pred)
        self.custom_metrics.update_state(y, pred)
        return {"loss": loss, "accuracy": self.custom_metrics.result()}

我就是这样称呼它的。

yoga_model = Model(seq_model)
yoga_model.compile(
    loss = keras.losses.CategoricalCrossentropy(from_logits=False),
    optimizer = keras.optimizers.Adam(lr=0.001),
    metrics = keras.metrics.CategoricalAccuracy(name="acc")
)
yoga_model.fit(train_ds, epochs=1, verbose=1)

请帮忙。帮助输入将不胜感激。

【问题讨论】:

    标签: keras python tensorflow machine-learning keras deep-learning


    【解决方案1】:

    在具有子类 API 的自定义模型中,实现 call 方法,如下所示:

    from tensorflow import keras 
    
    class Model(keras.Model):
       def __init__:
           self.model = model
       def train_step:
       def test_step:
       def compile: 
    
       # implement the call method
       def call(self, inputs, *args, **kwargs):
           return self.model(inputs)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 2012-07-22
      相关资源
      最近更新 更多