1

我正在使用 Keras 库进行序列标记。我已经在我的实验中使用预训练嵌入,使用这样的方法(https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html

我的代码(内部保存的嵌入):

    self._model = Sequential(name='core_sequential')
    self._model.add(Embedding(input_dim=weights.shape[0], 
                              output_dim=weights.shape[1],
                              weights=[weights],
                              name="embeddings_layer",trainable=False))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_1'))
    self._model.add(Bidirectional(LSTM(output_dim=300,
                                       return_sequences=distributed,
                                       activation="tanh",
                                       name="lstm_layer"),name='birnn_layer'))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_2'))
    self._model.add(TimeDistributed(Dense(output_dim=1,
                                          activation='sigmoid',
                                          name='dense_layer'), 
                    name="timesteps_layer"))
    self._model.compile(optimizer=Adam(lr=lr),
                        loss='binary_crossentropy', 
                        metrics=['accuracy'])

这工作得很好,我们只需要输入一个(X,max_sequence_size)形状的 nd 数组,它实际上是 X个max_sequence_size时间步长(单词索引)的填充序列。

在模型内部保存预训练嵌入完全扩展了模型的大小(每个模型 450MB)。如果有人想在他自己的系统上将这种架构用于多个模型,比如说 20 个模型,他需要大约 20 个模型。10GB 可保存所有型号!在这种情况下,瓶颈是每个模型都在内部保存了词嵌入权重,而它们总是相同的。

试图找到一种足够的方法来减小模型的大小,我认为最好在外部加载实际的特征向量(嵌入)。,这意味着加载一个(X,max_sequence_size, embeddings_size)形状的 nd 数组,它实际上是 实际嵌入的max_sequence_size时间步长的X个填充序列。

我找不到任何关于这个重要问题的讨论。在 Keras 文档中,嵌入似乎是 RNN 中唯一可用的选择,keras 社区似乎低估了这个内存问题。我试图找出解决方案。

解决方案(外部加载的嵌入):

    self._model = Sequential(name='core_sequential')
    self._model.add(InputLayer((None, 200)))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_1'))
    self._model.add(Bidirectional(LSTM(output_dim=300,
                                       return_sequences=distributed,
                                       activation="tanh",
                                       name="lstm_layer"),name='birnn_layer'))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_2'))
    self._model.add(TimeDistributed(Dense(output_dim=1,
                                          activation='sigmoid',
                                          name='dense_layer'), 
                    name="timesteps_layer"))
    self._model.compile(optimizer=Adam(lr=lr),
                        loss='binary_crossentropy', 
                        metrics=['accuracy'])

上面的代码有效,但请考虑以下几点:

  • 您可能需要从头开始微调!
  • 您必须格外小心序列的 max_length。很少有异常值(巨大的序列)可能会产生问题。

我建议以下解决方案。

更好的解决方案(外部加载的嵌入 + 掩蔽):

    self._model = Sequential(name='core_sequential')
    self._model.add(Masking(mask_value=0., input_shape=(None, 200)))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_1'))
    self._model.add(Bidirectional(LSTM(output_dim=300,
                                       return_sequences=distributed,
                                       activation="tanh",
                                       name="lstm_layer"),name='birnn_layer'))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_2'))
    self._model.add(TimeDistributed(Dense(output_dim=1,
                                          activation='sigmoid',
                                          name='dense_layer'), 
                    name="timesteps_layer"))
    self._model.compile(optimizer=Adam(lr=lr),
                        loss='binary_crossentropy', 
                        metrics=['accuracy'])

随意评论和批评,非常欢迎您!

4

1 回答 1

0

解决方案(外部加载的嵌入):

    self._model = Sequential(name='core_sequential')
    self._model.add(InputLayer((None, 200)))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_1'))
    self._model.add(Bidirectional(LSTM(output_dim=300,
                                       return_sequences=distributed,
                                       activation="tanh",
                                       name="lstm_layer"),name='birnn_layer'))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_2'))
    self._model.add(TimeDistributed(Dense(output_dim=1,
                                          activation='sigmoid',
                                          name='dense_layer'), 
                    name="timesteps_layer"))
    self._model.compile(optimizer=Adam(lr=lr),
                        loss='binary_crossentropy', 
                        metrics=['accuracy'])

上面的代码有效,但请考虑以下几点:

  • 您可能需要从头开始微调!
  • 您必须格外小心序列的 max_length。很少有异常值(巨大的序列)可能会产生问题。

我建议以下解决方案。

更好的解决方案(外部加载的嵌入 + 掩蔽):

    self._model = Sequential(name='core_sequential')
    self._model.add(Masking(mask_value=0., input_shape=(None, 200)))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_1'))
    self._model.add(Bidirectional(LSTM(output_dim=300,
                                       return_sequences=distributed,
                                       activation="tanh",
                                       name="lstm_layer"),name='birnn_layer'))
    self._model.add(Dropout(dropout_rate,name='dropout_layer_2'))
    self._model.add(TimeDistributed(Dense(output_dim=1,
                                          activation='sigmoid',
                                          name='dense_layer'), 
                    name="timesteps_layer"))
    self._model.compile(optimizer=Adam(lr=lr),
                        loss='binary_crossentropy', 
                        metrics=['accuracy'])

随意评论和批评,非常欢迎您!

于 2017-04-10T15:20:07.060 回答