【问题标题】:How to use CNN and LSTM for NLP with BERT embeddings?如何将 CNN 和 LSTM 用于带有 BERT 嵌入的 NLP?
【发布时间】:2020-09-28 13:13:54
【问题描述】:

我已将 imdb 数据集转换为维度为 768 的 BERT 嵌入。因此,我有 40000 个 768 个特征的样本用于训练和 10000 个用于验证的样本,大小相同为 768。我已经尝试了密集层,我已经达到了大约85% 的准确率,没有太多问题。但是,在使用 convs 层和 lstms 层时,我遇到了尺寸问题。我缺少的另一个概念是我不知道这些层的正确顺序。我假设它应该就在模型的入口处,因为这些层能够捕获时间依赖关系,并且通过 BERT 嵌入可以学习这些依赖关系。我正在使用 200 条评论的批量大小。提前感谢您的任何澄清。

我相信,由于我已经在使用 BERT 嵌入,因此我不需要具有 Embeddings 类型的输入层,但我也不确定这一点。

免责声明:经过一些实验,我认为 One 不需要 LSTM 层,也不需要 CNN。分类应该是密集的,因为嵌入应该带来所有的上下文信息。到那时我还不够聪明(仍然没有),也许我只是在尝试不同的方法

我的输入训练集:

np.array(x_train).shape
(40000, 768)

还有我正在使用的模型

import keras
from keras import models
from keras.models import Sequential
from keras import layers
from keras.layers import Embedding, Bidirectional, Dense, LSTM, Conv1D, MaxPooling1D, Flatten, Reshape, TimeDistributed
from keras import optimizers

reduce_lr = keras.callbacks.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.50, patience=2, verbose=1, mode='auto', cooldown=0, min_lr=0.00001)

early = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')

model1 = Sequential()

# CONVS + POOLING LAYERS or RECURRENT LAYERS
# CONVS + POOLING LAYERS or RECURRENT LAYERS

model1.add(Dense(526, activation='relu'))
model1.add(Dense(128, activation='relu'))
model1.add(Dense(64, activation='relu'))


model1.add(Dense(2, activation='softmax'))
model1.summary()

adam = optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)

model1.compile(loss='sparse_categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

history  = model1.fit(np.array(x_train), np.array(y_train),
 epochs= 20,
 batch_size = 200,
 validation_data = (np.array(x_val), np.array(y_val)), callbacks = [reduce_lr, early]
)

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    Conv1D 和 LSTM 需要 3D 数据。

    np.array(x_train).shape (40000, 768)

    正确的形状应该是(40000, 768, 1)

    所以,重塑你的阵列。

    x_train = x_train.reshpae(-1, 768, 1)

    model1 = Sequential()
    
    model1.add(Conv1D(128, 3, activation='relu')) # input_shape = (768,1)
    model1.add(Conv1D(256, 3,  activation='relu'))
    # flat
    model1.add(Flatten())
    
    model1.add(Dense(2, activation='softmax'))
    model1.summary()
    

    【讨论】:

    • 你好。感谢您的回答。你为什么把它重塑成1?为什么是 1?
    • 为什么时间维度应该设置为1?你知道这个问题的答案吗:我相信,由于我已经在使用 BERT 嵌入,我不需要具有 Embeddings 类型的输入层,但我也不确定这一点。我说的对吗?
    • 我认为如果输出的bert嵌入具有时间/空间依赖性,那么时间维度应该是768,否则为1。同样使用1个时间维度没有意义(我只是在上一个案例中做了一般性评论)。只需使用 768 个时间维度 (LSTM) 或空间维度 (CNN),每个时间步长 1 个特征,空间维度。
    • 那么,如何正确重塑 LSTM 或 RNN?我无法将数据重塑为 .reshape(-1, 768, 768) 因为它抱怨尺寸。
    • 不,只保留 (768,1) 用于 CNN1D 和 LSTM。正如我所说,每个时间步的特征数是 1。一个简单的例子,假设你有 100 个长度(x,y,z)轴的传感器数据。每个时间步您将有 100 个时间维度 3 特征。就您而言,您只有一个功能/频道。
    猜你喜欢
    • 2019-09-04
    • 2022-08-18
    • 1970-01-01
    • 2019-10-29
    • 2021-04-03
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多