微信運營是做什么的seo自然排名關鍵詞來源的優(yōu)缺點
PyTorch深度學習實戰(zhàn)(28)——對抗攻擊
- 0. 前言
- 1. 對抗攻擊
- 2. 對抗攻擊模型分析
- 3. 使用 PyTorch 實現(xiàn)對抗攻擊
- 小結
- 系列鏈接
0. 前言
近年來,深度學習在圖像分類、目標檢測、圖像分割等諸多領域取得了突破性進展,深度學習模型已經能夠以接近甚至超越人類水平的完成某些特定任務。但最近的研究表明,深度學習模型容易受到輸入數(shù)據(jù)中細微擾動的影響,從而導致模型輸出錯誤的預測。在圖像領域,此類擾動通常很小對于人眼而言甚至無法察覺,但它們卻能夠愚弄深度學習模型。針對深度學習模型的這種對抗攻擊,限制了深度學習的成功在更廣泛領域的應用。本節(jié)中,我們將介紹對抗攻擊 (Adversarial Attack
) 的基本概念,并使用 PyTorch
實現(xiàn)對抗攻擊生成可欺騙神經網絡的圖像。
1. 對抗攻擊
深度學習在執(zhí)行各種計算機視覺任務方面都有著優(yōu)異的準確性,但盡管深度學習模型的精確度很高,現(xiàn)代深度網絡卻容易被微小擾動形式的對抗攻擊所干擾,這些擾動對雖然對人類視覺系統(tǒng)而言幾乎無法感知,但卻可能導致神經網絡分類器完全改變其對圖像的預測。甚至,被攻擊的模型對錯誤的預測結果具有很高的置信度。對抗攻擊 (Adversarial Attack
) 是針對機器學習模型的一種攻擊方式,通過精心構造的數(shù)據(jù)輸入,來欺騙機器學習模型以使其產生錯誤的結果。
包含惡意擾動的數(shù)據(jù)通常稱為對抗樣本 (Adversarial Example
),而對抗攻擊 (Adversarial Attack
) 則是構建對抗樣本的并對目標模型實施攻擊的過程。例如,如下圖所示,通過在圖像中添加不明顯的擾動,并不會影響人類對其內容的判斷,但深度神經網絡卻對擾動后的圖像輸出了完全錯誤的分類結果。
2. 對抗攻擊模型分析
本質上,對抗攻擊是對輸入圖像值(像素)進行更改。在本節(jié)中,我們將學習如何調整輸入圖像,以使訓練后性能良好的深度學習模型對修改后的圖像輸出為指定類別而非原始類別:
- 使用紅狐圖像
- 指定模型預測對抗樣本的目標類別
- 導入預訓練模型,凍結模型參數(shù) (
gradients = False
) - 指定計算輸入圖像像素值(而非神經網絡的權重)的梯度,因為在進行對抗攻擊時,我們無法控制模型權重,只能修改輸入圖像
- 計算與模型預測和目標類別對應的損失
- 執(zhí)行反向傳播,獲取與每個輸入像素值相關的梯度
- 根據(jù)每個輸入像素值對應的梯度方向更新輸入圖像像素值
- 重復步驟
5-7
,直到模型以較高的置信度將修改后的圖像預測為指定類別
3. 使用 PyTorch 實現(xiàn)對抗攻擊
在本節(jié)中,我們使用 PyTorch
實現(xiàn)上述對抗攻擊策略,以生成對抗樣本。
(1) 導入相關庫、讀取輸入圖像和預訓練 ResNet50
模型,另外需要凍結模型參數(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) 導入 Imagenet
類別文件并為每個類別分配 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) 定義預測給定圖像類別的函數(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()}')
在以上代碼中,將輸入圖像轉換為張量(使用 image2tensor()
函數(shù)),并使用預訓練模型預測模型類別 clss
及對應概率 prob
。
(5) 定義對抗攻擊函數(shù) attack
。
attack()
函數(shù)使用 image
、model
和 target
作為輸入:
from tqdm import trange
losses = []
def attack(image, model, target, epsilon=1e-6):
將圖像轉換為張量,并指定計算輸入圖像梯度:
input = image2tensor(image)input.requires_grad = True
計算模型對給定輸入 input
的預測結果,然后計算目標類別 target
對應的損失值:
pred = model(input)loss = nn.CrossEntropyLoss()(pred, target)
通過反向傳播最小化損失值:
loss.backward()losses.append(loss.mean().item())
根據(jù)梯度方向小幅度更新圖像:
output = input - epsilon * input.grad.sign()
在以上代碼中,對輸入值進行小幅度(乘以 epsilon
)更新。也就是說,我們并未直接通過梯度大小更新圖像,而是通過在梯度方向上 (input.grad.sign()
) 乘以一個非常小的值 (epsilon
) 后更新圖像。
使用 tensor2image
方法將張量轉換回圖像后返回輸出:
output = tensor2image(output)del inputreturn output.detach()
(6) 將圖像修改為指定類別。
指定對抗攻擊的目標類別 desired_targets
:
modified_images = []
desired_targets = ['lemon', 'comic book', 'sax, saxophone']
循環(huán)遍歷 desired_targets
,并在每次迭代中將目標類別轉換為相應索引:
for target in desired_targets:target = torch.tensor([image_net_classes[target]])
修改圖像進行對抗攻擊,并將結果追加到列表 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)
繪制修改后的圖像,并顯示相應的類別:
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
可以看到,即使對圖像進行非常微小的改動(甚至在人眼看來并無差別),模型也會對擾動樣本以極高的置信度預測輸出錯誤的類別。
小結
盡管深度神經網絡在各種計算機視覺任務上具有很高的準確性,但研究表明它們容易受到微小擾動的影響,從而導致它們輸出完全錯誤的預測結果。由于深度學習是當前機器學習和人工智能的核心技術,這一缺陷引起了研究人員廣泛的興趣。本文首先介紹了對抗攻擊的基本概念,然后利用 PyTorch
實現(xiàn)了一種經典的對抗攻擊算法,通過在圖中添加微小擾動令紅狐圖像被錯誤的預測為指定類別,我們也可以通過改變攻擊的目標索引,來使圖像被錯誤分類為其它類別。
系列鏈接
PyTorch深度學習實戰(zhàn)(1)——神經網絡與模型訓練過程詳解
PyTorch深度學習實戰(zhàn)(2)——PyTorch基礎
PyTorch深度學習實戰(zhàn)(3)——使用PyTorch構建神經網絡
PyTorch深度學習實戰(zhàn)(4)——常用激活函數(shù)和損失函數(shù)詳解
PyTorch深度學習實戰(zhàn)(5)——計算機視覺基礎
PyTorch深度學習實戰(zhàn)(6)——神經網絡性能優(yōu)化技術
PyTorch深度學習實戰(zhàn)(7)——批大小對神經網絡訓練的影響
PyTorch深度學習實戰(zhàn)(8)——批歸一化
PyTorch深度學習實戰(zhàn)(9)——學習率優(yōu)化
PyTorch深度學習實戰(zhàn)(10)——過擬合及其解決方法
PyTorch深度學習實戰(zhàn)(11)——卷積神經網絡
PyTorch深度學習實戰(zhàn)(12)——數(shù)據(jù)增強
PyTorch深度學習實戰(zhàn)(13)——可視化神經網絡中間層輸出
PyTorch深度學習實戰(zhàn)(14)——類激活圖
PyTorch深度學習實戰(zhàn)(15)——遷移學習
PyTorch深度學習實戰(zhàn)(16)——面部關鍵點檢測
PyTorch深度學習實戰(zhàn)(17)——多任務學習
PyTorch深度學習實戰(zhàn)(18)——目標檢測基礎
PyTorch深度學習實戰(zhàn)(19)——從零開始實現(xiàn)R-CNN目標檢測
PyTorch深度學習實戰(zhàn)(20)——從零開始實現(xiàn)Fast R-CNN目標檢測
PyTorch深度學習實戰(zhàn)(21)——從零開始實現(xiàn)Faster R-CNN目標檢測
PyTorch深度學習實戰(zhàn)(22)——從零開始實現(xiàn)YOLO目標檢測
PyTorch深度學習實戰(zhàn)(23)——使用U-Net架構進行圖像分割
PyTorch深度學習實戰(zhàn)(24)——從零開始實現(xiàn)Mask R-CNN實例分割
PyTorch深度學習實戰(zhàn)(25)——自編碼器(Autoencoder)
PyTorch深度學習實戰(zhàn)(26)——卷積自編碼器(Convolutional Autoencoder)
PyTorch深度學習實戰(zhàn)(27)——變分自編碼器(Variational Autoencoder, VAE)