李宏毅作业六 Adversarial Attack对抗攻击

11 篇文章 6 订阅
8 篇文章 0 订阅

系列文章目录

李宏毅作业十 Generative Adversarial Network生成对抗网络(代码)
李宏毅作业九 Anomaly Detection异常检测
李宏毅作业八unsupervised无监督聚类学习
李宏毅作业七其三 Network Compression (Network Pruning)
李宏毅作业七其二 Network Compression (Knowledge Distillation)
李宏毅作业七其一 Network Compression (Architecuture Design)

前言


作业里,不仅有原始注释,还有我自己附加的注释,有不对的地方还请大家多多指教

运行环境是cloab
python3


一、下载资料并解压缩

# 下載資料
!gdown --id '14CqX3OfY9aUbhGp4OpdSHLvq2321fUB7' --output data.zip
# 解壓縮
!unzip -qq -u data.zip
# 確認目前的檔案
!ls

二、创建环境

1.引入库

import os
# 讀取 label.csv
import pandas as pd
# 讀取圖片
from PIL import Image
import numpy as np

import torch
# Loss function
import torch.nn.functional as F
# 讀取資料
import torchvision.datasets as datasets
from torch.utils.data import Dataset, DataLoader
# 載入預訓練的模型
import torchvision.models as models
# 將資料轉換成符合預訓練模型的形式
import torchvision.transforms as transforms
# 顯示圖片
import matplotlib.pyplot as plt

device = torch.device("cuda")

2.读取资料

# 實作一個繼承 torch.utils.data.Dataset 的 Class 來讀取圖片
class Adverdataset(Dataset):
    def __init__(self, root, label, transforms):


        # 圖片所在的資料夾
        self.root = root
        # 由 main function 傳入的 label
        self.label = torch.from_numpy(label).long()
        # 由 Attacker 傳入的 transforms 將輸入的圖片轉換成符合預訓練模型的形式
        self.transforms = transforms
        # 圖片檔案名稱的 list
        self.fnames = []

        for i in range(200):
            self.fnames.append("{:03d}".format(i))

    def __getitem__(self, idx):

      
        # 利用路徑讀取圖片
        img = Image.open(os.path.join(self.root, self.fnames[idx] + '.png'))
        # 將輸入的圖片轉換成符合預訓練模型的形式
        img = self.transforms(img)
        # 圖片相對應的 label
        label = self.label[idx]
        return img, label
    
    def __len__(self):
        # 由於已知這次的資料總共有 200 張圖片 所以回傳 200
        return 200

三、载入模型

