Я хотел бы реализовать пользовательскую функцию потерь для своей нейронной сети, чтобы учесть также влияние состязательных примеров во время обучения, вычисленных с помощью метода быстрого градиентного знака.
![Custom Loss Function](https://i.stack.imgur.com/O5v7Q.png)
, где J - это классическая c категориальная кросс-энтропия, рассчитанная по входам. И x + delta является примером состязательности.
Структура сети
Более подробно моя сеть выглядит следующим образом :
sentence = Input(shape=(story_maxlen,))
encoded_sentence = Embedding(vocab_size, embed_size, input_length=story_maxlen)(sentence)
question = Input(shape=(query_maxlen,))
encoded_question = Embedding(vocab_size, embed_size, input_length=query_maxlen)(question)
merged = concatenate([encoded_sentence, encoded_question], axis=1)
answer = LSTM(lstm_size, return_sequences=True)(merged)
answer = Dense(mlp_size, activation='tanh')(merged)
answer = Dropout(dropout_rate)(answer)
answer = Flatten()(answer)
answer = Dense(vocab_size, activation='softmax')(answer)
model = Model([sentence, question], answer)
model.compile(optimizer="adam", loss=my_loss_wrapper([sentence,question]), metrics=['accuracy'])
А затем моя пользовательская функция потерь с функцией генерирования альтернативных примеров:
def generate_advers(model, epsilon):
x1 = input_tensor[0]
x2 = input_tensor[1]
answer = y_true
x1 = tf.Variable(x1)
x2 = tf.Variable(x2)
with tf.GradientTape() as tape:
tape.watch([x1, x2])
proba = model([x1, x2])
loss = K.categorical_crossentropy(answer, proba[0])
# Get the gradients of the loss w.r.t to the input.
gradient = tape.gradient(loss, [x1, x2])
g1 = gradient[0]
g2 = gradient[1]
signed_grad_st = tf.sign(g1)
signed_grad_qu = tf.sign(g2)
delta_1 = tf.multiply(signed_grad_st, epsilon)
delta_2 = tf.multiply(signed_grad_qu, epsilon)
x1_adv = tf.add(x1, delta_1)
x2_adv = tf.add(x2, delta_2)
proba_adv = model([x1_adv, x2_adv])
loss_advers = K.categorical_crossentropy(label, proba_adv[0])
return loss_advers
def my_loss_wrapper(input_tensor):
def my_loss(y_true, y_pred):
alpha = 0.05
alpha_compl = 1.0 - alpha
epsilon = 0.15
loss_advers = generate_advers(model, epsilon)
loss_advers = alpha_compl*loss_advers
loss_true = K.categorical_crossentropy(y_true, y_pred)
loss_true = alpha*loss_true
total = loss_true + loss_advers
return total
return my_loss
Предоставление того, что мой ввод является закодированным вектором словарных индексов в форме:
[1,5,4,3,6,9...]
Я не понимаю, как вычислить градиент потерь по отношению к входу (он всегда отсутствует), что является фундаментальным для реализации FGSM. Есть ли у вас какие-либо предложения? Кроме того, как вы думаете, я на правильном пути?
Важно
Я могу вычислить градиент, если и только если я удалить Уровень встраивания из сети. Но тогда проблема в том, что я не могу тренировать свои вложения, и поэтому точность не увеличивается. Поэтому мне нужно, чтобы слой Embedded был в сети.