Как исправить нестабильные потери и точность во время тренировки? (бинарная классификация) - PullRequest
1 голос
/ 28 апреля 2019

В настоящее время я работаю над небольшим проектом двоичной классификации, использующим новый API-интерфейс keras в tenorflow.Проблема заключается в упрощенной версии проблемы Хиггса Бозона, опубликованной на Kaggle.com несколько лет назад.Форма набора данных - 2000x14, где первые 13 элементов каждой строки образуют входной вектор, а 14-й элемент - соответствующую метку.Вот пример указанного набора данных:

86.043,52.881,61.231,95.475,0.273,77.169,-0.015,1.856,32.636,202.068, 2.432,-0.419,0.0,0
138.149,69.197,58.607,129.848,0.941,120.276,3.811,1.886,71.435,384.916,2.447,1.408,0.0,1
137.457,3.018,74.670,81.705,5.954,775.772,-8.854,2.625,1.942,157.231,1.193,0.873,0.824,1

Я относительно новичок в машинном обучении и тензорном потоке, но мне знакомы понятия более высокого уровня, такие как функции потерь, оптимизаторы и функции активации.Я пробовал создавать различные модели, вдохновленные примерами проблем с двоичной классификацией, найденными в Интернете, но у меня возникают трудности с обучением модели.Во время обучения потеря некоторых предметов увеличивается в течение одной и той же эпохи, что приводит к нестабильному обучению.Точность достигает плато около 70%.Я пытался изменить скорость обучения и другие гиперпараметры, но безрезультатно.Для сравнения, я жестко закодировал полностью подключенную нейронную сеть с прямой связью, которая достигает примерно 80-85% точности для той же проблемы.

Вот моя текущая модель:

import tensorflow as tf
from tensorflow.python.keras.layers.core import Dense
import numpy as np
import pandas as pd

def normalize(array):
    return array/np.linalg.norm(array, ord=2, axis=1, keepdims=True)

x_train = pd.read_csv('data/labeled.csv', sep='\s+').iloc[:1800, :-1].values
y_train = pd.read_csv('data/labeled.csv', sep='\s+').iloc[:1800, -1:].values

x_test = pd.read_csv('data/labeled.csv', sep='\s+').iloc[1800:, :-1].values
y_test = pd.read_csv('data/labeled.csv', sep='\s+').iloc[1800:, -1:].values

x_train = normalize(x_train)
x_test = normalize(x_test)

