Python 对于负二项分布,我应该如何用Keras(和TensorFlow)编写损失函数?
我用负二项分布来建模变量。 与其预测预期平均值,我更愿意对分布的两个参数进行建模。所以我的神经网络的输出层由两个神经元组成。为此,我需要编写一个自定义损失函数。但下面的代码不起作用——这似乎是在张量上迭代的问题 对于负二项分布,我应该如何用Keras(和TensorFlow)编写损失函数 我只需要重写这段代码,代码对TensorFlow的张量很友好。根据我得到的错误,也许Python 对于负二项分布,我应该如何用Keras(和TensorFlow)编写损失函数?,python,tensorflow,keras,deep-learning,log-likelihood,Python,Tensorflow,Keras,Deep Learning,Log Likelihood,我用负二项分布来建模变量。 与其预测预期平均值,我更愿意对分布的两个参数进行建模。所以我的神经网络的输出层由两个神经元组成。为此,我需要编写一个自定义损失函数。但下面的代码不起作用——这似乎是在张量上迭代的问题 对于负二项分布,我应该如何用Keras(和TensorFlow)编写损失函数 我只需要重写这段代码,代码对TensorFlow的张量很友好。根据我得到的错误,也许tensorflow.map\u fn可能会导致一个解决方案,但我在这方面没有运气 这在总体上运行良好,但在Keras/Ten
tensorflow.map\u fn
可能会导致一个解决方案,但我在这方面没有运气
这在总体上运行良好,但在Keras/Tensorflow中不起作用
from scipy.stats import nbinom
from keras import backend as K
import tensorflow as tf
def loss_neg_bin(y_pred, y_true):
result = 0.0
for p, t in zip(y_pred, y_true):
result += -nbinom.pmf(t, p[0], min(0.99, p[1]))
return result
我得到的错误是:
TypeError:Tensor对象只有在执行急切时才可执行
启用。要在这个张量上迭代,请使用tf.map\u fn
您需要
tf.map\u fn
来实现循环,而tf.py\u func
来结束nbinom.pmf
。例如:
from scipy.stats import nbinom
import tensorflow as tf
def loss_neg_bin(y_pred, y_true):
result = 0.0
for p, t in zip(y_pred, y_true):
result += -nbinom.pmf(t, p[0], min(0.99, p[1]))
return result
y_pred= [[0.4, 0.4],[0.5, 0.5]]
y_true= [[1, 2],[1, 2]]
print('your version:\n',loss_neg_bin(y_pred, y_true))
def loss_neg_bin_tf(y_pred, y_true):
result = tf.map_fn(lambda x:tf.py_func(lambda p,t:-nbinom.pmf(t, p[0], min(0.99,p[1]))
,x
,tf.float64)
,(y_pred,y_true)
,dtype=tf.float64)
result = tf.reduce_sum(result,axis=0)
return result
y_pred_tf = tf.placeholder(shape=(None,2),dtype=tf.float64)
y_true_tf = tf.placeholder(shape=(None,2),dtype=tf.float64)
loss = loss_neg_bin_tf(y_pred_tf, y_true_tf)
with tf.Session() as sess:
print('tensorflow version:\n',sess.run(loss,feed_dict={y_pred_tf:y_pred,y_true_tf:y_true}))
# print
your version:
[-0.34313146 -0.13616026]
tensorflow version:
[-0.34313146 -0.13616026]
此外,如果使用tf.py_func
计算负二项式的概率质量函数作为损失反馈模型,则需要自己定义梯度函数
更新--添加可微负二项损失
nbinom
的概率质量函数为:
nbinom.pmf(k) = choose(k+n-1, n-1) * p**n * (1-p)**k
对于k>=0
,根据
所以我增加了可微负二项损失
import tensorflow as tf
def nbinom_pmf_tf(x,n,p):
coeff = tf.lgamma(n + x) - tf.lgamma(x + 1) - tf.lgamma(n)
return tf.cast(tf.exp(coeff + n * tf.log(p) + x * tf.log(1 - p)),dtype=tf.float64)
def loss_neg_bin_tf_differentiable(y_pred, y_true):
result = tf.map_fn(lambda x: -nbinom_pmf_tf(x[1]
, x[0][0]
, tf.minimum(tf.constant(0.99,dtype=tf.float64),x[0][1]))
,(y_pred,y_true)
,dtype=tf.float64)
result = tf.reduce_sum(result,axis=0)
return result
y_pred_tf = tf.placeholder(shape=(None,2),dtype=tf.float64)
y_true_tf = tf.placeholder(shape=(None,2),dtype=tf.float64)
loss = loss_neg_bin_tf_differentiable(y_pred_tf, y_true_tf)
grads = tf.gradients(loss,y_pred_tf)
y_pred= [[0.4, 0.4],[0.5, 0.5]]
y_true= [[1, 2],[1, 2]]
with tf.Session() as sess:
print('tensorflow differentiable version:')
loss_val,grads_val = sess.run([loss,grads],feed_dict={y_pred_tf:y_pred,y_true_tf:y_true})
print(loss_val)
print(grads_val)
# print
tensorflow differentiable version:
[-0.34313146 -0.13616026]
[array([[-0.42401619, 0.27393084],
[-0.36184822, 0.37565048]])]
你们试过使用吗?thx,这似乎是分布的唯一其他定义,并没有明确的方法如何将其用于损失函数。。同样不推荐,链接tensorflow概率库,这似乎很有希望,但我想用不同的方式。。。