pytorch制作CNN的类印象图 class impression(类别生成图)及生成对抗攻击样本
??本文給出完整代碼實(shí)現(xiàn)CNN模型的類別可視化輸入圖像——類印象圖,并基于此生成對(duì)抗樣本圖像。
1,完整代碼
??在上一篇文章中,我給出了CNN特征可視化的代碼,在此基礎(chǔ)上稍加修改就可以得到根據(jù)各類別反饋生成的輸入圖像。還是先給出完整代碼:
import torch import torchvision.models as models import cv2 import time t0 = time.time()mu = torch.Tensor([0.485, 0.456, 0.406]).unsqueeze(-1).unsqueeze(-1).cuda() std = torch.Tensor([0.229, 0.224, 0.225]).unsqueeze(-1).unsqueeze(-1).cuda() unnormalize = lambda x: x*std + mu normalize = lambda x: (x-mu)/stdbatch_size = 1 num_classes = 1000model = models.resnet18(pretrained=True).cuda() for params in model.parameters():params.requires_grad = False model.eval() ''' mask = torch.zeros((batch_size,3,224,224), dtype=torch.bool).cuda() mask[:,:,100:-100,100:-100] = True ''' for clas in range(num_classes):data = torch.rand(batch_size,3,224,224).cuda()data.requires_grad = True#optimizer = torch.optim.SGD([data], lr=6)#, momentum=0.99)optimizer = torch.optim.Adam([data], lr=0.1, weight_decay=1e-6)label = torch.tensor([clas]).cuda()one_hot= torch.zeros((batch_size,num_classes), dtype=torch.bool).cuda()label = label.reshape(-1,1)one_hot.scatter_(1, label, 1)for i in range(4001):data1 = (data - data.min()) / (data.max() - data.min())#data1 = data1 * maskdata1 = normalize(data1)optimizer.zero_grad()outputs = model(data1)loss = - outputs[one_hot].sum()loss.backward()optimizer.step()print('class:',outputs.max(1)[1].item())print('time: %.2f'%(time.time()-t0))data_i = data.clone()data_i = (data_i - data_i.min()) / (data_i.max() - data_i.min())#data_i = (data_i*mask)data_i = data_i[0].permute(1,2,0).data.cpu().numpy()*255data_i = data_i[...,::-1].astype('uint8') #注意cv2使用BGR順序cv2.imwrite('./class_impress/class_%d.png'%clas,data_i)注意:這里損失函數(shù)使用的目標(biāo)類別的輸出值最大,按說(shuō)像常規(guī)分類網(wǎng)絡(luò)那樣使用交叉熵CE也是可以的,但是畫(huà)出來(lái)的可視化效果不好,沒(méi)有使用這個(gè)損失的效果好。
2,效果圖
圖1.幾種ImageNet預(yù)訓(xùn)練網(wǎng)絡(luò)的類印象圖??這些生成的圖片看起來(lái)僅僅似乎有一些該類別對(duì)應(yīng)圖像的影子,AlexNet的生成圖還能看出點(diǎn)東西,其他幾個(gè)網(wǎng)絡(luò)的生成圖人眼很難辨認(rèn)。但使用原模型進(jìn)行驗(yàn)證,可以發(fā)現(xiàn)這種生成圖目標(biāo)類別的識(shí)別概率都接近100%。
??也有一些技術(shù)能夠使生成的圖片效果更好,甚至達(dá)到非常清晰悅目的程度,但這不是本文的目的,感興趣的可以看我另一篇文章,生成的圖片效果更好。
3,小區(qū)域生成圖
??我們還可以對(duì)輸入施加約束,比如只在圖像的某個(gè)小區(qū)域內(nèi)產(chǎn)生圖像,見(jiàn)代碼中的mask部分。這樣生成的圖片雖然只有極小的部分,但仍然可以使識(shí)別網(wǎng)絡(luò)產(chǎn)生接近100%的目標(biāo)類別識(shí)別概率。下圖給出用預(yù)訓(xùn)練ResNet18產(chǎn)生的100x100和24x24兩種尺寸的類別生成圖例子。
4,生成攻擊性對(duì)抗樣本
??為什么要在小區(qū)域內(nèi)生成類印象圖呢,想必大家已經(jīng)猜到了,這會(huì)是一種對(duì)抗攻擊方案。既然這樣的小圖片可以產(chǎn)生很強(qiáng)的網(wǎng)絡(luò)識(shí)別概率,那么我們把這個(gè)小圖片加入到其他自然圖片中,我們不就得到了一種對(duì)抗樣本攻擊方法嗎?我們把class0對(duì)應(yīng)的100x100生成圖和class8對(duì)應(yīng)的24x24生成圖添加到原始圖片中,得到的部分對(duì)抗樣本示例如下圖。
圖3.添加小區(qū)域類印象圖構(gòu)成的對(duì)抗樣本??使用100x100補(bǔ)丁圖攻擊時(shí),我在5000張ImageNet圖像像測(cè)試,達(dá)到了100%的攻擊率,使用24x24補(bǔ)丁圖攻擊時(shí),也達(dá)到了30%的攻擊率。
??但需要指出的是,這只是一種白盒攻擊手段,我上述試驗(yàn)中的小區(qū)域補(bǔ)丁圖是在ResNet18中生成的,它的攻擊圖片也只對(duì)ResNet18模型有效,如果換成其他模型攻擊失效。這也說(shuō)明,我們用這種方法生成的類印象圖是一種非常過(guò)擬合的與模型強(qiáng)相關(guān)的結(jié)果,并不是一種普適的只與類別相關(guān)的類印象圖。所以,類印象圖這個(gè)詞很準(zhǔn)確,它只是特定模型對(duì)某個(gè)類別的“印象”。找到一種廣大神經(jīng)網(wǎng)絡(luò)共同的類印象,才能找到一種黑盒攻擊方法,這作為我以后思考的問(wèn)題吧。
總結(jié)
以上是生活随笔為你收集整理的pytorch制作CNN的类印象图 class impression(类别生成图)及生成对抗攻击样本的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pytorch简单代码实现deep dr
- 下一篇: 好玩的deep dream(清晰版,py