AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现

  • 完整项目代码:https://github.com/yangdadage/AidLux_intelligent_transportation/tree/master
  • 课件及老师示例代码可关注AidLux公众号获取:AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第1张图片

1.车辆检测

通常情况下检测任务是整个算法解决方案的一个前置模型,通过检测车辆,行人,交通指示牌等目标,再对感兴趣的目标区域进行级联任务的后续处理。因此关于此次智慧交通项目,首先是完成一个车辆检测模型的训练与部署测试,作为后续对抗攻击与对抗防御、AI安全业务功能以及告警提示等任务的目标。

具体见项目代码中的Lesson3_code,详细讲解可见训练营笔记:AidLux智慧交通AI安全实战训练营3--车辆检测模型训练及部署教程。

2.AI对抗攻击&防御

2.1AI对抗攻击

对抗攻击(adversarial attack)是AI安全方向的重要分支,其核心逻辑是在数据中增加一些微小扰动,在人类视觉系统无法察觉的情况下,使得算法模型对这些数据产生误判。其中被增加扰动的数据也称为对抗样本。

下面是训练营笔记中的例子:

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第2张图片

下面是一些使用PGD攻击算法得到的例子:

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第3张图片

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第4张图片 

 具体的对抗攻击代码在Lesson4_code/attack_code.py中,包括更详细的讲解见笔记:AidLux智慧交通AI安全实战训练营4--AI对抗攻击&防御实践及部署教程。主要代码如下:

### 常规模型加载,mobilenet_v2为正常的图像分类模型
model = mobilenet_v2(weights=None)
model_param = torch.load(
    '/intelligent_transportation/Lesson4_code/model/mobilenet_v2-b0353104.pth'
)
model.load_state_dict(model_param)  # 预训练图像分类模型加载
model.eval()
model = nn.Sequential(normalize, model)
model = model.to(device)

### 数据预处理
np_img = get_image()  # 读取数据
img = torch.tensor(bhwc2bchw(np_img))[None, :, :, :].float().to(device)
imagenet_label2classname = ImageNetClassNameLookup()

### 测试模型输出结果
pred = imagenet_label2classname(predict_from_logits(model(img)))
print("test output:", pred)

### 输出原label
pred_label = predict_from_logits(model(img))

### 对抗攻击:PGD攻击算法
adversary = LinfPGDAttack(
    model, eps=8 / 255, eps_iter=2 / 255, nb_iter=80,
    rand_init=True)

### 完成攻击,输出对抗样本
advimg = adversary.perturb(img, pred_label)

### 展示源图片,对抗扰动,对抗样本以及模型的输出结果
show_images(model, img, advimg)

 上面代码使用的对抗攻击算法为PGD攻击算法。

2.2AI对抗防御

在对抗攻击技术出现之后,对抗防御技术也孕育而生。对抗防御一般针对对抗攻击技术而展开,有针对特定攻击的特定防御,也有一般性防御策略。详细对抗防御代码见Lesson4_code/defense_code.py,更多的对抗防御方法及展示见笔记。主要代码如下:

### 常规模型+GCM模块 加载
model_defense = Model().eval().to(device)

### 数据预处理
np_img = get_image()
img = torch.tensor(bhwc2bchw(np_img))[None, :, :, :].float().to(device)
imagenet_label2classname = ImageNetClassNameLookup()

### 测试模型输出结果
pred_defense = imagenet_label2classname(predict_from_logits(model_defense(img)))
print("test output:", pred_defense)

pre_label = predict_from_logits(model_defense(img))

### 对抗攻击:PGD攻击算法,使用攻击算法攻击GCM防御模型
adversary = LinfPGDAttack(
    model_defense, eps=8 / 255, eps_iter=2 / 255, nb_iter=80,
    rand_init=True, targeted=False)

### 完成攻击,输出对抗样本
advimg = adversary.perturb(img, pre_label)

### 展示源图片,对抗扰动,对抗样本以及模型的输出结果
show_images(model_defense, img, advimg)

