Большая разница в точности после тренировки модели и после загрузки этой модели - PullRequest
0 голосов
/ 02 апреля 2020

Я сделал модель Keras NN для обнаружения поддельных новостей. Мои особенности - средняя длина слов, средняя длина предложения, количество знаков препинания, количество заглавных слов, количество вопросов и т. Д. c. У меня есть 34 функции. У меня есть один выход, 0 и 1 (0 для подделки и 1 для реальных новостей). Я использовал 50000 образцов для обучения, 10000 для тестирования и 2000 для проверки. Значения моих данных изменяются от -1 до 10, поэтому разница между значениями невелика. Я использовал Стандартный Скалер, как это:

x_train, x_test, y_train, y_test = train_test_split(features, results, test_size=0.20, random_state=0)

scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)

validation_features = scaler.transform(validation_features)

Мой NN:

model = Sequential()
model.add(Dense(34, input_dim = x_train.shape[1], activation = 'relu')) # input layer requires input_dim param
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(1, activation='sigmoid')) # sigmoid instead of relu for final probability between 0 and 1

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

es = EarlyStopping(monitor='val_loss', min_delta=0.0, patience=0, verbose=0, mode='auto')
model.fit(x_train, y_train, epochs = 15, shuffle = True, batch_size=64, validation_data=(validation_features, validation_results), verbose=2, callbacks=[es])

scores = model.evaluate(x_test, y_test)
print(model.metrics_names[0], round(scores[0]*100,2), model.metrics_names[1], round(scores[1]*100,2))

Результаты:

Train on 50407 samples, validate on 2000 samples
Epoch 1/15
 - 3s - loss: 0.3293 - acc: 0.8587 - val_loss: 0.2826 - val_acc: 0.8725
Epoch 2/15
 - 1s - loss: 0.2647 - acc: 0.8807 - val_loss: 0.2629 - val_acc: 0.8745
Epoch 3/15
 - 1s - loss: 0.2459 - acc: 0.8885 - val_loss: 0.2602 - val_acc: 0.8825
Epoch 4/15
 - 1s - loss: 0.2375 - acc: 0.8930 - val_loss: 0.2524 - val_acc: 0.8870
Epoch 5/15
 - 1s - loss: 0.2291 - acc: 0.8960 - val_loss: 0.2423 - val_acc: 0.8905
Epoch 6/15
 - 1s - loss: 0.2229 - acc: 0.8976 - val_loss: 0.2495 - val_acc: 0.8870
12602/12602 [==============================] - 0s 21us/step
loss 23.95 acc 88.81

Проверка точности:

prediction = model.predict(validation_features , batch_size=64)

res = []
for p in prediction:
    res.append(p[0].round(0))

# Accuracy with sklearn
acc_score = accuracy_score(validation_results, res)
print("Sklearn acc", acc_score)  # 0.887

Сохранение модели:

model.save("new keras fake news acc 88.7.h5")
scaler_filename = "keras nn scaler.save"
joblib.dump(scaler, scaler_filename)

Я сохранил эту модель и этот скейлер. Когда я загружаю эту модель и этот скейлер, и когда я хочу делать прогноз, я получаю точность 52%, и это очень мало, потому что у меня была точность 88,7%, когда я тренировал эту модель. Я применил .transform к своим новым данным для тестирования.

validation_df = pd.read_csv("validation.csv")
validation_features = validation_df.iloc[:,:-1]
validation_results = validation_df.iloc[:,-1].tolist()

scaler = joblib.load("keras nn scaler.save") 
validation_features = scaler.transform(validation_features)


my_model_1 = load_model("new keras fake news acc 88.7.h5")
prediction = my_model_1.predict(validation_features , batch_size=64)

res = []
for p in prediction:
    res.append(p[0].round(0))

# Accuracy with sklearn - much lower 
acc_score = accuracy_score(validation_results, res)
print("Sklearn acc", round(acc_score,2))  # 0.52

Можете ли вы сказать мне, что я делаю не так, я много об этом читал на github и stackoverflow, но не смог найти ответ?

1 Ответ

1 голос
/ 02 апреля 2020

Трудно ответить на это без ваших реальных данных. Но есть пистолет для курения, что вызывает подозрения, что ваши данные проверки могут (очень) отличаться от ваших тренировочных и тестовых данных; и это вытекает из вашего предыдущего вопроса по этому вопросу:

Если я использую fit_transform в своих функциях [проверки набора], я не получаю ошибку, но я получаю точность 52%, и это ужасно (потому что у меня было 89,1%).

Хотя использование fit_transform для данных проверки действительно неверно методология (правильным является то, что вы делать здесь), на практике это должно , а не привести к такому высокому расхождению в точности.

Другими словами, я на самом деле видел много случаев, когда люди ошибочно применяли такие fit_transform подходы к своим данным проверки / развертывания, не осознавая при этом никакой ошибки, просто потому, что у них не было различий в производительности. - следовательно, они не предупреждены. И такая ситуация ожидается, если действительно все эти данные качественно схожи.

Но несоответствия, подобные вашим, приводят к серьезным подозрениям, что ваши данные проверки действительно (очень) отличаются от ваших данных обучения и тестирования. Если это так, то следует ожидать таких расхождений в производительности: вся практика ML основана на (часто неявном) допущении, что наши данные (обучение, проверка, тестирование, развертывание в реальных условиях и т. Д. c) не изменяются качественно , и все они получены из одного и того же статистического распределения.

Итак, следующий шаг здесь - выполнить предварительный анализ ваших данных обучения и проверки, чтобы исследовать это (на самом деле, это всегда считается шагом № 0 в любой прогнозной задаче). Я предполагаю, что даже элементарные меры (средние значения & max / min и т. Д. 1036 *) покажут, если между ними есть сильные различия, как я подозреваю.

В частности, Scikit-Learn StandardScaler использует

z = (x - u) / s

для преобразования, где u - среднее значение и s стандартное отклонение данных. Если эти значения значительно различаются между вашими обучающими и проверочными наборами, расхождение в производительности не должно быть неожиданным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...