我正在Keras的神经网络上工作,它将英语句子翻译成自定义语言。为此,我想创建一个自定义损失函数,该函数对每个句子进行预测并评估其是否符合自定义语言的语法规则,如果不符合,则为标准损失函数增加价值。
如何在每个时期之后评估张量,而在编译期间却无法评估?
以下是我的自定义损失函数。由于在模型编译期间尚无批次,因此y_pred的形状为(None,x,y),无法进行评估以获取预测。我要避免的想法是在编译期间分配标准损失函数,并在批到达时计算自定义损失。不幸的是,海关损失从未达到。
def custom_loss(tokenizer, punishment_rate):
def compile_loss(y_true, y_pred):
shape = K.int_shape(y_pred)
#standard loss function
loss = K.sparse_categorical_crossentropy(y_true, y_pred)
if shape[0] is not None:
#THIS is never reached and that's the problem
prediction = logits_to_text(K.eval(y_pred), tokenizer)
#test if prediction complies to grammar rules
compileable = compiles(prediction) ^ 1
compile_error = compileable * punishment_rate
loss = K.sparse_categorical_crossentropy(y_true, y_pred, axis=-1) * (1 + compile_error)
return loss
return compile_loss
是否只有在将张量填充批次时才有评估张量的解决方法?或者,在通过回调编译模型后更改损失函数,而不必重新编译模型?
答案 0 :(得分:0)
根据keras source,您可以使用损失函数包装器创建自定义损失函数类,然后将其无缝传递给模型。
例如:
#Import the wrapper
from keras.losses import LossFunctionWrapper
#Create your class extending the wrapper
class MyLossFunction(LossFunctionWrapper):
#Implement the constructor - here you can give extended arguments to it.
def __init__(self,
tokenizer,
punishment_rate,
reduction=losses_utils.Reduction.SUM_OVER_BATCH_SIZE,
name='my_custom_text_function'):
super(MyLossFunction, self).__init__(
my_function,
name=name,
reduction=reduction,
tokenizer = tokenizer,
punishment_rate= punishment_rate)
#Now you have to define your function "my_function":
#Please, notice that ALL loss functions that follow keras model needs two arguments:
#y_true (correct result) and y_pred (the result obtained in the network).
def my_function(y_true, y_pred, tokenizer, punishment_rate):
shape = K.int_shape(y_pred)
if shape[0] is not None:
prediction = logits_to_text(K.eval(y_pred), tokenizer)
#test if prediction complies to grammar rules
compileable = compiles(prediction) ^ 1
compile_error = compileable * punishment_rate
return K.sparse_categorical_crossentropy(y_true, y_pred, axis=-1) * (1 + compile_error)
return K.sparse_categorical_crossentropy(y_true, y_pred)
然后可以实例化它并在编译器中使用:
custom_loss= MyLossFunction(tokenizer = ..., punishment_rate = ...)
classifier.compile(optimizer=optimizer,
loss=custom_loss,
metrics= ['binary_accuracy'])