上面的对抗防御算法使用的是GCM防御算法。

3.整体流程串联

3.1整体流程

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第5张图片

3.2车辆检测+区域提取

车辆检测任务前面已经讲过,具体的车辆检测模型是YOLOv5,训练和部署过程均在笔记中。在原始图像中完成车辆目标框的开框定后,需要将咱们的感兴趣区域即车辆目标框提取出来,效果如下:

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第6张图片 

车辆区域提取代码在Lesson5_code/yolov5_extract.py中,具体车辆区域提取功能实现代码如下:

def extract_detect_res(img, all_boxes, image_name, save_folder=None):
    '''
    检测结果提取
    '''
    assert save_folder != None, '请输入保存地址!'

    img = img.astype(np.uint8)
    color_step = int(255/len(all_boxes))
    img_name_lst = []
    for bi in range(len(all_boxes)):
        if len(all_boxes[bi]) == 0:
            continue
        count = 0
        for box in all_boxes[bi]:
            x, y, w, h = [int(t) for t in box[:4]]
            #cv2.putText(img, f'{coco_class[bi]}', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
            #cv2.rectangle(img, (x,y), (x+w, y+h),(0, bi*color_step, 255-bi*color_step),thickness = 2)
            cut_img = img[y:(y+h), x:(x + w)]
            cv2.imwrite(f'{save_folder}' \
                 + image_name + "_" + str(count) + ".jpg",cut_img)
            img_name_lst.append(image_name + "_" + str(count) + ".jpg")
            count += 1

            # cvs.imshow(cut_img)
    return img_name_lst

 3.3对抗攻击

有了车辆区域后,就可以模拟真实的场景,模拟外部用户对模型进行攻击,使得模型识别的能力出现错乱。这里使用基于迁移的黑盒攻击,通过攻击算法生成车辆区域对抗样本,最后将对抗样本给到常规的识别模型即可完成攻击,具体的生成车辆区域对抗样本的代码见Lesson5_code/adv_code/black_attack.py,其中主要代码如下:

### 常规模型加载
# model = mobilenet_v2(pretrained=True)
model = mobilenet_v2(pretrained=None)
pretrain_param = torch.load('/home/intelligent_transportation/Lesson5_code/model/mobilenet_v2-b0353104.pth')
model.load_state_dict(pretrain_param)
model.eval()
model = nn.Sequential(normalize, model)
model = model.to(device)


### 替身模型加载
# model_su = resnet18(pretrained=True)
model_su = resnet18(pretrained=False)
resnet18_param = torch.load('/home/intelligent_transportation/Lesson5_code/model/resnet18-5c106cde.pth')
model_su.load_state_dict(resnet18_param)
model_su.eval()
model_su = nn.Sequential(normalize, model_su)
model_su = model_su.to(device)


### 对抗攻击:PGD攻击算法
# adversary = LinfPGDAttack(
#    model_su, eps=8/255, eps_iter=2/255, nb_iter=80,
#    rand_init=True, targeted=False)
adversary = FGSM(
    model_su, eps=8/255, eps_iter=2/255, nb_iter=80,
    rand_init=True, targeted=False
)


from pathlib import Path
src_img_path = Path('/home/intelligent_transportation/Lesson5_code/adv_code/orig_images')
img_path_lst = [p for p in src_img_path.rglob('*') if p.name.endswith('.jpg')]
for i, img_path in enumerate(img_path_lst):
    print(img_path)
    ### 数据预处理
    np_img = get_image(img_path=img_path)
    img = torch.tensor(bhwc2bchw(np_img))[None, :, :, :].float().to(device)
    imagenet_label2classname = ImageNetClassNameLookup()

    ### 测试模型输出结果
    pred = imagenet_label2classname(predict_from_logits(model(img)))
    print("test output:", pred)

    ### 输出原label
    pred_label = predict_from_logits(model_su(img))  
    # 使用替身模型的相关信息进行对抗样本的获取
    # 这包括替身模型的参数、输出label


    ### 完成攻击,输出对抗样本
    advimg = adversary.perturb(img, pred_label)

    ### 展示源图片,对抗扰动,对抗样本以及模型的输出结果
    show_images(model, img, advimg, img_name=f'show_{int(i)}_{pred}.png')

    ### 迁移攻击样本保存
    save_path = "/home/intelligent_transportation/Lesson5_code/adv_code/adv_results/"
    torchvision.utils.save_image(advimg.cpu().data, save_path + f"adv_image_{int(i)}_{pred}.png")

