总结:我的项目是尝试从各个角度测试对对象检测模型的 3D 对抗性攻击,我目前正在尝试获得模型纹理的累积梯度。我的方法是使用 torch.nn.CrossEntropyLoss() 来计算带有 loss.backward() 的纹理张量的损失。然后,我将获取纹理张量的梯度并将其添加到名为 accum_texture_grad 的值上。如果这是我通过循环的第一次迭代,它只会将 accum_texture_grad 的值设置为 texture_tensor.grad。
我的主要问题是,即使在调用 loss.backward() 之后,texture_tensor.grad 的值仍然为 None。因此,由于错误“AttributeError: 'NoneType' object has no attribute 'data'”,我无法设置累积纹理梯度值。有没有另一种方法可以让 texture_tensor.grad 获得一个值,或者以其他方式让累积的纹理渐变起作用?
基于 StackOverflow 上的类似问题,我尝试了一些解决方案。我已经测试过是否是纹理张量不是叶子的问题,或者损失值的 grad_fn 是否不正确。当我尝试打印这些值时,texture_tensor.is_leaf 为 True,并且打印损失显示 grad_fn 为 NllLossBackward,这应该是正确的。
此处显示了我当前代码的一些重要片段。
#(imports)
model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
#model = models.inception_v3(pretrained=True)
#Sets model to evaluation mode (results in layers/parts of model behaving differently such as BatchNorm layers)
model.eval()
# Defining a function for get a prediction result from the model
def get_prediction(img_path, threshold):
img = Image.open(img_path) # Load the image
print(type(img))
transform = tr.Compose([tr.ToTensor()]) # Defing PyTorch Transform
#model(img.tensors)
#img= model.transform(img)
img = transform(img) # Apply the transform to the image
print(type(img))
pred = model([img]) # Pass the image to the model
print(pred)
pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())] # Get the Prediction Score
pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().numpy())] # Bounding boxes
pred_score = list(pred[0]['scores'].detach().numpy())
true_pred_score = [pred_score]
global pred_tensor
pred_tensor = torch.tensor(true_pred_score).requires_grad_()
pred_t = [pred_score.index(x) for x in pred_score if x > threshold][-1] # Get list of index with score greater than threshold.
pred_boxes = pred_boxes[:pred_t+1]
pred_class = pred_class[:pred_t+1]
return pred_boxes, pred_class
# Defining a api function for object detection
def object_detection_api(img_path, threshold=0.5, rect_th=3, text_size=1.5, text_th=3):
boxes, pred_cls = get_prediction(img_path, threshold) # Get predictions
img = cv2.imread(img_path) # Read image with cv2
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB
for i in range(len(boxes)):
cv2.rectangle(img, boxes[i][0], boxes[i][1],color=(0, 255, 0), thickness=rect_th) # Draw Rectangle with the coordinates
cv2.putText(img,pred_cls[i], boxes[i][0], cv2.FONT_HERSHEY_SIMPLEX, text_size, (0,255,0),thickness=text_th) # Write the prediction class
class_arr.append(pred_cls[i])
plt.figure(figsize=(15,20)) # display the output image
plt.imshow(img)
plt.xticks([])
plt.yticks([])
plt.show()
target = Variable(torch.LongTensor([true_num_target]), requires_grad=False)
target = target.to(device)
#...(skipping to loss section)
#Calculate the loss
loss_fun = torch.nn.CrossEntropyLoss()
loss = loss_fun(pred_tensor, target)
#Calculate gradients of model in backward pass
loss.backward()
#Collect datagrad and accumulate
if accum_texture_grad is None:
print('LOSS')
print(loss)
print('IS LEAF')
print(texture_tensor.is_leaf)
print('DATA')
print(texture_tensor.data)
print('GRAD')
print(texture_tensor.grad)
accum_texture_grad = texture_tensor.grad.data.detach().clone()
else:
accum_texture_grad += texture_tensor.grad.data.detach().clone()
谢谢,如果需要任何其他信息,请随时告诉我。