FGSM方法生成交通信号牌的对抗图像样本

背景:

生成对抗样本,即扰动图像,让原本是“停车”的信号牌识别为“禁止驶入”

实验准备

模型:找一个训练好的,识别交通信号牌的CNN模型,灰度图像

模型地址:GitHub - Daulettulegenov/TSR_CNN: Traffic sign recognition

数据:Chinese Traffic Sign Database(CTSDB)

当下最受欢迎的国内交通标志数据集之一,该数据集容纳6164个交通标志图像,其中有58类交通标志。图像分为4170张图像的训练数据库和包含1994张图像的测试数据库两个子交通标志数据库。

官网链接:Traffic Sign Recogntion Database

数据结构: 

  • 模型在TSR_CNN-main下 
  • 8张目标表图像在 target下 
  • stop下是停止图像
  • no_entry下是禁止通行图像

对抗攻击

1、对抗步骤:

  1. 加载CNN模型
  2. 预测原始的输出类型,可以看到并不能正确的分类,因为是中文字幕“停”而不是 STOP。
  3. 需要迁移训练,让其识别中文的“停”
  4. 测试是否可以识别中文的停
  5. 预测新的输出类型,可以看到能正确的分类,即便是中文的“停”
  6. 生成扰动图像,原始图像增加扰动,让其能识别识别为no entry
  7. 保存扰动图像

2、代码如下:

ART-Adversarial Robustness Toolbox检测AI模型及对抗攻击的工具

import os
import cv2
import numpy as np
import tensorflow as tf
from art.estimators.classification import TensorFlowV2Classifier
from art.attacks.evasion import FastGradientMethod
from tensorflow.keras.models import load_model
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split

ID_CLASS_MAP = {
    0: 'Speed Limit 20 km/h',
    1: 'Speed Limit 30 km/h',
    2: 'Speed Limit 50 km/h',
    3: 'Speed Limit 60 km/h',
    4: 'Speed Limit 70 km/h',
    5: 'Speed Limit 80 km/h',
    6: 'End of Speed Limit 80 km/h',
    7: 'Speed Limit 100 km/h',
    8: 'Speed Limit 120 km/h',
    9: 'No passing',
    10: 'No passing for vechiles over 3.5 metric tons',
    11: 'Right-of-way at the next intersection',
    12: 'Priority road',
    13: 'Yield',
    14: 'Stop',
    15: 'No vechiles',
    16: 'Vechiles over 3.5 metric tons prohibited',
    17: 'No entry',
    18: 'General caution',
    19: 'Dangerous curve to the left',
    20: 'Dangerous curve to the right',
    21: 'Double curve',
    22: 'Bumpy road',
    23: 'Slippery road',
    24: 'Road narrows on the right',
    25: 'Road work',
    26: 'Traffic signals',
    27: 'Pedestrians',
    28: 'Children crossing',
    29: 'Bicycles crossing',
    30: 'Beware of ice/snow',
    31: 'Wild animals crossing',
    32: 'End of all speed and passing limits',
    33: 'Turn right ahead',
    34: 'Turn left ahead',
    35: 'Ahead only',
    36: 'Go straight or right',
    37: 'Go straight or left',
    38: 'Keep right',
    39: 'Keep left',
    40: 'Roundabout mandatory',
    41: 'End of no passing',
    42: 'End of no passing by vechiles over 3.5 metric tons'
}


def get_class_name(class_no):
    """
    根据类别编号返回对应的交通信号牌的名称
    :param class_no: 类别编号
    :return: 交通信号牌的名称
    """
    return ID_CLASS_MAP.get(class_no)


def grayscale(img):
    """
    将图像转换为灰度图像
    """
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return img


def equalize(img):
    """
    进行直方图均衡化
    """
    new_img = cv2.equalizeHist(img)
    return new_img


def preprocessing(img):
    """
    归一化处理
    """
    img = equalize(img)
    img = img / 255
    return img


def read_imgs(image_dir, label=0):
    """
    读取图片
    :param image_dir:
    :param label:
    :return:
    """
    image_files = os.listdir(image_dir)
    images = []
    labels = []
    for image_file in image_files:
        image_path = os.path.join(image_dir, image_file)
        image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  # 以灰度模式读取图片
        image = cv2.resize(image, (30, 30))
        img = preprocessing(image)
        images.append(img)
        labels.append(label)
    return images, labels