3.4对抗攻击监测+常规识别模型识别+喵提醒

此处的逻辑为:将车辆目标区域输入对抗攻击监测模型,注意,此时的车辆目标区域可能是正常样本也可能是对抗攻击样本,因此需要先一步通过监测模型进行监测。在完成对车辆目标区域的监测后,如果监测模型认为当前车辆区域为正常样本,则将其输入常规识别模型中对其进行识别,将识别出的车辆信息输入后续任务流程,而如果监测模型认为当前车辆区域为对抗攻击模型,则停止当前样本的后续业务流程,并通过喵提醒告警存在对抗风险。

对抗攻击监测+常规识别模型识别+喵提醒的实现代码在Lesson5_code/adv_code/detect_adv_code.py中,主要代码如下:

model = Model().eval().to(device)  # 常规识别模型

detect_model = Detect_Model().eval().to(device)  # 对抗攻击监测模型


if __name__ == '__main__':
    from pathlib import Path
    src_img_path = Path('/home/intelligent_transportation/Lesson5_code/adv_code/orig_images/')
    # img_path_lst = [p for p in src_img_path.rglob('*') if p.name.split('_')[0] == 'adv']
    img_path_lst = [p for p in src_img_path.rglob('*') if p.name.endswith('jpg')]
    for img_path in img_path_lst:
        print('=' * 60)
        print(img_path.name) 
        np_img = get_image(img_path)  # 读取车辆目标区域
        img = torch.tensor(bhwc2bchw(np_img))[None, :, :, :].float().to(device)  # 数据预处理
        imagenet_label2classname = ImageNetClassNameLookup()
        ### 对抗攻击监测
        detect_pred = detect_model(img)  # 对车辆目标区域进行监测
        print(detect_pred)

        if detect_pred > 0.5:  # 当监测模型认为其为对抗攻击样本时,通过喵提醒进行告警,并停止后续任务流程
            id = 'tHyzzn1'
            # 填写喵提醒中,发送的消息,这里放上前面提到的图片外链
            text = "出现对抗攻击风险!!"
            ts = str(time.time())  # 时间戳
            type = 'json'  # 返回内容格式
            request_url = "http://miaotixing.com/trigger?"

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47'}

            result = requests.post(request_url + "id=" + id + "&text=" + text + "&ts=" + ts + "&type=" + type,
                                headers=headers)
            print('存在对抗攻击风险!')
        else:  # 若监测模型认为当前样本为正常样本,则通过常规识别模型对其进行车辆识别
            pred = imagenet_label2classname(predict_from_logits(model(img)))
            print('=' * 60)
            print('result: ', pred)

喵提醒告警提醒:AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第7张图片

3.5整体串联

将上述各个部分进行串联,具体串联后的代码见Lesson5_code/app_main.py,其中主要代码如下:

