微信運(yùn)營(yíng)是做什么的seo自然排名關(guān)鍵詞來源的優(yōu)缺點(diǎn)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(28)——對(duì)抗攻擊
- 0. 前言
- 1. 對(duì)抗攻擊
- 2. 對(duì)抗攻擊模型分析
- 3. 使用 PyTorch 實(shí)現(xiàn)對(duì)抗攻擊
- 小結(jié)
- 系列鏈接
0. 前言
近年來,深度學(xué)習(xí)在圖像分類、目標(biāo)檢測(cè)、圖像分割等諸多領(lǐng)域取得了突破性進(jìn)展,深度學(xué)習(xí)模型已經(jīng)能夠以接近甚至超越人類水平的完成某些特定任務(wù)。但最近的研究表明,深度學(xué)習(xí)模型容易受到輸入數(shù)據(jù)中細(xì)微擾動(dòng)的影響,從而導(dǎo)致模型輸出錯(cuò)誤的預(yù)測(cè)。在圖像領(lǐng)域,此類擾動(dòng)通常很小對(duì)于人眼而言甚至無法察覺,但它們卻能夠愚弄深度學(xué)習(xí)模型。針對(duì)深度學(xué)習(xí)模型的這種對(duì)抗攻擊,限制了深度學(xué)習(xí)的成功在更廣泛領(lǐng)域的應(yīng)用。本節(jié)中,我們將介紹對(duì)抗攻擊 (Adversarial Attack
) 的基本概念,并使用 PyTorch
實(shí)現(xiàn)對(duì)抗攻擊生成可欺騙神經(jīng)網(wǎng)絡(luò)的圖像。
1. 對(duì)抗攻擊
深度學(xué)習(xí)在執(zhí)行各種計(jì)算機(jī)視覺任務(wù)方面都有著優(yōu)異的準(zhǔn)確性,但盡管深度學(xué)習(xí)模型的精確度很高,現(xiàn)代深度網(wǎng)絡(luò)卻容易被微小擾動(dòng)形式的對(duì)抗攻擊所干擾,這些擾動(dòng)對(duì)雖然對(duì)人類視覺系統(tǒng)而言幾乎無法感知,但卻可能導(dǎo)致神經(jīng)網(wǎng)絡(luò)分類器完全改變其對(duì)圖像的預(yù)測(cè)。甚至,被攻擊的模型對(duì)錯(cuò)誤的預(yù)測(cè)結(jié)果具有很高的置信度。對(duì)抗攻擊 (Adversarial Attack
) 是針對(duì)機(jī)器學(xué)習(xí)模型的一種攻擊方式,通過精心構(gòu)造的數(shù)據(jù)輸入,來欺騙機(jī)器學(xué)習(xí)模型以使其產(chǎn)生錯(cuò)誤的結(jié)果。
包含惡意擾動(dòng)的數(shù)據(jù)通常稱為對(duì)抗樣本 (Adversarial Example
),而對(duì)抗攻擊 (Adversarial Attack
) 則是構(gòu)建對(duì)抗樣本的并對(duì)目標(biāo)模型實(shí)施攻擊的過程。例如,如下圖所示,通過在圖像中添加不明顯的擾動(dòng),并不會(huì)影響人類對(duì)其內(nèi)容的判斷,但深度神經(jīng)網(wǎng)絡(luò)卻對(duì)擾動(dòng)后的圖像輸出了完全錯(cuò)誤的分類結(jié)果。
2. 對(duì)抗攻擊模型分析
本質(zhì)上,對(duì)抗攻擊是對(duì)輸入圖像值(像素)進(jìn)行更改。在本節(jié)中,我們將學(xué)習(xí)如何調(diào)整輸入圖像,以使訓(xùn)練后性能良好的深度學(xué)習(xí)模型對(duì)修改后的圖像輸出為指定類別而非原始類別:
- 使用紅狐圖像
- 指定模型預(yù)測(cè)對(duì)抗樣本的目標(biāo)類別
- 導(dǎo)入預(yù)訓(xùn)練模型,凍結(jié)模型參數(shù) (
gradients = False
) - 指定計(jì)算輸入圖像像素值(而非神經(jīng)網(wǎng)絡(luò)的權(quán)重)的梯度,因?yàn)樵谶M(jìn)行對(duì)抗攻擊時(shí),我們無法控制模型權(quán)重,只能修改輸入圖像
- 計(jì)算與模型預(yù)測(cè)和目標(biāo)類別對(duì)應(yīng)的損失
- 執(zhí)行反向傳播,獲取與每個(gè)輸入像素值相關(guān)的梯度
- 根據(jù)每個(gè)輸入像素值對(duì)應(yīng)的梯度方向更新輸入圖像像素值
- 重復(fù)步驟
5-7
,直到模型以較高的置信度將修改后的圖像預(yù)測(cè)為指定類別
3. 使用 PyTorch 實(shí)現(xiàn)對(duì)抗攻擊
在本節(jié)中,我們使用 PyTorch
實(shí)現(xiàn)上述對(duì)抗攻擊策略,以生成對(duì)抗樣本。
(1) 導(dǎo)入相關(guān)庫(kù)、讀取輸入圖像和預(yù)訓(xùn)練 ResNet50
模型,另外需要凍結(jié)模型參數(shù):
import numpy as np
import torch
from torch import nn
from matplotlib import pyplot as pltfrom torchvision.models import resnet50
model = resnet50(pretrained=True)
for param in model.parameters():param.requires_grad = False
model = model.eval()import requests
from PIL import Image
file = '5.png'
original_image = Image.open(file).convert('RGB')
original_image = np.array(original_image)
original_image = torch.Tensor(original_image)
(2) 導(dǎo)入 Imagenet
類別文件并為每個(gè)類別分配 ID
:
image_net_classes = 'https://gist.githubusercontent.com/yrevar/942d3a0ac09ec9e5eb3a/raw/238f720ff059c1f82f368259d1ca4ffa5dd8f9f5/imagenet1000_clsidx_to_labels.txt'
image_net_classes = requests.get(image_net_classes).text
image_net_ids = eval(image_net_classes)
image_net_classes = {i:j for j,i in image_net_ids.items()}
(3) 定義函數(shù)執(zhí)行圖像歸一化函數(shù) image2tensor()
與逆歸一化函數(shù) tensor2image()
:
from torchvision import transforms as T
from torch.nn import functional as F
normalize = T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
denormalize = T.Normalize([-0.485/0.229, -0.456/0.224, -0.406/0.225], [1/0.229, 1/0.224, 1/0.225])def image2tensor(input):x = normalize(input.clone().permute(2,0,1)/255.)[None]return x
def tensor2image(input):x = (denormalize(input[0].clone()).permute(1,2,0)*255.).type(torch.uint8)return x
(4) 定義預(yù)測(cè)給定圖像類別的函數(shù) predict_on_image()
:
def predict_on_image(input):model.eval()plt.imshow(input)# show(input)plt.show()input = image2tensor(input)pred = model(input)pred = F.softmax(pred, dim=-1)[0]prob, clss = torch.max(pred, 0)clss = image_net_ids[clss.item()]print(f'PREDICTION: `{clss}` @ {prob.item()}')
在以上代碼中,將輸入圖像轉(zhuǎn)換為張量(使用 image2tensor()
函數(shù)),并使用預(yù)訓(xùn)練模型預(yù)測(cè)模型類別 clss
及對(duì)應(yīng)概率 prob
。
(5) 定義對(duì)抗攻擊函數(shù) attack
。
attack()
函數(shù)使用 image
、model
和 target
作為輸入:
from tqdm import trange
losses = []
def attack(image, model, target, epsilon=1e-6):
將圖像轉(zhuǎn)換為張量,并指定計(jì)算輸入圖像梯度:
input = image2tensor(image)input.requires_grad = True
計(jì)算模型對(duì)給定輸入 input
的預(yù)測(cè)結(jié)果,然后計(jì)算目標(biāo)類別 target
對(duì)應(yīng)的損失值:
pred = model(input)loss = nn.CrossEntropyLoss()(pred, target)
通過反向傳播最小化損失值:
loss.backward()losses.append(loss.mean().item())
根據(jù)梯度方向小幅度更新圖像:
output = input - epsilon * input.grad.sign()
在以上代碼中,對(duì)輸入值進(jìn)行小幅度(乘以 epsilon
)更新。也就是說,我們并未直接通過梯度大小更新圖像,而是通過在梯度方向上 (input.grad.sign()
) 乘以一個(gè)非常小的值 (epsilon
) 后更新圖像。
使用 tensor2image
方法將張量轉(zhuǎn)換回圖像后返回輸出:
output = tensor2image(output)del inputreturn output.detach()
(6) 將圖像修改為指定類別。
指定對(duì)抗攻擊的目標(biāo)類別 desired_targets
:
modified_images = []
desired_targets = ['lemon', 'comic book', 'sax, saxophone']
循環(huán)遍歷 desired_targets
,并在每次迭代中將目標(biāo)類別轉(zhuǎn)換為相應(yīng)索引:
for target in desired_targets:target = torch.tensor([image_net_classes[target]])
修改圖像進(jìn)行對(duì)抗攻擊,并將結(jié)果追加到列表 modified_images
中:
image_to_attack = original_image.clone()for _ in trange(10):image_to_attack = attack(image_to_attack, model, target)modified_images.append(image_to_attack)
繪制修改后的圖像,并顯示相應(yīng)的類別:
for image in [original_image, *modified_images]:predict_on_image(image)
# PREDICTION: `lemon` @ 0.9999375343322754
# PREDICTION: `comic book` @ 0.9998908042907715
# PREDICTION: `sax, saxophone` @ 0.9997311234474182
可以看到,即使對(duì)圖像進(jìn)行非常微小的改動(dòng)(甚至在人眼看來并無差別),模型也會(huì)對(duì)擾動(dòng)樣本以極高的置信度預(yù)測(cè)輸出錯(cuò)誤的類別。
小結(jié)
盡管深度神經(jīng)網(wǎng)絡(luò)在各種計(jì)算機(jī)視覺任務(wù)上具有很高的準(zhǔn)確性,但研究表明它們?nèi)菀资艿轿⑿_動(dòng)的影響,從而導(dǎo)致它們輸出完全錯(cuò)誤的預(yù)測(cè)結(jié)果。由于深度學(xué)習(xí)是當(dāng)前機(jī)器學(xué)習(xí)和人工智能的核心技術(shù),這一缺陷引起了研究人員廣泛的興趣。本文首先介紹了對(duì)抗攻擊的基本概念,然后利用 PyTorch
實(shí)現(xiàn)了一種經(jīng)典的對(duì)抗攻擊算法,通過在圖中添加微小擾動(dòng)令紅狐圖像被錯(cuò)誤的預(yù)測(cè)為指定類別,我們也可以通過改變攻擊的目標(biāo)索引,來使圖像被錯(cuò)誤分類為其它類別。
系列鏈接
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(1)——神經(jīng)網(wǎng)絡(luò)與模型訓(xùn)練過程詳解
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(2)——PyTorch基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(3)——使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(4)——常用激活函數(shù)和損失函數(shù)詳解
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(5)——計(jì)算機(jī)視覺基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(6)——神經(jīng)網(wǎng)絡(luò)性能優(yōu)化技術(shù)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(7)——批大小對(duì)神經(jīng)網(wǎng)絡(luò)訓(xùn)練的影響
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(8)——批歸一化
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(9)——學(xué)習(xí)率優(yōu)化
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(10)——過擬合及其解決方法
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(11)——卷積神經(jīng)網(wǎng)絡(luò)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(12)——數(shù)據(jù)增強(qiáng)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(13)——可視化神經(jīng)網(wǎng)絡(luò)中間層輸出
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(14)——類激活圖
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(15)——遷移學(xué)習(xí)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(16)——面部關(guān)鍵點(diǎn)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(17)——多任務(wù)學(xué)習(xí)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(18)——目標(biāo)檢測(cè)基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(19)——從零開始實(shí)現(xiàn)R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(20)——從零開始實(shí)現(xiàn)Fast R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(21)——從零開始實(shí)現(xiàn)Faster R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(22)——從零開始實(shí)現(xiàn)YOLO目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(23)——使用U-Net架構(gòu)進(jìn)行圖像分割
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(24)——從零開始實(shí)現(xiàn)Mask R-CNN實(shí)例分割
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(25)——自編碼器(Autoencoder)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(26)——卷積自編碼器(Convolutional Autoencoder)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(27)——變分自編碼器(Variational Autoencoder, VAE)