def my_predict(model):
    """
    读取指定目录下的所有图像,然后使用模型进行预测,并打印出预测结果。
    """
    print('************my_predict*************')
    # 读取图片
    image_dir = r'D:\MyPython\adversarial\target'
    image_files = os.listdir(image_dir)
    images = []
    for image_file in image_files:
        image_path = os.path.join(image_dir, image_file)
        image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  # 以灰度模式读取图片
        image = cv2.resize(image, (30, 30))
        img = preprocessing(image)
        img = img.reshape(1, 30, 30, 1)
        images.append(img)
        # PREDICT IMAGE
        predictions = model.predict(img)
        predict_x = model.predict(img)
        classIndex = np.argmax(predict_x)
        probabilityValue = np.amax(predictions)
        print("img path:", image_file, " ==> ", str(classIndex) + " " + str(get_class_name(classIndex)))
        print(str(round(probabilityValue * 100, 2)) + "%")


def reset_model(model):
    """
    修改模型的结构,移除最后的分类层,然后添加一个新的分类层。
    """
    base_model = model
    # 移除最后的分类层
    base_model = Model(inputs=base_model.input, outputs=base_model.layers[-2].output)
    # 添加一个新的分类层
    output = Dense(2, activation='softmax', name='new_dense')(base_model.output)
    model = Model(inputs=base_model.input, outputs=output)
    # 编译模型
    model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
    return model


def retrain_with2label(model):
    """
    取两个目录下的所有图像,然后使用这些图像和对应的标签来训练模型。
    """
    print('************retrain_with2label*************')
    image_dir1 = r'D:\MyPython\adversarial\stop'
    image_dir2 = r'D:\MyPython\adversarial\no_entry'
    images1, labels1 = read_imgs(image_dir1, 0)
    images2, labels2 = read_imgs(image_dir2, 1)

    # 合并图片和标签
    images = images1 + images2
    labels = labels1 + labels2

    images = np.array(images, dtype='float32')
    # 如果模型的输入形状是(30, 30, 1),那么我们需要增加一个维度
    if model.input_shape[-1] == 1:
        images = np.expand_dims(images, axis=-1)

    labels = np.array(labels)
    labels = to_categorical(labels, num_classes=2)

    # 划分训练集和测试集
    train_images, test_images, train_labels, test_labels = train_test_split(images, labels, test_size=0.2)
    # 训练模型
    model.fit(train_images, train_labels, validation_data=(test_images, test_labels), epochs=10)


def my_predict2(model):
    """
    读取指定目录下的所有图像,然后使用模型进行预测,并返回预测结果和图像数据。
    """
    # 选择stop的图像,扰动前的
    images, _ = read_imgs(r'D:\MyPython\adversarial\target')
    if model.input_shape[-1] == 1:
        images = np.expand_dims(images, axis=-1)
    preds = model.predict(images)
    print('Predicted before:', preds.argmax(axis=1))
    return images


