【发布时间】:2020-04-17 12:13:08
【问题描述】:
我想为我的神经网络实现一个自定义损失函数,以便同时考虑对抗性示例在训练期间的贡献,使用快速梯度符号法计算。
其中 J 是针对输入计算的经典分类交叉熵。而 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 的基础。你有什么建议吗?另外,你认为我走对了吗?
重要
当且仅当我从网络中移除嵌入层时,我才能计算梯度。但是问题是我无法训练我的嵌入,因此准确性不会增加。所以我需要嵌入层在网络中。
【问题讨论】:
标签: python tensorflow keras neural-network