我想用一个分类器实现一个对抗性网络,该分类器的输出连接到一个对手,该对手必须根据分类器的输出猜测分类器输入的特定特征(一个讨厌的参数)(详细描述这样的对抗网络可以在这篇论文中找到:learning to pivot with adversarial networks
然后将像这样训练模型:
- 批量训练对手(分类器将被固定)
- 冻结对手
- 训练整个模型,而对手被冻结在一个批次上
- 解冻对手
- 重复其他批次
- 随机播放并重复其他时期
在训练对手时,我希望损失函数是分类交叉熵,而在训练整个模型时,我希望它是分类器的损失函数(二元交叉熵损失)减去对手的损失乘以参数:L_c() - b * L_a()
.
我见过的大多数对抗性训练代码都是在 Keras 中使用 train_on_batch 进行训练的。但是,由于我已经用另一个顺序模型设置了很多代码,并且我想重用它,我想知道是否有办法实现这个模型并在 Keras 中使用 model.fit 对其进行训练。
我想做的是使用 Keras 功能 API 设置模型,分类器输入作为输入,分类器和对手输出作为输出。我还会将该模型编译为只有一个输出的对抗模型。例如:
classifier_input = Input(shape=(10,))
x = Dense(50, activation='tanh')(classifier_input)
x = Dense(25, activation='tanh')(x)
x = Dense(5, activation='tanh')(x)
classifier_output = Dense(1, activation='sigmoid')(x)
x = Dense(30, activation='tanh')(classifier_output)
x = Dense(15, activation='tanh')(x)
x = Dense(5, activation='tanh')(x)
adversary_output = Dense(3, activation='sgimoid')(x)
adversary = Model(inputs=classifier_input , outputs=adversary_output)
adversary.compile(optimizer='Adamax', loss='categorical_crossentropy', metrics=['accuracy'])
final_model = Model(inputs=classifier_input,outputs=[classifier_output,adversary_output])
final_model.compile(optimizer='Adamax',
loss=['binary_crossentropy', 'categorical_crossentropy'],
loss_weights=[1.0, -0.1], metrics=['accuracy'])
然后我想在 on_batch_begin 中设置一个回调来训练对手(在冻结分类器中的层之后),然后使用 model.fit 代码完成对 final_model 的训练(我将冻结对手并解冻分类器层on_batch_begin 就在 final_model 的训练开始之前)。
但是后来我不知道是否可以将当前批次作为参数传递给 on_batch_begin。我是否必须在回调中设置自己的批次,还是可以通过 model.fit 传递批次?
有没有更好的方法在仍然使用 model.fit 的同时进行对抗训练?