5 白盒攻击算法

1 对抗样本的基本原理

从数学角度来描述对抗样本,输入数据为x,分类器为f,对应的分类结果表示为f(x)。假设存在一个非常小的扰动 ϵ \epsilon ϵ,使得:
f ( x + ϵ ) ≠ f ( x ) f(x+\epsilon)\ne f(x) f(x+ϵ)=f(x)

即分类结果发生了改变,那么 x + ϵ x+\epsilon x+ϵ就是一个对抗样本。

以一个例子来说明对抗样本的基本原理:

from sklearn import datasets
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
import torch
from torch import nn
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

device='cuda' if torch.cuda.is_available() else 'cpu'
print('the device used is: ',device)

n_features=1000
x,y=datasets.make_classification(n_samples=4000,n_features=n_features,n_classes=2,random_state=0)
x=MinMaxScaler().fit_transform(x)
x=torch.from_numpy(x).to(device)
y=torch.from_numpy(y).to(device)

class TestDatasets(Dataset):
  def __init__(self,x,y):
    self.x=x
    self.y=y
    
  def __len__(self):
    return x.shape[0]
  
  def __getitem__(self,idx):
    data=self.x[idx]
    label=self.y[idx]
    return data,label

class TestNetwork(nn.Module):
  def __init__(self):
    super(TestNetwork,self).__init__()
    self.layer1=nn.Linear(1000,2)
  def forward(self,x):
    x=self.layer1(x)
    return x
    
def train_loop(dataloader,model,loss_fn,optimizer):
  size=len(dataloader.dataset)
  for batch,(x,y) in enumerate(dataloader):
    pred=model(x)
    loss=loss_fn(pred,y)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    loss=loss.item()
    print('bach is: ',batch,' loss is: ',loss)

model=TestNetwork().to(device).to(torch.float64)

logits=model(x)
pred_probab=nn.Softmax(dim=1)(logits)
y_pred=pred_probab.argmax(1)
print(y_pred)

training_data=TestDatasets(x,y)
train_dataloader=DataLoader(training_data,batch_size=32,shuffle=True)


loss_fn=nn.CrossEntropyLoss()
learning_rate=1e-3
batch_size=64
epochs=1000
optimizer=torch.optim.SGD(model.parameters(),lr=learning_rate)

for i in range(epochs):
  print('start the ',i,' epochs')
  train_loop(train_dataloader,model,loss_fn,optimizer)

for i in range(10):
  data,label=training_data[i]
  logits=model(data)
  pred_probab=nn.Softmax()(logits)
  y_pred=pred_probab.argmax()
  print('the predicted label is: ',logits,' the truth is: ',label)

通过datasets库可以随机生成样本数据,其中n_samples表示生成的对抗样本数量,n_features为每个样本的特征数,n_classes表示生成的样本对应的标签的种类数,random_state为随机种子值。在上面的例子中我们生成4000个维度(即特征数量)为1000的样本,标签种类只有两种。

4 FGM FGSM算法

4.1 FGM FGSM基本原理

这个算法在《Explaining and Harnessing Adversarial Examples》论文中提出,可以作为无定向攻击和定向攻击算法使用。假设图片原始数据为 x x x,图片识别的结果为 y y y,原始图像上叠加细微的变化 η \eta η,数学公式表示如下:

x ~ = x + η \tilde{x}=x+\eta x~=x+η

将修改后的图像输入分类模型中, x x x与参数矩阵 ω T \omega^T ωT相乘:

ω T x ~ = ω T x + ω T η \omega^T\tilde{x}=\omega^Tx+\omega^T\eta ωTx~=ωTx+ωTη

对分类结果的影响还要受到激活函数的作用,攻击样本的生成过程就是追求以微小的修改,通过激活函数的作用,对分类结果产生最大化的变化。Goodfellow指出,如果我们的变化量与梯度的变化方向完全一致,那么将会对分类结果产生较大的变化(sign函数可以保证与梯度方向一致???)。

η = sign ( ω ) \eta=\text{sign}(\omega) η=sign(ω)

x x x的维数为 n n n时,模型的参数在每个维度的平均值为 m m m η \eta η的无穷范数为 ϵ \epsilon ϵ,每个维度的微小修改与梯度函数方向一致,累计的效果为 n m ϵ nm\epsilon nmϵ。当数据的维度 n n n很大时,虽然 η \eta η非常小,但是累计的效果可以较大,该效果作用到激活函数上,有可能对分类结果产生较大影响。

