为啥即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”?

Posted

技术标签:

【中文标题】为啥即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”?【英文标题】:Why am I getting "Received a label value of 6 which is outside the valid range of [0, 1)" even when I am using sparse_categorical_crossentrpy?为什么即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”? 【发布时间】:2019-11-22 13:24:00 【问题描述】:

所以,我正在尝试使用 7 种面部表情来制作情绪分类器。我知道为了使用整数标签而不是 0 和 1,需要使用 sparse_categorical_crossentropy 并且需要将输出层激活作为 softmax,但它没有按预期工作。

我正在使用来自这里的数据集https://www.kaggle.com/ashishpatel26/facial-expression-recognitionferchallenge

代码

import pandas as pd
import numpy as np
from PIL import Image
import random
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.optimizers import RMSprop
from keras.layers import Conv1D, MaxPooling1D
from keras.layers import Activation, Dropout, Flatten, Dense

emotion = 0 : 'Angry', 1 : 'Disgust',2 : 'Fear',3 : 'Happy',
           4 : 'Sad',5 : 'Surprise',6 : 'Neutral'
df=pd.read_csv('fer.csv')
faces=df.values[0:500,1]
faces=faces.tolist()
emos=df.values[0:500,0]

for i in range(len(faces)):
    faces[i]=[int(x) for x in faces[i].split()]
    emos[i]=int(emos[i])

faces=np.array(faces)
faces=np.expand_dims(faces, axis=2)

model = Sequential()

model.add(Conv1D(16, 3, padding='same', input_shape=(2304,1), activation='relu'))
model.add(Conv1D(16, 3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))

model.add(Conv1D(32, 3, padding='same', activation='relu'))
model.add(Conv1D(32, 3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))

model.add(Conv1D(64, 3, padding='same', activation='relu'))
model.add(Conv1D(64, 3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))

model.add(Conv1D(128, 3, padding='same', activation='relu'))
model.add(Conv1D(256, 3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))

model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(1, activation='softmax'))
    
model.compile(loss='sparse_categorical_crossentropy',
            optimizer='adam',
            metrics=['accuracy'])

model.fit(faces,emos,epochs=10,batch_size=8)
model.save_weights('model.h5')

错误

W tensorflow/core/framework/op_kernel.cc:1401] OP_REQUIRES failed at sparse_xent_op.cc:90 : Invalid argument: Received a label value of 6 which is outside the valid range of [0, 1).  Label values: 6 0 2 4 6 0 0 3
Traceback (most recent call last):
  File "FEClassifier.py", line 56, in <module>
    model.fit(faces,emos,epochs=10,batch_size=8)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\keras\engine\training.py", line 1039, in fit
    validation_steps=validation_steps)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\keras\engine\training_arrays.py", line 199, in fit_loop
    outs = f(ins_batch)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py", line 2715, in __call__
    return self._call(inputs)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py", line 2675, in _call
    fetched = self._callable_fn(*array_vals)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 1439, in __call__
    run_metadata_ptr)
  File "C:\Users\nrj10\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: Received a label value of 6 which is outside the valid range of [0, 1).  Label values: 6 0 2 4 6 0 0 3
         [[node loss/dense_3_loss/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits]]

【问题讨论】:

【参考方案1】:

如果你有 N 个类(N > 2),无论你是否使用稀疏标签,最后一层都需要有 N 个神经元:

model.add(Dense(7, activation='softmax'))

不要忘记稀疏标签只是为了方便,您的模型仍然需要为每个类生成一个分数

【讨论】:

我误以为 Dense(n) 用于输出 n 值。这清除了它。谢谢:)【参考方案2】:

最后一层应该有类或类别的数量。

在这种情况下,因为有 7 个类

emotion = 0 : 'Angry', 1 : 'Disgust',2 : 'Fear',3 : 'Happy',
       4 : 'Sad',5 : 'Surprise',6 : 'Neutral'

最后一层应该改变

model.add(Dense(1, activation='softmax'))

到这里

model.add(Dense(7, activation='softmax'))

【讨论】:

以上是关于为啥即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?

为啥即使我使用 Alamofire 发出请求,我的应用程序仍然冻结?

为啥即使使用提交后 sql plus 也不会保存新行?

为啥 fastlane 比赛让我输入密码,即使我已经输入

即使我使用 API Post 请求发送数据,为啥 req 正文是 [重复]

为啥我的 Xcode 编译器告诉我我使用了值类型,即使我使用了类?