Fasterrcnn : ValueError: In training mode, targets should be passed when trying to add num_of_classes

num_classes = 2 

model= torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
in_features = model.roi_heads.box_predictor.cls_score.in_features
model.roi_heads.box_predictor =torchvision.models.detection.fasterrcnn_resnet50_fpn(in_features, num_classes)

params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=0.005,
                            momentum=0.9, weight_decay=0.0005)

# and a learning rate scheduler which decreases the learning rate by
# 10x every 3 epochs
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                               step_size=3,
                                               gamma=0.1)

model.train()
for epoch in tqdm(range(1)):
    for images,targets in tqdm(data_loader):
        print(len(images))
        print(len(targets))
        print(images)
        print(targets)
        #images = list(image.to(device) for image in images)
        #targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        
        for target in targets:
            print(target["boxes"])
        images = list(image.to(device) for image in images)
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        loss_dict = model(images, targets)
        print(loss_dict)
        losses = sum(loss for loss in loss_dict.values())
        losses.backward()

        optimizer.zero_grad()
        optimizer.step()

The following code gives an errors of : ValueError: In training mode, targets should be passed

However this doesn’t give and works fine

#model.train()


#print(inputs)
#print(targets)
#model = models.detection.fasterrcnn_resnet50_fpn()
model= torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)


params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=0.005,
                            momentum=0.9, weight_decay=0.0005)

# and a learning rate scheduler which decreases the learning rate by
# 10x every 3 epochs
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                               step_size=3,
                                               gamma=0.1)

model.train()
for epoch in tqdm(range(1)):
    for images,targets in tqdm(data_loader):
        print(len(images))
        print(len(targets))
        print(images)
        print(targets)
        #images = list(image.to(device) for image in images)
        #targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        
        for target in targets:
            print(target["boxes"])
        images = list(image.to(device) for image in images)
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        loss_dict = model(images, targets)
        print(loss_dict)
        losses = sum(loss for loss in loss_dict.values())
        losses.backward()

        optimizer.zero_grad()
        optimizer.step()

So when I try to change number of classes i will this problem couldn’t figure about why this happening if you can help, i will be happy

Based on your first code snippet you are adding another fasterrcnn_resnet50_fpn to the initial model.roi_heads.box_predictor, which would expect the same inputs and targets as model.
I guess the preceding layer of model.roi_heads.box_predictor doesn’t output the expectged input and target tensors, so that the “nested” fasterrcnn_resnet50_fpn model will fail.
Is this indeed your use case or were you planning to add another module to model.roi_heads.box_predictor?

from torchvision.models.detection.faster_rcnn import FastRCNNPredictor

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)

device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

num_classes = 2 # 1 class (person) + background

in_features = model.roi_heads.box_predictor.cls_score.in_features

model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)

model=model.to(device)

Thank you very much for your response, I understood what I made was wrong, I revised my model to this and now works fine :slight_smile: