如何使用 Keras 的分类单热标签进行训练?
How can I use categorical one-hot labels for training with Keras?
我有这样的输入:
[
[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)
谢谢!
有很多东西没有加起来。
我假设您正在尝试解决顺序分类任务,即您的数据形状为 (<batch size>, <sequence length>, <feature length>)
。
在批处理生成器中,您创建了一个批处理,其中包含一个长度为 8038 的序列和每个序列元素 463 个特征。您创建一个匹配的 Y 批次进行比较,它由一个序列组成,有 8038 个元素,每个元素的大小为 2。
你的问题是 Y
与最后一层的输出不匹配。您的 Y
是三维的,而您的模型的输出只是二维的:Y.shape = (1, 8038, 2)
与 dense_1.shape = (1,1)
不匹配。这解释了您收到的错误消息。
解决方案:您需要在 LSTM 层中启用 return_sequences=True
以 return 序列而不是仅最后一个元素(有效地删除 time-dimension)。这将在 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())
我有这样的输入:
[
[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)
谢谢!
有很多东西没有加起来。
我假设您正在尝试解决顺序分类任务,即您的数据形状为 (<batch size>, <sequence length>, <feature length>)
。
在批处理生成器中,您创建了一个批处理,其中包含一个长度为 8038 的序列和每个序列元素 463 个特征。您创建一个匹配的 Y 批次进行比较,它由一个序列组成,有 8038 个元素,每个元素的大小为 2。
你的问题是 Y
与最后一层的输出不匹配。您的 Y
是三维的,而您的模型的输出只是二维的:Y.shape = (1, 8038, 2)
与 dense_1.shape = (1,1)
不匹配。这解释了您收到的错误消息。
解决方案:您需要在 LSTM 层中启用 return_sequences=True
以 return 序列而不是仅最后一个元素(有效地删除 time-dimension)。这将在 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())