长版(您可以跳过此版本)
我对Tensorflow和Keras都很陌生,我正在尝试使用NLP进行情感分析(正面/负面句子)我找到了非常着名的denny britz implementation“卷积神经网络用于句子分类”纸并试了一下。我的实现和我刚刚联系的实现之间的唯一区别是我使用预训练的矢量而不是当场训练它们。
它工作得非常好,使用预训练的矢量,在我的整个数据的一小部分样本训练后,我的验证集的准确度为81%。 然而,我试图移动我的整个数据,并在保存检查点时在训练和磁盘空间时快速耗尽两个ram。
问题来自于实现处理句子的方式,对于每个句子,它存储每个单词在该句子中的整个嵌入,而不是在预训练的嵌入文件中可以找到这些嵌入的索引。所以你可以想象一下如何使用300维度的嵌入来耗尽内存。
在寻找通过使用索引来提高效率的方法时,我发现Keras显然已经内置了对该功能的支持。
值得庆幸的是,我发现这个repository显然实现了Keras中的denny britz实现(参数中有一些差异,根据存储库的所有者,不应该影响准确性)
我必须稍微修改代码才能使用索引而不是完全嵌入,并认为我的修改部分是正确的,您可以在下面找到我的代码。存储库所有者说他的Keras建立在Theano之上,而不是Tensorflow,这也是值得的。但在阅读完差异后,我认为这不应成为我问题的原因。
简短版
我尝试修改第二个链接上的代码,使其尽可能与第一个链接类似,生成的代码(如下所示)运行但结果无法比较。使用第一个链接中的代码,我在训练集上获得了87%的准确率,在一个时期之后获得了81%的验证集。使用下面的代码,这些准确度分别为72%和62%,这更糟糕。
filter_sizes = [3, 4, 5]
num_filters = 128
hidden_dims = 50
dropout_prob = 0.5
max_sentence_len = 64
#(word embedding dimension = 300)
model_input = Input(shape=(max_sentence_len,), dtype='int32')
z =Embedding(word_embeddings.shape[0],
word_embeddings.shape[1],
input_length=max_sentence_len,
weights=[word_embeddings],
trainable=False)(model_input)
z = Dropout(dropout_prob)(z)
# Convolutional block
conv_blocks = []
for sz in filter_sizes:
conv = Convolution1D(filters=num_filters,
kernel_size=sz,
padding="valid",
activation="relu",
strides=1)(z)
conv = MaxPooling1D(pool_size=2)(conv)
conv = Flatten()(conv)
conv_blocks.append(conv)
z = Concatenate()(conv_blocks) if len(conv_blocks) > 1 else conv_blocks[0]
z = Dropout(dropout_prob)(z)
z = Dense(hidden_dims, activation="relu")(z)
model_output = Dense(1, activation="sigmoid")(z)
model = Model(model_input, model_output)
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
# Train the model
model.fit(X_train, y_train, batch_size=64, epochs=2,
validation_split=0.05, verbose=1)
我一直试图在过去的几个小时内调整一些参数/图层,但我仍然没有达到tensorflow实现的性能。我做错了吗?