【问题标题】:Keras does not accept the target label due to its shape?Keras 不接受目标标签,因为它的形状?
【发布时间】:2020-01-10 03:19:26
【问题描述】:

我试图让 Keras 处理一个分类问题,该问题有五个分类目标标签(1、2、3、4、5)。由于某种原因,我在使用 StratifiedKFold 时无法使其正常工作。 X 和 y 分别是形状为 (500, 20) 和 (500, ) 的 NumPy 数组。

错误消息是“ValueError: Error when checks target: expected dense_35 to have shape (1,) but got array with shape (5,)”,这让我认为错误肯定出在目标变量。同样值得注意的是,每次尝试运行代码时,“dense_35”中的数字似乎都不同。

random_state = 123
n_splits = 10
cv = StratifiedKFold(n_splits=n_splits, 
random_state=random_state, shuffle=False)

def baseline_model():
    nn_model = Sequential()
    nn_model.add(Dense(units=50, input_dim=X.shape[1], init='normal',
                       activation= 'relu' ))
    nn_model.add(Dense(30, init='normal', activation='relu'))
    nn_model.add(Dense(10, init='normal', activation='relu'))
    nn_model.add(Dense(1, init='normal', activation='softmax'))

    nn_model.compile(optimizer='adam', loss='categorical_crossentropy',
                     metrics = ['accuracy'])
    return nn_model

for train, test in cv.split(X, y):   
    X_train, X_test = X[train], X[test]
    y_train, y_test = y[train], y[test]

    np_utils.to_categorical(y_train)
    np_utils.to_categorical(y_test)

    estimator = KerasClassifier(build_fn=baseline_model,
                                epochs=200, batch_size=5,
                                verbose=0)

    estimator.fit(X_train, y_train)
    y_pred = estimator.predict(X_test)

The numpy array (y), that I am trying to split:
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5]

【问题讨论】:

    标签: python keras scikit-learn classification cross-validation


    【解决方案1】:

    由于是分类问题,有五个分类目标标签,最后一个dense layer(输出层)必须有5个单元:

    def baseline_model():
        nn_model = Sequential()
        nn_model.add(Dense(units=50, input_dim=X.shape[1], init='normal',
                           activation= 'relu' ))
        nn_model.add(Dense(30, init='normal', activation='relu'))
        nn_model.add(Dense(10, init='normal', activation='relu'))
    
        #Output layer
        nn_model.add(Dense(5, init='normal', activation='softmax'))
        nn_model.compile(optimizer='adam', loss='categorical_crossentropy',
                         metrics = ['accuracy'])
        return nn_model
    

    【讨论】:

      【解决方案2】:
      random_state = 123
      n_splits = 10
      cv = StratifiedKFold(n_splits=n_splits, random_state=random_state, shuffle=False)
      def baseline_model():
          nn_model = Sequential(name='model_name')
          nn_model.add(Dense(units=50, input_dim=X.shape[1], init='normal',
                             activation= 'relu', name='dense1'))
          nn_model.add(Dense(30, init='normal', activation='relu', name='dense2'))
          nn_model.add(Dense(10, init='normal', activation='relu', name='dense3'))
          # code changed here
          nn_model.add(Dense(5, init='normal', activation='softmax', name='dense4'))
      
          nn_model.compile(optimizer='adam', loss='categorical_crossentropy',
                           metrics = ['accuracy'])
          return nn_model
      
      for train, test in cv.split(X, y):   
          X_train, X_test = X[train], X[test]
          y_train, y_test = y[train], y[test]
      
          # the error is due to this step
          # you have specified only one output in the last dense layer (dense4)
          # but you are giving input of length 5
          np_utils.to_categorical(y_train)
          np_utils.to_categorical(y_test)
      
          estimator = KerasClassifier(build_fn=baseline_model,
                                      epochs=200, batch_size=5,
                                      verbose=0)
          estimator.fit(X_train, y_train)
          y_pred = estimator.predict(X_test)
      
      • 通过在图层中指定 name 参数,您可以命名图层。这样,您每次都会得到明确的图层名称,以防每次出错。
      • model.summary() 是另一个有用的函数,您可以使用它检查每一层的输出形状。

      【讨论】:

      • 没错——网络只需要一个热编码向量
      • 哇,真不敢相信我错过了。现在看起来很明显。非常感谢!
      猜你喜欢
      • 2021-06-27
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      相关资源
      最近更新 更多