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_splitID_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 imgdef equalize(img):"""进行直方图均衡化"""new_img = cv2.equalizeHist(img)return new_imgdef preprocessing(img):"""归一化处理"""img = equalize(img)img = img / 255return imgdef 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, labelsdef 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 IMAGEpredictions = 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 modeldef 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 + images2labels = labels1 + labels2images = 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 imagesdef 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博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wargames与bash知识17

Wargames与bash知识17 Bandit25(Bandit26) 关卡提示 从bandit25登录到bandit26应该相当容易…用户bandit26的shell不是/bin/bash,而是其他东西。找出它是什么,它是如何工作的,以及如何摆脱它。 推荐命令 ssh, cat, …

CSS基础笔记-05layout

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》《CSS基础笔记-03选择器》《CSS基础笔记-04cascade-specificity-inheritance》 文章目录 CSS基础笔记系列什么是CSS布局布局方法normal flowflexboxgridfloats 总结 什么是CSS布局 CSS布局是指在页面中对元素…

c语言学生管理系统

创建结构体里面包含学生的各种信息。 struct xs {int xh;char xm[20];int gs, yy, wl;double pj;struct xs* next; }; 创建菜单 void menu() {printf("\n************************************\n");printf("* 学生管理系统(1.0&#xff0…

C# 图解教程 第5版 —— 第25章 反射和特性

文章目录 25.1 元数据和反射25.2 Type 类25.3 获取 Type 对象25.4 什么是特性25.5 应用特性25.6 预定义的保留特性25.6.1 Obsolete 特性25.6.2 Conditional 特性25.6.3 调用者信息特性25.6.4 DebuggerStepThrough 特性25.6.5 其他预定义特性 25.7 关于应用特性的更多内容25.7.1…

51-12 多模态论文串讲—BLIP 论文精读

视觉语言预训练VLP模型最近在各种多模态下游任务上获得了巨大的成功,目前还有两个主要局限性: (1) 模型角度: 大多数方法要么采用encoder模型,要么采用encoder-decoder模型。然而,基于编码器的模型不太容易直接转换到文本生成任务&#xff0…

代码随想录 Leetcode242. 有效的字母异位词

题目&#xff1a; 代码&#xff08;首刷看解析 2024年1月14日&#xff09;&#xff1a; class Solution { public:bool isAnagram(string s, string t) {int hash[26] {0};for(int i 0; i < s.size(); i) {hash[s[i] - a];}for(int i 0; i < t.size(); i) {hash[t[i]…

【动态规划】dp多状态问题

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;按摩师&#x1f449;&…

一元二次方程虚数解

对一元二次方程axbxc0 (a≠0)&#xff1b;若判别式△b-4ac<0,则方程无实根,虚数解为&#xff1a;x(-b i√(4ac-b))/(2a)。 只含有一个未知数&#xff08;一元&#xff09;&#xff0c;并且未知数项的最高次数是2&#xff08;二次&#xff09;的整式方程叫做一元二次方程[1] …

如何申请IP地址证书

什么是IP地址证书&#xff1f; IP地址证书是一种用于验证网站服务器身份的数字证书&#xff0c;它可以确保网站与用户之间的通信安全。与传统的域名证书不同&#xff0c;IP地址证书直接针对服务器的IP地址进行认证&#xff0c;适用于没有独立域名的网站或需要对多个域名进行统…

树莓派ubuntu22桌面配置(一)

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

Python 中的字符串匹配识别文本中的相似性

更多Python学习内容&#xff1a;ipengtao.com 字符串匹配是自然语言处理&#xff08;NLP&#xff09;和文本处理中的一个重要任务&#xff0c;它可以识别文本之间的相似性、找到相同或相似的模式&#xff0c;以及进行文本分类和信息检索等应用。本文将深入探讨Python中的字符串…

ssh 远程登录协议

一、SSH 服务 1.1 SSH 基础 SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程 复制等功能。SSH 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令&#xff0c;SSH 为建立在应…

坚持刷题|翻转二叉树

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

vue前端开发自学基础,动态切换组件的显示

vue前端开发自学基础,动态切换组件的显示&#xff01;这个是需要借助于&#xff0c;一个官方提供的标签&#xff0c;名字叫【Component】-[代码demo:<component :is"ComponetShow"></component>]。 下面看看代码详情。 <template><h3>动态…

opencv多张图片实现全景拼接

最近camera项目需要用到全景拼接&#xff0c;故此查阅大量资料&#xff0c;终于将此功能应用在实际项目上&#xff0c;下面总结一下此过程中遇到的一些问题及解决方式&#xff0c;同时也会将源码附在结尾处&#xff0c;供大家参考&#xff0c;本文采用的opencv版本为3.4.12。 首…

Qt/QML编程学习之心得:小键盘keyboard(36)

小键盘对于qml应用是经常用到的,在qml里面,就如一个fileDialog也要自己画一样,小键盘keyboard也是要自己画的,对于相应的每个按键的clicked都要一一实现的。 这里有一个示例: 代码如下: import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Window 2.0 im…

文件夹名称大小写转换的方法:提高文件管理效率的关键

在计算机的文件管理中&#xff0c;文件夹名称的大小写是经常被忽视的一个细节。这个看似微不足道的细节&#xff0c;却可能影响到文件管理效率和查找速度。下面一起来看云炫文件管理器如何批量修改文件夹名称大小写转换的方法&#xff0c;提高文件管理效率。 文件夹名称字母大…

使用swift创建第一个ios程序

一、安装xcode 先到app store中下载一个Xcode app 二、创建项目 1、项目设定 创建ios app 2、工程结构 三、修改代码实现按键联动 四、运行测试

S1-08 流和消息缓冲区

流缓冲区 流缓冲区一般用在不同设备或者不同进程间的通讯&#xff0c;为了提高数据处理效率和性能&#xff0c;设置的一定大小的缓冲区&#xff0c;流缓冲区可以用来存储程序中需要处理的数据、对象、报文等信息&#xff0c;使程序对可以对这些信息进行预处理、排序、过滤、拆…