Keras 如何使用LSTM进行文本分类

Keras 如何使用LSTM进行文本分类,keras,deep-learning,nlp,lstm,text-classification,Keras,Deep Learning,Nlp,Lstm,Text Classification,我正在使用LSTM模型进行文本分类,我在验证数据中获得98%的准确率,但当我提交时得到0分,请帮助我如何做,我是NLP的初学者。 我有这样的数据 train.head() id category text 0 959 0 5573 1189 4017 1207 4768 8542 17 1189 5085 5773 1 994 0 6315 7507 6700 4742 1944 2692 3647 4413 6700 2 995 0 5015 8067

我正在使用LSTM模型进行文本分类,我在验证数据中获得98%的准确率,但当我提交时得到0分,请帮助我如何做,我是NLP的初学者。 我有这样的数据

train.head()
    id  category    text
0   959 0   5573 1189 4017 1207 4768 8542 17 1189 5085 5773
1   994 0   6315 7507 6700 4742 1944 2692 3647 4413 6700
2   995 0   5015 8067 5335 1615 7957 5773
3   996 0   2925 7199 1994 4647 7455 5773 4518 2734 2807 8...
4   997 0   7136 1207 6781 237 4971 3669 6193
我在这里应用标记器:

from keras.preprocessing.text import Tokenizer
max_features = 1000
tokenizer = Tokenizer(num_words=max_features)
tokenizer.fit_on_texts(list(X_train))
X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)
我在这里应用序列填充:

from keras.preprocessing import sequence
max_words = 30
X_train = sequence.pad_sequences(X_train, maxlen=max_words)
X_test = sequence.pad_sequences(X_test, maxlen=max_words)
print(X_train.shape,X_test.shape)
这是我的模型:

batch_size = 64
epochs = 5

max_features = 1000
embed_dim = 100
num_classes = train['category'].nunique()
  model = Sequential()
    model.add(Embedding(max_features, embed_dim, input_length=X_train.shape[1]))
    model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
    model.add(MaxPooling1D(pool_size=2))    
    model.add(LSTM(100, dropout=0.2))
    model.add(Dense(num_classes, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, 30, 100)           100000    
_________________________________________________________________
conv1d_3 (Conv1D)            (None, 30, 32)            9632      
_________________________________________________________________
max_pooling1d_3 (MaxPooling1 (None, 15, 32)            0         
_________________________________________________________________
conv1d_4 (Conv1D)            (None, 15, 32)            3104      
_________________________________________________________________
max_pooling1d_4 (MaxPooling1 (None, 7, 32)             0         
_________________________________________________________________
lstm_2 (LSTM)                (None, 100)               53200     
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 202       
=================================================================
Total params: 166,138
Trainable params: 166,138
Non-trainable params: 0
_________________________________________________________________
None
以下是我的时代:

model_history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=batch_size, verbose=1)

Train on 2771 samples, validate on 693 samples
Epoch 1/5
2771/2771 [==============================] - 2s 619us/step - loss: 0.2816 - acc: 0.9590 - val_loss: 0.1340 - val_acc: 0.9668
Epoch 2/5
2771/2771 [==============================] - 1s 238us/step - loss: 0.1194 - acc: 0.9664 - val_loss: 0.0809 - val_acc: 0.9668
Epoch 3/5
2771/2771 [==============================] - 1s 244us/step - loss: 0.0434 - acc: 0.9843 - val_loss: 0.0258 - val_acc: 0.9899
Epoch 4/5
2771/2771 [==============================] - 1s 236us/step - loss: 0.0150 - acc: 0.9958 - val_loss: 0.0423 - val_acc: 0.9899
Epoch 5/5
2771/2771 [==============================] - 1s 250us/step - loss: 0.0064 - acc: 0.9984 - val_loss: 0.0532 - val_acc: 0.9899
在我将预测功能应用于测试数据之后: 我的提交文件如下:

   submission.head()





  id    category
0   3729    0.999434
1   3732    0.999128
2   3761    0.999358
3   5       0.996779
4   7       0.998702
submission.head()
    id         category
0   3729    1
1   3732    1
2   3761    1
3   5       1
4   7       1
我的实际提交文件如下:

   submission.head()





  id    category
0   3729    0.999434
1   3732    0.999128
2   3761    0.999358
3   5       0.996779
4   7       0.998702
submission.head()
    id         category
0   3729    1
1   3732    1
2   3761    1
3   5       1
4   7       1

看起来您需要将结果转换回文字!当您标记和填充时,会将单词转换为数字。你只需要把它们换回来!例如:

transformed_category = []
for cat in submission['category']:
   transformed_category.append(tokenizer.word_index(cat))
为了教育的缘故。。。它之所以这样做,是因为数学实际上不能在字符串上执行——至少,不像数字那样容易。所以,当你的神经网络中有文本时,在输入网络之前,它们需要转化为数字表示。矢量器(您的标记器就是这样做的)和“一个热门”或“分类”是最常见的方法。在任何一种情况下,一旦你从网络中获得了结果,你就可以将它们重新转换为人类的语言

评论后编辑
嗨!所以,是的,我在歪着看柱子。你得到的值是1(或者非常接近),因为sigmoid只能在0和1之间选择,但是,看起来你想要这样,因为你的损失是二进制交叉熵。通过乙状结肠激活,大值将自动接近1。所以我想说你需要重新考虑你的输出层。看起来您发送的是数字数组,并且您希望得到一个范围大于0到1的类别,因此考虑将Y数据转换为,使用softmax作为最终输出激活,并将您的损失更改为
categorical\u crossentropy

@您有权访问它不起作用的测试数据吗?我对文本数据应用了相同的过程。请参见此处max\u features=1000 tokenizer=tokenizer(num\u words=max\u features)tokenizer。在文本(列表(test['text'])test te=tokenizer.text\u到序列(test['text'])test_text=sequence.pad_sequences(test_te,maxlen=max_words)pred=model.predict(test_text)感谢LonedRanger的解决方案,但我的提交文件是对类别数据给予1s。我该怎么办。哈哈,对不起,我看错了列。我将用正确的回答编辑我的答案。你好,LoneDeranger,我正在将激活函数sigmoid更改为softmax,将损失函数binary_crossentropy更改为Category_crossentropy,在提交文件时,我仍然得到相同的0分,并且我将to_categoricals函数应用于y变量。但仍然得到同样的0分。