我需要一些keras损失功能的帮助 . 我一直在使用Tensorflow后端在keras上实现自定义丢失功能 .
我已经在numpy中实现了自定义丢失函数,但如果它可以转换为keras损失函数则会很棒 . loss函数采用数据帧和一系列用户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
我试图实现keras损失功能 . 我从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"]()]]
任何形式的帮助将非常感激 .
2 回答
在Keras中实现参数化自定义丢失功能有两个步骤 . 首先,编写系数/度量的方法 . 其次,编写一个包装函数来按照Keras需要的方式格式化事物 .
(y_true, y_pred)
作为参数 . 所以我们需要一个单独的函数来返回另一个函数:最后,您可以在Keras
compile
中使用它:首先,不可能在Keras损失函数中“从
y_true
和y_pred
中提取numpy数组” . 您必须使用Keras后端功能(或TF功能)来操作张量来计算损耗 .换句话说,最好不要使用if-else和循环来考虑计算损失的“矢量化”方法 .
您的损失函数可以通过以下步骤计算:
在
encodings
中的所有矢量对之间生成成对欧几里德距离的矩阵 .生成矩阵
I
,如果user_i == user_j
,则其元素I_ij
为1,如果user_i != user_j
,则为-1 .元素乘以两个矩阵,并总结元素以获得最终损失 .
这是一个实现:
我假设
user_id
是上面代码中的整数 . 这里的技巧是使用K.expand_dims
来实现成对操作 . 它's probably a bit difficult to understand at a first glance, but it'非常有用 .它应该给出与
custom_loss_numpy
相同的损失值(由于K.epsilon()
会有一点点差异):我在损失函数中犯了一个错误 .
当此功能用于训练时,由于Keras自动将
y_true
更改为至少2D,因此参数user_id
不再是1D张量 . 它的形状将是(batch_size, 1)
.要使用此功能,必须删除额外的轴: