Reputation: 361
Hey I am getting the error
ValueError: All bounding boxes should have positive height and width. Found invaid box [264.0, 632.0, 264.0, 633.3333740234375] for target at index 2.
Epoch 1/1
Mini-batch: 1/1220 Loss: 0.1509
Mini-batch: 101/1220 Loss: 0.1201
Mini-batch: 201/1220 Loss: 0.1103
Mini-batch: 301/1220 Loss: 0.1098
Mini-batch: 401/1220 Loss: 0.1076
Mini-batch: 501/1220 Loss: 0.1056
Mini-batch: 601/1220 Loss: 0.1044
Mini-batch: 701/1220 Loss: 0.1035
ValueError Traceback (most recent call last)
in ()
13
14 # Calculate losses
—> 15 loss_dict = model(images, targets)
16 batch_loss = sum(loss for loss in loss_dict.values()) / len(loss_dict)
17
1 frames
/usr/local/lib/python3.6/dist-packages/torchvision/models/detection/generalized_rcnn.py in forward(self, images, targets)
91 raise ValueError(“All bounding boxes should have positive height and width.”
92 " Found invaid box {} for target at index {}."
—> 93 .format(degen_bb, target_idx))
94
95 features = self.backbone(images.tensors)
ValueError: All bounding boxes should have positive height and width. Found invaid box [264.0, 632.0, 264.0, 633.3333740234375] for target at index 2.
I cant find a bounding box that has these coordinates in label csv file. Can anybody please help me out with this.
here is my dataset class
from torch.utils.data import Dataset, DataLoader
Inherit from pytorch Dataset for convenience
class DamageDataset(Dataset):
def __init__(self, dataframe):
super().__init__()
self.filename = dataframe['filename'].unique()
self.df = dataframe
def __len__(self) -> int:
return len(self.filename)
def __getitem__(self, index: int):
filename = self.filename[index]
image = read_image_from_train_folder(filename).astype(np.float32)
# Scale to [0,1] range expected by the pre-trained model
image /= 255.0
# Convert the shape from [h,w,c] to [c,h,w] as expected by pytorch
image = torch.from_numpy(image).permute(2,0,1)
records = self.df[self.df['filename'] == filename]
boxes = records[['xmin', 'ymin', 'xmax', 'ymax']].values
classes= records['class'].values
damage_labels=[]
damage_dict={
'D00': 1,
'D10': 2,
'D20': 3,
'D40': 4,
}
for label in classes:
damage_labels.append(damage_dict[label])
boxes = torch.as_tensor(boxes, dtype=torch.float32)
n_boxes = boxes.shape[0]
# there is only one foreground class, WHEAT
labels = torch.as_tensor(damage_labels, dtype=torch.float32)
target = {}
target['boxes'] = boxes
target['labels'] = labels
return image, target
and here is my train code:
num_epochs = 1
Prepare the model for training
model = model.to(device)
model.train()
for epoch in range(num_epochs):
print("Epoch %i/%i " % (epoch + 1, num_epochs) )
average_loss = 0
for batch_id, (images, targets) in enumerate(train_data_loader):
# Prepare the batch data
images, targets = move_batch_to_device(images, targets)
# Calculate losses
loss_dict = model(images, targets)
batch_loss = sum(loss for loss in loss_dict.values()) / len(loss_dict)
# Refresh accumulated optimiser state and minimise losses
optimizer.zero_grad()
batch_loss.backward()
can someone help me find out the index of this bounding box so that I can delete it, I have iterated through my dataframe using the code:
for idx, row in merge_labels.iterrows():
if(row[‘xmin’]==264 and row[‘ymin’]== 632 and row[‘xmax’]== 264 and row[‘ymax’]== 633.3333740234375 ):
print(idx)
but it doesnt print any index. thank you
Upvotes: 5
Views: 5422
Reputation: 121
I think you need to check your images bounding boxes. I resolved this issue by making sure that my xmin < xmax and ymin < ymax. if xmin equal to xmax, then it would be a line
Upvotes: 1
Reputation: 136
This is happening because of resize transform applied in fasterRCNN in detection module. If you are explicitly applying a resize operation, the bounding box generated coordinates will change as per the resize definition but if you haven't applied a resize transform and your image min and max size is outsider (800,1333) then a default resize transform is applied.
check the below snippets from the pytorch git repo.
Module: /torchvision/models/detection; Exception generated in generalized_rcnn.py
degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
if degenerate_boxes.any():
# print the first degenerate box
bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
degen_bb: List[float] = boxes[bb_idx].tolist()
raise ValueError("All bounding boxes should have positive height and width."
" Found invalid box {} for target at index {}."
.format(degen_bb, target_idx))
Default min max image size; Module: detection/ faster_rcnn
def __init__(self, backbone, num_classes=None,
# transform parameters
min_size=800, max_size=1333,
image_mean=None, image_std=None,
............................
transform = GeneralizedRCNNTransform(min_size, max_size, image_mean, image_std)
Target resizing; Module: detection / transform.py
def resize_boxes(boxes, original_size, new_size):
# type: (Tensor, List[int], List[int]) -> Tensor
ratios = [
torch.tensor(s, dtype=torch.float32, device=boxes.device) /
torch.tensor(s_orig, dtype=torch.float32, device=boxes.device)
for s, s_orig in zip(new_size, original_size)
]
ratio_height, ratio_width = ratios
xmin, ymin, xmax, ymax = boxes.unbind(1)
xmin = xmin * ratio_width
xmax = xmax * ratio_width
ymin = ymin * ratio_height
ymax = ymax * ratio_height
return torch.stack((xmin, ymin, xmax, ymax), dim=1)
You can fix this by removing/correcting bounding boxes where xmin and xmax or ymin and ymax are equal in the original dataset.
Upvotes: 3