如何在Tensorflow中实现此自定义损失函数? [英] how can i implement this custom loss function in tensorflow?

查看:133
本文介绍了如何在Tensorflow中实现此自定义损失函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的损失函数:

我想为以下模型实现上述损失功能:

I want to implement the above loss function for the following model:

model_s=tf.keras.Sequential([
tf.keras.layers.Dense(100, input_shape=(50,),activation='tanh'),
tf.keras.layers.Dense(100,activation='tanh'),
tf.keras.layers.Dense(50,activation='sigmoid')])

model_s.compile(optimizer='adam',
             loss=loss_fn,
             metrics="accuracy",)


model_s.fit(x_train,y_train,epochs=5,batch_size=512)

我已经以两种方式实现了该功能,但是在两种情况下我都遇到错误.情况1:

I have implemented the function in two ways, but in both cases I encounter an error. case 1:

def loss_fn(y_true,y_pred):
    y=tf.math.argmax(y_true)
    loss=(-(tf.math.log(y_pred[y])+tf.reduce_sum(tf.math.log(1-y_pred[:y]))))
    return tf.reduce_mean(loss)

#example
y_true=tf.constant([0,0,0,0,1])
y_pred=tf.constant([0,0,0,0,.9])
loss_fn(y_true,y_pred)

<tf.Tensor: shape=(), dtype=float32, numpy=0.105360545>

错误情况1:

TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got <tf.Tensor 'loss_fn/ArgMax:0' shape=(50,) dtype=int64>

情况2:

def loss_fn(y_true,y_pred):
    i=0
    loss=[]
    for pre in y_pred:
        y=tf.math.argmax(y_true[i])
        loss.append(-(tf.math.log(pre[y])+tf.reduce_sum(tf.math.log(1-pre[:y]))))
        i += 1
    return tf.reduce_mean(loss, axis=-1)

#example
y_true=tf.constant([[0,0,0,0,1],[0,0,0,1,0]])
y_pred=tf.constant([[0,0,0,0,.99],[0,0,0,.9,.3]])
loss_fn(y_true,y_pred)
<tf.Tensor: shape=(), dtype=float32, numpy=0.057705436>

错误情况2:

ValueError: Tried to convert 'input' to a tensor and failed. Error: The tensor 'Tensor("loss_fn/while/Neg:0", shape=(), dtype=float32)' cannot be accessed here: it is defined in another function or code block. Use return values, explicit Python locals or TensorFlow collections to access it. Defined in: FuncGraph(name=loss_fn_while_body_3814, id=2579287922312); accessed from: FuncGraph(name=train_function, id=2579286968840).

我知道第一种情况可能由于其输入形式而不适用于不同的批次大小,但是我已经对第二种情况的细节进行了很多更改,但一件事始终保持不变:显示错误而不起作用:(

I know the first case may not work for different batch sizes due to its input form, but I have changed the details of the second case a lot, but one thing has always remained the same: showing an error and not working function :(

推荐答案

与其尝试索引您的预测,不如使用您的真实标签(采用一站式格式)作为掩码以获取第i个预测(您可以通过跨行相乘和相加来完成此操作).然后使用argmax为第二部分创建一个序列掩码.

Instead of trying to index into your predictions, just use your true labels (which are in one-hot format) as a mask to get the i-th prediction (you can accomplish this with a multiply and sum across rows). Then use your argmax to create a sequence mask for the second part.

尝试一下:

import tensorflow as tf


def custom_loss_fn(y_true, y_pred, num_labels=5):
    idx = tf.math.argmax(y_true, 1)
    msk = tf.cast(tf.sequence_mask(idx, num_labels), tf.float32)
    # 1st part
    fst = -tf.math.log(tf.math.reduce_sum(y_true * y_pred, 1))
    # 2nd part
    snd = tf.math.reduce_sum(tf.math.log(1.0 - y_pred * msk, 1))
    return tf.math.reduce_mean(fst + snd)

测试1 :

y_true = tf.constant([[0, 0, 0, 0, 1]], tf.float32)
y_pred = tf.constant([[0, 0, 0, 0, 0.9]])

custom_loss_fn(y_true, y_pred)
# <tf.Tensor: shape=(), dtype=float32, numpy=0.105360545>

测试2 :

y_true = tf.constant([[0, 0, 0, 0, 1], [0, 0, 0, 1, 0]], tf.float32)
y_pred = tf.constant([[0, 0, 0, 0, 0.99], [0, 0, 0, 0.9, 0.3]])

custom_loss_fn(y_true, y_pred)
# <tf.Tensor: shape=(), dtype=float32, numpy=0.057705436>

这篇关于如何在Tensorflow中实现此自定义损失函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