4.2 使用Pytorch实现FGM
device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')

img.requires_grad=True

for param in model.parameters():
	param.requires_grad=False

optimizer=torch.optim.Adam([img])
loss_func=torch.nn.CrossEntropyLoss()

epochs=100
e=0.001

target=288
target=Variable(torch.Tensor([float(target)]).to(device).long())

for epoch in range(epochs):
	output=model(img)
	loss=loss_func(output,target)
	label=np.argmax(output.data.cpu().numpy())

	print("epoch={} loss={} label={}".format(epoch,loss,label))

	if(label==target):
		print("success")
		break
	
	optimizer.zero_grad()
	loss.backward()

	img.data=img.data=e*torch.sign(img.grad.data)

5 DeepFool算法

5.1 DeepFool基本原理

DeepFool算法在《deepFool: a simple and accurate method to fool deep neural networks》中提出。它通常作为一种无定向攻击算法,相对于FGM而言,不用指定学习速率 ϵ \epsilon ϵ,算法本身可以计算出相对FGM更小的扰动来达到供给目的。

假设分割平面是一个直线,直线的两侧分别对应不同的分类结果,如果想改变其中某点 x 0 x_0 x0的分类结果,我们一定要跨过分割平面。显然最短的移动距离就是垂直分割平面进行移动,我们将这个距离记作 r ∗ ( x 0 ) r_*(x_0) r(x0),分类器为 f f f,那么存在如下关系:

r ∗ ( x 0 ) = a r g m i n ∥ r ∥ 2 s u b j e c t   t o s i g n ( f ( x 0 + r ) ) ≠ s i g n ( f ( x 0 ) ) r_*(x_0)=argmin\Vert r\Vert^2\\ subject\ to\quad sign(f(x_0+r))\ne sign(f(x_0)) r(x0)=argminr2subject tosign(f(x0+r))=sign(f(x0))

二分类的DeepFool算法可以用伪代码描述为:

DeepFool
输入:图像 x x x,分类器 f f f
初始化 x 0 = x , i = 0 x_0=x,i=0 x0=x,i=0
w h i l e   s i g n ( f ( x i ) ) = = s i g n ( f ( x 0 ) )   d o : while\ sign(f(x_i))==sign(f(x_0))\ do: while sign(f(xi))==sign(f(x0)) do:
r i − = f ( x i ) ∥ ∇ f ( x i ) ∥ 2 2 ∇ f ( x i ) \quad r_i-=\frac{f(x_i)}{\Vert\nabla f(x_i)\Vert_2^2}\nabla f(x_i) ri=f(xi)22f(xi)f(xi)
x r + 1 = x r + r i \quad x_{r+1}=x_r+r_i xr+1=xr+ri
i = i + 1 \quad i=i+1 i=i+1
e n d   w h i l e end\ while end while
r e t u r n   r ^ = ∑ r i return\ \hat{r}=\sum r_i return r^=ri

定义分类器 f f f在第 k k k种分类上的概率为 f k ( x ) f_k(x) fk(x),那么分类的最终标签可以表示为其中概率最大的那个分类:

k ^ ( x ) = arg max ⁡ k f k ( x ) \hat{k}(x)=\argmax_k f_k(x) k^(x)=kargmaxfk(x)

多分类的DeepFool攻击算法可以当成二分类的扩展,伪码描述为:

DeepFool
输入:图像 x x x,分类器 f f f,分类输出 k ^ ( x ) \hat{k}(x) k^(x)
初始化: x 0 = x , i = 0 x_0=x,i=0 x0=x,i=0
w h i l e   k ^ ( x ) = = k ^ ( x 0 )   d o while\ \hat{k}(x)==\hat{k}(x_0)\ do while k^(x)==k^(x0) do
f o r   k ≠ k ^ ( x 0 )   d o \quad for\ k\ne\hat{k}(x_0)\ do for k=k^(x0) do
ω k ′ = ∇ f k ( x i ) − ∇ f k ^ ( x 0 ) ( x i ) \quad\quad \omega'_k=\nabla f_k(x_i)-\nabla f_{\hat{k}(x_0)}(x_i) ωk=fk(xi)fk^(x0)(xi)
f k ′ = f k ( x i ) − f k ^ ( x 0 ) ( x i ) \quad\quad f'_k=f_k(x_i)-f_{\hat{k}(x_0)}(x_i) fk=fk(xi)fk^(x0)(xi)
e n d   f o r \quad end\ for end for

待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值