CNN是现在非常流行的模型。在很多图像检索问题中,CNN模型的效果在过去的基础上有了很大的提升,但是CNN毕竟还没有彻底解决这些问题,CNN还是有自己的弱点。这个弱点不能算是它特有的问题,但是因为它的效果实在是太好了,所以很多人甚至迷信了它,所以这盆冷水就泼在了它身上。大神们看到了CNN模型的强大,却忍不住发问:难道CNN有什么问题吗?比如我们用CNN搭建人脸识别模型,在训练数据集和测试数据集上都表现不错。很好,但是会不会有一些用例它会误判,我们可以找到生成这些用例的模式吗?我们可以想象一下,如果我们对之前识别正确的数据稍作改动,可能还是会被正确识别。所以我们有一个计划。每次我们对图像做一点改变,我们都会把图像传给CNN进行测试,然后看CNN的预测结果有没有变化。如果没有变化,我们将保存图像,然后让我们进行下一轮更改。经过几轮修改后,我们输出生成的图像,看看图像会是什么样子。这里我们以MNIST为例,以下是我们的修改方案:使用MNIST训练集训练一个CNN模型,我们的CNN模型结构为:conv32*3*3->relu->maxpool2*2->conv64*3*6->relu->maxpool2*2->fc256->dropout0.5->fc10。找一个训练数据,把它的数据范围限制在0到1之间。我们对每个像素随机增减一个-0.1到0.1之间的数,从而得到64张随机图像,然后通过CNN模型进行预测。这64张图像的预测标签,从中选择具有相同原始标签的图像。经过几轮迭代,我们可以看到这个随机变化的数字变成了什么。我们选择一个数字0:经过50次迭代,我们得到这张图片:经过100次迭代,我们得到这张图片:经过150次迭代,我们得到这张图片:经过200次迭代,我们得到这样一张图片:到目前为止,可以看到那数字依旧依稀可见,但实际上图像已经变得模糊,其中混入了很多乱七八糟的信息,与原来的数字完全不同。这个套路叫“忽悠CNN”,东北话就是忽悠。继续迭代,我们可以生成更精彩的图像。当然,这只是愚弄CNN模型的一种方式,我们还有其他的方式来生成图像。其他方法这里不再介绍。对于这种忽悠,大神们也给出了机器学习相关的解释:CNN模型毕竟还是判别模型。如果我们设图像为X,标签为y,CNN模型就相当于找到p(y|X)的值。判别模型相当于描述“这个标签的图像是怎样的图像”,而满足这些条件的图像有时并不是真正带有标签的图像。而上面的闪烁套路就是利用了这个漏洞。在上面的例子中,我们使用这种傻瓜方法来保留原始标签的模糊图像,我们也可以让CNN将非模糊图像误认为是另一个标签。比如下图经过40轮迭代后识别为6:这些套路的出现让我们对CNN有了一点警惕。如果想让CNN完全hold住手写数字,还需要其他方法来辅助。否则,这样的事故总会发生。那么有没有办法解决这个问题呢?
