Keras: частичное обратное распространение для энкодера - PullRequest
0 голосов
/ 27 мая 2019

Обзор

Привет, в настоящее время я пытаюсь построить модель рекомендательной системы авто-кодировщика, используя keras (я не уверен, что использую Tensorflow), в настоящее время застряла причина Я не могу заставить keras сделать частичное обратное распространение. (Пожалуйста, помогите с кодом, если это возможно, или примеры из других источников) .

Как работает AutoEnc RecSys

Идея системы состоит в том, чтобы подавать высокоуровневые данные оценки (функция 4k +) с набором нулей («еще не проверенных») в кодировщик, а затем декодировать их обратно в исходное измерение. Ранее введенный ноль будет изменен на некоторое число, и это число будет действовать как результат прогнозирования.

Проблема в

Когда вы подаете пачку нулей в кодировщик, кодировщик научится выводить как множество нулей, так и вывод ( они думают, что входные 0 - это целевой выход, который не является ожидаемым результатом ) (0 означает непредсказуемый / не оцененный).

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

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

Есть ли способ, чтобы керасы не делали подпорку на весах, введенных нулями?

Аналогично выпадению, но это не случайно, вместо этого отключите узел / вес, если вход для этого узла равен нулю)

Я пытался искать кучу страниц, в основном, с помощью Tensorflow и создать собственную функцию градиента. Некоторые другие предлагают просто использовать маску, поскольку нулевые потери = нулевые градиенты = отсутствие обратного распространения, но это работает только для предсказания одного числа, в то время как моя система будет возвращать данные высокой размерности (то же измерение, что и входные данные).

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

Некоторые детали: AutoEncoder Architechture: https://prnt.sc/ntzmbf

Моя модель:

from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LeakyReLU

model = Sequential()
model.add(Dense(128, input_shape=(4000,)))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(4000, activation="softmax"))

Пользовательская функция потери (замаскированная)

import keras.backend as K

# Custom MSE (only calculate loss from non-masked value)
def masked_mse(mask_value):

    def f(y_true, y_pred):
        mask_true = K.cast(K.not_equal(y_true, mask_value), K.floatx())
        masked_squared_error = K.square(mask_true * (y_true - y_pred))
        masked_mse = K.sum(masked_squared_error, axis=-1) / K.sum(mask_true, axis=-1)
        return masked_mse

    f.__name__ = 'Masked MSE (mask_value={})'.format(mask_value)
    return f
model.compile(optimizer='adam', loss=masked_mse(0))
model.fit(X_train.values, X_train.values,
          validation_data=(X_val.values, X_val.values),
          epochs=100,
          batch_size=128,
          verbose=1,
          )
Input example :   [3, 0,   0, 0,   1, 0, ..., 2, 1]
Expected output : [3, 0.1, 2, 0.3, 1, 1, ..., 2, 1]

СПАСИБО:)

...