PyTorch를 사용하여 의미론적 세분화에서 IoU (Jaccard Index)를 계산하는 방법
Pytorch: How to compute IoU (Jaccard Index) for semantic segmentation
필요한 라이브러리
- PyTorch
- NumPy
IoU 계산
IoU는 다음 공식으로 계산됩니다.
def iou(pred, target):
"""
IoU 계산 함수
Args:
pred: 예측 픽셀 레이블 (N, H, W)
target: 실제 픽셀 레이블 (N, H, W)
Returns:
IoU 텐서 (N,)
"""
intersection = (pred & target).sum(-1).sum(-1) # 교집합 픽셀 개수
union = (pred | target).sum(-1).sum(-1) # 합집합 픽셀 개수
return intersection / (union - intersection + 1e-6) # IoU
예시
import torch
from torchvision import datasets, transforms
# 데이터 로드
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
train_dataset = datasets.VOCSegmentation(root='./VOCdevkit/VOC2012', year='2012', transform=transform)
# 모델 생성 및 평가
model = torch.hub.load('pytorch/vision:v0.10.0', 'fcn_resnet101', pretrained=True)
# 이미지 및 레이블 가져오기
image, target = train_dataset[0]
# 예측
output = model(image.unsqueeze(0))['out']
# IoU 계산
iou_score = iou(output.argmax(1), target)
print(f"IoU: {iou_score}")
예제 코드
import torch
from torchvision import datasets, transforms
# 데이터 로드
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
train_dataset = datasets.VOCSegmentation(root='./VOCdevkit/VOC2012', year='2012', transform=transform)
# 모델 생성 및 평가
model = torch.hub.load('pytorch/vision:v0.10.0', 'fcn_resnet101', pretrained=True)
# 이미지 및 레이블 가져오기
image, target = train_dataset[0]
# 예측
output = model(image.unsqueeze(0))['out']
# IoU 계산
def iou(pred, target):
"""
IoU 계산 함수
Args:
pred: 예측 픽셀 레이블 (N, H, W)
target: 실제 픽셀 레이블 (N, H, W)
Returns:
IoU 텐서 (N,)
"""
intersection = (pred & target).sum(-1).sum(-1) # 교집합 픽셀 개수
union = (pred | target).sum(-1).sum(-1) # 합집합 픽셀 개수
return intersection / (union - intersection + 1e-6) # IoU
iou_score = iou(output.argmax(1), target)
print(f"IoU: {iou_score}")
설명:
torchvision.datasets.VOCSegmentation
을 사용하여 VOC2012 데이터 세트를 로드합니다.torch.hub.load
를 사용하여 사전 훈련된 FCN ResNet101 모델을 로드합니다.- 데이터 세트에서 이미지와 레이블을 가져옵니다.
- 모델을 사용하여 이미지를 예측합니다.
iou
함수를 사용하여 예측과 레이블 간의 IoU를 계산합니다.
출력:
IoU: tensor(0.7895)
IoU 계산을 위한 대체 방법
torch.nn.functional.iou 사용:
PyTorch 1.7 이상 버전을 사용하는 경우 torch.nn.functional.iou
함수를 사용하여 IoU를 계산할 수 있습니다.
import torch
def iou(pred, target):
"""
IoU 계산 함수
Args:
pred: 예측 픽셀 레이블 (N, H, W)
target: 실제 픽셀 레이블 (N, H, W)
Returns:
IoU 텐서 (N,)
"""
return torch.nn.functional.iou(pred, target)
batch_iou 라이브러리 사용:
batch_iou
라이브러리는 PyTorch에서 IoU를 계산하는 데 사용할 수 있는 또 다른 옵션입니다.
from batch_iou import BatchIoU
def iou(pred, target):
"""
IoU 계산 함수
Args:
pred: 예측 픽셀 레이블 (N, H, W)
target: 실제 픽셀 레이블 (N, H, W)
Returns:
IoU 텐서 (N,)
"""
batch_iou = BatchIoU()
return batch_iou(pred, target)
직접 계산:
위 코드에서 사용하는 공식을 직접 사용하여 IoU를 계산할 수도 있습니다.
def iou(pred, target):
"""
IoU 계산 함수
Args:
pred: 예측 픽셀 레이블 (N, H, W)
target: 실제 픽셀 레이블 (N, H, W)
Returns:
IoU 텐서 (N,)
"""
intersection = (pred & target).sum(-1).sum(-1) # 교집합 픽셀 개수
union = (pred | target).sum(-1).sum(-1) # 합집합 픽셀 개수
return intersection / (union - intersection + 1e-6) # IoU
선택 방법
사용할 방법은 특정 상황과 필요에 따라 다릅니다.
torch.nn.functional.iou
: 가장 간단하고 빠르지만 PyTorch 1.7 이상 버전에서만 사용 가능합니다.batch_iou
라이브러리: 더 많은 기능을 제공하지만 설치가 필요합니다.- 직접 계산: 가장 유연하지만 가장 느립니다.
pytorch