Fisher信息量检测对抗样本代码详解

2022 年 7 月 3 日 PaperWeekly


©PaperWeekly 原创 · 作者 | 鬼谷子




引言

在上一篇《Fisher信息量在对抗样本中的应用》中详尽地阐述了 Fisher 信息量在对抗攻击,防御,以及检测中的应用,并解析了三篇具有代表性的论文。Fisher 信息量是可以用来去挖掘深度学习模型对抗行为的深层原因的非常好用一个数学工具。

本文主要基于用 Fisher 信息量去检测对抗样本的一篇论文《Inspecting adversarial examples using the Fisher information》的代码进行深度解析,该论文提出了三个指标对对抗样本进行检测分别是 Fisher 信息矩阵迹,Fisher 信息二次型和 Fisher 信息敏感度。本文会对论文中直接给出的结果的中间证明过程进行补充,而且代码中一些重要的关键细节也会在对应的章节中有所说明。




Fisher信息矩阵迹
给定输入样本 ,神经网路的输出一个 维概率向量 ,则关于神经网络参数 的 Fisher 信息矩阵的连续形式和离散形式如下所示:


其中可知 。需要注意的是,计算一个非常小规模的神经网络,Fisher 信息矩阵的计算量 也是棘手的,更何况是那些动辄就上亿的参数量规模的神经网络,计算量更加庞大。因为原论文目的是只关注检测对抗样本,不需要详细计算 Fisher 信息矩阵中每个精确值,给定样本 Fisher 信息量的一个取值范围即可作为检测的指标,所以论文中采用 Fisher 信息矩阵的迹作为检测指标,具体计算公式如下所示:



要知道理论分析和实际编程总会有一些出入,在以上公式推导中,是将神经网络里的所有权重参数当成一个一维参数向量来考虑,但实际编程中时,神经网络的参数是按层排序的,不过当在求解Fisher信息量的时候,这两种情况时一致的。假设有一个四隐层的神经网络,参数分别是 ,则对应的参数和梯度如下所示:


进一步可知两种情况下 Fisher 信息矩阵的迹相等:



此时可以发现使用反向传播计算 Fisher 信息矩阵的迹的计算量为 ,要远远小于计算 Fisher 信息矩阵的计算量




Fisher信息二次型

矩阵 的迹可以写成 ,其中 为单位向量,即第 个元素为 ,其余元素为 ,这可以理解为 散度对每个参数变化的平均值。受此启发,作者可以选择一个特定的方向和度量,而不是在完全正交的基础上求平均值,即有如下二次型:


其中给定的向量 与参数 和数据点 有关:



当对 进行归一化时,则有如下二次型:



这里需要注意的是选取的方向并不唯一,如果想让二次型的取值达到最大,则是 Fisher 矩阵的最大特征值,选取的方向为在最大特征值对应的特征向量。需要指明一点的是,Fisher 矩阵的迹要大于 Fisher 矩阵的最大特征值,具体证明如下所示:



其中 为矩阵 的特征对角矩阵, 为单位正交矩阵。在具体的实际编程中,为了简化计算,会利用有限差分计算来估计反向传播求梯度的结果,由泰勒公式可知:



进而则有:





Fisher信息敏感度

为了进一步获得可利用的 Fisher 信息量,作者在输入样本中随机引入一个单随机变量 ,即有:

其中  ,并且 有相同的维度。对于这个被扰动的输入 ,对其 Fisher 信息矩阵为:



其中 ,该矩阵的第 行,第 列的元素可以表示为:



又因为 的第 行,第 列的元素为:



则有泰勒展开式可知:



其中上公式的第二项 矩阵可以表示为:



又因为 是一个均值为 ,方差为 的随机变量,进而则有:



综合以上推导结果,则有:



最后可以得到与论文中相同的结果:


与上一节求 Fisher 矩阵二次型一样,作者也对扰动样本 的 Fisher 矩阵求二次型,则有:
其中:

假如给定的扰动向量 是单位向量 ,即 。在实际编程中利用有限差分来估计反反向传播求梯度的结果,进而则有:



以上公式在论文中被称为 Fisher 信息敏感度(FIS),它主要用于评估第 个输入节点的重要性。




代码示例

Fisher 信息矩阵的迹,Fisher 信息二次型以及 Fisher 信息敏感度的代码示例和实验结果如下所示,对应上文的原理介绍,可以更好的理解代码示例中相关原理的实现细节。

import torch
import torch.nn.functional as F
from copy import deepcopy


