Python Keras中的自定义平均方向精度损失函数

Python Keras中的自定义平均方向精度损失函数,python,tensorflow,neural-network,keras,Python,Tensorflow,Neural Network,Keras,我试图将Keras中的损失函数定义为: def mda(y_true, y_pred): """Compute Mean Directional Accuracy. https://en.wikipedia.org/wiki/Mean_Directional_Accuracy_(MDA) Parameters ---------- y_true : tensor y_pred : tensor Returns -------

我试图将Keras中的损失函数定义为:

def mda(y_true, y_pred):
    """Compute Mean Directional Accuracy.

    https://en.wikipedia.org/wiki/Mean_Directional_Accuracy_(MDA)

    Parameters
    ----------
    y_true : tensor
    y_pred : tensor

    Returns
    -------
    mda : tensor
    """
    s = K.equal(K.sign(y_true[1:] - y_true[:-1]),
                 K.sign(y_pred[1:] - y_pred[:-1]))
    return K.mean(K.cast(s, K.floatx()))

我在TensorFlow中有一个例子,它似乎有效:

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt


def mda(y, y_hat):
    c = tf.equal(tf.sign(y[1:] - y[:-1]), tf.sign(y_hat[1:] - y_hat[:-1]))
    return tf.reduce_mean(tf.cast(c, tf.float32))

y = np.array([0, 1, 2, 1, 0, 1])
y_hat = np.array([0, 1, 0, 1, 0, 1])
plt.plot(y)
plt.plot(y_hat, alpha=.6)
plt.show()

sess = tf.Session()
print(sess.run(mda(tf.constant(y), tf.constant(y_hat))))
相应的绘图:

mda
result:0.6,这是3/5,在这种情况下是有意义的,因为5个方向中有3个是正确预测的

但是,如果我尝试在Keras中实现此代码:

def mda(y_true, y_pred):
    """Compute Mean Directional Accuracy.

    https://en.wikipedia.org/wiki/Mean_Directional_Accuracy_(MDA)

    Parameters
    ----------
    y_true : tensor
    y_pred : tensor

    Returns
    -------
    mda : tensor
    """
    s = K.equal(K.sign(y_true[1:] - y_true[:-1]),
                 K.sign(y_pred[1:] - y_pred[:-1]))
    return K.mean(K.cast(s, K.floatx()))
我得到一个
ValueError:不支持任何值。
我无法解析

日志:

ValueError回溯(最近一次调用)
在()
67回调=[reduce_lr],
68验证数据=(teX,teY),
--->69详细=1)
70打印(“运行时:”,time.time()-start)
71
/anaconda/lib/python3.6/site-packages/keras/models.py适合(self、x、y、批量大小、历元、详细信息、回调、验证拆分、验证数据、混洗、类权重、样本权重、初始历元、**kwargs)
861类重量=类重量,
862样品重量=样品重量,
-->863初始_历元=初始_历元)
864
865 def评估(自我、x、y、批次大小=32、详细=1、,
/anaconda/lib/python3.6/site-packages/keras/engine/training.py适合(self、x、y、批量大小、历元、冗余、回调、验证拆分、验证数据、无序排列、类权重、样本权重、初始历元、**kwargs)
1411其他:
1412英寸=x+y+样本重量
->1413自我制造训练功能()
1414 f=自整列功能
1415
/anaconda/lib/python3.6/site-packages/keras/engine/training.py in_make_train_函数(self)
935自身收集的可训练重量,
936自我约束,
-->937.总损耗)
938更新=自我更新+培训更新
939#获取损失和指标。在每次调用时更新权重。
/获取更新(self、params、constraints、loss)中的anaconda/lib/python3.6/site-packages/keras/optimizers.py
231对于拉链中的p、g、a(参数、梯度、蓄能器):
232#更新累加器
-->233新_a=self.rho*a+(1.-self.rho)*K.square(g)
234.自我更新.附加(K.更新(a,新的_a))
235 new_p=p-lr*g/(K.sqrt(new_a)+self.epsilon)
/anaconda/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py位于方形(x)中
1369 A张量。
1370     """
->1371返回tf.广场(x)
1372
1373
/anaconda/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py(x,name)
472指数=x指数,值=x平方,密集形状=x密集形状)
473其他:
-->474返回gen_math_ops.square(x,name=name)
475
476
/anaconda/lib/python3.6/site-packages/tensorflow/python/ops/gen_math_ops.py(x,name)
2731一个“张量”。与“x”的类型相同。
2732   """
->2733结果=_op_def_lib.apply_op(“Square”,x=x,name=name)
2734返回结果
2735
/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in apply_op(self,op_type_name,name,**关键字)
502#将#转换为#张量认为它有什么类型?
503观测值=运算。内部转换为张量(
-->504个值,如_ref=input_arg.is_ref).dtype.name
505前缀=(“%s”Op的输入“%s”具有不匹配的类型%s)%
506(输入名称,操作类型名称,观察))
/内部的anaconda/lib/python3.6/site-packages/tensorflow/python/framework/ops.py\u convert\u to\u tensor(值、数据类型、名称、as\u ref、首选数据类型)
714
715如果ret为无:
-->716 ret=conversion\u func(值,dtype=dtype,name=name,as\u ref=as\u ref)
717
718如果未实施ret:
/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in_constant_tensor_conversion_函数(v,dtype,name,as_ref)
174 as_ref=False):
175=作为参考
-->176返回常量(v,dtype=dtype,name=name)
177
178
/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in constant(值、数据类型、形状、名称、验证形状)
163张量_值=attr_值_pb2.AttrValue()
164 tensor_value.tensor.CopyFrom(
-->165 tensor\u util.make\u tensor\u proto(值,dtype=dtype,shape=shape,verify\u shape=verify\u shape))
166 dtype\u value=attr\u value\u pb2.AttrValue(type=tensor\u value.tensor.dtype)
167常数张量=g.create\u op(
/make_tensor_proto中的anaconda/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py(值、数据类型、形状、验证形状)
358其他:
359如果值为无:
-->360提升值错误(“不支持任何值”)
361#如果提供了dtype,则强制numpy数组为该类型
362#如有可能提供。
ValueError:不支持任何值。
我也无法用TensorFlow重现此错误,例如,我试图用
None
替换
y_hat
值中的一个,但这会引发不同的错误


我不确定
ValueError
是否意味着运行时没有生成任何
值,或者是我把Keras实现搞砸了。我非常感谢您的帮助。

我尝试了您提供的代码,它在我的计算机上运行得很好

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import keras as K


def mda(y_true, y_pred):
    s = K.equal(K.sign(y_true[1:] - y_true[:-1]),
                 K.sign(y_pred[1:] - y_pred[:-1]))
    return K.mean(K.cast(s, K.floatx()))


y = np.array([0, 1, 2, 1, 0, 1])
y_hat = np.array([0, 1, 0, 1, 0, 1])
plt.plot(y)
plt.plot(y_hat, alpha=.6)
plt.show()

sess = tf.Session()
print(sess.run(mda(tf.constant(y), tf.constant(y_hat)))

你的Tensorflow/Keras设置是什么?

MAD是不可微的,你的梯度是
None