Как определить пользовательские потери в Keras с различными значениями? - PullRequest
0 голосов
/ 25 марта 2020

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

My AE определяется следующим образом:

input_fts = Input(shape=(self.input_length,), name='ae_input')

encoded = Dense(1826, activation='relu', name='e_dense1')(input_fts)
encoded = Dense(932, activation='relu', name='e_dense2')(encoded)
encoded = Dense(428, activation='relu', name='e_dense3')(encoded)

encoded = Dropout(0.1)(encoded)
code = Dense(self.encoding_length, activation='relu', name='code')(encoded)

decoded = Dense(428, activation='relu', name='d_dense4')(code)
decoded = Dense(932, activation='relu', name='d_dense5')(decoded)
decoded = Dense(1826, activation='relu', name='d_dense6')(decoded)
output_fts = Dense(self.output_length, activation='relu', name='ae_output')(decoded)

ae = Model(inputs=input_fts, outputs=output_fts)
ae.compile(optimizer='adam', loss=ModelFactory.custom_loss(code, self.S, self.lambda_), metrics=['mae', 'acc'])

Моя потеря:

@staticmethod
def custom_loss(layer, S, lambda_):
    def loss(y_true, y_pred):
        return K.mean(K.square(y_pred - y_true), axis=-1) + lambda_ * K.mean(K.square(layer - S[0, :]), axis=-1)

    return loss

Это работает, но это не совсем то, что я хочу. Я хочу, чтобы пример в S был выбран на основе того, какой пример был оценен в то время, поэтому S [0,:] будет S [i,:], где «i» - это индекс примера.

Переменная «слой» представляет собой тензор формы [Нет, 312]. Переменная S представляет собой массив NumPy o формы [1194, 312], где 1194 - количество примеров, которые у меня есть в моем тренировочном наборе. Я догадывался, что мне пришлось преобразовать S в тензор какого-то типа. Поэтому я попытался:

self.S = K.variable(S)

И изменил custom_loss на:

... lambda_ * K.mean(K.square(layer - S), axis=-1)

Теперь проблема в том, что я получаю несоответствие формы между моей партией и S:

tensorflow.python.framework.errors_impl.InvalidArgumentError:  Incompatible shapes: [128] vs. [1194]

Обучение AE настроено следующим образом:

self.model.fit(x_train, x_train, epochs=nepochs, batch_size=128, shuffle=True, verbose=1,
                                      validation_split=0.2, callbacks=[classification])

Как настроить S в зависимости от размера партии?

1 Ответ

0 голосов
/ 25 марта 2020

Если я правильно понимаю, S - это просто еще один вход в вашу модель. В этом случае вы можете добавить второй входной слой для S и передать S в модель во время обучения. Это будет выглядеть примерно так:

input_fts = Input(shape=(self.input_length,), name='ae_input')
S_in = Input(shape=(312,), name='s_input')

encoded = Dense(1826, activation='relu', name='e_dense1')(input_fts)
encoded = Dense(932, activation='relu', name='e_dense2')(encoded)
encoded = Dense(428, activation='relu', name='e_dense3')(encoded)

encoded = Dropout(0.1)(encoded)
code = Dense(self.encoding_length, activation='relu', name='code')(encoded)

decoded = Dense(428, activation='relu', name='d_dense4')(code)
decoded = Dense(932, activation='relu', name='d_dense5')(decoded)
decoded = Dense(1826, activation='relu', name='d_dense6')(decoded)
output_fts = Dense(self.output_length, activation='relu', name='ae_output')(decoded)

ae = Model(inputs=[input_fts, S_in], outputs=output_fts)

ae.add_loss(self.lambda_ * K.mean(K.square(S_in-code)))
ae.add_loss(K.mean(K.square(input_fts - output_fts)))

ae.compile(optimizer='adam')

Затем вы передадите свой обычный ввод и S для прогнозирования с помощью списков (см. https://keras.io/getting-started/functional-api-guide/).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...