lass Attacker:
    def __init__(self, img_dir, label):

        # 讀入預訓練模型 vgg16
        self.model = models.vgg16(pretrained = True)
        self.model.cuda()
        self.model.eval()
        self.mean = [0.485, 0.456, 0.406]
        self.std = [0.229, 0.224, 0.225]
        # 把圖片 normalize 到 0~1 之間 mean 0 variance 1
        # 在作业三已经提及了,注释过了该方法的具体内容
        self.normalize = transforms.Normalize(self.mean, self.std, inplace=False)
        transform = transforms.Compose([                
                        transforms.Resize((224, 224), interpolation=3),
                        transforms.ToTensor(),
                        self.normalize
                    ])
        
        # 利用 Adverdataset 這個 class 讀取資料,将标签值和训练值给dataset
        self.dataset = Adverdataset('./data/images', label, transform)
        
        # __init__中的几个重要的输入:1、dataset,这个就是PyTorch已有的数据读取接口
        #(比如torchvision.datasets.ImageFolder)或者自定义的数据接口的输出,
        # 该输出要么是torch.utils.data.Dataset类的对象,要么是继承自torch.utils.data.Dataset类的自定义类的对象。
        # 2、batch_size,根据具体情况设置即可。3、shuffle(打乱数据),一般在训练数据中会采用
        self.loader = torch.utils.data.DataLoader(
                self.dataset,
                batch_size = 1,
                shuffle = False)
        

    # FGSM 攻擊
    def fgsm_attack(self, image, epsilon, data_grad):#epsilon是后面自己设置数,体现噪声的强度

        # 找出 gradient 的方向
        sign_data_grad = data_grad.sign()
        # 將圖片加上 gradient 方向乘上 epsilon 的 noise
        perturbed_image = image + epsilon * sign_data_grad#生成有噪音的图片
        return perturbed_image
    
    def attack(self, epsilon):

        # 存下一些成功攻擊後的圖片 以便之後顯示
        adv_examples = []
        wrong, fail, success = 0, 0, 0
        for (data, target) in self.loader:
            data, target = data.to(device), target.to(device)#把数据转化为cpu,或者GPU的数据类型
            data_raw = data;
            data.requires_grad = True#自动计算梯度

            # 將圖片丟入 model 進行測試 得出相對應的 class
            output = self.model(data)
            init_pred = output.max(1, keepdim=True)[1]

            # 如果 class 錯誤 就不進行攻擊
            if init_pred.item() != target.item():
                wrong += 1
                continue
            
            # 如果 class 正確 就開始計算 gradient 進行 FGSM 攻擊
            loss = F.nll_loss(output, target)
            self.model.zero_grad()#梯度置零,防止叠加
            loss.backward()
            data_grad = data.grad.data
            perturbed_data = self.fgsm_attack(data, epsilon, data_grad)

            # 再將加入 noise 的圖片丟入 model 進行測試 得出相對應的 class        
            output = self.model(perturbed_data)
            final_pred = output.max(1, keepdim=True)[1]
          
            if final_pred.item() == target.item():
                # 辨識結果還是正確 攻擊失敗
                fail += 1
            else:
                # 辨識結果失敗 攻擊成功
                success += 1
                # 將攻擊成功的圖片存入
                if len(adv_examples) < 5:
                  adv_ex = perturbed_data * torch.tensor(self.std, device = device).view(3, 1, 1) + torch.tensor(self.mean, device = device).view(3, 1, 1)
                  adv_ex = adv_ex.squeeze().detach().cpu().numpy() 
                  #squeeze 数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的数去掉第一个维数为一的维度之后就变成(3)行


                  data_raw = data_raw * torch.tensor(self.std, device = device).view(3, 1, 1) + torch.tensor(self.mean, device = device).view(3, 1, 1)
                  data_raw = data_raw.squeeze().detach().cpu().numpy()
                  adv_examples.append( (init_pred.item(), final_pred.item(), data_raw , adv_ex) )        
        final_acc = (fail / (wrong + success + fail))
        
        print("Epsilon: {}\tTest Accuracy = {} / {} = {}\n".format(epsilon, fail, len(self.loader), final_acc))
        return adv_examples, final_acc

四、运行成果

if __name__ == '__main__':
    # 讀入圖片相對應的 label
    df = pd.read_csv("./data/labels.csv")
    df = df.loc[:, 'TrueLabel'].to_numpy()
    label_name = pd.read_csv("./data/categories.csv")
    label_name = label_name.loc[:, 'CategoryName'].to_numpy()
    # new 一個 Attacker class
    attacker = Attacker('./data/images', df)
    # 要嘗試的 epsilon
    epsilons = [0.1, 0.01]

    accuracies, examples = [], []

    # 進行攻擊 並存起正確率和攻擊成功的圖片
    for eps in epsilons:
        ex, acc = attacker.attack(eps)
        accuracies.append(acc)
        examples.append(ex)

五、生成攻击后的图片

