我有使用 Keras 和 TensorFlow 对时尚 MNIST 进行分类,该分类遵循此教程。它使用 AdamOptimizer 查找使网络损失函数最小的模型参数值。网络的输入是一个形状为 [28, 28] 的 2-D 张量,输出是一个形状为 [10] 的 1-D 张量,这是 softmax 函数的结果。
网络训练好后,我想将优化器用于另一个任务:找到一个使输出张量的一个元素最大化的输入。如何做到这一点?是否可以使用 Keras 或必须使用更底层的 API?
由于对于给定的输出,输入不是唯一的,因此如果我们能够对输入可以取的值施加一些约束,那就更好了。
训练后的模型格式如下:
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
解决方案
答案 1
- 在输入层之后添加一个与输入维度相同的密集层,并将其设置为可训练。
- 冻结模型的所有其他层。(除了你添加的层)
- 将单位矩阵作为输入,并根据所需的输出训练模型。
这篇文章和你可能会有帮助,如果你想根据输入进行反向传播。这有点像你正在追求的目标,但你可以得到直觉。
答案 2
- 在训练完成后,我们需要首先指定输出并定义我们要最大化的损失函数:
from keras import backend as K
output_class = 0 # the index of the output class we want to maximize
output = model.layers[-1].output
loss = K.mean(output[:,output_class]) # get the average activation of our desired class over the batch
- 接下来,我们需要对我们定义的损失相对于输入层进行梯度:
grads = K.gradients(loss, model.input)[0] # the output of `gradients` is a list, just take the first (and only) element
- 接下来,我们需要定义一个后端函数,该函数获取初始输入图像并给出损失和梯度值作为输出,以便我们可以在下一步中使用它来实现优化过程:
func = K.function([model.input], [loss, grads])
- 最后,我们实现梯度上升优化过程:
import numpy as np
input_img = np.random.random((1, 28, 28)) # define an initial random image
lr = 1. # learning rate used for gradient updates
max_iter = 50 # number of gradient updates iterations
for i in range(max_iter):
loss_val, grads_val = func([input_img])
input_img += grads_val * lr # update the image based on gradients
答案 3
-
首先创建两个自定义层:
- 可训练输入
- 获取感兴趣的标签概率
-
然后,使用这些层构建新的模型,冻结中间层,并训练该模型以最大化感兴趣的标签的概率。
-
最后,检索可训练输入层的权重,这些权重对应于使感兴趣标签的概率最大的输入。
答案 4
-
将所有数据馈送至网络,并为每个样本保存 softmax 之后的输出层。
-
对于 3 个类,其中您想找到第 1 类最佳的输入,您正在寻找第一部分较高的输出。例如:[1 0 0]
-
实际上输出表示网络对样本属于某个类的概率或置信度。