SSD error with change input size from (300, 300) to (640, 480)
See original GitHub issueWhen I change input image size from (300, 300) to (640, 480) in config file, I got an error
command: python tools/train.py configs/ssd.py --validate
Traceback (most recent call last): File “tools/train.py”, line 95, in <module> main() File “tools/train.py”, line 91, in main logger=logger) File “/home/ubuntu/work/mmdetection/mmdet/apis/train.py”, line 61, in train_detector _non_dist_train(model, dataset, cfg, validate=validate) File “/home/ubuntu/work/mmdetection/mmdet/apis/train.py”, line 197, in _non_dist_train runner.run(data_loaders, cfg.workflow, cfg.total_epochs) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/mmcv/runner/runner.py”, line 356, in run epoch_runner(data_loaders[i], **kwargs) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/mmcv/runner/runner.py”, line 262, in train self.model, data_batch, train_mode=True, **kwargs) File “/home/ubuntu/work/mmdetection/mmdet/apis/train.py”, line 39, in batch_processor losses = model(**data) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 493, in call result = self.forward(*input, **kwargs) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/torch/nn/parallel/data_parallel.py”, line 150, in forward return self.module(*inputs[0], **kwargs[0]) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 493, in call result = self.forward(*input, **kwargs) File “/home/ubuntu/work/mmdetection/mmdet/models/detectors/base.py”, line 84, in forward return self.forward_train(img, img_meta, **kwargs) File “/home/ubuntu/work/mmdetection/mmdet/models/detectors/single_stage.py”, line 55, in forward_train *loss_inputs, gt_bboxes_ignore=gt_bboxes_ignore) File “/home/ubuntu/work/mmdetection/mmdet/models/anchor_heads/ssd_head.py”, line 207, in loss cfg=cfg) File “/home/ubuntu/work/mmdetection/mmdet/core/utils/misc.py”, line 24, in multi_apply return tuple(map(list, zip(*map_results))) File “/home/ubuntu/work/mmdetection/mmdet/models/anchor_heads/ssd_head.py”, line 129, in loss_single cls_score, labels, reduction=‘none’) * label_weights File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/torch/nn/functional.py”, line 2056, in cross_entropy return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction) File “/home/ubuntu/miniconda3/envs/open-mmlab/lib/python3.7/site-packages/torch/nn/functional.py”, line 1869, in nll_loss .format(input.size(0), target.size(0))) ValueError: Expected input batch_size (32706) to match target batch_size (32679).
Maybe this caused by I changed the deafult boxes generate process in mmdet/mmdet/models/anchor_heads/ssd_head.py
that the shape between cls_score
and labels
does not match in Line 128 ssd_head.py
.
What I changed in ssd_head.py
are as follow,
# total:
# 1. use fixed scales
# 2. not use aspect ratio flip (no 1/r)
# 3. reduce anchor num in last out layer (by not using sqrt(max_size / min_size) ,
not add aspect ratio = 1)
class SSDHead(AnchorHead):
def __init__(self,
input_size=300,
num_classes=81,
in_channels=(512, 1024, 512, 256, 256, 256),
anchor_strides=(8, 16, 32, 64, 100, 300),
basesize_ratio_range=(0.1, 0.9),
anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
target_means=(.0, .0, .0, .0),
target_stds=(1.0, 1.0, 1.0, 1.0)):
super(AnchorHead, self).__init__()
self.input_size = input_size
self.num_classes = num_classes
self.in_channels = in_channels
self.cls_out_channels = num_classes
#num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios] # <- changed
num_anchors = [3, 3, 3, 3, 3, 2]
reg_convs = []
cls_convs = []
for i in range(len(in_channels)):
reg_convs.append(
nn.Conv2d(
in_channels[i],
num_anchors[i] * 4,
kernel_size=3,
padding=1))
cls_convs.append(
nn.Conv2d(
in_channels[i],
num_anchors[i] * num_classes,
kernel_size=3,
padding=1))
self.reg_convs = nn.ModuleList(reg_convs)
self.cls_convs = nn.ModuleList(cls_convs)
min_ratio, max_ratio = basesize_ratio_range
min_ratio = int(min_ratio * 100)
max_ratio = int(max_ratio * 100)
step = int(np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
min_sizes = []
max_sizes = []
'''
for r in range(int(min_ratio), int(max_ratio) + 1, step):
min_sizes.append(int(input_size * r / 100))
max_sizes.append(int(input_size * (r + step) / 100))
if input_size == 300:
if basesize_ratio_range[0] == 0.15: # SSD300 COCO
min_sizes.insert(0, int(input_size * 7 / 100))
max_sizes.insert(0, int(input_size * 15 / 100))
elif basesize_ratio_range[0] == 0.2: # SSD300 VOC
min_sizes.insert(0, int(input_size * 10 / 100))
max_sizes.insert(0, int(input_size * 20 / 100))
elif input_size == 512:
if basesize_ratio_range[0] == 0.1: # SSD512 COCO
min_sizes.insert(0, int(input_size * 4 / 100))
max_sizes.insert(0, int(input_size * 10 / 100))
elif basesize_ratio_range[0] == 0.15: # SSD512 VOC
min_sizes.insert(0, int(input_size * 7 / 100))
max_sizes.insert(0, int(input_size * 15 / 100))
'''
min_sizes = [8, 16, 32, 64, 128, 256] # <- changed
max_sizes = [16, 32, 64, 128, 256, 270] # <- changed
self.anchor_generators = []
self.anchor_strides = anchor_strides
for k in range(len(anchor_strides)):
base_size = min_sizes[k]
stride = anchor_strides[k]
ctr = ((stride - 1) / 2., (stride - 1) / 2.)
#scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])] # <- changed
if k == (len(anchor_strides)-1):
scales = [1.]
else:
scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
#ratios = [1.] # <- changed
ratios = []
for r in anchor_ratios[k]:
# ratios += [1 / r, r] # 4 or 6 ratio # <- changed
ratios += [r] # 4 or 6 ratio
if not k == (len(anchor_strides)-1):
ratios.append(1.)
anchor_generator = AnchorGenerator(
base_size, scales, ratios, scale_major=False, ctr=ctr)
indices = list(range(len(ratios)))
#indices.insert(1, len(indices)) # <- changed
#print(indices)
anchor_generator.base_anchors = torch.index_select(
anchor_generator.base_anchors, 0, torch.LongTensor(indices))
self.anchor_generators.append(anchor_generator)
self.target_means = target_means
self.target_stds = target_stds
self.use_sigmoid_cls = False
self.cls_focal_loss = False
How can I fixed it?
Where to change the variable named labels
generate process, which in Line 129 ssd_head.py
?
Thank you for any help.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
it seems that it needs to meet the requirement as below:
Unlike other detectors, the architecture and settings of SSD is related to the image resolution, and you may come across issues if you simply change the resolution. You need to understand your modifications if you want to use resolutions other than 300 or 512.