我正在尝试编写一个自定义损失函数,该函数将通过调用外部函数(不是用 keras/tensorflow 后端函数编写)在正向传递之后但在反向传播之前对 NN 输出进行操作。对输出进行操作与理想输出之间的差异是我想要用于误差计算的差异。
我有一个自定义损失函数 loss_function(y_true, y_pred),它使用 tf.py_function 调用外部函数,并将 y_pred 参数传递给该函数。
理想情况下,我想将 y_pred 参数转换为 numpy 数组,将此数组与我的函数一起使用以返回另一个 numpy 数组,将此 numpy 数组转换为 tf 张量,然后根据需要在损失函数中使用它。这是自定义错误函数:
def loss_function(y_true,y_pred):
y_pred2 = tf.py_function(func=SOA, inp=[y_pred], Tout=tf.float32)
return tf.reduce_mean(tf.pow(y_true - y_pred2,2))
这是它调用的外部函数“SOA”,它只是将其转换为 numpy 数组,然后再转换回 tf 张量:
def SOA(y_pred):
y_pred0 = np.square(np.copy(y_pred))
print(type(y_pred0))
y_pred1 = tf.convert_to_tensor((y_pred0))
print(type(y_pred1))
return y_pred1
我可以使用各种 tf 函数直接在外部函数中的 y_pred 上进行操作,但是如果我将其转换为 numpy 数组(例如使用 np.copy(...)),然后使用 tf.convert_to_tensor 将其转换回来给出以下错误:
InvalidArgumentError: In[0] is not a matrix
[[{{node training_188/Adam/gradients/dense_299/MatMul_grad/MatMul}}]]
此外,如果我使用 y_true 而不是 y_pred,它会给出不同的错误:
ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
这对我来说似乎很奇怪,因为它似乎在区分完全相同类型 () 的对象。
最佳答案
你的帖子有点令人困惑,但根据tf.py_func
的文档,你的函数SOA
应该返回ndarray(这是numpy数组类型)而不是张量。因此省略转换并看看这是否有帮助。
试试这个:
def SOA(y_pred):
y_pred0 = np.square(np.copy(y_pred))
print(type(y_pred0))
return y_pred0
关于python - 为什么我的自定义损失函数不接受转换后的 numpy 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56770549/