class FISHER_OPERATION(object):
        def __init__(self, input_data, network, vector, epsilon = 1e-3):
                self.input = input_data
                self.network = network
                self.vector = vector
                self.epsilon = epsilon

        # Computes the fisher matrix quadratic form along the specific vector
        def fisher_quadratic_form(self):
                fisher_sum = 0
                ## Computes the gradient of parameters of each layer
                for i, parameter in enumerate(self.network.parameters()):
                        ## Store the original parameters
                        store_data = deepcopy(parameter.data)
                        parameter.data += self.epsilon * self.vector[i]
                        log_softmax_output1 = self.network(self.input)
                        softmax_output1 = F.softmax(log_softmax_output1, dim=1)
                        parameter.data -= 2 * self.epsilon * self.vector[i]
                        log_softmax_output2 = self.network(self.input)
                        solfmax_output2 = F.softmax(log_softmax_output2, dim=1)
                        parameter.data = store_data
                        # The summation of finite difference approximate
                        fisher_sum += (((log_softmax_output1 - log_softmax_output2)/(2 * self.epsilon))*((softmax_output1 - solfmax_output2)/(2 * self.epsilon))).sum()
                return fisher_sum


        # Computes the fisher matrix trace
        def fisher_trace(self):
                fisher_trace = 0
                output = self.network(self.input)
                output_dim = output.shape[1]
                parameters = self.network.parameters()
                ## Computes the gradient of parameters of each layer
                for parameter in parameters:
                        for j in range(output_dim):
                                self.network.zero_grad()
                                log_softmax_output = self.network(self.input)
                                log_softmax_output[0,j].backward()
                                log_softmax_grad = parameter.grad
                                self.network.zero_grad()
                                softmax_output = F.softmax(self.network(self.input), dim=1)
                                softmax_output[0,j].backward()
                                softmax_grad = parameter.grad
                                fisher_trace += (log_softmax_grad * softmax_grad).sum()
                return fisher_trace


        # Computes fisher information sensitivity for x and v.
        def fisher_sensitivity(self):
                output = self.network(self.input)
                output_dim = output.shape[1]
                parameters = self.network.parameters()
                x = deepcopy(self.input.data)
                x.requires_grad = True
                fisher_sum = 0
                for i, parameter in enumerate(parameters):
                        for j in range(output_dim):
                                store_data = deepcopy(parameter.data)
                                # plus eps
                                parameter.data += self.epsilon * self.vector[i]
                                log_softmax_output1 = self.network(x)
                                log_softmax_output1[0,j].backward()
                                new_plus_log_softmax_grad = deepcopy(x.grad.data)
                                x.grad.zero_()
                                self.network.zero_grad()
                                softmax_output1 = F.softmax(self.network(x), dim=1)
                                softmax_output1[0,j].backward()
                                new_plus_softmax_grad = deepcopy(x.grad.data)
                                x.grad.zero_()
                                self.network.zero_grad()
                                # minus eps
                                parameter.data -= 2 * self.epsilon * self.vector[i]
                                log_softmax_output2 = self.network(x)
                                log_softmax_output2[0,j].backward()
                                new_minus_log_softmax_grad = deepcopy(x.grad.data)
                                x.grad.zero_()
                                self.network.zero_grad()
                                softmax_output2 = F.softmax(self.network(x), dim=1)
                                softmax_output2[0,j].backward()
                                new_minus_softmax_grad = deepcopy(x.grad.data)
                                x.grad.zero_()
                                self.network.zero_grad()
                                # reset and evaluate
                                parameter.data = store_data
                                fisher_sum += 1/(2 * self.epsilon)**2 * ((new_plus_log_softmax_grad - new_minus_log_softmax_grad)*(new_plus_softmax_grad - new_minus_softmax_grad))
                return fisher_sum

import torch
import torch.nn as nn
import fisher

network = nn.Sequential(
                nn.Linear(15,4),
                nn.Tanh(),
                nn.Linear(4,3),
                nn.LogSoftmax(dim=1)
    )
epsilon = 1e-3
input_data = torch.randn((1,15))
network.zero_grad()
output = network(input_data).max()
output.backward()
vector = []
for parameter in network.parameters():
    vector.append(parameter.grad.clone())

FISHER = fisher.FISHER_OPERATION(input_data, network, vector, epsilon)
print("The fisher matrix quadratic form:", FISHER.fisher_quadratic_form())
print("The fisher matrix trace:", FISHER.fisher_trace())
print("The fisher information sensitivity:", FISHER.fisher_sensitivity())