if __name__ == '__main__':
    # 车辆检测

    # AidLite初始化:调用AidLite进行AI模型的加载与推理,需导入aidlite
    aidlite = aidlite_gpu.aidlite()
    # Aidlite模型路径
    model_path = '/home/intelligent_transportation/Lesson5_code/yolov5_code/aidlux/yolov5_car_best-fp16.tflite'
    # 定义输入输出shape
    in_shape = [1 * 640 * 640 * 3 * 4]
    out_shape = [1 * 25200 * 6 * 4]
    # 加载Aidlite检测模型:支持tflite, tnn, mnn, ms, nb格式的模型加载
    aidlite.ANNModel(model_path, in_shape, out_shape, 4, 0)
    
    imgs_path = "/home/intelligent_transportation/Lesson5_code/yolov5_code/data/images/tests"
    # 设置测试集路径
    images_lst = os.listdir(imgs_path)
    images_lst = [p for p in images_lst if p.endswith('jpg') or p.endswith('png')]
    print(images_lst)
    # extract_res: frame_lst, pred_lst, images_lst
    extract_res = extract_car_img(imgs_path, images_lst)


    # 检测框提取

    save_folder = "/home/intelligent_transportation/Lesson5_code/yolov5_code/aidlux/extract_results/"
    # 图片裁剪,提取车辆目标区域
    car_img_name_lst = []
    for frame, pred, img_name in zip(*extract_res):
        img_name_lst = extract_detect_res(frame, pred, img_name, save_folder)
        car_img_name_lst.extend(img_name_lst)
    assert car_img_name_lst != [], '没有提取到车辆框!'


    # 使用对抗样本

    ### 替身模型加载
    normalize = NormalizeByChannelMeanStd(
        mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    # model_su = resnet18(pretrained=True)
    model_su = resnet18(pretrained=False)
    resnet18_param = torch.load('/home/intelligent_transportation/Lesson5_code/model/resnet18-5c106cde.pth')
    model_su.load_state_dict(resnet18_param)
    model_su.eval()
    model_su = nn.Sequential(normalize, model_su)
    model_su = model_su.to(device)

    ### 对抗攻击:PGD攻击算法
    # adversary = LinfPGDAttack(
    #    model_su, eps=8/255, eps_iter=2/255, nb_iter=80,
    #    rand_init=True, targeted=False)
    adversary = FGSM(
        model_su, eps=8/255, targeted=False
    )   
    
    use_advimg = False
    print(f'是否使用对抗样本: {use_advimg}...')
    print('车辆框信息:', car_img_name_lst)
    img_res = []
    for i, img_name in enumerate(car_img_name_lst):
        print(img_name)
        img_path = save_folder + img_name
        if use_advimg:
            advimg, advimg_path = get_advimg(img_path)
            img_res.append(advimg)
        else:
            np_img = get_image(img_path)
            img = torch.tensor(bhwc2bchw(np_img))[None, :, :, :].float().to(device)
            img_res.append(img)
    
    # AI安全监测与告警
    model = Model().eval().to(device)
    detect_model = Detect_Model().eval().to(device)
    imagenet_label2classname = ImageNetClassNameLookup()

    for img in img_res:
        ### 对抗攻击监测
        print(img.size())
        detect_pred = detect_model(img)
        print(detect_pred)

        if detect_pred > 0.5:
            id = 'tHyzzn1'
            # 填写喵提醒中,发送的消息,这里放上前面提到的图片外链
            text = "出现对抗攻击风险!!"
            ts = str(time.time())  # 时间戳
            type = 'json'  # 返回内容格式
            request_url = "http://miaotixing.com/trigger?"

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47'}

            result = requests.post(request_url + "id=" + id + "&text=" + text + "&ts=" + ts + "&type=" + type,
                                headers=headers)
            print('存在对抗攻击风险!')
        else:
            pred = imagenet_label2classname(predict_from_logits(model(img)))
            print('=' * 60)
            print('result: ', pred)

 测试图片在Lesson5_code/yolov5_code/data/images/tests中,对tests中的所有图片进行车辆检测和目标区域提取后,后续通过监测模型对所有车辆目标区域进行监测,若正常则进行车辆识别,若不正常则告警。测试结果如下:

AidLux智慧交通实战-车辆检测&AI对抗攻防算法实现_第8张图片

 4.测试结果展示

AI训练营测试素材测试结果展示:

测试视频测试结果:

aidlux智慧交通项目测试视频

5.心得体会

本次训练营的主题为智慧交通,第一期智慧城市的训练营我也参加了,一如既往的内容丰富,解答翔实。

你可能感兴趣的:(人工智能)