神经网络的显著性地图(使用Keras)

11

我有一个在Keras中训练好的全连接多层感知器。我将N维特征向量输入它,它会为输入向量预测M个类别中的一个。训练和预测都很顺利。现在我想分析哪一部分输入特征向量实际上是导致某个特定类别的原因。
例如,假设有两个类别A和B,以及一个输入向量f。向量f属于类别A,网络正确地预测了它 - 网络的输出是A=1 B=0。由于我拥有一些领域知识,我知道整个f并不是f属于A的原因,只有f内部的某个部分才是负责这一点的原因。我想知道神经网络是否已经捕捉到了这一点。如果将其类比为图像,则如果一幅图像I中有一只猫(带有一些草地背景),并且经过训练的网络能够正确地预测出来,则该网络必须知道整幅图像并不是一只猫;网络内部知道猫在图像中的位置。同样,在我的情况下,网络知道f的哪一部分使它属于类别A。我想知道那部分是什么。

我搜索了一下,相信我想做的是为我的网络找到显著性图,针对给定的输入。我理解得正确吗?
如果我理解正确,那么显著性图就是简单的(输出变化)/(输入变化),可以通过一次反向传播操作来找到,其中我找到了关于输入的导数。
我在Keras中找到了以下代码片段,但我不太确定它是否正确:

   inp = model.layers[0].get_input()
   outp = model.layers[-1].get_output()
   max_outp = T.max(outp, axis=1)
   saliency = theano.grad(max_outp.sum(), wrt=inp)
在上面的代码中,当计算梯度时,反向传播实际上是否发生了?输出是输入的非线性函数,因此找到梯度的唯一方法是执行反向传播。但在上面的代码中,没有任何连接theano和网络的东西,那么theano如何在这里“知道”网络呢?据我所知,使用Theano计算梯度时,我们首先根据输入和输出来定义函数。因此,theano必须知道那个非线性函数是什么。我不认为在上面的代码片段中是这样的。。 更新:上面的代码无法工作,因为我有一个完全连接的MLP。它会给出一个错误,说“Dense对象没有get_output()”。我有以下Keras函数,用于计算给定输入的网络输出。现在我想找到该函数相对于输入的梯度:
    get_output = K.function([self.model.layers[0].input],[self.model.layers[-1].output])

你使用的Keras版本是哪个? - Marcin Możejko
1个回答

7
我找到了解决方案:
    get_output = theano.function([model.layers[0].input],model.layers[-1].output,allow_input_downcast=True)
    fx = theano.function( [model.layers[0].input] ,T.jacobian(model.layers[-1].output.flatten(),model.layers[0].input), allow_input_downcast=True)
    grad = fx([input_feature])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接