【问题标题】:nan values in loss in keras modelkeras模型中损失的nan值
【发布时间】:2019-10-06 15:58:33
【问题描述】:

我有以下数据形状

X_Train.shape,Y_Train.shape
Out[52]: ((983, 19900), (983,))
X_Test.shape,Y_Test.shape
Out[53]: ((52, 19900), (52,))

我正在运行一个简单的二元分类器,因为 Y_train 和 Y_test 可以是 1 或 2

import  keras
import  tensorflow as tf
from keras import  layers
from keras.layers import Input, Dense
from keras.models import Model,Sequential
import numpy as np
from  keras.optimizers import  Adam

myModel = keras.Sequential([
    keras.layers.Dense(1000,activation=tf.nn.relu,input_shape=(19900,)),
    keras.layers.Dense(64, activation=tf.nn.relu),
    keras.layers.Dense(32, activation=tf.nn.relu),
    keras.layers.Dense(1, activation=tf.nn.softmax)
])

myModel.compile(optimizer='adam', loss='sparse_categorical_crossentropy',metrics=['accuracy'])
myModel.fit(X_Train, Y_Train, epochs=100,batch_size=1000)
test_loss,test_acc=myModel.evaluate(X_Test,Y_Test)

代码输出

训练损失和准确性

Epoch 1/100
983/983 [==============================] - 1s 1ms/step - loss: nan - acc: 0.4608
Epoch 2/100
983/983 [==============================] - 0s 206us/step - loss: nan - acc: 0.4873
Epoch 3/100
983/983 [==============================] - 0s 200us/step - loss: nan - acc: 0.4883
Epoch 4/100
983/983 [==============================] - 0s 197us/step - loss: nan - acc: 0.4883
Epoch 5/100
983/983 [==============================] - 0s 194us/step - loss: nan - acc: 0.4873
Epoch 6/100
983/983 [==============================] - 0s 202us/step - loss: nan - acc: 0.4863
Epoch 7/100
983/983 [==============================] - 0s 198us/step - loss: nan - acc: 0.4863
Epoch 8/100
983/983 [==============================] - 0s 194us/step - loss: nan - acc: 0.4883
Epoch 9/100
983/983 [==============================] - 0s 196us/step - loss: nan - acc: 0.4873
Epoch 10/100
983/983 [==============================] - 0s 198us/step - loss: nan - acc: 0.4873
Epoch 11/100
983/983 [==============================] - 0s 200us/step - loss: nan - acc: 0.4893
Epoch 12/100
983/983 [==============================] - 0s 198us/step - loss: nan - acc: 0.4873
Epoch 13/100
983/983 [==============================] - 0s 194us/step - loss: nan - acc: 0.4873
Epoch 14/100
983/983 [==============================] - 0s 197us/step - loss: nan - acc: 0.4883
Epoch 97/100
    983/983 [==============================] - 0s 196us/step - loss: nan - acc: 0.4893
Epoch 98/100
    983/983 [==============================] - 0s 199us/step - loss: nan - acc: 0.4883
Epoch 99/100
    983/983 [==============================] - 0s 193us/step - loss: nan - acc: 0.4883
Epoch 100/100
    983/983 [==============================] - 0s 196us/step - loss: nan - acc: 0.4863

测试损失和准确性

test_loss,test_acc
Out[58]: (nan, 0.4615384661234342)

我还检查了我的数据中是否有任何 nan 值

np.isnan(X_Train).any()
Out[5]: False
np.isnan(Y_Train).any()
Out[6]: False
np.isnan(X_Test).any()
Out[7]: False
np.isnan(Y_Test).any()
Out[8]: False

我的问题是为什么我的训练精度没有提高,为什么损失是 nan 以及为什么没有 one-hot 编码输出中的 softmax 工作正常?

注意1:我很抱歉我的数据很大,所以我不能在这里分享,但如果有什么方法可以在这里分享,那么我准备好了。

注意2我的训练数据中有很多零值

【问题讨论】:

标签: python tensorflow keras


【解决方案1】:

有时在 Keras 中,ReluSoftmax 的组合会导致数值问题,因为 Relu 可以产生对应于非常小的概率的大正值。

尝试使用tanh 而不是Relu

【讨论】:

  • 我的最后一层激活函数是否正确,因为我正在使用 softmax 而不对输出数据进行热编码?
【解决方案2】:

如果你在损失中得到 NaN 值,这意味着输入在函数域之外。发生这种情况的原因有多种。以下是追踪原因的几个步骤,

1) 如果输入在功能域之外,则确定这些输入是什么。跟踪输入值到成本函数的进展。

2) 检查输入数据集中是否有 null 或 nan 值。可以通过

DataFrame.isnull().any() 

3) 更改输入数据的缩放比例。将 0 和 1 之间的数据标准化以开始训练。

4) 改变权重初始化方法。

很难指出深度神经网络的确切解决方案。因此,请尝试上述方法,它应该可以让您大致了解问题所在。

【讨论】:

  • 好的,我现在正在尝试规范化,是的,你是对的,我需要追踪到我从文件中读取数据的数据集的最开始。
【解决方案3】:

Softmax 激活在这里不是正确的选择。输出层上只有一个神经元。

让我们考虑一下 softmax 函数是如何定义的。(图片来自 wikepedia.org)

.
由于最后一层只有一个神经元, 对于 的所有值都将为 1。

由于您使用的是sparse_categorical_crossentropy,因此 keras(或 tensorflow)可以从 logits 的形状中推断出类的数量。 In keras(or tensorflow) the shape of logits is assumed to be [BATCH_SIZE, NUM_CLASSES]。您的 logits 的形状是 [None, 1],因此 keras 假设您的课程数量为 1,但您正在喂食多个课程(0 或 1),这会导致错误。

这里正确的激活函数是 sigmoid(tanh 也可以通过将数据集目标更改为 -1 或 1 来工作)。损失应该是binary_crossentropy

myModel = keras.Sequential([
    keras.layers.Dense(1000,activation=tf.nn.relu,input_shape=(19900,)),
    keras.layers.Dense(64, activation=tf.nn.relu),
    keras.layers.Dense(32, activation=tf.nn.relu),
    keras.layers.Dense(1, activation="sigmoid")
])

myModel.compile(optimizer='adam', loss='binary_crossentropy',metrics=['accuracy'])

【讨论】:

  • 我如何在这里使用 softmax,因为我知道在这种情况下我需要在输出端有两个神经元,并为输出使用一个热编码,所以你能指导我一点吗?
  • 因此标签需要转换为一个热编码向量,就像在我的特定情况下,如果我在输出层指定两个神经元,那么 Y_train 维度应该是 (983,2) 而 Y_test 维度应该是 ( 52,2) 我说的对吗?
  • 这也可行,但我提供了简单的解决方案,请查看。
  • 你是对的人,谢谢。现在我失去了,但问题是我的准确度没有像以前那样提高到 0.48 以上。我的意思是为什么它根本没有得到改善,我现在真的厌倦了这个 .048 数字!
  • 您得到的准确度要低得多,因为您的输入特征非常高(19900)并且模型无法处理这种高维输入空间。这个问题通常被称为Curse of Dimensionality。如果数据集的数量很大,这个问题就会得到解决。您有两个选择,1. 增加数据集的数量 2. 找到减少输入特征数量的方法 (Feature Engineering)。
猜你喜欢
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 2021-09-06
  • 2021-05-02
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多