Различная точность обучения для разных моделей, но одинаковая точность тестирования - PullRequest
0 голосов
/ 07 февраля 2020

Я работаю над разработкой классификатора глубокого обучения - 2 класса. Набор данных, с которым я работаю, несбалансирован. Я сделал выборку вниз, чтобы решить то же самое. Затем я создаю небольшую выборку данных обоих классов и создаю модель глубокого обучения следующим образом:

dl_model = Sequential()

n_cols = X_train.shape[1]

dl_model.add(Dense(1024, activation='relu', input_shape=(n_cols,)))
dl_model.add(Dense(512, activation='relu'))
dl_model.add(Dense(256, activation='relu'))
dl_model.add(Dense(256, activation='relu'))
dl_model.add(Dense(128, activation='relu'))
dl_model.add(Dense(64, activation='relu'))
dl_model.add(Dense(2, activation='softmax'))

adam= optimizers.Adam(lr=0.001)

dl_model.compile(optimizer=adam, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

early_stopping_monitor = EarlyStopping(patience=3)

dl_model.fit(X_train, y_train, epochs=10, validation_split=0.2, batch_size=1000,callbacks=[early_stopping_monitor], shuffle=True)

model_json = dl_model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)

dl_model.save_weights("model.h5")

Для настройки различных гиперпараметров я получаю следующие результаты:

Модель 1 - train_loss: 7.7971 - train_acc: 0.5160 - val_loss: 9.6992 - val_acc: 0.3982

Модель 2 - train_loss: 2.8257 - train_acc: 0.8201 - val_loss: 2.9312 - val_acc: 0.8160

Модель 3 - train_loss: 3.1887 - train_acc: 0.8002 - val_loss: 3.5195 - val_acc: 0.7808

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

sc = MinMaxScaler()
X = sc.fit_transform(X)

json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("model.h5")

loaded_model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
score = loaded_model.evaluate(X, y, verbose=0)
print("Deep learning accuracy %s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))

Все вышеперечисленные 3 модели дают одинаковую точность . Даже такая же путаница матрицы. Что может быть причиной? Разве 3 модели не должны давать разные результаты, поскольку у них разная точность обучения / метрики?

Обновление:

При загрузке любой из моделей я получаю одинаковую точность 97.82% и путаницу матрица как:

[[143369      0]

 [  2958      0]]

1 Ответ

1 голос
/ 07 февраля 2020

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

Точность, которую вы имеете в тесте набор одинаков из-за того, что ни model_1, ни model_2, ни model_3 не способны отличить guish class 1 от класса 2 и, таким образом, все трое знают, как распознать класс 1, но не могут распознать класс 2. В Другими словами, когда вы тестируете на своем тестовом наборе, результаты одинаковы, независимо от различий, которые вы видите во время обучения.

Это наблюдение может быть легко выведено из матрицы путаницы, которую вы там отобразили.

Предположим, вы не знаете вышеприведенное наблюдение. Давайте рассмотрим простую математику:

  • 143369 + 2958 = 146327.
  • (143369/146327) * 100 = 97,97% (что немного больше, чем указанная вами точность, но в том же поле - небольшая разница проистекает из evaluate_score в keras)

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

Давайте теперь приступим к решению этой проблемы!

Поскольку мы упомянули это наблюдение, вы должны сделать следующее для решения этой проблемы (или некоторые из вместе взятые):

Во-первых, начните с более низкой скорости обучения (0,0001 - намного лучший начальный выбор).

Во-вторых, обратитесь к следующим процедурам, чтобы получить хороший Модель:

  1. Снимите EarlyStopping(patience=3).
  2. Сохраните свою лучшую модель в соответствии с метрикой c, отличной от точности (например, F1-Score)
  3. Уменьшите скорость обучения во время тренировки (ReduceLROnPlateau). Вы можете использовать следующий обратный вызов, который гораздо более подходит в вашем случае, чем ранний останов: https://keras.io/callbacks/#reducelronplateau
  4. Использовать обогащение набора данных. Лучший способ справиться с несбалансированными наборами данных - это использовать передискретизацию. Вместо того, чтобы занижать выборку хорошо представленного класса и, таким образом, уменьшать дисперсию вашего набора данных, вы можете сбалансировать поддержку классов, добавив больше примеров в свой класс меньшинства.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...