在有条件的情况下在keras中实现自定义损失功能

黑色面膜:

我需要有关角膜脱落功能的帮助。我一直在使用Tensorflow后端在keras上实现自定义损失功能。

我已经在numpy中实现了自定义损失函数,但是如果可以将其转换为keras损失函数,那就太好了。损失函数采用数据帧和一系列用户ID。如果user_id不同,则相同user_id的欧几里得距离为正和负。该函数返回数据帧的标量距离总和。

def custom_loss_numpy (encodings, user_id):
# user_id: a pandas series of users
# encodings: a pandas dataframe of encodings

    batch_dist = 0

    for i in range(len(user_id)):
         first_row = encodings.iloc[i,:].values
         first_user = user_id[i]

         for j in range(i+1, len(user_id)):
              second_user = user_id[j]
              second_row = encodings.iloc[j,:].values

        # compute distance: if the users are same then Euclidean distance is positive otherwise negative.
            if first_user == second_user:
                tmp_dist = np.linalg.norm(first_row - second_row)
            else:
                tmp_dist = -np.linalg.norm(first_row - second_row)

            batch_dist += tmp_dist

    return batch_dist

我试图实现成角膜功能丧失的功能。我从y_true和y_pred张量对象中提取了numpy数组。

def custom_loss_keras(y_true, y_pred):
    # session of my program
    sess = tf_session.TF_Session().get()

    with sess.as_default():
        array_pred = y_pred.eval()
        print(array_pred)

但是我收到以下错误。

tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'dense_1_input' with dtype float and shape [?,102]
 [[Node: dense_1_input = Placeholder[dtype=DT_FLOAT, shape=[?,102], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

任何形式的帮助将非常感激。

Yu-Yang :

首先,不可能在Keras损失函数中“ y_true提取numpy数组y_pred”。您必须使用Keras后端函数(或TF函数)来操作张量以计算损耗。

换句话说,最好考虑一种“向量化”的方式来计算损失,而不使用if-else和loops。

您的损失函数可以按照以下步骤计算:

  1. 在中的所有向量对之间生成成对的欧几里得距离矩阵encodings
  2. 生成一个I元素I_ij为1 的矩阵如果为user_i == user_j-1 user_i != user_j
  3. 将两个矩阵逐个元素相乘,然后对元素求和以得出最终损失。

这是一个实现:

def custom_loss_keras(user_id, encodings):
    # calculate pairwise Euclidean distance matrix
    pairwise_diff = K.expand_dims(encodings, 0) - K.expand_dims(encodings, 1)
    pairwise_squared_distance = K.sum(K.square(pairwise_diff), axis=-1)

    # add a small number before taking K.sqrt for numerical safety
    # (K.sqrt(0) sometimes becomes nan)
    pairwise_distance = K.sqrt(pairwise_squared_distance + K.epsilon())

    # this will be a pairwise matrix of True and False, with shape (batch_size, batch_size)
    pairwise_equal = K.equal(K.expand_dims(user_id, 0), K.expand_dims(user_id, 1))

    # convert True and False to 1 and -1
    pos_neg = K.cast(pairwise_equal, K.floatx()) * 2 - 1

    # divide by 2 to match the output of `custom_loss_numpy`, but it's not really necessary
    return K.sum(pairwise_distance * pos_neg, axis=-1) / 2

我假设user_id上面的代码是整数。这里的技巧是K.expand_dims用于实现成对操作。乍一看可能有点困难,但这很有用。

它应该给出与相同的损耗值custom_loss_numpy(由于会有一些差异K.epsilon()):

encodings = np.random.rand(32, 10)
user_id = np.random.randint(10, size=32)

print(K.eval(custom_loss_keras(K.variable(user_id), K.variable(encodings))).sum())
-478.4245

print(custom_loss_numpy(pd.DataFrame(encodings), pd.Series(user_id)))
-478.42953553795815

我在损失函数上犯了一个错误。

在训练中使用此功能时,由于Keras会自动更改y_true为至少2D,因此参数user_id不再是1D张量。它的形状将是(batch_size, 1)

为了使用此功能,必须移除多余的轴:

def custom_loss_keras(user_id, encodings):
    pairwise_diff = K.expand_dims(encodings, 0) - K.expand_dims(encodings, 1)
    pairwise_squared_distance = K.sum(K.square(pairwise_diff), axis=-1)
    pairwise_distance = K.sqrt(pairwise_squared_distance + K.epsilon())

    user_id = K.squeeze(user_id, axis=1)  # remove the axis added by Keras
    pairwise_equal = K.equal(K.expand_dims(user_id, 0), K.expand_dims(user_id, 1))

    pos_neg = K.cast(pairwise_equal, K.floatx()) * 2 - 1
    return K.sum(pairwise_distance * pos_neg, axis=-1) / 2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

自定义Keras损失函数,有条件地创建零梯度

在有条件的情况下使用Jackson对符合自定义条件的跳过对象进行序列化时修改HTTP代码(春季启动)

如何在有条件的情况下在 mongoDB 上插入数据

在不使用回调的情况下在 Keras 中实现自定义指标

在有条件的情况下使用“输入”

有条件地捕获闭包中的变量以实现自定义控件

如何在有条件的情况下减去熊猫中的两列

如何在有条件的情况下删除SQL Server中的重复行?

在有条件的情况下退出 Jess 中的规则执行

如何在有条件的情况下控制 YAML 中的作业流?

具有条件返回值的自定义损失

在y_true和y_pred具有不同大小的keras中实现自定义损失功能

抓取表中的所有行,并在有条件的情况下抓取一行

如何在有条件的情况下使用RemoveAll删除列表中的多个项目?

mysql-在有条件的情况下选择并插入查询到多个表中

Keras 自定义损失具有使用的功能之一和条件

确保代码在有条件的情况下运行两次

如何在有条件的情况下替换冲突(对于SQLite)?

MySQL在有条件的情况下连接两列

熊猫在有条件的情况下将数组列转换为多列

熊猫:在有条件的情况下查找最大值

仅在有条件的情况下运行crontab

如何在有条件的情况下导出到CSV?

LINQ-在有条件的情况下为可选/可为空

Python Pandas:自连接,用于在有条件的情况下运行累计总数

是否可以在有条件的情况下使用救援?

在有条件的情况下,在标签的顶部添加标签。

Rails仅在有条件的情况下验证唯一性

Laravel如何在有条件的情况下进行雄辩的雄辩多次联接?