自定义损失函数通过梯度下降在每一步进行更新

发布于 2021-01-29 16:56:41

从这篇文章中,我们可以编写一个自定义损失函数。现在,假设自定义损失函数取决于参数a:

def customLoss(yTrue,yPred):
    return (K.log(yTrue) - K.log(yPred))**2+a*yPred

我们如何像梯度权重那样以梯度下降的方式在每一步更新参数a?

a_new= a_old - alpha * (derivative of custom loss with respect to a)

PS的实际海关损失与上述不同。请给我一个适用于任何自定义损失函数的通用答案,而不是上述示例的答案。

关注者
0
被浏览
50
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    创建一个自定义层来保存可训练参数。该层不会在调用中返回输入,但是我们将使用输入来遵守如何创建层。

    class TrainableLossLayer(Layer):
    
        def __init__(self, a_initializer, **kwargs):
            super(TrainableLossLayer, self).__init__(**kwargs)
            self.a_initializer = keras.initializers.get(a_initializer)
    
        #method where weights are defined
        def build(self, input_shape):
            self.kernel = self.add_weight(name='kernel_a', 
                                      shape=(1,),
                                      initializer=self.a_initializer,
                                      trainable=True)
            self.built=True
    
        #method to define the layers operation (only return the weights)
        def call(self, inputs):
            return self.kernel
    
        #output shape
        def compute_output_shape(self, input_shape):
            return (1,)
    

    使用模型中的图层获取a任何输入(这与顺序模型不兼容):

    a = TrainableLossLayer(a_init, name="somename")(anyInput)
    

    现在,您可以尝试以某种丑陋的方式定义损失:

    def customLoss(yTrue,yPred):
        return (K.log(yTrue) - K.log(yPred))**2+a*yPred
    

    如果这可行,那就准备好了。


    您也可以尝试使用更复杂的模型(如果您不希望a像这样在损失中使用跳过层,这可能会导致模型保存/加载问题)

    在这种情况下,您将需要将其y_train作为输入而不是输出:

    y_true_inputs = Input(...)
    

    您的损失函数将进入一个Lambda正确接受所有参数的层:

    def lambdaLoss(x):
        yTrue, yPred, alpha = x
        return (K.log(yTrue) - K.log(yPred))**2+alpha*yPred
    
    loss = Lambda(lambdaLoss)([y_true_inputs, original_model_outputs, a])
    

    您的模型将输出以下损失:

    model = Model([original_model_inputs, y_true_inputs], loss)
    

    您将具有虚拟损失功能:

    def dummyLoss(true, pred):
        return pred
    
    model.compile(loss = dummyLoss, ...)
    

    并训练为:

    model.fit([x_train, y_train], anything_maybe_None_or_np_zeros ,....)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看