• 카테고리

    질문 & 답변
  • 세부 분야

    딥러닝 · 머신러닝

  • 해결 여부

    미해결

안녕하세요. CAM 연산 때 사용하는 label에 대해서 질문이 있습니다

21.07.08 14:04 작성 조회수 123

0

안녕하세요. 강의 잘 듣고 있습니다

CAM 연산하는 과정에서 의문점이 있어서요. 크게 상관은 없을 것 같은데, 정확하게 CAM 연산을 보려면 모델이 예측한 라벨에 대해서 CAM 연산을 수행하는 것이 맞죠? 코드는 정답 라벨을 가지고 해서, 크게 상관은 없겠지만 의도하신 것이 맞는지 궁금합니다

감사합니다

def cam(model, trainset, img_sample, img_size):
    model.eval()
    with torch.no_grad(): # requires_grad 비활성화

        model.layer4[1].bn2.register_forward_hook(get_activation('final')) # feature extraction의 마지막 feature map 구하기
        data, label = trainset[img_sample] # 이미지 한 장과 라벨 불러오기
        data.unsqueeze_(0) # 4차원 3차원 [피쳐수 ,너비, 높이] -> [1,피쳐수 ,너비, 높이]
        _ = model(data.to(device))
        act = activation['final'].squeeze() # 4차원 [1,피쳐수 ,너비, 높이] -> 3차원 [피쳐수 ,너비, 높이]
        w = model.fc.weight # classifer의 가중치 불러오기
        
        for idx in range(act.size(0)): # CAM 연산
            if idx == 0:
                tmp = act[idx] * w[label][idx] 
            else:
                tmp += act[idx] * w[label][idx]

        # 모든 이미지 팍셀값을 0~255로 스케일하기 
        normalized_cam = tmp.cpu().numpy()
        normalized_cam = (normalized_cam - np.min(normalized_cam)) / (np.max(normalized_cam) - np.min(normalized_cam))
        original_img = np.uint8((data[0][0] / 2 + 0.5) * 255)

        # 원본 이미지 사이즈로 리사이즈
        cam_img = cv2.resize(np.uint8(normalized_cam * 255), dsize=(img_size, img_size)) 
        
    return cam_img, original_img

답변 1

답변을 작성해보세요.

1

안녕하세요.

정말 좋은 질문입니다!

이해하신 부분이 맞습니다. 

예측값에 대한 CAM이미지는 label 대신 예측 라벨을 넣어주시면 됩니다!

모델 쪽에 아래와 같이 수정해 주시고 

output = model(data.to(device))
_, prediction = torch.max(output, 1)
for문 안에 라벨 label 대신  prediction.item()을 사용하시면 됩니다. 
예측값과 실제값이 다른 경우 CAM이미지도 당연히 다르게 나옵니다.
실제값을 기준으로 하게 되면 실제 클래스에 영향을 주는 분포가 나오게 되며 원래 방법과 같이 예측값으로 계산하면 예측 클래스에 대한 히트맵이 나오게 됩니다.
영상에서 관련 내용에 대한 자세한 언급이 없었네요.
질문 감사해요 :)
열공 하세요!