Модель, обученная с использованием LSTM, предсказывает только одно значение для всех - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть набор данных с 4000 строк и двух столбцов.Первый столбец содержит несколько предложений, а второй столбец содержит несколько чисел для него.Есть около 4000 предложений, и они классифицируются по 100 различным номерам.Например:

Sentences                                         Codes

Google headquarters is in California              87390
Steve Jobs was a great man                        70214
Steve Jobs has done great technology innovations  70214
Google pixel is a very nice phone                 87390
Microsoft is another great giant in technology    67012
Bill Gates founded Microsoft                      67012 

Аналогичным образом, в общей сложности 4000 строк содержат эти предложения, и эти строки классифицируются с помощью 100 таких кодов

Я пробовал приведенный ниже код, но когда я прогнозирую, он предсказывает одно и то же значение для всех.Иными словами, y_pred дает массив с такими же значениями.

Могу ли я знать, где происходит неправильный код

import pandas as pd
import numpy as np

xl = pd.ExcelFile("dataSet.xlsx")
df = xl.parse('Sheet1') 

#df = df.sample(frac=1).reset_index(drop=True)# shuffling the dataframe


df = df.sample(frac=1).reset_index(drop=True)# shuffling the dataframe
X = df.iloc[:, 0].values
Y = df.iloc[:, 1].values

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
import pickle 

count_vect = CountVectorizer()
X = count_vect.fit_transform(X)

tfidf_transformer = TfidfTransformer()
X = tfidf_transformer.fit_transform(X)

X = X.toarray()

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_Y = LabelEncoder()
Y = labelencoder_Y.fit_transform(Y)
y = Y.reshape(-1, 1)  # Because Y has only one column

onehotencoder = OneHotEncoder(categories='auto')
Y = onehotencoder.fit_transform(y).toarray()


from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

inputDataLength = len(X_test[0])
outputDataLength = len(Y[0])

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence
from keras.layers import Dropout

# fitting the model
embedding_vector_length = 100
model = Sequential()
model.add(Embedding(outputDataLength,embedding_vector_length, input_length=inputDataLength))
model.add(Dropout(0.2))
model.add(LSTM(outputDataLength))
model.add(Dense(outputDataLength, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=20)
y_pred = model.predict(X_test)
invorg = model.inverse_transform(y_test)
y_test = labelencoder_Y.inverse_transform(invorg)
inv = onehotencoder.inverse_transform(y_pred)
y_pred = labelencoder_Y.inverse_transform(inv)

1 Ответ

2 голосов
/ 08 апреля 2019

Вы используете binary_crossentropy даже если у вас есть 100 классы. Что не правильно делать. Для этого вы должны использовать categorical_crossentropy.

Скомпилируйте свою модель следующим образом,

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

Кроме того, вы прогнозируете с помощью модели и конвертируете в метки классов, как это,

y_pred = model.predict(X_test)
inv = onehotencoder.inverse_transform(y_pred)
y_pred = labelencoder_Y.inverse_transform(inv)

Поскольку ваша модель активируется с помощью softmax, чтобы получить метку класса, вы должны найти argmax прогнозов.

Например, если прогноз был [0.2, 0.3, 0.0005, 0.99], вам нужно взять argmax, что даст вам вывод 3. Класс с высокой вероятностью.

Таким образом, вы должны изменить код предсказания следующим образом:

y_pred = model.predict(X_test)
y_pred = np.argmax(y_pred, axis=1)
y_pred = labelencoder_Y.inverse_transform(y_pred)

invorg = np.argmax(y_test, axis=1)
invorg = labelencoder_Y.inverse_transform(invorg)

Теперь у вас будут фактические метки классов в invorg и прогнозируемые метки классов в y_pred

...