Случайная инициализация скрытого состояния LSTM в керасе - PullRequest
1 голос
/ 05 марта 2020

Я использовал модель для моего проекта создания музыки c. Модель создается следующим образом:

        self.model.add(LSTM(self.hidden_size, input_shape=(self.input_length,self.notes_classes),return_sequences=True,recurrent_dropout=dropout) ,)
        self.model.add(LSTM(self.hidden_size,recurrent_dropout=dropout,return_sequences=True))
        self.model.add(LSTM(self.hidden_size,return_sequences=True))
        self.model.add(BatchNorm())
        self.model.add(Dropout(dropout))
        self.model.add(Dense(256))
        self.model.add(Activation('relu'))
        self.model.add(BatchNorm())
        self.model.add(Dropout(dropout))
        self.model.add(Dense(256))
        self.model.add(Activation('relu'))
        self.model.add(BatchNorm())
        self.model.add(Dense(self.notes_classes))
        self.model.add(Activation('softmax'))

После обучения этой модели с точностью до 70%. Каждый раз, когда я генерирую музыку c, она всегда выдает одинаковые начальные ноты с небольшим разбросом для любых вводимых заметок. Я думаю, что это условие можно решить путем инициализации скрытого состояния LSTM в начале генерации. Как я могу это сделать?

1 Ответ

1 голос
/ 05 марта 2020

Есть два состояния, state_h, который является последним выходным шагом; и state_c, который является состоянием переноса или памятью.

Вы должны использовать функциональную модель API, чтобы иметь более одного входа:

main_input = Input((self.input_length,self.notes_classes))
state_h_input = Input((self.hidden_size,))
state_c_input = Input((self.hidden_size, self.hidden_size))

out = LSTM(self.hidden_size, return_sequences=True,recurrent_dropout=dropout,
           initial_state=[state_h_input, state_c_input])(main_input)

#I'm not changing the following layers, they should have their own states if you want to

out = LSTM(self.hidden_size,recurrent_dropout=dropout,return_sequences=True)(out)
out = LSTM(self.hidden_size,return_sequences=True)(out)
out = BatchNorm()(out)
out = Dropout(dropout)(out)
out = Dense(256)(out)
out = Activation('relu')(out)
out = BatchNorm()(out)
out = Dropout(dropout)(out)
out = Dense(256)(out)
out = Activation('relu')(out)
out = BatchNorm()(out)
out = Dense(self.notes_classes)(out)
out = Activation('softmax')(out)

self.model = Model([main_input, state_h_input, state_c_input], out)

Следуя этому подходу, можно даже использовать выходы других слоев в качестве начальных состояний, если вы хотите обучаемы начальные состояния.

Большое изменение состоит в том, что вам нужно будет передать состояния для обучения и прогнозирования:

model.fit([original_inputs, state_h_data, state_c_data], y_train) 

Где вы можете использовать нули для состояний во время обучения.

...