[Python] RuntimeError: mat1 and mat2 shapes cannot be multiplied when using gradcam

Discussão em 'Python' iniciado por Stack, Abril 29, 2025.

  1. Stack

    Stack Membro Participativo

    I made a cnn model like this and trained the batch dataset. My data preprocessing code was this

    train_dir = r'C:\Users\roobe\BACH\norm\train\patches\train' # 훈련 데이터 폴더
    val_dir = r'C:\Users\roobe\BACH\norm\train\patches\val' # 검증 데이터 폴더

    # 데이터 전처리 정의 (크기 조정, 텐서로 변환, 정규화)
    transform = transforms.Compose([
    transforms.Resize((224, 224)), # 크기 조정
    transforms.ToTensor(), # 이미지 -> 텐서
    transforms.Normalize([0.5]*3, [0.5]*3) # 정규화
    ])


    # ImageFolder로 데이터셋 불러오기
    train_dataset = datasets.ImageFolder(root=train_dir, transform=transform)
    val_dataset = datasets.ImageFolder(root=val_dir, transform=transform)

    # DataLoader 생성 (훈련 데이터는 shuffle=True로 설정)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) # 훈련 데이터는 섞기
    val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False) # 검증 데이터는 섞지 않음

    # 클래스 목록 출력 (라벨 확인)
    print("클래스 목록:", train_dataset.classes) # ['0', '1', '2', '3'] 등의 출력



    and I made CNN model like this

    class CNN(nn.Module):
    def __init__(self):
    super(CNN, self).__init__()
    # L1 ImgIn shape=(15161, 224, 224, 3)
    self.layer1 = torch.nn.Sequential(
    nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=2),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=2, stride=2))
    # L2 ImgIn shape=(?, 32, 56, 56)
    self.layer2 = torch.nn.Sequential(
    nn.Conv2d(32, 64, 3, stride=2, padding=1),
    nn.ReLU(),
    nn.MaxPool2d(2, stride=2))

    self.dropout = nn.Dropout2d(p=0.5) # Dropout 레이어 추가
    self.fc = nn.Linear(64*14*14, 4)
    nn.init.kaiming_normal_(self.fc.weight)

    def forward(self, x):
    out = self.layer1(x)
    out = self.layer2(out)
    out = self.dropout(out) # Dropout 적용
    out = out.view(out.size(0), -1) # Flatten
    out = self.fc(out)
    return out


    It worked well in test and train code, but when I tried to make heatmap with gradcam, they kept give me message like
    RuntimeError: mat1 and mat2 shapes cannot be multiplied (1x16384 and 12544x4). I've checked the image after resizing and the size was like this
    torch.Size([32, 3, 224, 224]). The code I used for gradcam wa this:

    import os
    from PIL import Image
    import numpy as np
    import torch
    import matplotlib.pyplot as plt
    from torchvision import transforms, models
    from pytorch_grad_cam import GradCAM
    from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
    from pytorch_grad_cam.utils.image import show_cam_on_image
    from torchvision.transforms import Compose, ToTensor, Normalize
    import math

    def preprocess_image(img: np.ndarray, mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) -> torch.Tensor:
    preprocessing = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=mean, std=std)
    ])
    return preprocessing(img.copy()).unsqueeze(0)

    # 이미지 폴더 경로 설정
    img_folder = 'C:/Users/roobe/BACH/norm/train/patches/val'
    img_files = [os.path.join(root, file) for root, dirs, files in os.walk(img_folder)
    for file in files if file.endswith(('.png', '.jpg', '.jpeg'))]

    # 최대 20개 이미지만 시각화
    img_files = img_files[:20]

    # 모델 불러오기
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    model = CNN().to(device)
    model.load_state_dict(torch.load('cnnnew.pth'))
    model.eval()

    # Grad-CAM 인스턴스 설정
    cam = GradCAM(model=model, target_layers=[model.layer2[0]])

    # 시각화
    num_images = len(img_files)
    cols = 5
    rows = math.ceil(num_images / cols)
    plt.figure(figsize=(20, 4 * rows))

    for idx, img_path in enumerate(img_files):
    img_pil = Image.open(img_path).convert('RGB')
    img_np = np.array(img_pil).astype(np.float32) / 255.
    input_tensor = preprocess_image(img_np).to(device)

    # 예측 및 Grad-CAM 계산
    output = model(input_tensor)
    pred_class = torch.argmax(output, dim=1).item()
    targets = [ClassifierOutputTarget(pred_class)]
    grayscale_cam = cam(input_tensor=input_tensor, targets=targets)[0]
    visualization = show_cam_on_image(img_np, grayscale_cam, use_rgb=True)

    # 서브플롯에 시각화 결과 표시
    plt.subplot(rows, cols, idx + 1)
    plt.imshow(visualization)
    plt.axis('off')
    plt.title(f"Class {pred_class}\n{os.path.basename(img_path)}", fontsize=9)

    plt.tight_layout()
    plt.show()


    any advice would be thankful!

    Continue reading...

Compartilhe esta Página