提问者:小点点

使用theano函数定制keras中的损失函数


我想使用我自己的binary_crossentropy,而不是使用Keras库自带的。这是我的自定义函数:

    import theano
    from keras import backend as K

    def elementwise_multiply(a, b): # a and b are tensors
       c = a * b
       return theano.function([a, b], c)

    def custom_objective(y_true, y_pred):  
       first_log = K.log(y_pred)
       first_log = elementwise_multiply(first_log, y_true)
       second_log = K.log(1 - y_pred)
       second_log = elementwise_multiply(second_log, (1 - y_true))
       result = second_log + first_log
       return K.mean(result, axis=-1)

注意:这是为了练习。我知道T. nnet。binary_crossentropy(y_pred,y_true)

但是,当我编译模型时:

sgd = SGD(lr=0.001)
model.compile(loss = custom_objective, optimizer = sgd)

我得到这个错误:

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () 36 37 sgd = SGD(lr=0.001) ---

C:\Program Files(x86)\Anaconda3\lib\site-包\keras\models.py在编译中(self,优化器,丢失,class_mode)418 else: 419掩码=无--

C:\Program Files(x86)\Anaconda3\lib\site-包\keras\models.py加权(y_true,y_pred,权重,掩码)80"'81#score_array有ndim

custom_objective(y_truey_pred)11second_log=K. log(1-K.clip(y_true,K.epsilon(),np.inf))12second_log=elementwise_multiply(second_log,(y_true))---

TypeError:'Function'和'Function'不支持的操作数类型

当我用内联函数替换elementwise_multiply时:

def custom_objective(y_true, y_pred):  
    first_log = K.log(y_pred)    
    first_log = first_log * y_true
    second_log = K.log(1 - y_pred)
    second_log = second_log * (1-y_true)
    result = second_log + first_log
    return K.mean(result, axis=-1)

模型编译但损失值为nan:

纪元1/1 945/945 [==============================] - 62s-损失: nan-acc:0.0011-val_loss:nan-val_acc:0.0000e 00

有人能帮我拿一下这个吗?!

谢啦


共1个答案

匿名用户

我发现了问题。我必须将返回值乘以“-1”,因为我使用随机梯度下降(sgd)作为优化器,而不是随机梯度上升!

这是代码,它就像一个魅力:

import theano
from keras import backend as K

def custom_objective(y_true, y_pred):  
    first_log = K.log(y_pred)    
    first_log = first_log * y_true
    second_log = K.log(1 - y_pred)
    second_log = second_log * (1 - y_true)
    result = second_log + first_log
    return (-1 * K.mean(result))