【问题标题】:LSTM CNN training and test accuracy are same with low prediction probabilityLSTM CNN 训练和测试精度相同,预测概率低
【发布时间】:2018-06-24 13:23:33
【问题描述】:

我在 python 中编写了一个代码,将非结构化文本标记为从 0 到 11 的 12 个标签之一。该代码是 LSTM CNN 模型,但训练和测试精度是相同的。当我对模型进行预测时,非结构化文本属于 12 个类别之一的概率似乎非常低。我无法找到为什么会发生这种情况的解释。我已经浏览了答案,但大多数在线解决方案似乎很难解释,因为我是 python 和神经网络的初学者。

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.layers.embeddings import Embedding
import pandas as pd
from keras.preprocessing import text as keras_text, sequence as keras_seq
from sklearn.model_selection import train_test_split
from keras.layers import Dense, Flatten, LSTM, Conv1D, MaxPooling1D, Dropout, Activation


#Preparing training data
raw = pd.read_fwf(Trainset)
xtrain_obfuscated = pd.read_fwf(Trainset_x)
ytrain = pd.read_fwf(Trainset_y,header=None)
xtrain_obfuscated['label']=ytrain[0]
xtrain_obfuscated.rename(columns={0:'text'}, inplace=True)

#Reading test file
xtest_obfuscated = pd.read_fwf(testset,header=None)
xtest_obfuscated.rename(columns={0:'text'}, inplace=True)

#One-hot encoding on training data
xtrain_encoded = pd.get_dummies(xtrain_obfuscated, columns=['label'])

#df_encoded_copy=df_encoded.copy()

#List sentences train
#Text matrix to be fed into neural network
train_sentence_list = xtrain_encoded["text"].fillna("unknown").values
list_classes = ["label_0","label_1","label_2",'label_3',"label_4","label_5","label_6","label_7","label_8","label_9","label_10","label_11"]
y = xtrain_encoded[list_classes].values

#List sentences test
test_sentence_list = xtest_obfuscated["text"].fillna("unknown").values

max_features = 20000
maxlen = raw[0].map(len).max()
batch_size=32

#Sequence Generation
tokenizer = keras_text.Tokenizer(char_level = True)
tokenizer.fit_on_texts(list(train_sentence_list))
# train data
train_list_tokenized = tokenizer.texts_to_sequences(train_sentence_list)
X = keras_seq.pad_sequences(train_list_tokenized, maxlen=maxlen)

X_train, X_valid= train_test_split(X, test_size=0.2)
y_train, y_valid= train_test_split(y, test_size=0.2)
# test data
test_list_tokenized = tokenizer.texts_to_sequences(test_sentence_list)
X_test = keras_seq.pad_sequences(test_list_tokenized, maxlen=maxlen)
#Model
embedding_vector_length = 128
model = Sequential()
model.add(Embedding(max_features, embedding_vector_length, input_length=maxlen))
model.add(Dropout(0.2))
model.add(Conv1D(filters=64, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=4))
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(12, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train, y_train, epochs=3, batch_size=64)
#cross_val_score(model, X_train, y, cv=3)
# Final evaluation of the model
scores = model.evaluate(X_valid, y_valid, verbose=0)
#print("Accuracy: %.2f%%" % (scores[1]*100))
a = model.predict(X_test)

【问题讨论】:

  • 另外,我不确定max_features = 20000的使用。它在这里做什么以及它的值应该如何设置。

标签: python neural-network deep-learning conv-neural-network lstm


【解决方案1】:

试试这个:改变

model.add(Dense(12, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.add(Dense(12, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

【讨论】:

    【解决方案2】:

    作为R。 Giskard 建议,如果有超过 2 个类,sigmoid 激活确实可以更改为softmax(这将使您的输出总和为 1),binary_crossentropy 应切换为@987654325 @。 binary_crossentropy - 顾名思义 - 专为二进制分类问题而设计。

    至于单个类中的准确性差,可能有多种原因。最明显的一个可能是数据集平衡——问题类中的训练样本量是否与其他类中的训练样本量大致相同?在尝试构建分类器之前先分析您的数据。

    此外,您似乎是从一个相当复杂的模型开始的,在此基础上添加了您自己的字符嵌入。您是否首先尝试了一种更简单的方法来更好地了解数据?诸如 TF-IDF 之类的东西可以对数据进行矢量化,并且更容易解释分类器,例如随机森林模型。如果更简单的模型能够解决您的问题,则无需自定义 NN 架构。您可以从 scikit-learn 之类的库开始,并在决定使用深度学习之前执行一些基本测试以更好地理解数据。尤其是因为 DL 模型通常需要大量的训练集才能达到良好的效果。

    事实上,您可能根本不应该从头开始构建自定义嵌入或模型。使用 FastText 或 BERT 等预构建模型可能会产生更好的结果。

    【讨论】:

      猜你喜欢
      • 2020-11-06
      • 1970-01-01
      • 2021-09-14
      • 2020-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2020-07-08
      相关资源
      最近更新 更多