【问题标题】:Random Initialisation of Hidden State of LSTM in keraskeras中LSTM隐藏状态的随机初始化
【发布时间】:2020-03-05 15:43:13
【问题描述】:

我为我的音乐生成项目使用了一个模型。模型创建如下

        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% 的准确率训练此模型后,每当我生成音乐时,它总是给出相同类型的起始音符,无论输入音符如何变化都很少。我认为可以通过在生成开始时初始化 LSTM 的隐藏状态来解决这个问题。我该怎么做?

【问题讨论】:

    标签: tensorflow keras deep-learning lstm


    【解决方案1】:

    有两种状态,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) 
    

    您可以在训练期间使用零来表示状态。

    【讨论】:

    • 因此,在您的解决方案中,我只需将 state_c_input 更改为其形状的一些随机矩阵。我说的对吗?
    • 是的,也许 H 也是。我只是不完全确定这些状态的形状在我的回答中是否正确。 (如果他们不正确,你会得到一个错误,然后我们可以讨论更多:p)
    • 如何找到形状