532 lines
22 KiB
Python
532 lines
22 KiB
Python
import fnmatch
|
||
import math
|
||
import os
|
||
import sys
|
||
import time
|
||
from operator import itemgetter
|
||
|
||
import gc
|
||
import numpy as np
|
||
import torch
|
||
import torch.optim as optim
|
||
import torch.nn as nn
|
||
import torch.nn.functional as F
|
||
from PIL import Image
|
||
from torch.utils.data import Dataset
|
||
from torchvision import transforms
|
||
|
||
# from darknet import Darknet
|
||
|
||
from median_pool import MedianPool2d
|
||
|
||
# print('starting test read')
|
||
# im = Image.open('data/horse.jpg').convert('RGB')
|
||
# print('img read!')
|
||
|
||
|
||
class MaxProbExtractor(nn.Module):
|
||
"""MaxProbExtractor: extracts max class probability for class from YOLO output.
|
||
|
||
Module providing the functionality necessary to extract the max class probability for one class from YOLO output.
|
||
|
||
"""
|
||
|
||
def __init__(self, cls_id, num_cls, config):
|
||
super(MaxProbExtractor, self).__init__()
|
||
self.cls_id = cls_id
|
||
self.num_cls = num_cls
|
||
self.config = config
|
||
self.anchor_num = 3
|
||
|
||
def forward(self, YOLOoutput):
|
||
# get values neccesary for transformation
|
||
if YOLOoutput.dim() == 3:
|
||
YOLOoutput = YOLOoutput.unsqueeze(0)
|
||
batch = YOLOoutput.size(0)
|
||
assert (YOLOoutput.size(1) == (5 + self.num_cls) * self.anchor_num)
|
||
h = YOLOoutput.size(2)
|
||
w = YOLOoutput.size(3)
|
||
# transform the output tensor from [batch, 425, 19, 19] to [batch, 80, 1805]
|
||
output = YOLOoutput.view(batch, self.anchor_num, 5 + self.num_cls, h * w) # [batch, 5, 85, 361]
|
||
output = output.transpose(1, 2).contiguous() # [batch, 85, 5, 361]
|
||
output = output.view(batch, 5 + self.num_cls, self.anchor_num * h * w) # [batch, 85, 1805]
|
||
output_objectness = torch.sigmoid(output[:, 4, :]) # [batch, 1805] # 是否有物体
|
||
output = output[:, 5:5 + self.num_cls, :] # [batch, 80, 1805]
|
||
# perform softmax to normalize probabilities for object classes to [0,1]
|
||
normal_confs = torch.nn.Softmax(dim=1)(output) # 物体类别
|
||
# we only care for probabilities of the class of interest (person)
|
||
confs_for_class = normal_confs[:, self.cls_id, :] # 类别 序号对应的为人
|
||
confs_if_object = output_objectness # confs_for_class * output_objectness
|
||
confs_if_object = confs_for_class * output_objectness
|
||
confs_if_object = self.config.loss_target(output_objectness, confs_for_class)
|
||
# find the max probability for person
|
||
max_conf, max_conf_idx = torch.max(confs_if_object, dim=1)
|
||
|
||
return max_conf
|
||
|
||
|
||
class NPSCalculator(nn.Module):
|
||
"""NMSCalculator: calculates the non-printability score of a patch.
|
||
|
||
Module providing the functionality necessary to calculate the non-printability score (NMS) of an adversarial patch.
|
||
|
||
"""
|
||
|
||
def __init__(self, printability_file, patch_side):
|
||
super(NPSCalculator, self).__init__()
|
||
self.printability_array = nn.Parameter(self.get_printability_array(printability_file, patch_side),
|
||
requires_grad=False)
|
||
|
||
def forward(self, adv_patch):
|
||
# calculate euclidian distance between colors in patch and colors in printability_array
|
||
# square root of sum of squared difference
|
||
color_dist = (adv_patch - self.printability_array + 0.000001)
|
||
color_dist = color_dist ** 2
|
||
color_dist = torch.sum(color_dist, 1) + 0.000001
|
||
color_dist = torch.sqrt(color_dist)
|
||
# only work with the min distance
|
||
color_dist_prod = torch.min(color_dist, 0)[0] # test: change prod for min (find distance to closest color)
|
||
# calculate the nps by summing over all pixels
|
||
nps_score = torch.sum(color_dist_prod, 0)
|
||
nps_score = torch.sum(nps_score, 0)
|
||
return nps_score / torch.numel(adv_patch)
|
||
|
||
def get_printability_array(self, printability_file, side):
|
||
printability_list = []
|
||
|
||
# read in printability triplets and put them in a list
|
||
with open(printability_file) as f:
|
||
for line in f:
|
||
printability_list.append(line.split(","))
|
||
|
||
printability_array = []
|
||
for printability_triplet in printability_list:
|
||
printability_imgs = []
|
||
red, green, blue = printability_triplet
|
||
printability_imgs.append(np.full((side, side), red))
|
||
printability_imgs.append(np.full((side, side), green))
|
||
printability_imgs.append(np.full((side, side), blue))
|
||
printability_array.append(printability_imgs)
|
||
|
||
printability_array = np.asarray(printability_array)
|
||
printability_array = np.float32(printability_array)
|
||
pa = torch.from_numpy(printability_array)
|
||
return pa
|
||
|
||
|
||
class TotalVariation(nn.Module):
|
||
"""TotalVariation: calculates the total variation of a patch.
|
||
|
||
Module providing the functionality necessary to calculate the total Variation (TV) of an adversarial patch.
|
||
|
||
TotalVariation:计算补丁的总变化。
|
||
该模块提供了计算对抗性补丁的总变化 (TV) 所需的功能。
|
||
|
||
"""
|
||
|
||
def __init__(self):
|
||
super(TotalVariation, self).__init__()
|
||
|
||
def forward(self, adv_patch):
|
||
# bereken de total variation van de adv_patch
|
||
tvcomp1 = torch.sum(torch.abs(adv_patch[:, :, 1:] - adv_patch[:, :, :-1] + 0.000001), 0)
|
||
tvcomp1 = torch.sum(torch.sum(tvcomp1, 0), 0)
|
||
tvcomp2 = torch.sum(torch.abs(adv_patch[:, 1:, :] - adv_patch[:, :-1, :] + 0.000001), 0)
|
||
tvcomp2 = torch.sum(torch.sum(tvcomp2, 0), 0)
|
||
tv = tvcomp1 + tvcomp2
|
||
return tv / torch.numel(adv_patch)
|
||
|
||
|
||
class PatchTransformer(nn.Module):
|
||
"""PatchTransformer: transforms batch of patches
|
||
|
||
Module providing the functionality necessary to transform a batch of patches, randomly adjusting brightness and
|
||
contrast, adding random amount of noise, and rotating randomly. Resizes-patches according to as size based on the
|
||
batch of labels, and pads them to the dimension of an image.
|
||
|
||
变换一批补丁,随机调整亮度和对比度,添加随机数量的噪声,随机旋转。 根据标签批次的大小调整补丁大小,并将它们填充到图像的尺寸中。
|
||
|
||
"""
|
||
|
||
def __init__(self):
|
||
super(PatchTransformer, self).__init__()
|
||
self.min_contrast = 0.8
|
||
self.max_contrast = 1.2
|
||
self.min_brightness = -0.1
|
||
self.max_brightness = 0.1
|
||
self.noise_factor = 0.10
|
||
self.minangle = -20 / 180 * math.pi
|
||
self.maxangle = 20 / 180 * math.pi
|
||
self.medianpooler = MedianPool2d(7, same=True) # 中值池化
|
||
'''
|
||
kernel = torch.cuda.FloatTensor([[0.003765, 0.015019, 0.023792, 0.015019, 0.003765],
|
||
[0.015019, 0.059912, 0.094907, 0.059912, 0.015019],
|
||
[0.023792, 0.094907, 0.150342, 0.094907, 0.023792],
|
||
[0.015019, 0.059912, 0.094907, 0.059912, 0.015019],
|
||
[0.003765, 0.015019, 0.023792, 0.015019, 0.003765]])
|
||
self.kernel = kernel.unsqueeze(0).unsqueeze(0).expand(3,3,-1,-1)
|
||
'''
|
||
|
||
def forward(self, adv_patch, lab_batch, img_size, do_rotate=True, rand_loc=True):
|
||
# adv_patch = F.conv2d(adv_patch.unsqueeze(0),self.kernel,padding=(2,2))
|
||
adv_patch = self.medianpooler(adv_patch.unsqueeze(0))
|
||
# Determine size of padding
|
||
pad = (img_size - adv_patch.size(-1)) / 2
|
||
# Make a batch of patches
|
||
adv_patch = adv_patch.unsqueeze(0) # .unsqueeze(0) # 这里又扩大一维,变成5维 1, 1, 3, 300, 300
|
||
adv_batch = adv_patch.expand(lab_batch.size(0), lab_batch.size(1), -1, -1, -1) # adv_batch !! 不是adv_patch!! 8, 14, 3, 300, 300
|
||
batch_size = torch.Size((lab_batch.size(0), lab_batch.size(1))) # 8, 14
|
||
|
||
# Contrast, brightness and noise transforms
|
||
|
||
# Create random contrast tensor
|
||
contrast = torch.cuda.FloatTensor(batch_size).uniform_(self.min_contrast, self.max_contrast)
|
||
contrast = contrast.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1)
|
||
contrast = contrast.expand(-1, -1, adv_batch.size(-3), adv_batch.size(-2), adv_batch.size(-1))
|
||
contrast = contrast.cuda()
|
||
|
||
# Create random brightness tensor
|
||
brightness = torch.cuda.FloatTensor(batch_size).uniform_(self.min_brightness, self.max_brightness)
|
||
brightness = brightness.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1)
|
||
brightness = brightness.expand(-1, -1, adv_batch.size(-3), adv_batch.size(-2), adv_batch.size(-1))
|
||
brightness = brightness.cuda()
|
||
|
||
# Create random noise tensor
|
||
noise = torch.cuda.FloatTensor(adv_batch.size()).uniform_(-1, 1) * self.noise_factor
|
||
|
||
# Apply contrast/brightness/noise, clamp
|
||
adv_batch = adv_batch * contrast + brightness + noise
|
||
|
||
adv_batch = torch.clamp(adv_batch, 0.000001, 0.99999) # 限制到0到1之间
|
||
|
||
# Where the label class_id is 1 we don't want a patch (padding) --> fill mask with zero's
|
||
cls_ids = torch.narrow(lab_batch, 2, 0, 1) # torch.narrow(input,dim,start,length) 从dim开始,返回共享内存的数据start到start+length-1
|
||
cls_mask = cls_ids.expand(-1, -1, 3) # 接上,这里取出 lab_batch的代表id那列,相当于现在的lab_batch[..., 0]
|
||
cls_mask = cls_mask.unsqueeze(-1)
|
||
cls_mask = cls_mask.expand(-1, -1, -1, adv_batch.size(3))
|
||
cls_mask = cls_mask.unsqueeze(-1)
|
||
cls_mask = cls_mask.expand(-1, -1, -1, -1, adv_batch.size(4)) # cls_mask 的大小是 8, 14, 3, 300, 300 数据是类别
|
||
msk_batch = torch.cuda.FloatTensor(cls_mask.size()).fill_(1) - cls_mask # 这里取出有人所对应的msk
|
||
|
||
# Pad patch and mask to image dimensions
|
||
mypad = nn.ConstantPad2d((int(pad + 0.5), int(pad), int(pad + 0.5), int(pad)), 0) # (padding_left、padding_right、padding_top、padding_bottom) 填充0
|
||
adv_batch = mypad(adv_batch) # 用0填充到416
|
||
msk_batch = mypad(msk_batch)
|
||
|
||
# Rotation and rescaling transforms
|
||
anglesize = (lab_batch.size(0) * lab_batch.size(1)) # 这里是旋转的数量
|
||
if do_rotate:
|
||
angle = torch.cuda.FloatTensor(anglesize).uniform_(self.minangle, self.maxangle)
|
||
else:
|
||
angle = torch.cuda.FloatTensor(anglesize).fill_(0)
|
||
|
||
# Resizes and rotates
|
||
current_patch_size = adv_patch.size(-1)
|
||
lab_batch_scaled = torch.cuda.FloatTensor(lab_batch.size()).fill_(0) # lab_batch_scaled是在原图上的尺寸?
|
||
lab_batch_scaled[:, :, 1] = lab_batch[:, :, 1] * img_size
|
||
lab_batch_scaled[:, :, 2] = lab_batch[:, :, 2] * img_size
|
||
lab_batch_scaled[:, :, 3] = lab_batch[:, :, 3] * img_size
|
||
lab_batch_scaled[:, :, 4] = lab_batch[:, :, 4] * img_size
|
||
target_size = torch.sqrt(
|
||
((lab_batch_scaled[:, :, 3].mul(0.2)) ** 2) + ((lab_batch_scaled[:, :, 4].mul(0.2)) ** 2))
|
||
target_x = lab_batch[:, :, 1].view(np.prod(batch_size))
|
||
target_y = lab_batch[:, :, 2].view(np.prod(batch_size))
|
||
targetoff_x = lab_batch[:, :, 3].view(np.prod(batch_size))
|
||
targetoff_y = lab_batch[:, :, 4].view(np.prod(batch_size))
|
||
if (rand_loc):
|
||
off_x = targetoff_x * (torch.cuda.FloatTensor(targetoff_x.size()).uniform_(-0.4, 0.4))
|
||
target_x = target_x + off_x
|
||
off_y = targetoff_y * (torch.cuda.FloatTensor(targetoff_y.size()).uniform_(-0.4, 0.4))
|
||
target_y = target_y + off_y
|
||
target_y = target_y - 0.05
|
||
scale = target_size / current_patch_size # 原图相对于补丁大小的缩放因子?
|
||
scale = scale.view(anglesize)
|
||
|
||
s = adv_batch.size()
|
||
adv_batch = adv_batch.view(s[0] * s[1], s[2], s[3], s[4])
|
||
msk_batch = msk_batch.view(s[0] * s[1], s[2], s[3], s[4])
|
||
|
||
tx = (-target_x + 0.5) * 2
|
||
ty = (-target_y + 0.5) * 2
|
||
sin = torch.sin(angle)
|
||
cos = torch.cos(angle)
|
||
|
||
# Theta = rotation,rescale matrix
|
||
theta = torch.cuda.FloatTensor(anglesize, 2, 3).fill_(0)
|
||
theta[:, 0, 0] = cos / scale
|
||
theta[:, 0, 1] = sin / scale
|
||
theta[:, 0, 2] = tx * cos / scale + ty * sin / scale
|
||
theta[:, 1, 0] = -sin / scale
|
||
theta[:, 1, 1] = cos / scale
|
||
theta[:, 1, 2] = -tx * sin / scale + ty * cos / scale
|
||
|
||
b_sh = adv_batch.shape
|
||
grid = F.affine_grid(theta, adv_batch.shape)
|
||
|
||
adv_batch_t = F.grid_sample(adv_batch, grid)
|
||
msk_batch_t = F.grid_sample(msk_batch, grid)
|
||
|
||
'''
|
||
# Theta2 = translation matrix
|
||
theta2 = torch.cuda.FloatTensor(anglesize, 2, 3).fill_(0)
|
||
theta2[:, 0, 0] = 1
|
||
theta2[:, 0, 1] = 0
|
||
theta2[:, 0, 2] = (-target_x + 0.5) * 2
|
||
theta2[:, 1, 0] = 0
|
||
theta2[:, 1, 1] = 1
|
||
theta2[:, 1, 2] = (-target_y + 0.5) * 2
|
||
|
||
grid2 = F.affine_grid(theta2, adv_batch.shape)
|
||
adv_batch_t = F.grid_sample(adv_batch_t, grid2)
|
||
msk_batch_t = F.grid_sample(msk_batch_t, grid2)
|
||
|
||
'''
|
||
adv_batch_t = adv_batch_t.view(s[0], s[1], s[2], s[3], s[4])
|
||
msk_batch_t = msk_batch_t.view(s[0], s[1], s[2], s[3], s[4])
|
||
|
||
adv_batch_t = torch.clamp(adv_batch_t, 0.000001, 0.999999)
|
||
# img = msk_batch_t[0, 0, :, :, :].detach().cpu()
|
||
# img = transforms.ToPILImage()(img)
|
||
# img.show()
|
||
# exit()
|
||
|
||
return adv_batch_t * msk_batch_t
|
||
|
||
|
||
class PatchApplier(nn.Module):
|
||
"""PatchApplier: applies adversarial patches to images.
|
||
|
||
Module providing the functionality necessary to apply a patch to all detections in all images in the batch.
|
||
|
||
PatchApplier:对图像应用对抗补丁。
|
||
|
||
"""
|
||
|
||
def __init__(self):
|
||
super(PatchApplier, self).__init__()
|
||
|
||
def forward(self, img_batch, adv_batch):
|
||
advs = torch.unbind(adv_batch, 1) # 沿1维解开
|
||
for adv in advs:
|
||
img_batch = torch.where((adv == 0), img_batch, adv) # 对图像相应的坐标位置替换其像素?好像还没到图像的环节
|
||
return img_batch
|
||
|
||
|
||
'''
|
||
class PatchGenerator(nn.Module):
|
||
"""PatchGenerator: network module that generates adversarial patches.
|
||
|
||
Module representing the neural network that will generate adversarial patches.
|
||
|
||
"""
|
||
|
||
def __init__(self, cfgfile, weightfile, img_dir, lab_dir):
|
||
super(PatchGenerator, self).__init__()
|
||
self.yolo = Darknet(cfgfile).load_weights(weightfile)
|
||
self.dataloader = torch.utils.data.DataLoader(InriaDataset(img_dir, lab_dir, shuffle=True),
|
||
batch_size=5,
|
||
shuffle=True)
|
||
self.patchapplier = PatchApplier()
|
||
self.nmscalculator = NMSCalculator()
|
||
self.totalvariation = TotalVariation()
|
||
|
||
def forward(self, *input):
|
||
pass
|
||
'''
|
||
|
||
|
||
class InriaDataset(Dataset):
|
||
"""InriaDataset: representation of the INRIA person dataset.
|
||
|
||
Internal representation of the commonly used INRIA person dataset.
|
||
Available at: http://pascal.inrialpes.fr/data/human/
|
||
|
||
Attributes:
|
||
len: An integer number of elements in the
|
||
img_dir: Directory containing the images of the INRIA dataset.
|
||
lab_dir: Directory containing the labels of the INRIA dataset.
|
||
img_names: List of all image file names in img_dir.
|
||
shuffle: Whether or not to shuffle the dataset.
|
||
|
||
"""
|
||
|
||
def __init__(self, img_dir, lab_dir, max_lab, imgsize, shuffle=True):
|
||
n_png_images = len(fnmatch.filter(os.listdir(img_dir), '*.png')) # 614 fnmatch.filter返回一个list
|
||
n_jpg_images = len(fnmatch.filter(os.listdir(img_dir), '*.jpg')) # 0
|
||
n_images = n_png_images + n_jpg_images # 图像的总数
|
||
n_labels = len(fnmatch.filter(os.listdir(lab_dir), '*.txt'))
|
||
assert n_images == n_labels, "Number of images and number of labels don't match"
|
||
self.len = n_images
|
||
self.img_dir = img_dir
|
||
self.lab_dir = lab_dir
|
||
self.imgsize = imgsize
|
||
self.img_names = fnmatch.filter(os.listdir(img_dir), '*.png') + fnmatch.filter(os.listdir(img_dir), '*.jpg')
|
||
self.shuffle = shuffle
|
||
self.img_paths = []
|
||
for img_name in self.img_names:
|
||
self.img_paths.append(os.path.join(self.img_dir, img_name))
|
||
self.lab_paths = []
|
||
for img_name in self.img_names:
|
||
lab_path = os.path.join(self.lab_dir, img_name).replace('.jpg', '.txt').replace('.png', '.txt')
|
||
self.lab_paths.append(lab_path)
|
||
self.max_n_labels = max_lab # label的长度
|
||
|
||
def __len__(self):
|
||
return self.len
|
||
|
||
def __getitem__(self, idx):
|
||
assert idx <= len(self), 'index range error'
|
||
img_path = os.path.join(self.img_dir, self.img_names[idx])
|
||
lab_path = os.path.join(self.lab_dir, self.img_names[idx]).replace('.jpg', '.txt').replace('.png', '.txt')
|
||
image = Image.open(img_path).convert('RGB')
|
||
if os.path.getsize(lab_path): # check to see if label file contains data.
|
||
label = np.loadtxt(lab_path)
|
||
else:
|
||
label = np.ones([5])
|
||
|
||
label = torch.from_numpy(label).float()
|
||
if label.dim() == 1:
|
||
label = label.unsqueeze(0)
|
||
|
||
image, label = self.pad_and_scale(image, label)
|
||
transform = transforms.ToTensor()
|
||
image = transform(image)
|
||
label = self.pad_lab(label)
|
||
# print("image size :", image.shape)
|
||
# print("label size :", label.shape)
|
||
return image, label
|
||
|
||
def pad_and_scale(self, img, lab):
|
||
"""
|
||
|
||
Args:
|
||
img:
|
||
|
||
Returns:
|
||
|
||
"""
|
||
w, h = img.size
|
||
if w == h:
|
||
padded_img = img
|
||
else:
|
||
dim_to_pad = 1 if w < h else 2
|
||
if dim_to_pad == 1:
|
||
padding = (h - w) / 2
|
||
padded_img = Image.new('RGB', (h, h), color=(127, 127, 127))
|
||
padded_img.paste(img, (int(padding), 0))
|
||
lab[:, [1]] = (lab[:, [1]] * w + padding) / h
|
||
lab[:, [3]] = (lab[:, [3]] * w / h)
|
||
else:
|
||
padding = (w - h) / 2
|
||
padded_img = Image.new('RGB', (w, w), color=(127, 127, 127))
|
||
padded_img.paste(img, (0, int(padding)))
|
||
lab[:, [2]] = (lab[:, [2]] * h + padding) / w
|
||
lab[:, [4]] = (lab[:, [4]] * h / w)
|
||
resize = transforms.Resize((self.imgsize, self.imgsize))
|
||
padded_img = resize(padded_img) # choose here
|
||
return padded_img, lab
|
||
|
||
def pad_lab(self, lab):
|
||
pad_size = self.max_n_labels - lab.shape[0]
|
||
if (pad_size > 0):
|
||
padded_lab = F.pad(lab, (0, 0, 0, pad_size), value=1) # (左边填充数, 右边填充数, 上边填充数, 下边填充数)
|
||
else:
|
||
padded_lab = lab
|
||
return padded_lab
|
||
|
||
|
||
if __name__ == '__main__':
|
||
if len(sys.argv) == 3:
|
||
img_dir = sys.argv[1]
|
||
lab_dir = sys.argv[2]
|
||
|
||
else:
|
||
print('Usage: ')
|
||
print(' python load_data.py img_dir lab_dir')
|
||
sys.exit()
|
||
|
||
test_loader = torch.utils.data.DataLoader(InriaDataset(img_dir, lab_dir, shuffle=True),
|
||
batch_size=3, shuffle=True)
|
||
|
||
cfgfile = "cfg/yolov2.cfg"
|
||
weightfile = "weights/yolov2.weights"
|
||
printfile = "non_printability/30values.txt"
|
||
|
||
patch_size = 400
|
||
|
||
darknet_model = Darknet(cfgfile)
|
||
darknet_model.load_weights(weightfile)
|
||
darknet_model = darknet_model.cuda()
|
||
patch_applier = PatchApplier().cuda()
|
||
patch_transformer = PatchTransformer().cuda()
|
||
prob_extractor = MaxProbExtractor(0, 80).cuda()
|
||
nms_calculator = NMSCalculator(printfile, patch_size)
|
||
total_variation = TotalVariation()
|
||
'''
|
||
img = Image.open('data/horse.jpg').convert('RGB')
|
||
img = img.resize((darknet_model.width, darknet_model.height))
|
||
width = img.width
|
||
height = img.height
|
||
img = torch.ByteTensor(torch.ByteStorage.from_buffer(img.tobytes()))
|
||
img = img.view(height, width, 3).transpose(0, 1).transpose(0, 2).contiguous()
|
||
img = img.view(1, 3, height, width)
|
||
img = img.float().div(255.0)
|
||
img = torch.autograd.Variable(img)
|
||
|
||
output = darknet_model(img)
|
||
'''
|
||
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)
|
||
|
||
tl0 = time.time()
|
||
tl1 = time.time()
|
||
for i_batch, (img_batch, lab_batch) in enumerate(test_loader):
|
||
tl1 = time.time()
|
||
print('time to fetch items: ', tl1 - tl0)
|
||
img_batch = img_batch.cuda()
|
||
lab_batch = lab_batch.cuda()
|
||
adv_patch = Image.open('data/horse.jpg').convert('RGB')
|
||
adv_patch = adv_patch.resize((patch_size, patch_size))
|
||
transform = transforms.ToTensor()
|
||
adv_patch = transform(adv_patch).cuda()
|
||
img_size = img_batch.size(-1)
|
||
print('transforming patches')
|
||
t0 = time.time()
|
||
adv_batch_t = patch_transformer.forward(adv_patch, lab_batch, img_size)
|
||
print('applying patches')
|
||
t1 = time.time()
|
||
img_batch = patch_applier.forward(img_batch, adv_batch_t)
|
||
img_batch = torch.autograd.Variable(img_batch)
|
||
img_batch = F.interpolate(img_batch, (darknet_model.height, darknet_model.width))
|
||
print('running patched images through model')
|
||
t2 = time.time()
|
||
|
||
for obj in gc.get_objects():
|
||
try:
|
||
if torch.is_tensor(obj) or (hasattr(obj, 'data') and torch.is_tensor(obj.data)):
|
||
try:
|
||
print(type(obj), obj.size())
|
||
except:
|
||
pass
|
||
except:
|
||
pass
|
||
|
||
print(torch.cuda.memory_allocated())
|
||
|
||
output = darknet_model(img_batch)
|
||
print('extracting max probs')
|
||
t3 = time.time()
|
||
max_prob = prob_extractor(output)
|
||
t4 = time.time()
|
||
nms = nms_calculator.forward(adv_patch)
|
||
tv = total_variation(adv_patch)
|
||
print('---------------------------------')
|
||
print(' patch transformation : %f' % (t1 - t0))
|
||
print(' patch application : %f' % (t2 - t1))
|
||
print(' darknet forward : %f' % (t3 - t2))
|
||
print(' probability extraction : %f' % (t4 - t3))
|
||
print('---------------------------------')
|
||
print(' total forward pass : %f' % (t4 - t0))
|
||
del img_batch, lab_batch, adv_patch, adv_batch_t, output, max_prob
|
||
torch.cuda.empty_cache()
|
||
tl0 = time.time()
|