我正在实现一个模型,该模型具有复杂的损耗项,需要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。