Error

[Error - Pytorch] RuntimeError : Boolean value of Tensor with more than on values is ambiguous

Y30L 2024. 2. 28. 16:30

Pytorch를 사용하여 Siamese Network 기반 ML 모델을 구현하던 중 RuntimeError : Boolean value of Tensor with more than on values is ambiguous 에러가 발생하였다.

 

1. 에러 내용

Siamese Network 모델의 Train 과정 이후 Performace 측정을 위해 코드를 돌리던 중 Tensor의 값과 관련된 에러가 발생하였다. 에러가 발생한 코드는 아래와 같으며 Model의 Predict 결과를 Threshold 기준으로 하여 판단하는 부분에서 에러가 발생하였다.

def evaluate_model(model, test_loader, device):
    model.eval()  # 모델을 평가 모드로 설정
    correct = 0
    total = 0
    threshold = 0.6

    with torch.no_grad():  # 기울기 계산을 비활성화
        for img1, img2, labels in test_loader:
            img1, img2, labels = img1.to(device), img2.to(device), labels.to(device)
            outputs = model(img1, img2)
            print(outputs)
            # 에러가 발생한 지점
            if outputs >= threshold:
                predicted = 1.0
            else:
                predicted = 0.0
            total += labels.size(0)
            correct += (predicted.view(-1) == labels).sum().item()

    accuracy = 100 * correct / total
    print(f'Accuracy on the test set: {accuracy:.4f}%')

# device 설정
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 평가 실행
evaluate_model(model, test_loader, device)

 

 

2. 문제 해결

왜 이런 에러가 발생했을까? 우선 해당 에러가 어떤 에러인지 확인해야 한다.

RuntimeError : Boolean value of Tensor with more than on values is ambiguous 해당 에러는 Tensor 값을 Boolean 값으로 비교할 때 발생하는 에러이므로 우선적으로 Output(Model Test의 Predict) 값을 확인하였다.

 

Output 값은 아래와 같이 단일 값이 아닌 20개의 값으로 이루어져 있는데 20개의 값 모두를 단순히 Threshold 값과 비교를 하였기 때문에 에러가 발생하였다.

# OutPut 값
tensor([[0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005],
        [0.5005]], device='cuda:0')

 

이를 해결하기 위해 각 객체가 Threshold 이상이라면 1.0(정상) 이하라면 0.0(이상)으로 판단을 하도록 하였고 각 객체 접근 및 조건에 부합하는지 확인하기 위해 torch.where()를 사용하였다.

 

torch.where()함수는 첫번째 인자로 Target으로 하는 Tensor 및 조건문, 두번째 인자로 해당 Tensor의 각 객체가 조건을 만족할 경우 Return할 Value, 세번째 인자로는 해당 Tensor의 각 객체가 조건을 만족하지 않을 경우 Return할 Value를 필요로 한다.

torch.where()

 

이를 실제 코드에 적용하였을 때 문제는 바로 해결되었으며 적용한 코드는 아래와 같다. outputs Tensor의 객체 하나하나 검사를 하는데 각 객체가 threshold 값 이상이라면 1.0, 이하라면 0.0 값을 predicted 값으로 생성하게 된다.

with torch.no_grad():  # 기울기 계산을 비활성화
    for img1, img2, labels in test_loader:
        img1, img2, labels = img1.to(device), img2.to(device), labels.to(device)
        outputs = model(img1, img2).squeeze() 
        predicted = torch.where(outputs >= threshold, 1.0, 0.0).to(device)  # 예측값 생성
        total += labels.size(0)
        correct += (predicted == labels).sum().item()