如何独家使用Keras`add_loss`

时间:2019-05-26 08:50:06

标签: python tensorflow machine-learning keras

我正在实现一个模型,该模型具有复杂的损耗项,需要Keras add_loss函数。我希望将我的模型实现为tf.keras.Model(请参见documentation)。不幸的是,似乎Keras无法处理使用add_loss的情况,但是compile没有得到损失函数的说明。

这是“工作”的一个最小示例(没有做任何有趣的事,但是没有引发错误):

import tensorflow as tf
import numpy as np    

class Model(tf.keras.Model):

    def __init__(self, *args, **kwargs):
        super(Model, self).__init__(*args, **kwargs)    
        self.layer = tf.keras.layers.Dense(3, 
                       activation=tf.keras.activations.relu)

    def call(self, inputs, **kwargs):    
        output = self.layer(inputs)
        return output


if __name__ == '__main__':
    tf.random.set_random_seed(1)
    m = Model()    
    x = np.array([[1., 2., 3.]])
    y = np.array([[0., 1., 0.5]])    
    m.compile(tf.keras.optimizers.SGD(), 
              loss=tf.keras.losses.mean_squared_error)
    m.fit(x, y, epochs=100, verbose=0)
    print(m.predict(x))
    # [[0.         0.99999666 0.5000101 ]]

但是,我不需要“外部”损失函数,只需要用add_loss指定一个函数,这是行不通的。 我曾希望下面的代码做与上面的代码完全相同的事情:

# Same imports...

class Model(tf.keras.Model):

    # def __init__ ...

    def call(self, inputs, **kwargs):    
        output = self.layer(inputs)
        error = tf.keras.losses.mean_squared_error([0., 1., 0.5], output)
        self.add_loss(error)
        return output


if __name__ == '__main__':    
    tf.random.set_random_seed(1)
    m = Model()    
    x = np.array([[1., 2., 3.]])    
    m.compile(tf.keras.optimizers.SGD())
    m.fit(x, epochs=100, verbose=0)
    print(m.predict(x))

但不起作用。 特别是从m.fit(x)我收到错误消息

AttributeError: 'Model' object has no attribute 'total_loss'

一种可能的解决方法是添加一个琐碎的损失函数

def no_loss(*args):
    return tf.keras.backend.constant(0.0)

但是我希望有一个更优雅的解决方案。

我正在使用Tensorflow 1.13.1。

0 个答案:

没有答案