且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Keras中创建自定义目标函数?

更新时间:2022-06-27 05:53:11

这是我的小片段,用于编写新的损失函数并在使用前对其进行测试:

Here is my small snippet to write new loss functions and test them before using:

import numpy as np

from keras import backend as K

_EPSILON = K.epsilon()

def _loss_tensor(y_true, y_pred):
    y_pred = K.clip(y_pred, _EPSILON, 1.0-_EPSILON)
    out = -(y_true * K.log(y_pred) + (1.0 - y_true) * K.log(1.0 - y_pred))
    return K.mean(out, axis=-1)

def _loss_np(y_true, y_pred):
    y_pred = np.clip(y_pred, _EPSILON, 1.0-_EPSILON)
    out = -(y_true * np.log(y_pred) + (1.0 - y_true) * np.log(1.0 - y_pred))
    return np.mean(out, axis=-1)

def check_loss(_shape):
    if _shape == '2d':
        shape = (6, 7)
    elif _shape == '3d':
        shape = (5, 6, 7)
    elif _shape == '4d':
        shape = (8, 5, 6, 7)
    elif _shape == '5d':
        shape = (9, 8, 5, 6, 7)

    y_a = np.random.random(shape)
    y_b = np.random.random(shape)

    out1 = K.eval(_loss_tensor(K.variable(y_a), K.variable(y_b)))
    out2 = _loss_np(y_a, y_b)

    assert out1.shape == out2.shape
    assert out1.shape == shape[:-1]
    print np.linalg.norm(out1)
    print np.linalg.norm(out2)
    print np.linalg.norm(out1-out2)


def test_loss():
    shape_list = ['2d', '3d', '4d', '5d']
    for _shape in shape_list:
        check_loss(_shape)
        print '======================'

if __name__ == '__main__':
    test_loss()

在这里您可以看到我正在测试binary_crossentropy损失,并定义了2个单独的损失,一个numpy版本(_loss_np)另一个张量版本(_loss_tensor)[注意:如果只使用keras函数,则它将同时适用于Theano和Tensorflow ...,但是如果您依赖其中之一,也可以通过K.theano.tensor.function或K.tf.function引用它们.

Here as you can see I am testing the binary_crossentropy loss, and have 2 separate losses defined, one numpy version (_loss_np) another tensor version (_loss_tensor) [Note: if you just use the keras functions then it will work with both Theano and Tensorflow... but if you are depending on one of them you can also reference them by K.theano.tensor.function or K.tf.function]

稍后,我将比较输出形状和输出的L2范数(应该几乎相等)和差异的L2范数(应该接近0)

Later I am comparing the output shapes and the L2 norm of the outputs (which should be almost equal) and the L2 norm of the difference (which should be towards 0)

一旦您对损失功能正常运行感到满意,您可以将其用作:

Once you are satisfied that your loss function is working properly you can use it as:

model.compile(loss=_loss_tensor, optimizer=sgd)