【问题标题】:How can I use categorical one-hot labels for training with Keras?如何使用分类单热标签进行 Keras 训练?
【发布时间】:2017-06-11 08:40:05
【问题描述】:

我的输入如下所示:

[
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
...]

形状为(1, num_samples, num_features),标签如下所示:

[
[0, 1]
[1, 0]
[1, 0]
...]

形状为(1, num_samples, 2)

但是,当我尝试运行以下 Keras 代码时,我收到此错误: ValueError: Error when checking model target: expected dense_1 to have 2 dimensions, but got array with shape (1, 8038, 2)。根据我的阅读,这似乎源于我的标签是二维的,而不仅仅是整数。这是正确的吗?如果是,如何在 Keras 中使用 one-hot 标签?

代码如下:

num_features = 463
trX = np.random(8038, num_features)
trY = # one-hot array of shape (8038, 2) as described above

def keras_builder():  #generator to build the inputs
    while(1):
        x = np.reshape(trX, (1,) + np.shape(trX))
        y = np.reshape(trY, (1,) + np.shape(trY))
        print(np.shape(x)) # (1, 8038, 463)
        print(np.shape(y)) # (1, 8038, 2)
        yield x, y

model = Sequential()
model.add(LSTM(100, input_dim = num_features))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit_generator(keras_builder(), samples_per_epoch = 1, nb_epoch=3, verbose = 2, nb_worker = 1)

立即抛出上述错误:

Traceback (most recent call last):
  File "file.py", line 35, in <module>
    model.fit_generator(keras_builder(), samples_per_epoch = 1, nb_epoch=3, verbose = 2, nb_worker = 1)
  ...
ValueError: Error when checking model target: expected dense_1 to have 2 dimensions, but got array with shape (1, 8038, 2)

谢谢!

【问题讨论】:

    标签: python machine-learning keras one-hot-encoding


    【解决方案1】:

    有很多事情没有加起来。

    我假设您正在尝试解决顺序分类任务,即您的数据形状为(&lt;batch size&gt;, &lt;sequence length&gt;, &lt;feature length&gt;)

    在您的批次生成器中,您创建一个批次,其中包含一个长度为 8038 的序列和每个序列元素 463 个特征。您创建一个匹配的 Y 批次进行比较,由一个包含 8038 个元素的序列组成,每个元素的大小为 2。

    您的问题是Y 与最后一层的输出不匹配。您的 Y 是 3 维的,而您的模型的输出只是 2 维的:Y.shape = (1, 8038, 2)dense_1.shape = (1,1) 不匹配。这解释了您收到的错误消息。

    解决方案:需要在 LSTM 层启用return_sequences=True 以返回一个序列而不是仅返回最后一个元素(有效去除时间维度)。这将在 LSTM 层给出(1, 8038, 100) 的输出形状。由于Dense 层无法处理顺序数据,您需要将其单独应用于每个序列元素,这是通过将其包装在TimeDistributed 包装器中来完成的。这将为您的模型提供输出形状(1, 8038, 1)

    您的模型应如下所示:

    from keras.layers.wrappers import TimeDistributed
    
    model = Sequential()
    model.add(LSTM(100, input_dim=num_features, return_sequences=True))
    model.add(TimeDistributed(Dense(1, activation='sigmoid')))
    

    在检查模型摘要时很容易发现这一点:

    print(model.summary()) 
    

    【讨论】:

      猜你喜欢
      • 2018-08-28
      • 2018-04-17
      • 2017-08-17
      • 2021-06-13
      • 2018-03-07
      • 2020-06-26
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多