摘要:
如何不使用目标检测也能把目标定位出来?
在计算机视觉领域,弱监督定位是一项重要任务,它旨在通过仅使用图像级别的标签来确定图像中物体的位置。其中,类激活图(Class Activation Map,CAM)成为一种常用的方法,它能够可视化模型的注意力区域,帮助我们理解模型在图像分类中的决策依据。而Grad-CAM采用梯度信息实现定位,且加适用于任意网络架构。
通过可视化与灵活的写入网络体系中,Grad-CAM可以很好的将模型感兴趣的区域定位出来,再结合opencv对图像或视频的处理,可以让我们实现类似于目标检测的效果。
详细步骤
首先,我们来简单的实现一下Grad-CAM,这个在我往期的文章里有讲到:Grad-CAM——模型所关注的
代码:
class GradCAM:
def __init__(self, model):
self.model = model
self.model.eval()
self.features = None
self.gradients = None
self.model.features.register_forward_hook(self.save_features_hook)
self.model.features.register_backward_hook(self.save_gradients_hook)
def save_features_hook(self, module, input, output):
self.features = output
def save_gradients_hook(self, module, grad_input, grad_output):
self.gradients = grad_output[0]
def calculate_cam(self, input_tensor, target_class):
output = self.model(input_tensor)
self.model.zero_grad()
one_hot = torch.zeros_like(output)
one_hot[0][target_class] = 1
output.backward(gradient=one_hot, retain_graph=True)
pooled_gradients = F.adaptive_avg_pool2d(self.gradients, 1)
cam = torch.mul(self.features, pooled_gradients).sum(dim=1, keepdim=True)
cam = F.relu(cam)
cam = F.interpolate(cam, input_tensor.size()[2:], mode="bilinear", align_corners