У меня есть данные машинного обучения с бинарными функциями. Как я могу заставить автоэнкодер возвращать двоичные данные? - PullRequest
0 голосов
/ 20 мая 2019

У меня есть набор данных следующего вида: серия из М наблюдений N-мерных данных.Для того, чтобы получить скрытые факторы из этих данных, я хочу создать отдельный автокодер скрытого слоя, обученный этим данным.Каждое измерение одного наблюдения - это либо 0, либо 1. Но модель keras возвращает значения с плавающей точкой.Есть ли способ добавить слой для принудительного ввода 0 или 1 в качестве выходных данных?

Я пытался использовать простую модель keras для решения этой проблемы.Он требует хорошей точности данных, но при просмотре необработанных данных он правильно предсказывает 0 и часто полностью игнорирует 1. 1. 1003 *

n_nodes = 50
input_1 = tf.keras.layers.Input(shape=(x_train.shape[1],))
x = tf.keras.layers.Dense(n_nodes, activation='relu')(input_1)
output_1 = tf.keras.layers.Dense(x_train.shape[1], activation='sigmoid')(x)

model = tf.keras.models.Model(input_1, output_1)
my_optimizer = tf.keras.optimizers.RMSprop()
my_optimizer.lr = 0.002
model.compile(optimizer=my_optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=10000)
predictions = model.predict(x_test)

Эти наблюдения я затем проверяю, просматривая все эксперименты и проверяя,большое (> 0,1) значение возвращается для элементов, которые равны 1. Производительность очень низкая на 1.

Я видел, что потери сходятся около 10000 эпох.Однако автоэнкодер не может правильно предсказать почти все 1 в наборе данных.Даже при задании ширины скрытого слоя, равной размерности данных (n_nodes = x_train.shape[1]), автоэнкодер все еще дает плохую производительность, даже ухудшаясь, если я увеличиваю ширину скрытого слоя.

1 Ответ

0 голосов
/ 20 мая 2019

[0, 1] выходные данные, как правило, должны быть округлены таким образом, чтобы> = 0,5 округлялось до 1 при выводе окончательного прогноза и <0,5 округлялось до 0. Однако ваши метки должны быть значениями с плавающей запятой <code>{0.0, 1.0} для функции потерь (которую я ожидаю, что они уже). Вы можете вычислить точность, округлив выходные данные и сравнив их с двоичными метками, чтобы подсчитать ошибки для {0, 1}, но они должны быть в форме [0.0, 1.0], чтобы расчеты потерь и градиентов работали.

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

1) Ваш плотный слой "сужения" должен быть значительно меньше, чем ваш ввод. Делая его меньше, вы заставляете авто-кодер запоминать типичную форму ввода, которую можно использовать для вывода. Эта репрезентативная форма, вероятно, хорошо обобщает. Если вы увеличите размер скрытого слоя, сеть будет иметь гораздо больше возможностей для запоминания входных данных.

2) У вас может быть гораздо больше 0 значений, чем 1 значений, если это так, то при отсутствии фактического обучения сеть может застрять, просто прогнозируя 0 как «лучшее предположение», потому что это «обычно» право". Это более сложная проблема. Вы можете подумать о том, чтобы умножить потери на вектор labels * eta + 1, это эффективно увеличит скорость обучения меток. Пример: ваши метки [0, 1, 0], eta - это значение гиперпараметра> 1, скажем, eta = 2.0. labels * eta = [1.0, 3.0, 1.0], который увеличивает градиент сигнала на 1 значение, увеличивая потери только на 1. Это не пуленепробиваемый метод повышения важности класса 1, но попробовать это просто. Если это приведет к какому-либо улучшению, проследите за этим рассуждением более подробно.

3) У вас есть 1 скрытый слой, что означает, что вы ограничены линейными отношениями, вы можете попробовать 3 скрытых слоя, чтобы добавить немного нелинейности. Ваш центральный слой должен быть довольно маленьким, попробуйте что-то вроде 5 или 10 нейронов, ему нужно сжать данные в довольно узкую точку сужения, чтобы извлечь представление общего назначения.

...