更多阅读




#投 稿 通 道#

 让你的文字被更多人看到 



如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。


总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 


PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析科研心得竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。


📝 稿件基本要求:

• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注 

• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题

• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算


📬 投稿通道:

• 投稿邮箱:hr@paperweekly.site 

• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者

• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿


△长按添加PaperWeekly小编




🔍


现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧


·

登录查看更多
0

相关内容

对抗样本由Christian Szegedy等人提出,是指在数据集中通过故意添加细微的干扰所形成的输入样本,导致模型以高置信度给出一个错误的输出。在正则化背景下,通过对抗训练减少原有独立同分布的测试集的错误率——在对抗扰动的训练集样本上训练网络。 对抗样本是指通过在数据中故意添加细微的扰动生成的一种输入样本,能够导致神经网络模型给出一个错误的预测结果。 实质:对抗样本是通过向输入中加入人类难以察觉的扰动生成,能够改变人工智能模型的行为。其基本目标有两个,一是改变模型的预测结果;二是加入到输入中的扰动在人类看起来不足以引起模型预测结果的改变,具有表面上的无害性。对抗样本的相关研究对自动驾驶、智能家居等应用场景具有非常重要的意义。
【多伦多大学博士论文】深度学习中的训练效率和鲁棒性
专知会员服务
47+阅读 · 2021年9月9日
专知会员服务
42+阅读 · 2020年7月7日
[CVPR 2020-港中文-MIT] 神经架构搜索鲁棒性
专知会员服务
25+阅读 · 2020年4月7日
2020图机器学习GNN的四大研究趋势,21篇论文下载
专知会员服务
135+阅读 · 2020年2月10日
一文详解基于流的深度生成模型
PaperWeekly
1+阅读 · 2022年7月7日
对抗子空间维度探讨
PaperWeekly
0+阅读 · 2022年2月13日
一文详解Vision Transformer(附代码)
PaperWeekly
4+阅读 · 2022年1月19日
矩阵视角下的Transformer详解(附代码)
PaperWeekly
3+阅读 · 2022年1月4日
一文搞懂反向传播
机器学习与推荐算法
18+阅读 · 2020年3月12日
详解常见的损失函数
七月在线实验室
20+阅读 · 2018年7月12日
论文浅尝 | 用可微的逻辑规则学习完成知识库推理
开放知识图谱
14+阅读 · 2018年7月5日
徒手实现CNN:综述论文详解卷积网络的数学本质
机器之心
25+阅读 · 2017年11月19日
神经网络bp算法推导
统计学习与视觉计算组
11+阅读 · 2017年11月17日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
3+阅读 · 2014年12月31日
国家自然科学基金
2+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
Arxiv
0+阅读 · 2022年9月4日
Arxiv
0+阅读 · 2022年9月2日
Arxiv
11+阅读 · 2018年1月18日
VIP会员
相关VIP内容
【多伦多大学博士论文】深度学习中的训练效率和鲁棒性
专知会员服务
47+阅读 · 2021年9月9日
专知会员服务
42+阅读 · 2020年7月7日
[CVPR 2020-港中文-MIT] 神经架构搜索鲁棒性
专知会员服务
25+阅读 · 2020年4月7日
2020图机器学习GNN的四大研究趋势,21篇论文下载
专知会员服务
135+阅读 · 2020年2月10日
相关资讯
一文详解基于流的深度生成模型
PaperWeekly
1+阅读 · 2022年7月7日
对抗子空间维度探讨
PaperWeekly
0+阅读 · 2022年2月13日
一文详解Vision Transformer(附代码)
PaperWeekly
4+阅读 · 2022年1月19日
矩阵视角下的Transformer详解(附代码)
PaperWeekly
3+阅读 · 2022年1月4日
一文搞懂反向传播
机器学习与推荐算法
18+阅读 · 2020年3月12日
详解常见的损失函数
七月在线实验室
20+阅读 · 2018年7月12日
论文浅尝 | 用可微的逻辑规则学习完成知识库推理
开放知识图谱
14+阅读 · 2018年7月5日
徒手实现CNN:综述论文详解卷积网络的数学本质
机器之心
25+阅读 · 2017年11月19日
神经网络bp算法推导
统计学习与视觉计算组
11+阅读 · 2017年11月17日
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
3+阅读 · 2014年12月31日
国家自然科学基金
2+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
1+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
Top
微信扫码咨询专知VIP会员