ZeroDivisionError: integer division or modulo by zero

boingboing·2024년 8월 29일

boxes += [boxes[i % len(boxes)] for i in range(num_duplicates)]

에러 발생 위치

train.py의


    for epoch in range(0, args.epochs): # 100번. 
     ...
        train_losses, train_iter_metrics = train_one_epoch(args, model, optimizer, train_loader, epoch, criterion)

train_one_epoch 부분의 train_loader.


def train_one_epoch(args, model, optimizer, train_loader, epoch, criterion):
   ...

	# 여기 아래 줄에서 에러 발생함. 
    for batch, batched_input in enumerate(train_loader): # trainloader에서 batch size만큼 데이터 가져와서 학습하는 부분. 

위의 train Loader enumerate부분에서

DataLoader.py의 TrainingDataset 클래스에서

	__getitem__
    boxes = get_boxes_from_mask(mask_tensor)
  • dataloader 사용 시 get_boxes_from_mask 사용.

def get_boxes_from_mask(mask, box_num=1, std = 0.1, max_pixel = 5):
    """
    Args:
        mask: Mask, can be a torch.Tensor or a numpy array of binary mask.
        box_num: Number of bounding boxes, default is 1.
        std: Standard deviation of the noise, default is 0.1.
        max_pixel: Maximum noise pixel value, default is 5.
    Returns:
        noise_boxes: Bounding boxes after noise perturbation, returned as a torch.Tensor.
    """
    if isinstance(mask, torch.Tensor):
        mask = mask.numpy()
        
    label_img = label(mask)
    regions = regionprops(label_img)

    # Iterate through all regions and get the bounding box coordinates
    boxes = [tuple(region.bbox) for region in regions]

    # If the generated number of boxes is greater than the number of categories,
    # sort them by region area and select the top n regions
    if len(boxes) >= box_num:
        sorted_regions = sorted(regions, key=lambda x: x.area, reverse=True)[:box_num]
        boxes = [tuple(region.bbox) for region in sorted_regions]

    # If the generated number of boxes is less than the number of categories,
    # duplicate the existing boxes
    elif len(boxes) < box_num:
        num_duplicates = box_num - len(boxes)
        boxes += [boxes[i % len(boxes)] for i in range(num_duplicates)]

부분의 utils.py 부분에서 발생.

ZeroDivisionError: integer division or modulo by zero

  • 학습 과정에서 해당 에러 발생함.
boxes += [boxes[i % len(boxes)] for i in range(num_duplicates)] 
  • bounding box 갯수가 0인 경우.

부분에서 에러 발생. len(boxes)가 0. 즉 bounding box 갯수로 나눔.

해결

  • 물어봐서 해결함.

utils.py에


    # Iterate through all regions and get the bounding box coordinates
    boxes = [tuple(region.bbox) for region in regions]

    if len(boxes) > 0 : # 이 if문을 추가함. 
    
        # If the generated number of boxes is greater than the number of categories,
        # sort them by region area and select the top n regions
        if len(boxes) >= box_num:
            sorted_regions = sorted(regions, key=lambda x: x.area, reverse=True)[:box_num]
            boxes = [tuple(region.bbox) for region in sorted_regions]

        # If the generated number of boxes is less than the number of categories,
        # duplicate the existing boxes
        elif len(boxes) < box_num:
            num_duplicates = box_num - len(boxes)
            boxes += [boxes[i % len(boxes)] for i in range(num_duplicates)]

        # Perturb each bounding box with noise
        noise_boxes = []
        for box in boxes:
            y0, x0,  y1, x1  = box
            width, height = abs(x1 - x0), abs(y1 - y0)
            # Calculate the standard deviation and maximum noise value
            noise_std = min(width, height) * std
            max_noise = min(max_pixel, int(noise_std * 5))
            # Add random noise to each coordinate
            try:
                noise_x = np.random.randint(-max_noise, max_noise)
            except:
                noise_x = 0
            try:
                noise_y = np.random.randint(-max_noise, max_noise)
            except:
                noise_y = 0
            x0, y0 = x0 + noise_x, y0 + noise_y
            x1, y1 = x1 + noise_x, y1 + noise_y
            noise_boxes.append((x0, y0, x1, y1))
    else:  # 이 if-else문을 추가함. 
        noise_boxes = [(0,0,mask_size_x,mask_size_y)].
        # 이 부분 추가됨. segmentation 작업의 첫 부분에 필요한 bounding box가 만들어지지 않으면, 전체 box를 bounding box로 잡는 예외처리를 추가함. 
    else:

와... 나는 고치는데 3일 걸렸는데도 실패했는데 어떻게 보자마자 바로 고쳤지..??ㄷㄷ

0개의 댓글