def run_art(images):
    """
    使用对抗性攻击来生成对抗样本,并保存对抗样本和平均扰动。
    """
    # 创建一个目标标签(我们希望模型将0 stop识别为1 no entry)
    target_label = to_categorical(1, num_classes=2)
    target_label = np.tile(target_label, (len(images), 1))

    # 创建ART分类器
    classifier = TensorFlowV2Classifier(
        model=model,
        nb_classes=2,
        input_shape=(30, 30, 1),
        loss_object=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
        clip_values=(0, 1)
    )
    # 创建FGSM实例
    attack = FastGradientMethod(estimator=classifier, targeted=True)

    # 初始化对抗样本为原始图像
    adv_images = np.copy(images)

    for i in range(100):  # 最多迭代100次
        # 生成对抗样本的扰动
        perturbations = attack.generate(x=adv_images, y=target_label) - adv_images

        # 计算所有样本的平均扰动
        avg_perturbation = np.mean(perturbations, axis=0)

        # 将平均扰动添加到所有对抗样本上
        adv_images += avg_perturbation

        # 使用模型对对抗样本进行预测
        preds = model.predict(adv_images)
        print('Iteration:', i, 'Predicted after:', preds.argmax(axis=1))

        # 如果所有的预测结果都为1,那么停止迭代
        if np.all(preds.argmax(axis=1) == 1):
            break

    # 保存对抗样本
    for i in range(len(adv_images)):
        # 将图像的数据类型转换为uint8,并且将图像的值范围调整到[0, 255]
        img = (adv_images[i] * 255).astype(np.uint8)
        # 保存图像
        print(f'save adversarial picture: adversarial_image_{i}.png')
        cv2.imwrite(f'adversarial_image_{i}.png', img)

    # 归一化平均扰动并保存为图像
    avg_perturbation = (avg_perturbation - np.min(avg_perturbation)) / (
                np.max(avg_perturbation) - np.min(avg_perturbation))
    # 将平均扰动的值范围调整到[0, 255],并转换为uint8类型
    avg_perturbation = (avg_perturbation * 255).astype(np.uint8)
    # 将灰度图像转换为RGB图像
    avg_perturbation_rgb = cv2.cvtColor(avg_perturbation, cv2.COLOR_GRAY2RGB)
    # 保存图像
    print(f'save perturbation picture: perturbation_image.png')
    cv2.imwrite('perturbation_image.png', avg_perturbation_rgb)


if __name__ == "__main__":
    # 加载CNN模型
    model = load_model(r'D:\MyPython\adversarial\TSR_CNN-main\CNN_model_3.h5', compile=False)
    # 预测原始的输出类型,可以看到并不能正确的分类,因为是中文字幕“停”而不是 STOP。
    my_predict(model)
    # 需要迁移训练,让其识别中文的“停”
    model = reset_model(model)
    # 测试是否可以识别中文的停
    retrain_with2label(model)
    # 预测新的输出类型,可以看到能正确的分类,即便是中文的“停”
    images = my_predict2(model)
    # 生成扰动图像,原始图像增加扰动,让其能识别识别为no entry,保存扰动图像
    run_art(images)

3、实验结果:

3.1运行日志

************my_predict*************
img path: 052_0001_j.png  ==>  28 Children crossing
99.83%
img path: 052_0005_j.png  ==>  3 Speed Limit 60 km/h
50.46%
img path: 052_0011.png  ==>  3 Speed Limit 60 km/h
52.22%
img path: 052_0013.png  ==>  8 Speed Limit 120 km/h
93.85%
img path: 052_1_0002_1_j.png  ==>  35 Ahead only
26.76%
img path: capture_20240114141426681.bmp  ==>  40 Roundabout mandatory
89.58%
img path: capture_20240114141515221.bmp  ==>  17 No entry
34.44%
img path: capture_20240114141530130.bmp  ==>  33 Turn right ahead
42.66%
************retrain_with2label*************
Epoch 1/10
3/3 [==============================] - 1s 107ms/step - loss: 1.2774 - accuracy: 0.4857 - val_loss: 0.2057 - val_accuracy: 1.0000
Epoch 2/10
3/3 [==============================] - 0s 32ms/step - loss: 0.2968 - accuracy: 0.8714 - val_loss: 0.1363 - val_accuracy: 1.0000
Epoch 3/10
3/3 [==============================] - 0s 33ms/step - loss: 0.1908 - accuracy: 0.9286 - val_loss: 0.1200 - val_accuracy: 1.0000
Epoch 4/10
3/3 [==============================] - 0s 31ms/step - loss: 0.1482 - accuracy: 0.9429 - val_loss: 0.1365 - val_accuracy: 1.0000
Epoch 5/10
3/3 [==============================] - 0s 31ms/step - loss: 0.0665 - accuracy: 1.0000 - val_loss: 0.1404 - val_accuracy: 1.0000
Epoch 6/10
3/3 [==============================] - 0s 32ms/step - loss: 0.0638 - accuracy: 0.9857 - val_loss: 0.1384 - val_accuracy: 1.0000
Epoch 7/10
3/3 [==============================] - 0s 31ms/step - loss: 0.0347 - accuracy: 0.9857 - val_loss: 0.1278 - val_accuracy: 1.0000
Epoch 8/10
3/3 [==============================] - 0s 30ms/step - loss: 0.0228 - accuracy: 0.9857 - val_loss: 0.1143 - val_accuracy: 0.8889
Epoch 9/10
3/3 [==============================] - 0s 32ms/step - loss: 0.0056 - accuracy: 1.0000 - val_loss: 0.1030 - val_accuracy: 0.8889
Epoch 10/10
3/3 [==============================] - 0s 32ms/step - loss: 0.0112 - accuracy: 1.0000 - val_loss: 0.0898 - val_accuracy: 0.8889
Predicted before: [0 0 0 0 0 0 0 0]
Iteration: 0 Predicted after: [0 0 0 0 1 1 0 0]
Iteration: 1 Predicted after: [1 1 1 1 1 1 1 1]
save adversarial picture: adversarial_image_0.png
save adversarial picture: adversarial_image_1.png
save adversarial picture: adversarial_image_2.png
save adversarial picture: adversarial_image_3.png
save adversarial picture: adversarial_image_4.png
save adversarial picture: adversarial_image_5.png
save adversarial picture: adversarial_image_6.png
save adversarial picture: adversarial_image_7.png
save perturbation picture: perturbation_image.png

