我正在尝试拟合一个输出变量始终为正的 keras 模型。我想使用伽马分布来模拟这个问题。问题是损失总是输出 NAN。
我构建了以下 keras 模型:
model_max = tf.keras.Sequential([
tf.keras.layers.Dense(20,input_dim=10, activation="relu"),
tf.keras.layers.Dense(15,activation="relu"),
tf.keras.layers.Dense(10,activation="relu"),
tf.keras.layers.Dense(5,activation="relu"),
tf.keras.layers.Dense(2),
tfp.layers.DistributionLambda(lambda t:
tfd.Gamma(concentration = tf.math.softplus(0.005*t[...,:1])+0.001,
rate = tf.math.softplus(0.005*t[...,1:])+0.001)
),
])
请注意,我使用了 softplus,因为分布的两个参数都必须是正数。我还添加了 0.001 以确保参数始终大于零。
我的损失函数如下:
def gamma_loss(y_true, my_dist):
dist_mean = my_dist.mean()
dist_stddev = my_dist.stddev()
alpha = (dist_mean / dist_stddev)**2
beta = dist_mean / dist_stddev**2
gamma_distr = tfd.Gamma(concentration=alpha, rate=beta)
return -tf.reduce_mean(gamma_distr.log_prob(y_true))
这个功能似乎工作正常。例如,如果我运行以下代码,它运行良好:
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
def gamma_loss(y_true, my_dist):
dist_mean = my_dist.mean()
dist_stddev = my_dist.stddev()
alpha = (dist_mean / dist_stddev)**2
beta = dist_mean / dist_stddev**2
#print(alpha)
gamma_distr = tfd.Gamma(concentration=alpha, rate=beta)
return -tf.reduce_mean(gamma_distr.log_prob(y_true)).numpy()
dist = tfd.Gamma(1,1)
gamma_loss(100, dist)
但是,如果我使用以下行编译它:
model_max.compile(optimizer=tf.optimizers.Adam(learning_rate = 0.001),loss=gamma_loss)
损失总是输出 nan
我究竟做错了什么?我尝试了不同的损失函数,但似乎没有任何效果。我认为这与集中论点有关,因为我已经有一个与正态分布类似的模型。在那个模型中,我没有使用 softplus 作为平均值(loc),因为该分布接受任何正值或负值。我使用了标准偏差的确切结构,因为它在正态分布中也必须是正的。它工作得很好。为什么它不适用于 Gamma 分布?
感谢您向任何可以帮助我了解我做错了什么的人提供建议。