午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

對抗學習新進展:MIT和微軟聯(lián)合出品“元對抗擾動”

 我愛計算機視覺 2021-12-06
導言:
元學習是過去幾年AI領(lǐng)域域非常熱門的的學習方法之一,各種研究工作都是基于元學習展開的。元學習的目標是使得分類模型能夠獲取一種學會學習調(diào)參的能力,使得模型可以在獲取已有知識的基礎(chǔ)上能夠自適應快速學習新的任務。該論文是將元學習應用到對抗擾動中,作者提出一種元對抗擾動生成方法,該方法是一種更好的對抗擾動初始化的方法。

元對抗擾動可以使得干凈樣本圖像在僅通過一步梯度上升更新后以高概率使得模型錯誤分類。實驗結(jié)果表明,各種先進的神經(jīng)網(wǎng)絡模型容易受到元對抗擾動的攻擊,而且元對抗擾動具有很好的可遷移性,并能很好地推廣到不可見的數(shù)據(jù)樣本點和不同的神經(jīng)網(wǎng)絡模型中。

詳細信息如下:


  • 論文鏈接:https:///abs/2111.10291



      01      

論文方法

受元學習方法的啟發(fā),該論文的主要目的是訓練一種元對抗擾動,該擾動可以在一步或幾步更新內(nèi)對新數(shù)據(jù)點進行更有效的攻擊。

給定隨機初始化的元對抗擾動,參數(shù)為的目標分類器,交叉熵損失函數(shù),數(shù)據(jù)集。在數(shù)據(jù)集中采樣出一批數(shù)據(jù),通過梯度上升法生成新的對抗擾動。作者的目標是找到一個單一的元對抗擾動,以便新的樣本數(shù)據(jù)在幾次迭代后能夠以高概率使得模型分類器分類出錯,具體的優(yōu)化形式如下所示:


該論文的具體步驟如下,首先使用單步或多步梯度上升法去計算新數(shù)據(jù)點的對抗擾動,具體的計算公式如下所示:


其中步長是一個超參數(shù)。

更精確的數(shù)學表述如下所示:


元對抗擾動非常重視自適應性,接下來利用以上生成的擾動在新的樣本數(shù)據(jù)上去更新擾動,具體的公式如下所示:


其中是元步長。最后將得到的元對抗擾動投影到可行空間中。為了能夠更直觀的理解論文算法的細節(jié),做了如下算法示意圖:


這里需要注意的是,在該論文中求解梯度時,遇到了元學習學習初始化參數(shù)方法一樣的問題,即求解梯度的過程中會涉及到矩陣的計算。

梯度補充計算過程如下所示:


如上公式所示,是一個矩陣。要知道矩陣的計算會往往會涉及到大量的計算成本,作者在本文中沒有明確給出這個問題應對方法。在實際編程的時候,我采用的是的簡化計算量的方法,在下面的程序代碼里會有所體現(xiàn)。

整個元對抗擾動算法流程圖如下所示:



      02      

實驗結(jié)果

下表為元對抗擾動三種方法的對比結(jié)果。可以發(fā)現(xiàn)要顯著優(yōu)于其它兩種方法。對于所有網(wǎng)絡,的改善率約為10-20%。


下表總結(jié)了在七個模型之間的可遷移性。對于每個分類模型,計算一個元對抗擾動,并顯示該擾動遷移到所有其他模型的精度,同時對目標模型進行一步更新,其中在最下面一行顯示了在初始化時不使用的精度。實驗結(jié)果可以發(fā)現(xiàn),生成的對抗擾動在模型之間具有很好的遷移性。


如下圖所示,數(shù)據(jù)集的規(guī)模越大,性能越好。另外,即使只使用10幅圖像計算元對抗擾動,這種擾動仍然會導致模型的分類精確度比原始下降15%左右。這說明了元對抗擾動在看不見的數(shù)據(jù)點上具有驚人的泛化能力,可以在非常小的訓練數(shù)據(jù)集上進行計算。



      03      

程序代碼


論文中沒有給出元對抗擾動的具體代碼,以下是筆者自己根據(jù)算法流程圖以及對矩陣如何計算的理解編寫的簡化的完整程序。

import torchimport torch.nn as nnimport torch.utils.data as Dataimport numpy as npimport osimport torch.nn.functional as Fimport random
def generate_dataset(sample_num, class_num, X_shape): Label_list = [] Sample_list = [] for i in range(sample_num): y = np.random.randint(0, class_num) Label_list.append(y) Sample_list.append(np.random.normal(y, 0.2, X_shape)) return Sample_list, Label_list
def Sample_dataset(numpy_dataset, batch_size): index_list = random.sample(range(0, len(numpy_dataset[0])), batch_size) data_list = [] label_list = [] for index in index_list: data_list.append(numpy_dataset[0][index]) label_list.append(numpy_dataset[1][index]) return torch.tensor(data_list).to(torch.float32), torch.tensor(label_list).to(torch.int64)

class Normal_Dataset(Data.Dataset): def __init__(self, Numpy_Dataset): super(Normal_Dataset, self).__init__() self.data_tensor = torch.tensor(Numpy_Dataset[0]).to(torch.float32) self.target_tensor = torch.tensor(Numpy_Dataset[1]).to(torch.int64)
def __getitem__(self, index): return self.data_tensor[index], self.target_tensor[index]
def __len__(self): return self.data_tensor.size(0)
class Classifer(nn.Module): def __init__(self): super(Classifer, self).__init__() self.conv1 = nn.Conv2d(in_channels = 3, out_channels = 10, kernel_size = 9) # 10, 36x36 self.conv2 = nn.Conv2d(in_channels = 10, out_channels = 20, kernel_size = 17 ) # 20, 20x20 self.fc1 = nn.Linear(20*20*20, 512) self.fc2 = nn.Linear(512, 7)
def forward(self, x): in_size = x.size(0) out = self.conv1(x) out = F.relu(self.conv2(out)) out = out.view(in_size, -1) out = F.relu(self.fc1(out)) out = self.fc2(out) out = F.softmax(out, dim=1) return out

def MAP(DataLoader, alpha, beta, model, loss_fn, PI_epsilon,input_shape, epoches, numpy_dataset): v = torch.zeros(input_shape) # [3, 44, 44] for epoch in range(epoches): for batch_x, batch_y in DataLoader: v.requires_grad = True # Evaluate nable_vL(f_theta) using B with v outputs = model(batch_x + v) # [2, 3, 44, 44] + [3, 44, 44] = [2, 3, 44, 44] loss = loss_fn(outputs, batch_y) loss.backward() # Compute v_prime v_prime = (v + alpha * v.grad.data).detach_() v_prime.requires_grad = True # Sample B_prime dataset batch_x_prime, batch_y_prime = Sample_dataset(numpy_dataset, 2) # Evaluate nable_vL(f_theta) using B_prime with v_prime outputs_prime = model(batch_x_prime + v_prime) loss_prime = loss_fn(outputs_prime, batch_y_prime) loss_prime.backward() # Update v v = (v + beta * v_prime.grad).detach() return v
if __name__ == '__main__': input_shape = (3,44,44) numpy_dataset = generate_dataset(100, 7, input_shape) Dataset = Normal_Dataset(numpy_dataset) DataLoader = Data.DataLoader( dataset = Dataset, batch_size = 2, shuffle = True, num_workers = 0, ) model = Classifer() loss_fn = nn.CrossEntropyLoss() alpha = 0.01 belta = 0.01 epoches = 1 MAP(DataLoader, alpha, belta, model, loss_fn, 'PI', input_shape, epoches, numpy_dataset)

END

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多