【问题标题】:ValueError: Error when checking target: expected dense_16 to have shape (1,) but got array with shape (30,)ValueError:检查目标时出错:预期dense_16的形状为(1,),但数组的形状为(30,)
【发布时间】:2020-10-18 14:34:09
【问题描述】:

我遇到了这个错误,从我从类似问题的答案中看到的所有内容,这是由于没有指定最后一层有 30 个神经元,因为您想要的输出是一个大小为 30 的数组。但这是不是我的情况,我已经指定了这一点,所以如果神经元的数量和输出形状完全匹配,我会发现这个错误很奇怪。下面是可能导致此错误的代码部分(images_gray 是一个 numpy 数组,由形状为 (2000, 128, 128) 的灰度图像组成,result_array 是大小为 30 的 numpy 数组的列表)。

images_gray = np.reshape(images_gray, (len(images_gray), img_rows, img_cols, 1))
to_shuffle = list(zip(images_gray, result_array))
random.shuffle(to_shuffle)
im_input, res_output = zip(*to_shuffle)
im_input, res_output = np.array(im_input[:10]), np.array(res_output[:10])
img_rows, img_cols, _ = np.shape(im_input[0])
input_shape = (img_rows, img_cols, 1)
if K.image_data_format() == 'channels_first':
    input_shape = (1, img_rows, img_cols)
model = buildCNN(input_shape)
adadelta = keras.optimizers.Adadelta(lr=0.5)
model.compile(loss="sparse_categorical_crossentropy",optimizer=adadelta,metrics=['accuracy'])
model.fit(im_input, res_output, batch_size=128, epochs=10, verbose=1)

这是buildCNN() 函数:

def buildCNN(input_shape):
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3,3),activation='relu',input_shape=input_shape))
    model.add(Conv2D(64, (3,3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128,activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(30, activation='sigmoid'))
    return model

当我使用model.sumary() 时我得到了什么:

【问题讨论】:

    标签: python machine-learning keras neural-network conv-neural-network


    【解决方案1】:

    如果您的目标(y 值)的长度为 30,那么我假设您想要进行多类分类。在这种情况下,您在输出层中使用了错误的激活函数,应该是 softmax 而不是 sigmoid

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

    sigmoid 用于二分类。

    如果你想做二进制分类,那么你的目标(y 值)的长度应该是 1,而不是 30。

    另外请注意,您很可能会收到另一个错误,因为如果您的目标值是 one-hot 编码的(假设它们是长度为 30 的数组),那么要选择的正确损失函数是 categorical_crossentropy

    sparse_categorical_crossentropy 损失用于当标签以整数形式提供时(不是 one-hot 编码)进行多类分类。

    所以在one-hot编码标签的情况下,compile方法应该这样调用

    model.compile(loss="categorical_crossentropy",optimizer=adadelta,metrics=['accuracy'])
    

    【讨论】:

    • 我尝试了这个更改但我仍然得到同样的错误,我尝试了relu激活功能但它也不起作用。
    • relu 和 sigmod 都不能工作,这不是 math/keras 的工作方式。如果您有 one-hot 编码标签,则需要具有分类交叉熵损失的 softmax。如果这个组合给你一个错误,那么你的标签编码不正确。
    • 再次,请确保您使用的是categorical_crossentropy loss,而不是sparse_categorical_crossentropy loss,以防单热编码标签,否则您将面临上述错误。
    • 我没有看到关于损失的评论,一旦我改变它,它也可以正常工作。谢谢!
    猜你喜欢
    • 2018-12-31
    • 2019-03-05
    • 2019-05-10
    • 2020-02-21
    • 2018-12-29
    • 2020-08-23
    • 2019-01-10
    • 2020-08-09
    • 2020-03-19
    相关资源
    最近更新 更多