YOLOv5 implements class activation map (Grad-CAM)

I wanted to draw the class activation map of YOLOv5 before, but after trying for a long time without success, I accidentally found that someone in the YOLOv5 issue has implemented a gram-cam that supports drawing a certain layer of the network, but it seems that it has not yet been incorporated into the YOLOv5 project: Add GradCAM integration

1. How to use

  • Open the github link above :
    insert image description here
  • Click onFiles changed :
    insert image description here
  • Copy explainer.py in the explainer folder here to the file directory of yolov5 :
    insert image description here
  • Specify parameters :
def parseopt():  
    parser = argparse.ArgumentParser()  
    # 指定你训练好的网络权重路径  
    parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'runs/train/yolov5l/weights/best.pt', help='model path or triton URL')  
    # 指定要画类激活图的图像路径(目前只支持一张一张地画)  
    parser.add_argument('--source', type=str, default='/home/ding/fyw/YOLOv5/data/images/0.jpg', help='file/dir/URL/glob/screen/0(webcam)')  
    parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')  
    # 指定gpu  
    parser.add_argument('--device', default='1', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')  
    # 选择类激活图类型  
    parser.add_argument('--method',  
                        type=str,  
                        default='EigenCAM',  
                        help='the method to use for interpreting the feature maps')  
    parser.add_argument('--verbose', action='store_true', help='verbose log')
  • Just run :
    python explainer/explainer.py

2. How to draw the class activation map of a specific layer

Here we take YOLOv5l as an example. First, we print(model)print out the model (too long to show only part of it):

YOLOV5TorchObjectDetector(
  (model): DetectionModel(
    (model): Sequential(
      (0): Conv(
        (conv): Conv2d(3, 64, kernel_size=(6, 6), stride=(2, 2), padding=(2, 2), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
        (act): SiLU()
      )
      (1): Conv(
        (conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
        (act): SiLU()   # grad_cam 1
      )
      (2): C3(
        (cv1): Conv(
          (conv): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn): BatchNorm2d(64, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
          (act): SiLU()
        )
        (cv2): Conv(
          (conv): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn): BatchNorm2d(64, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
          (act): SiLU()
        )
        (cv3): Conv(
          (conv): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn): BatchNorm2d(128, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
          (act): SiLU()
        )
        (m): Sequential(
          (0): Bottleneck(
            (cv1): Conv(
              (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
              (bn): BatchNorm2d(64, eps=0.001, momentum=0.03, affine=True, track_running_stats=True)
              (act): SiLU()   # grad_cam 2
            )

For example, if you want to draw grad_cam 1(see the comments of the model file above), then modify the code target_layers:
insert image description here
modify to:
target_layers = [model.model.model.model[1]._modules['act']]
If you want to draw grad_cam 2, modify to:
target_layers = [model.model.model.model[2]._modules['m']._modules['0']._modules['cv1']._modules['act']]
For any other layer in the model, follow the above method analogy That's fine.

In addition, errors caused by version issues may occur when running this code:

TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

Modify this line of code and add .cpu():
insert image description here

Guess you like

Origin blog.csdn.net/Fyw_Fyw_/article/details/130511164