Python Tensorflow神经网络损失值NaN

Python Tensorflow神经网络损失值NaN,python,tensorflow,neural-network,loss,tf-slim,Python,Tensorflow,Neural Network,Loss,Tf Slim,我试图在一个大数据集上建立一个简单的多层感知器模型,但我得到的损失值为nan。奇怪的是:在第一个训练步骤之后,损失值不是nan,大约是46(这是非常低的。当我运行逻辑回归模型时,第一个损失值大约是3600)。但是,紧接着,损失价值不断下降。我也使用tf.print来调试它 该模型的目标是预测约4500个不同的类别,因此这是一个分类问题。当使用tf.print时,我看到在第一个训练步骤(或通过MLP前馈)之后,从最后一个完全连接的层得出的预测似乎是正确的(所有数字都在1和4500之间变化)。但是,

我试图在一个大数据集上建立一个简单的多层感知器模型,但我得到的损失值为nan。奇怪的是:在第一个训练步骤之后,损失值不是nan,大约是46(这是非常低的。当我运行逻辑回归模型时,第一个损失值大约是3600)。但是,紧接着,损失价值不断下降。我也使用tf.print来调试它

该模型的目标是预测约4500个不同的类别,因此这是一个分类问题。当使用tf.print时,我看到在第一个训练步骤(或通过MLP前馈)之后,从最后一个完全连接的层得出的预测似乎是正确的(所有数字都在1和4500之间变化)。但是,在这之后,最后一个完全连接的层的输出要么全部为0,要么为其他常量(0)

有关我的模型的一些信息:

  • 三层模型。所有完全连接的层

  • 批量为1000

  • 学习率为.001(我也尝试了.1和.01,但没有改变)

  • 使用CrossEntropyLoss(我确实添加了一个epsilon值来防止log0)

  • 使用AdamOptimizer

  • 学习率衰减为0.95

该模型的确切代码如下:(我正在使用TF Slim库)


任何帮助都将不胜感激!非常感谢你

由于某些原因,您的训练过程出现了分歧,您的体重可能会有无穷大的值,这会造成损失。原因可能很多,请尝试更改您的训练参数(使用较小的批进行测试)

此外,对于分类器中的最后一个输出使用relu不是常用的方法,请尝试使用sigmoid。

两个(可能更多)原因说明它不起作用:

  • 您跳过或不适当地应用了对象的特征缩放 投入和产出。因此,数据可能难以处理 对于Tensorflow
  • 使用ReLu,这是一个不连续的函数,可能会引起问题。尝试使用其他激活函数,如tanh或sigmoid

  • 据我所知,Relu并没有对神经网络的上界设置上限,因此它更可能根据其实现来解收敛

    尝试将所有激活功能切换为tanh或sigmoid。在CNN中,Relu通常用于卷积

    它也很难确定你的去覆盖是否是由于交叉熵,因为我们不知道你是如何用你的ε值影响它的。试着只使用剩余部分,它简单得多,但仍然有效


    另外,一个5000-5000-4500神经网络是巨大的。你不太可能真的需要这么大的网络

    非常感谢你的帮助!将最后一层更改为sigmoid实际上修复了NaN丢失错误。尽管如此,对于某个常数仍然,所有预测类仍然是[0 0 0 0]或[5 5 5 5]。只是想知道,你怎么知道你的训练过程何时出现了分歧?我注意到我的损失值有时会上下波动非常感谢你的评论!将最后一层更改为sigmoid实际上修复了NaN丢失错误。现在,损失值一开始似乎正常(大约3600),但随后迅速下降到约23,这是非常奇怪的。您能否详细阐述一下关于功能缩放的第一点?非常感谢。当然想象一种情况,在这种情况下,您有两个不同规模的功能集(例如,房价x1:~1e6美元,面积x2:~10-100平方米)。如果不按比例缩放,您的优化算法可能会在“最陡”(超)曲面上来回反弹,甚至可能最终无法收敛(因此可能是NaN)。对于给定的示例,您可以想象(x1,x2)曲面具有如此陡峭的山谷。现在,如果你应用特征缩放(xi-Oh ok,这是一种比较不同单元特征的方法。我不确定我是否理解你所说的“不缩放时,你的优化函数可能会反弹并在最陡峭的超曲面上进退”的意思。为什么它会来回反弹?我可能遗漏了一些与单位无关的东西。假设你有两个特征,那么你的损失函数J(x1,x2)看起来像一个普通的曲面:它有丘陵和山谷。如果你使用诸如梯度下降之类的优化器,它会尝试找出最陡峭的路径,并在那里迈出一步,以减少它(min J(x1,x2))。如果x1的数量级为百万,x2的数量级为数百,会发生什么?那么x1与x2相比会发生很大变化,因此会产生尖锐的谷。梯度J的每一步现在都可以“跳跃”穿过这样的谷,并且很可能不会到达底部(收敛问题,NaN…).哦,好的。我现在明白了。因此,扩展我的功能将是防止这种情况发生的方法。非常感谢你的帮助!谢谢你的评论!我将更改激活函数。至于神经元的数量,我有5000个,因为大约有4500个输出类。因此,基于我的信念,神经元的数量应该比神经元的数量多是输出类。还是我遗漏了什么?谢谢!很多人建议将隐藏层节点数设置为介于numb_输入和numb_输出之间。作为使用标准前馈模型的MNIST数据集上的一个轶事,我仅使用8个隐藏节点就能够获得91%的准确率。(784个输入,8个隐藏节点,10个输出)但是直到我创建了一个包含大约280个隐藏节点的网络,我才能够获得超过97%的准确度。我不相信节点的数量需要线性扩展,但是因为连接的数量是指数扩展的。即numb_weights layer_n*layer_n+1。我认为Alex Graves的一篇研究论文指出,增加nu神经元的数量有助于训练,但一旦聚合,通常只需要最初训练的节点数量的一小部分。我现在不记得来源,但我会看看是否可以挖掘它并在可以的时候将其链接起来。我会尝试使用一个网络
    input_layer = slim.fully_connected(model_input, 5000, activation_fn=tf.nn.relu)
    hidden_layer = slim.fully_connected(input_layer, 5000, activation_fn=tf.nn.relu)
    output = slim.fully_connected(hidden_layer, vocab_size, activation_fn=tf.nn.relu)
    output = tf.Print(output, [tf.argmax(output, 1)], 'out = ', summarize = 20, first_n = 10)
    return {"predictions": output}