如何将 Bert 嵌入提供给 LSTM

Posted

技术标签:

【中文标题】如何将 Bert 嵌入提供给 LSTM【英文标题】:How to feed Bert embeddings to LSTM 【发布时间】:2019-09-04 06:50:52 【问题描述】:

我正在研究用于文本分类问题的 Bert + MLP 模型。本质上,我正在尝试用基本的 LSTM 模型替换 MLP 模型。

是否可以创建带有嵌入的 LSTM?或者,最好创建一个带有嵌入层的 LSTM?

更具体地说,我很难尝试创建嵌入式矩阵,因此我可以使用 Bert 嵌入创建嵌入层。

def get_bert_embeddings(dataset='gap_corrected_train',
                        dataset_path=TRAIN_PATH,
                        bert_path=BERT_UNCASED_LARGE_PATH,
                        bert_layers=BERT_LAYERS):
    """Get BERT embeddings for all files in dataset_path and specified BERT layers and write them to file."""
    df = None
    for file in os.listdir(dataset_path):
        if df is None:
            df = pd.read_csv(dataset_path+'/'+file, sep='\t')
        else:
            next_df = pd.read_csv(dataset_path+'/'+file, sep='\t')
            df = pd.concat([df, next_df], axis=0)
            df.reset_index(inplace=True, drop=True)

    for i, layer in enumerate(bert_layers):
        embeddings_file = INTERIM_PATH + 'emb_bert' + str(layer) + '_' + dataset + '.h5'
        if not os.path.exists(embeddings_file):
            print('Embeddings file: ', embeddings_file)
            print('Extracting BERT Layer 0 embeddings for 1...'.format(layer, dataset))
            print("Started at ", time.ctime())

            emb = get_bert_token_embeddings(df, bert_path, layer)
            emb.to_hdf(embeddings_file, 'table')

            print("Finished at ", time.ctime())

def build_mlp_model(input_shape):
    input_layer = layers.Input(input_shape)



    input_features = layers.Input((len(FEATURES),))
    x = layers.Concatenate(axis=1, name="concate_layer")([input_layer, input_features]) 


    x = layers.Dense(HIDDEN_SIZE, name='dense1')(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.Dropout(DROPOUT, seed=RANDOM)(x)

    x = layers.Dense(HIDDEN_SIZE//2, name='dense2')(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.Dropout(DROPOUT//2, seed=RANDOM)(x)

    x = layers.Dense(HIDDEN_SIZE//4, name='dense3')(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.Dropout(DROPOUT//2, seed=RANDOM)(x)

    output_layer = layers.Dense(3, name='output', kernel_regularizer = regularizers.l2(LAMBDA))(x)
    output_layer = layers.Activation('softmax')(output_layer)

    model = models.Model(input=[input_layer, input_features], output=output_layer, name="mlp")
    return model

【问题讨论】:

你弄明白了吗? 还没有。 github中有几个例子。 可以使用嵌入层创建 LSTM。 Keras 提供了可以与 LSTM 一起使用的嵌入层 @AshwinGeetD'Sa 有该信息的网站吗? 这里有关于嵌入层的信息:keras.io/layers/embeddings 【参考方案1】:

您可以创建首先使用嵌入层的模型,然后是 LSTM,然后是 Dense。 比如这里:

deep_inputs = Input(shape=(length_of_your_data,))
embedding_layer = Embedding(vocab_size, output_dim = 3000, trainable=True)(deep_inputs)
LSTM_Layer_1 = LSTM(512)(embedding_layer) 
dense_layer_1 = Dense(number_of_classes, activation='softmax')(LSTM_Layer_1) 
model_AdGroups = Model(inputs=deep_inputs, outputs=dense_layer_1) 

【讨论】:

对不起。如果我只想应用 Bert,我可以用 Bert 替换代码中的 lstm 吗? 是的,我想是的。

以上是关于如何将 Bert 嵌入提供给 LSTM的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地为 PyTorch 中的嵌入、LSTM 和线性层提供输入?

BERT 词嵌入预处理是如何工作的

将时间序列数据提供给有状态 LSTM 的正确方法?

BERT实战:使用DistilBERT作为词嵌入进行文本情感分类,与其它词向量(FastText,Word2vec,Glove)进行对比

[语音识别] 文本加标点--准备训练数据 (适用于LSTM与BERT)

BERT - 从多个输出与单个输出中提取 CLS 嵌入