簡體   English   中英

LSTM CNN訓練和測試准確性相同,但預測概率較低

[英]LSTM CNN training and test accuracy are same with low prediction probability

我已經在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)

試試這個:改變

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'])

正如R. Giskard所建議的那樣,如果存在兩個以上的類,則可以將sigmoid激活確實更改為softmax (這將使您的輸出總計為1),並且binary_crossentropy應該切換為categorical_crossentropy 顧名思義, binary_crossentropy用於二進制分類問題。

至於單個類別內的准確性差,可能有多種原因。 最明顯的一個可能是數據集的平衡-問題班級中的培訓樣本數量是否與其他班級相同? 嘗試構建分類器之前,請先分析數據。

另外,您似乎是從一個非常復雜的模型開始的,在該模型上您自己嵌入了角色。 您是否首先嘗試過一種更簡單的方法來更好地理解數據? 像TF-IDF這樣的東西可以對數據進行矢量化處理,並且更容易解釋分類器,例如隨機森林模型。 如果更簡單的模型能夠解決您的問題,則無需自定義NN架構。 您可以從scikit-learn類的庫開始,並進行一些基本測試以更好地理解數據,然后再決定使用深度學習。 特別是由於DL模型通常需要大量的訓練集才能達到良好的效果。

實際上,您可能根本不應該從頭開始構建自定義嵌入或模型。 使用FastText或BERT等預建模型可能會產生更好的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM