Как правильно инициализировать скрытое состояние на первом этапе декодера LSTM в Керасе - PullRequest
0 голосов
/ 01 мая 2019

В настоящее время я реализую модель attr2seq, как описано в этой статье Dong et al. (2018) в Keras, и я полностью застрял при инициализации скрытых векторов на первом временном шаге декодера LSTM с использованием закодированных векторов атрибутов $ a $ (последний абзац в разделе «3.2 Декодер последовательности»). Поэтому я хочу найти решение о том, как использовать закодированные векторы атрибутов для правильной инициализации скрытых векторов на первом временном шаге изменения декодера последовательности LSTM.

Я тестировал первый подход в соответствии с предложением здесь , где один делает слой LSTM переходящим в состояние, а затем указывает скрытое состояние после успешной компиляции модели (и убедитесь, что shuffle = False при примерке модели тоже). Однако одной из проблем этого подхода является то, что вам нужно указать конкретный размер пакета, и если у вас есть количество выборок данных, которые не делятся на этот размер пакета, программа завершит работу с ошибкой (т. Е. Exception: In a stateful network, you should only pass inputs with a number of samples that can be divided by the batch size.. Также при подгонке модели обучаются только слои LSTM, тогда как кодеры атрибутов не учитываются во время обучения, что приводит к необученным векторам атрибутов. неправильно.

Еще один подход, который я опробовал, состоял в том, чтобы символически установить начальное скрытое состояние, присваивая значения initial_state, который включен в call(…) методы для рекуррентных слоев в Keras. Однако из исходного кода здесь я понял, что необходимо предоставить матрицы весов для обеспечения некоторого пользовательского начального состояния слоя LSTM, и я, к сожалению, не знаю, как это сделать, хотя я думаю, что такого рода инициализация нужна, но для скрытых векторов на первом временном шаге (т.е. t=0), а не для весов на первом временном шаге. Может быть, кто-то мог бы это сделать, но я этого не делаю, так как я не слишком привык к Керасу (или глубокому изучению этого вопроса).

Коды примерно показывают, как должна выглядеть модель более или менее. При запуске кодов в моей программе я получаю сообщение об ошибке ValueError: An initial_state was passed that is not compatible with cell.state_size. Received state_spec=[InputSpec(shape=(None, 514), ndim=2)]; however cell.state_size is (514, 514), которое заставляет меня понять, что initial_state требует матрицы весов, а не произвольного числа состояний для каждой отдельной точки данных.

    x_drug = Input(shape=(onehotted_drugs.shape[1],))
    x_cond = Input(shape=(onehotted_conds.shape[1],))
    x_rating = Input(shape=(onehotted_ratings.shape[1],))

    g_drug = Dense(self.attr_size)(x_drug)
    g_cond = Dense(self.attr_size)(x_cond)
    g_rating = Dense(self.attr_size)(x_rating)
    g_concatenated = Concatenate()([g_drug, g_cond, g_rating])
    a = Dense(self.num_layers * self.hidden_size, activation = "tanh")(g_concatenated)
    hidden_vectors = [Lambda(lambda l: slice(l, (0, self.hidden_size*i), (-1, self.hidden_size*(i+1))))(a) for i in range(self.num_layers)]

    x_prev_words = Input(shape = (self.num_tokens,))
    ground_zero = Dense(self.hidden_size, use_bias = False)(x_prev_words)
    lstm_layers = [LSTM(self.hidden_size, input_shape = (self.max_sequence_length - 1, self.hidden_size), return_sequences = True)(RepeatVector(self.max_sequence_length - 1)(ground_zero), initial_state = hidden_vectors[0])]
    for i in range(1, self.num_layers):
      lstm_layers.append(LSTM(self.hidden_size, return_sequences = False if i==self.num_layers-1 else True)(lstm_layers[-1], initial_state = hidden_vectors[i]))

    next_word_dist = Dense(self.num_tokens, activation = "softmax")(lstm_layers[-1])    
    self.dong = Model(inputs=[x_drug, x_cond, x_rating, x_prev_words], outputs=[next_word_dist])
    self.dong.compile(loss = "categorical_crossentropy", optimizer = "rmsprop")

Если вам потребуется дополнительная информация или коды для проверки, не стесняйтесь сообщить мне. Спасибо всем за помощь, которую я могу получить в этом вопросе!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...