Python 3.x 在Tensorflow概率中具有3个隐藏密度变化层的回归模型将nan作为训练期间的损失返回

Python 3.x 在Tensorflow概率中具有3个隐藏密度变化层的回归模型将nan作为训练期间的损失返回,python-3.x,regression,tensorflow2.0,tensorflow-probability,densevariational,Python 3.x,Regression,Tensorflow2.0,Tensorflow Probability,Densevariational,我逐渐熟悉了张量流概率,在这里我遇到了一个问题。在训练期间,模型返回nan作为损失(可能意味着导致溢出的巨大损失)。由于合成数据的函数形式并不过于复杂,而且数据点与参数的比率乍一看并不可怕,至少我想知道问题是什么,以及如何纠正 代码如下--附带一些可能有用的图像: # Create and plot 5000 data points x_train = np.linspace(-1, 2, 5000)[:, np.newaxis] y_train = np.power(x_train, 3)

我逐渐熟悉了张量流概率,在这里我遇到了一个问题。在训练期间,模型返回nan作为损失(可能意味着导致溢出的巨大损失)。由于合成数据的函数形式并不过于复杂,而且数据点与参数的比率乍一看并不可怕,至少我想知道问题是什么,以及如何纠正

代码如下--附带一些可能有用的图像:

# Create and plot 5000 data points

x_train = np.linspace(-1, 2, 5000)[:, np.newaxis]
y_train = np.power(x_train, 3) + 0.1*(2+x_train)*np.random.randn(5000)[:, np.newaxis]

plt.scatter(x_train, y_train, alpha=0.1)
plt.show()

训练模型
问题似乎出在损失函数中:没有指定位置和尺度的独立正态分布的负对数似然会导致未驯服的方差,从而导致最终损失值的放大。既然你在用变分层做实验,你一定对认知不确定性的估计感兴趣,为此,我建议应用常数方差

我试图在以下几行中对您的代码进行一些细微的更改:

  • 首先,最终输出y_out直接来自最终变分层,没有任何独立的正态分布层:

    y_out =    tfpl.DenseVariational(units=1,
                      make_prior_fn=prior,
                      make_posterior_fn=posterior,
                      kl_weight=1/x_train.shape[0])(x)
    
  • 其次,损失函数现在包含必要的正态分布计算,但需要使用静态方差,以避免在培训期间损失扩大:

     def nll(y_true, y_pred):
                       dist = tfp.distributions.Normal(loc=y_pred, scale=1.0)
                       return tf.reduce_sum(-dist.log_prob(y_true))
    
  • 然后以与之前相同的方式编译和训练模型:

     model.compile(loss=nll, optimizer= 'Adam')
     history = model.fit(x_train, y_train, epochs=3000)
    
  • 最后,让我们从经过训练的模型中抽取100个不同的预测,并绘制这些值,以可视化模型的认知不确定性:

     predicted = [model(x_train) for _ in range(100)]
     for i, res in enumerate(predicted):
                       plt.plot(x_train, res , alpha=0.1)
     plt.scatter(x_train, y_train, alpha=0.1)
     plt.show()
    
  • 3000个历次之后,结果如下所示(将训练点数减少到3000,而不是5000,以加快训练速度):

     model.compile(loss=nll, optimizer= 'Adam')
     history = model.fit(x_train, y_train, epochs=3000)
    
     predicted = [model(x_train) for _ in range(100)]
     for i, res in enumerate(predicted):
                       plt.plot(x_train, res , alpha=0.1)
     plt.scatter(x_train, y_train, alpha=0.1)
     plt.show()