Как я могу использовать однозначные ярлыки для тренировок с 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?
Вот код:
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)
Спасибо!
1 ответ
Есть много вещей, которые не складываются.
Я предполагаю, что вы пытаетесь решить задачу последовательной классификации, т.е. ваши данные имеют вид (<batch size>, <sequence length>, <feature length>)
,
В вашем генераторе пакетов вы создаете пакет, состоящий из одной последовательности длиной 8038 и 463 элементов на элемент последовательности. Вы создаете сопоставляемую партию Y для сравнения, состоящую из одной последовательности с 8038 элементами, каждый из которых имеет размер 2.
Ваша проблема в том, что Y
не совпадает с выводом последнего слоя. Ваш Y
является 3-мерным, в то время как выходные данные вашей модели только 2-мерные: Y.shape = (1, 8038, 2)
не совпадает dense_1.shape = (1,1)
, Это объясняет сообщение об ошибке, которое вы получаете.
Решение этого: вам нужно включить return_sequences=True
на уровне LSTM возвращать последовательность вместо только последнего элемента (эффективно удаляя измерение времени). Это дало бы выходную форму (1, 8038, 100)
на уровне LSTM. Так как 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())