3.2 结果分析

通过以上日志可知,迭代了两轮后,预测由“停”字标签==>变成了“禁止”标签

8张目标图像+扰动后的对抗图像如下,依稀可见“停”字:

对抗扰动 如下:


 参考:

https://www.cnblogs.com/bonelee/p/17797484.html

国内外交通标志数据集 - 知乎

Keras导入自定义metric模型报错: unknown metric function: Please ensure this object is passed to`custom_object‘_自定义的metric不被调用-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/319865.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于elementUI的el-table组件实现按住某一行数据上下滑动选中/选择或取消选中/选择鼠标经过的行

实现代码 <template><div :class"$options.name"><el-tablestyle"user-select: none"ref"table":data"tableData":row-class-name"row_class_name"mousedown.native"mousedownTable"row-click&q…

Elasticsearch 索引文档时create、index、update的区别【学习记录】

本文基于elasticsearch7.3.0版本。 一、思维导图 elasticsearch中create、index、update都可以实现插入功能&#xff0c;但是实现原理并不相同。 二、验证index和create 由上面思维导图可以清晰的看出create、index的大致区别&#xff0c;下面我们来验证下思维导图中的场景&…

树莓派ubuntu22桌面配置(一)

烧录系统至树莓派 下载系统&#xff1a;https://ubuntu.com/download/raspberry-pi 选择合适的版本下载 镜像安装器安装&#xff1a;终端输入&#xff1a; sudo snap install rpi-imager 打开镜像安装器&#xff0c;按照需求选择树莓派版本与要写入的系统还有安装的u盘 方案…

YOLOv5源码中的参数超详细解析(7)— yolo.py

前言:Hello大家好,我是小哥谈。YOLOv5是一种先进的目标检测算法,它可以实现快速和准确的目标检测。yolo.py是YOLOv5项目中的一个Python文件,用于实现目标检测算法。该文件包含了YOLOv5模型的定义、训练和推理过程。本节课就结合源码对yolo.py文件进行逐行解析~!🌈 前期…

【Vue3】2-12 : 【案例】搜索关键词加筛选条件的综合

本书目录&#xff1a;点击进入 一、【案例】搜索关键词加筛选条件的综合 1.1、逻辑 1.2、效果 1.3、json数据 - 02-data.json 1.4、代码 一、【案例】搜索关键词加筛选条件的综合 1.1、逻辑 计算属性 - 绑定list&#xff0c;并过滤 input 双向绑定 - 当input改变时&…

带你拿捏SpringBoot自动装配的核心技术?模块装配(@EnableXXX注解+@Import)+ 条件装配(@ConditionalXXX)

文章目录 Profile激活指定配置文件主配置文件中指定激活的profile命令行激活设置虚拟机参数激活 profile控制不到的地方 Spring原生的条件装配注解ConditionalConditional接口讲解案例讲解 Spring Boot封装的条件装配注解ConditionalXXX自己实现ConditionalOnBeanSpringBoot 源…

NLP论文阅读记录 - WOS | 2022 使用语言特征空间的抽象文本摘要的神经注意模型

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Neural A…

熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建

简介: 熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建 可搭建!运营级!首次公开! 赏金赛源码,用户通过平台打比赛,赢了获得奖金奖励, 金币赛、赏金赛、vip赛等种赛事 可开王者荣耀、和平精英比赛 支持1v1、单排、双排组、战队排等多种比赛模式 …

【Kafka-3.x-教程】-【六】Kafka 外部系统集成 【Flume、Flink、SpringBoot、Spark】

【Kafka-3.x-教程】专栏&#xff1a; 【Kafka-3.x-教程】-【一】Kafka 概述、Kafka 快速入门 【Kafka-3.x-教程】-【二】Kafka-生产者-Producer 【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft 【Kafka-3.x-教程】-【四】Kafka-消费者-Consumer 【Kafka-3.x-教程】-【五…

坚持刷题|翻转二叉树

坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天先刷个简单的&#xff1a;翻转二叉树 题目 226.翻转二叉树 考察点 翻转二叉树又称为镜像二叉树&#xff0c;使用Java实现翻转二叉树通常是为了考察对二叉树的基本操作和递归的理解能力 递归的理解&#xff1a; 能够理解…

TongLINKQ(1):TongLINKQ概述

1 TongLINKQ简介 TongLinkQ 是面向分布式应用的消息中间件产品&#xff0c;主要功能是在应用程序之间进行实时、高效和可靠的传递消息&#xff0c;使得消息在不同的网络协议、不同的计算机系统和不同的应用软件之间进行网络传输。 TongLinkQ 应用程序可灵活地运行在多平台的多…

Vulnhub靶机:driftingblues 2

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;driftingblues2&#xff08;10.0.2.18&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entr…

Http协议简述

目录 HTTP-概述 2.1.1 介绍 2.2.2 特点 2.2 HTTP-请求协议 2.3 HTTP-响应协议 2.3.1 格式介绍 2.3.2 响应状态码 HTTP-概述 2.1.1 介绍 HTTP&#xff1a;Hyper Text Transfer Protocol(超文本传输协议)&#xff0c;规定了浏览器与服务器之间数据传输的规则。 http是互联…

React入门 - 06(TodoList 列表数据的新增和删除)

本章内容 目录 一、实践一下 React 的列表渲染二、TodoList 新增功能三、列表循环的 key四、删除 上一节内容我们完成了输入框中可以自由输入内容&#xff0c;这一节我们继续 TodoList功能的完善&#xff1a;列表数据的新增和删除。 在开始之前&#xff0c;我们先介绍一下 Re…

C++力扣题目222--完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面一层的节点都集中在该层最左边的若干位置。若最…

目标检测-One Stage-YOLOv7

文章目录 前言一、YOLOv7的不同版本二、YOLOv7的网络结构二、YOLOv7的创新点三、创新点的详细解读ELAN和E-ELANBoF训练技巧计划型重参化卷积辅助训练模块标签分配Lead head guided label assignerCoarse-to-fine lead head guided label assigner 基于级联模型的复合缩放方法 总…

面试官问,如何在十亿级别用户中检查用户名是否存在?

面试官问&#xff0c;如何在十亿级别用户中检查用户名是否存在&#xff1f; 前言 不知道大家有没有留意过&#xff0c;在使用一些app注册的时候&#xff0c;提示你用户名已经被占用了&#xff0c;需要更换一个&#xff0c;这是如何实现的呢&#xff1f;你可能想这不是很简单吗…

java获取已经发送谷歌邮件的打开状态

1.前言 现在网上的方案都是在邮件里面插入一张图片的地址&#xff0c;当收件人打开之后&#xff0c;就会发送请求到指定路径的服务器上&#xff0c;然后在请求的controller里面处理邮件的状态&#xff0c;这个方案确实是行得通的&#xff0c;本文章只是给大家避个坑&#xff0…

从传统训练到预训练和微调的训练策略

目录 前言1 使用基础模型训练手段的传统训练策略1.1 随机初始化为模型提供初始点1.2 目标函数设定是优化性能的关键 2 BERT微调策略: 适应具体任务的精妙调整2.1 利用不同的representation和分类器进行微调2.2 通过fine-tuning适应具体任务 3 T5预训练策略: 统一任务形式以提高…