Я пытаюсь создать авто-кодер для процессов.Каждый процесс представляет собой последовательность событий, и каждое событие представляет собой число от 0 до 461 (и важно, что события с близкими числами не похожи, числа были выданы случайным образом).Каждый процесс имеет длину 60, а общее количество процессов составляет n
.Поэтому мои входные данные - массив (n, 60)
.
. Сначала я создал слой Embedding для преобразования номеров событий в одно горячее представление:
BLOCK_LEN = 60
EVENTS_CNT = 462
input = Input(shape=(BLOCK_LEN,))
embedded = Embedding(input_dim=EVENTS_CNT+1, input_length=BLOCK_LEN, output_dim=200)(input)
emb_model = Model(input, embedded)
emb_model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 60) 0
_________________________________________________________________
embedding_1 (Embedding) (None, 60, 200) 92600
=================================================================
Total params: 92,600
Trainable params: 92,600
Non-trainable params: 0
_________________________________________________________________
None
Во-вторых, я создал основную модель Seq2Seq.(используя эту библиотеку ):
seq_model = Seq2Seq(batch_input_shape=(None, BLOCK_LEN, 200), hidden_dim=200, output_length=BLOCK_LEN, output_dim=EVENTS_CNT)
Результирующая модель:
model = Sequential()
model.add(emb_model)
model.add(seq_model)
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
model_1 (Model) (None, 60, 200) 92600
_________________________________________________________________
model_12 (Model) (None, 60, 462) 1077124
=================================================================
Total params: 1,169,724
Trainable params: 1,169,724
Non-trainable params: 0
_________________________________________________________________
Также у меня есть своя собственная метрика точности (потому что точность lib не подходит для моегоdata):
def symbol_acc(y_true, y_pred):
isEqual = K.cast(K.equal(y_true, y_pred), K.floatx())
return K.mean(isEqual)
И компиляция:
model.compile(loss=tf.losses.sparse_softmax_cross_entropy,optimizer='adam', target_tensors=[tf.placeholder(tf.int32, [None, 60])], metrics=[symbol_acc])
Почему компиляция выглядит так: сначала модель имела еще один слой model.add(TimeDistributed(Dense(EVENTS_CNT, activation='softmax')))
, а компиляция была model.compile(loss=custom_categorical_crossentropy, optimizer='rmsprop', metrics=[symbol_acc])
.Но такая модель выдает ошибку «ValueError: Ошибка при проверке цели: ожидалось, что time_distributed_2 будет иметь 3 измерения, но получил массив с формой (2714, 60)».Теперь все формы подходят.
Но теперь у меня есть новая проблема (ключевой момент моей истории): формы в метрике symbol_acc
разыскиваются:
Фигуры (symbol_acc): (?, 60) (?,?, 462)
Итак, массив true
имеет форму (?, 60)
и прогнозируется - (?, ?, 462)
.Каждое значение в значениях true
60 представляет собой число от 0 до 461 (представляет истинное число событий), а каждое значение в значениях predicted
60 представляет собой вектор размера 462 распределения вероятностей для каждого числа от 0 до 461 (длякаждое из 462 событий) (для каждого из 462 событий).Я хочу сделать true
такой же формы, как и predicted
: для каждого из 60 значений создайте вектор размером 462 с 1 на позиции номера события и 0 на других.
Итак, мои вопросы:
- Как изменить форму массива в метрике, если до подгонки модели у меня нет данных?Максимум, который я получил, равен
K.gather(K.eye(462), tf.cast(number, tf.int32))
: этот код создает массив с одним «горячим» номером 1 в позиции number
.Но я не понимаю, как применить его к массиву, не зная этого массива. - Может быть, есть более простой способ решить эту проблему?
Я новичок в kerasи NNs, поэтому я не уверен, что все шаги верны.Если вы видите какую-либо ошибку, пожалуйста, сообщите.