Странное поведение при попытке предсказать теннисных миллионеров с помощью Keras (Точность валидации)

Вопрос или проблема

Я пытаюсь создать нейронную сеть с помощью Keras для предсказания теннисистов ATP, которые получат более 1 миллиона долларов призовых, основываясь на их весе и росте (из набора данных, который я собрал несколько недель назад), но столкнулся с странным поведением, особенно в отношении валидационной точности. Иногда она достигает 84-85%, что разумно, поскольку SVM и GaussianNB кажутся способными достигать только 83,3% в лучшем случае (посмотрите этот пост для получения дополнительной информации), но иногда она составляет всего около 15%. И точность, как правило, вообще не меняется, если я добавляю мощность или увеличиваю количество эпох. Я думаю, что одна из самых странных тенденций в этой проблеме заключается в том, что потеря, по сравнению с полученной низкой точностью, оказывается довольно небольшой:

Потери на тесте и валидации довольно малы, но точность ужасна.

Весь код доступен в этой репозитории (особенно в ATP NN.ipynb и atp_python_2018-08-27_1-1500.json), но основная его часть:

model = Sequential()
model.add(Dense(20, activation = 'relu', input_shape = (2,)))
model.add(Dense(20, activation = 'relu'))
model.add(Dense(2))
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics = ['accuracy'])
model_training = model.fit(x = hw_a, y = prize_a_bin, epochs = 4, validation_split = 0.1)

Сначала я думал, что это происходит из-за того, что разбиение на валидацию, выполняемое Keras, может получать немного неправильные наборы, которые не совсем согласованы с остальными данными, поскольку миллионеры составляют только 10% от всего набора данных, но, похоже, это не так, странность сохраняется. Единственный шаблон, который я как-то могу распознать, заключается в том, что нормальная производительность и странная дополняют друг друга, т.е. если одна составляет 85%, то другая будет 100% – 85% = 15%. Это связано с какой-то ошибкой, которую я совершил?

Кстати, поскольку я новичок в Keras, нужно ли было мне указывать функцию активации последнего слоя? Я предполагаю, что по умолчанию он использует либо softmax, либо sigmoid, но, похоже, нет разницы, если я укажу любое из них. Интересно, почему, используя только один класс (либо миллионер, либо нет), нужно изменять y в to_categorical и иметь два нейрона – вместо одного – в выходном слое.

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

Это был бы ответ от ветерана, но я не таковым являюсь.

Вам следует использовать binary_crossentropy в качестве функции потерь, и тогда, я думаю, вы сможете не использовать to_categorical.

Тогда последний слой должен иметь активацию sigmoid.

Дополнительно

Попробуйте использовать только один нейрон в последнем слое: Dense(1, activation='sigmoid')

Проблема с точностью может заключаться в том, как вы разбиваете данные: возможно, только образцы из одного класса попадают в валидацию или в тренировочные данные. Я предлагаю вам использовать train_test_split из sklearn с фиксированным random_state или чем-то подобным.

Попробуйте эти вещи и посмотрите, поможет ли это:

1.) Явно укажите функцию активации в последнем слое как sigmoid.

2.) Функция потерь должна быть binary_crossentropy.

3.) Попробуйте использовать другую метрику вместо accuracy.

4.) В входном и скрытом слое попробуйте использовать leaky_relu.

5.) Также укажите batch_size при подгонке модели.

Дайте знать, если хоть что-то из этого сработает.

Удачи!

Ответ или решение

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

1. Подбор функции потерь

В вашем коде используется функция потерь categorical_crossentropy, которая предназначена для многоклассовой классификации. Поскольку ваша задача заключается в бинарной классификации (миллионер или нет), вам следует переключиться на использование функции потерь binary_crossentropy. Это обеспечит более корректное обучение модели для данной задачи. Вы можете изменить строку компиляции модели следующим образом:

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

2. Активация выходного слоя

Выходной слой вашей модели должен содержать одну нейронную единицу с функцией активации sigmoid, так как вы решаете задачу бинарной классификации. Таким образом, изменения в коде будут следующими:

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

3. Подготовка данных

Важно убедиться, что ваши данные корректно разделены на обучающую и валидационную выборки. Возможно, вы столкнулись с проблемой, когда данные распределяются неравномерно, и в одной из выборок может оказаться больше экземпляров одного класса. Рекомендую использовать train_test_split из библиотеки sklearn для более надежного разделения данных:

from sklearn.model_selection import train_test_split

# Разделение данных.
X_train, X_val, y_train, y_val = train_test_split(hw_a, prize_a_bin, test_size=0.1, random_state=42, stratify=prize_a_bin)

Обратите внимание на параметр stratify, который поможет сохранить пропорции классов в обеих выборках.

4. Увеличение количества эпох и управление переменной степенью обучения

Поскольку ваша модель может не обучаться должным образом за 4 эпохи, попробуйте увеличить это значение. Убедитесь, что вы используете параметр batch_size, который может помочь в обучении и избегании переобучения. Установите значение параметра epochs на 50 или более и добавьте параметр batch_size:

model_training = model.fit(x=X_train, y=y_train, epochs=50, validation_data=(X_val, y_val), batch_size=32)

5. Использование других метрик и функции активации

Попробуйте использовать leaky_relu в скрытых слоях, так как он может помочь улучшить обучение:

from keras.layers import LeakyReLU

model.add(Dense(20))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(20))
model.add(LeakyReLU(alpha=0.1))

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

Вывод

Следуя этим рекомендациям, вы увеличите шансы на получение более стабильной и точной модели. Самое главное — это правильное разделение данных и выбор подходящих функций потерь и активации. Надеюсь, что эти изменения помогут вам достичь высоких результатов в вашей задаче предсказания миллионеров в теннисе. Удачи!

Оцените материал
Добавить комментарий

Капча загружается...