cnt = 0
plt.figure(figsize=(30, 30))
for i in range(len(epsilons)):#遍历之前eps里的元素,idx值为0,1

    for j in range(len(examples[i])):#遍历样本值,
        cnt += 1

        #subplot(nrows, ncols, plot_number)
        #或者写成subplot(nrows ncols plot_number)也行(中间不用逗号,前提是只能是三位数)
        #这个函数用来表示把figure分成nrows*ncols的子图表示,
        #nrows:子图的行数
        #ncols:子图的列数
        #plot_number 索引值,表示把图画在第plot_number个位置(从左下角到右上角)
        plt.subplot(len(epsilons),len(examples[0]) * 2,cnt)
        plt.xticks([], [])#坐标轴变名用法
        plt.yticks([], [])
        if j == 0:
            plt.ylabel("Eps: {}".format(epsilons[i]), fontsize=14)

        orig,adv,orig_img, ex = examples[i][j]

        # plt.title("{} -> {}".format(orig, adv))
        plt.title("original: {}".format(label_name[orig].split(',')[0]))
        orig_img = np.transpose(orig_img, (1, 2, 0))#转置(0,1,2)->(1, 2, 0)
        plt.imshow(orig_img)
        cnt += 1
        plt.subplot(len(epsilons),len(examples[0]) * 2,cnt)
        plt.title("adversarial: {}".format(label_name[adv].split(',')[0]))
        ex = np.transpose(ex, (1, 2, 0))
        plt.imshow(ex)
plt.tight_layout()
plt.show()

总结

在前几个作业的学习下,这次程序基本都能看懂。

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 李宏毅是一位著名的机器学习专家,他在GAN(生成对抗网络)方面做出了重要贡献。GAN是一种包含两个神经网络的模型,一个称为生成器(Generator),另一个称为判别器(Discriminator)。GAN的目标是让生成器尽可能地生成与真实样本相似的数据。 在李宏毅作业代码讲解中,他会介绍GAN的基本原理、算法和代码实现。首先,他会讲解生成器和判别器的结构和原理,包括生成器如何生成样本,以及判别器如何对生成的样本进行评价。 然后,李宏毅会详细解释GAN的损失函数和优化方法。他会讲解如何使用反向传播算法更新生成器和判别器的参数,以使它们在训练中达到更好的表现。此外,他还会解释GAN的训练过程中可能遇到的一些问题,并提供解决方法。 在代码方面,李宏毅会给出一个简单的实例,展示如何使用Python和深度学习框架(如TensorFlow或PyTorch)来实现一个基本的GAN模型。他会详细解释每个代码部分的功能和作用,并给出相应的代码注释,方便学习者理解。 总的来说,李宏毅的GAN网络作业代码讲解涵盖了GAN的基本原理、算法和实现细节。通过他的讲解,学习者可以更好地理解并应用GAN,从而在生成对抗网络领域取得更好的成果。 ### 回答2: 李宏毅是一位著名的机器学习深度学习专家,他的GAN(生成对抗网络)网络作业代码讲解十分受欢迎。 GAN是一种由生成器和判别器组成的对抗性网络模型。生成器尝试生成与真实数据相似的新样本,而判别器则负责判断这些样本是真实的还是伪造的。GAN网络的训练过程是通过生成器和判别器之间的对抗来进行的。 在李宏毅的GAN网络作业代码讲解中,他通常会从基本概念开始讲解,介绍GAN网络的工作原理和训练过程。他会解释生成器和判别器的结构以及它们的作用,包括如何设计合适的神经网络模型来实现生成器和判别器。 接着,他会具体解释代码中各部分的功能和实现细节。他会展示如何使用Python和深度学习框架(如Tensorflow)来编写GAN网络的代码,并演示如何处理数据、构建网络结构、定义损失函数和优化器等。 此外,李宏毅还会给出一些GAN网络的应用案例,例如生成图像、语音合成等。他会详细说明如何调整和优化代码,以实现更好的生成效果。 总之,李宏毅的GAN网络作业代码讲解是非常有帮助和详细的,对于想要深入了解和学习GAN网络的人来说,这是一份宝贵的学习资料。通过他的讲解,我们可以更好地理解和应用GAN网络,为自己的深度学习项目增添新的工具和技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值