【问题标题】:Keras ValueError: Error when checking target: expected dense_1 to have 3 dimensionsKeras ValueError:检查目标时出错:预期dense_1有3个维度
【发布时间】:2019-09-26 22:29:15
【问题描述】:

我正在使用带有 tensorflow 后端的 keras,并且在为我的模型确定图层的正确形状时遇到了问题。

我已经阅读了this 关于各种keras层属性差异的有用解释。

这是我的模型的架构:

我正在尝试使用分类标签进行二元分类(逻辑回归),因此最后一层是具有 1 个单元的 Dense 层,我假设它的正类评估为 1,负类评估为 0。

这是我的模型的总结:

我在网络一侧的输入是 10158,另一侧是 20316。我总共有 1370 个样本。我的 train_data 的形状是 (1370, 1, 10158),标签的形状是 (1, 1370),批量大小是 100。

input_layer = Input(shape=(1,no_terms), name='docs')
s = Lambda(lambda x: x+1)(input_layer)
log_layer = Lambda(log, name='tf_output')(input_layer)

tpr_fpr = np.zeros((2, no_terms))
tpr_fpr[0,:] = np.sum(train_docs[np.where(train_label>0), :]>0, axis=1
                      )/np.sum(train_label>0) * (1000)
tpr_fpr[1,:] = np.sum(train_docs[np.where(train_label>0), :]>0, axis=1
                     )/np.sum(train_label <= 0) * (1000)

k_constants = backend.constant(np.reshape(tpr_fpr.T, (1,2*no_terms)))
fixed_input = Input(tensor=k_constants, shape=(1, 2*no_terms), name='tpr_fpr')
h = Dense(int(300), activation='relu', name='hidden', input_shape=(1, 2*no_terms), 
          trainable=True)(fixed_input)
h = Dropout(0.2, name="D")(h)
cd = Dense(units=no_terms, activation='relu', name='cd', trainable=True)(h)


prod = Multiply()([log_layer, cd])
o = Lambda(lambda x:(x/backend.sqrt(backend.sum(x * x,axis=1,keepdims=True))))(prod)
o = ReLU(max_value=None, negative_slope=0.0, threshold=0.0)(o)
o = Dense(1, activation='sigmoid', input_shape=(no_terms,))(o)


model_const = Model(fixed_input,cd)
model = Model([input_layer, fixed_input], o)

op = optimizers.RMSprop(learning_rate=.1, rho=0.9)
model.compile(optimizer=op, loss=mean_squared_error, metrics=['accuracy'])
plot_model(model, to_file='model.png')
model.summary()
batchSize = 100

checkpoint = ModelCheckpoint(filepath="a.hdf5",monitor='val_acc', mode='max', 
                             save_best_only=True)
earlystop=EarlyStopping(monitor='val_loss', patience=20)

train_docs.shape = (train_docs.shape[0], 1, train_docs.shape[1])
train_label = to_categorical(train_label, num_classes=2, dtype='float32')
model.fit(train_docs, train_label, epochs=10, batch_size=batchSize, 
          validation_data=(test_docs, test_label), 
          callbacks=[earlystop, checkpoint], verbose=1)

这是我得到的错误: “ValueError:检查目标时出错:预期dense_1有3维,但得到的数组形状为(1430, 2)”

我不知道 (1430, 2) 形状指的是什么以及为什么会出现此错误。

【问题讨论】:

  • 你的 lambda 层可能有问题。
  • 但得到的数组形状...是输入的数据,而不是模型的形状 - 对我来说,您的数据似乎有误
  • 为了更好地提供帮助,您的模型和数据的代码将比图像(您可以完全删除)提供更多帮助。
  • @OverLordGoldDragon 我已经添加了之前的代码(有问题的那个)和解决方案代码,此时我不确定这是一个真正的修复还是只是避免错误。如果您查看这些代码并向我解释为什么以前的结构不起作用,我将不胜感激。谢谢。
  • @TheGuywithTheHat lambda 层很好。问题出在形状上。

标签: python tensorflow keras


【解决方案1】:

您确实直接解决了问题 - 方法如下:

  • Keras 二进制分类需要形状为(batch_size, 1) 的标签(“目标”)。原因:最后一层的目标是输出 predictions,将与 labels 进行比较以计算指标(损失、准确性等) - 并且标签的形状为 @987654323 @
  • 以上也是为什么to_categorical 是一个问题 - 请参阅下面来自docs 的sn-p;对于二进制分类,one-hot 编码是多余的,因为binary_crossentropy 直接将标签与提供的预测进行比较
  • Keras Dense 期望输入为 2D:(batch_size, input_dim)。您的重塑使输入成为 3D:(batch_size, 1, input_dim)
  • 以上也是shape=(1, no_terms) --> shape=(no_terms,) 提供帮助的原因;事实上,两者都适合您当时提供的数据形状。完整的批次形状只包括批次暗淡:(batch_size, no_terms) (no_terms == input_dim)
  • 最后,对于二元分类,使用 loss='binary_crossentropy' - 分类问题切勿使用均方误差(除非出于非常特殊的原因)
# Consider an array of 5 labels out of a set of 3 classes {0, 1, 2}:
> labels
array([0, 2, 1, 2, 0])
# `to_categorical` converts this into a matrix with as many
# columns as there are classes. The number of rows
# stays the same.
> to_categorical(labels)
array([[ 1.,  0.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]], dtype=float32)

【讨论】:

  • 感谢您的详尽解释。
  • @Ehsan 很高兴事情得到解决;也考虑投票
【解决方案2】:

好吧,我找到了错误的解决方案,但仍然不明白为什么以前的形状没有成功,坦率地说,这个修复在无数次尝试和错误中取得了成功。

我将以下图层输入从形状格式(1,x)更改为(x,)格式:

    input_layer = Input(shape=(no_terms,), name='docs')

    k_constants = backend.constant(np.reshape(tpr_fpr.T, (1,2*no_terms)))
    fixed_input = Input(tensor=k_constants, shape=(2*no_terms,), name='tpr_fpr')
    h = Dense(int(300), activation='relu', name='hidden', input_shape=(2*no_terms,), trainable=True)(fixed_input)

    o = ReLU(max_value=None, negative_slope=0.0, threshold=0.0)(o)
    o = Dense(1, activation='sigmoid', input_shape=(no_terms,))(o)

并且还从代码中删除了以下几行:

    train_docs.shape = (train_docs.shape[0], 1, train_docs.shape[1])
    train_label = to_categorical(train_label, num_classes=2, dtype='float32')

现在我只使用形状标签 (#no_of_samples, 1),它是二进制而非分类标签。

所以新的结构是:

我希望有人能解释一下以前的模型有什么问题,这样我就不会再犯同样的错误了。

谢谢。

【讨论】:

    【解决方案3】:

    检查目标:预计dense_1 有3 个维度,但得到的数组形状为(1430, 2)"

    这意味着 dense_1 有 3 个维度,但如果您在图像处理中设计此模型,则您的输入只有 2 个维度,在这种情况下,您已声明图像形状 yhat 为 ((48,48),1) & ((48,48 ),3) 这里 1 用于灰度,3 用于 rgb 图像

    【讨论】:

    • 嗯,我的工作是在文本域中,我的原始数据是形状格式(#No_Of_Samples,#No_TF_as_Features)但我将数据重新塑造为 shpae(#No_Of_Samples,1,#No_TF_as_Features) .
    猜你喜欢
    • 1970-01-01
    • 2018-07-25
    • 2019-11-18
    • 2018-04-04
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    相关资源
    最近更新 更多