model = tf.keras.Sequential()
model.add(Dense(9, input_dim=13, activation=tf.nn.sigmoid)
model.add(Dense(6, activation=tf.nn.sigmoid))
model.add(Dense(1, activation=tf.nn.sigmoid))

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

model.fit(x_train, y_train, epochs=50)
model.evaluate(x_test, y_test)

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

  32/1800 [..............................] - ETA: 0s - loss: 0.6830 - acc: 0.5938
1152/1800 [==================>...........] - ETA: 0s - loss: 0.6175 - acc: 0.6727
1800/1800 [==============================] - 0s 52us/step - loss: 0.6098 - acc: 0.6861
Epoch 54/250

  32/1800 [..............................] - ETA: 0s - loss: 0.5195 - acc: 0.8125
1376/1800 [=====================>........] - ETA: 0s - loss: 0.6224 - acc: 0.6672
1800/1800 [==============================] - 0s 43us/step - loss: 0.6091 - acc: 0.6850
Epoch 55/250

Что может быть причиной этих колебаний в обучении в такой простой модели?Спасибо


РЕДАКТИРОВАТЬ:

Я последовал некоторым предложениям из комментариев и соответственно изменил модель.Теперь это выглядит примерно так:

model = tf.keras.Sequential()
model.add(Dense(250, input_dim=13, activation=tf.nn.relu))
model.add(Dropout(0.4))
model.add(Dense(200, activation=tf.nn.relu))
model.add(Dropout(0.4))
model.add(Dense(100, activation=tf.nn.relu))
model.add(Dropout(0.3))
model.add(Dense(50, activation=tf.nn.relu))
model.add(Dense(1, activation=tf.nn.sigmoid))

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

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

Колебания

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

Он отлично работает для одного пакета, обновляет веса для другого и эффективно изменяет ранее выученные соединения, «разучивая».Вот почему потеря также является скачкообразной, так как сеть пытается приспособиться к задаче, которую вы ей дали.

Сигмовидная активация и ее насыщение могут также доставлять вам неприятности (так как градиент раздавлен на небольшую область и большинствообновления градиента равны нулю).Быстрое исправление - используйте ReLU активацию, как описано ниже.

Кроме того, нейронная сеть не заботится о точности , а только сводит к минимуму величину потерь (что она пытается сделать большую часть времени).Скажем, он предсказывает вероятности: [0.55, 0.55, 0.55, 0.55, 0.45] для классов [1, 1, 1, 1, 0], поэтому его точность равна 100%, но она довольно неопределенная.Теперь, скажем, следующее обновление подталкивает сеть к прогнозированию вероятностей: [0.8, 0.8, 0.8, 0.8, 0.55].В этом случае потери упадут, , но при этом точность будет , с 100% до 80%.

КСТАТИ. Вы можете проверить оценки дляЛогистическая регрессия и посмотреть, как она выполняет эту задачу (поэтому один слой с выходом только).

Некоторые вещи, которые необходимо учитывать

1.Размер вашей нейронной сети

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

В вашем случае я сомневаюсь, что модельбыть в состоянии изучить эти отношения с размером слоев, которые вы предоставляете.Попробуйте увеличить размер, особенно в более ранних слоях (возможно, 50 / 100 для начинающих) и посмотрите, как он себя ведет.

2.Функция активации

Сигмоид легко насыщается (небольшая область, где происходят изменения, большинство значений - почти 0 или 1).В настоящее время он редко используется в качестве активации перед узким местом (последний слой).Наиболее распространенным в настоящее время является ReLU, который не склонен к насыщению (по крайней мере, когда вход положительный) или его вариациям.Это также может помочь.

3.Скорость обучения

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

Возможно, вы захотите прочитать о Циклическая скорость обучения (или в оригинальной исследовательской работе Лесли Н. Смита . Там вы можете найти информацию о том, каквыберите эвристический выбор хорошей скорости обучения и настройте несколько простых планировщиков скорости обучения. Эти методы использовались командами fast.ai в соревнованиях CIFAR10 с действительно хорошими результатами. На их сайте или в документации их библиотеки вы можете найти One Cycle Policy и поиск скорости обучения (на основе работы вышеупомянутого исследователя). Это должно помочь вам начать работу в этой области, я думаю.

4. Нормализация

Не уверен, но эта нормализация выглядит довольно нестандартно для меня (никогда не видел, чтобы это делалось так). Хорошая нормализация является основой дляКонвергенция сетей в Урале (если данные уже не достаточно близки к нормальному распределению).Обычно вычитается среднее значение и делится на стандартное отклонение для каждого признака.Вы можете проверить некоторые схемы в scikit-learn библиотеке , например.

5.Глубина

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

переобучения

Когда сеть переходит на данные, вы можете использовать некоторые методы регуляризации (трудно сказать, что может помочь, вам следует проверить их самостоятельно), некоторые из них включают:

  • Более высокая скорость обучения с пакетной нормализацией, сглаживающей пространство обучения.
  • Меньшее количество нейронов (взаимосвязи, изучаемые сетью, должны были бы интуитивно быть более репрезентативными для распределения данных).
  • Меньший размер партии также имеет эффект регуляризации.
  • Выпадение, хотя трудно определить хороший показатель отсева. Будет прибегать к нему, как последний. Кроме того, известно, что он сталкивается с методами пакетной нормализации (хотя существуют методы для их объединения, см. здесь или здесь , вы можете найти больше в Интернете).
  • регуляризация L1 / L2, причем вторая применяется гораздо более широко (если у вас нет специальных знаний, указывающих, что L1 может работать лучше)
  • Увеличение данных - я бы попробовал это сначала, в основном из-за любопытства. Поскольку ваши функции непрерывны, вы можете захотеть добавить некоторый случайный шум в зависимости от партии, генерируемой из распределения Гаусса. Уровень шума должен быть небольшим, стандартное отклонение около 1e-2 или 1e-3, вам придется проверить эти значения экспериментально.
  • Ранняя остановка - после N эпох без улучшения в проверочном наборе вы заканчиваете свое обучение. Довольно распространенная техника, должна использоваться практически каждый раз. Не забудьте сохранить лучшую модель на проверочном наборе и установить patience (N, упомянутый выше) на какое-то значение среднего размера (не устанавливайте терпение на 1 эпоху или около того, нейронная сеть может легко улучшиться через 5 или около того).

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

0 голосов
/ 29 апреля 2019

Все баллы Саймона велики, но другая возможная причина: вы перетасовываете свой набор данных?Если нет, и ваши данные содержат некоторую упорядоченную систематическую погрешность, ваша модель может настраиваться на один «конец» набора данных, только для плохой работы на другом «конце».

...