faster_rcnn_resnet50 / src /backbone.py
0Curious0's picture
Added src files
6ca1e94 verified
Raw
History Blame Contribute Delete
3.05 kB
import copy
import torch
import torch.nn as nn
from torchvision.models import resnet50, ResNet50_Weights
from torchvision import transforms
from torchvision.transforms import functional as TF
# creating a backbone class as we will be using different backbones in training
class Backbone(nn.Module):
def __init__(self, pretrained=True):
# calling the super class of Backbone class
super().__init__()
# loading the resnet50 model with pretrained weights
weights = ResNet50_Weights.DEFAULT if pretrained else None
base_model = resnet50(weights=weights)
# base_model.children() returns an iterator over immediate children modules, so we can convert it to a list
# removing the conv5_x layer as in the paper and the last 2 avg_pool, fc layers
self.backbone = nn.Sequential(*list(base_model.children())[:-3])
def forward(self, x):
# passing the input through the backbone model
x = self.backbone(x)
return x
# Here we could have used transforms.Compose(lambda img : resize_shorter_side(img), ToTensor()) without returning the target
# But as a practice, we will create custom transform classes to handle both the image and its corresponding annotation dictionary.
# Create a custom transform class to convert PIL images to PyTorch tensors and apply the resize transformation
class ToTensorTransform:
def __call__(self, img, target):
img = TF.to_tensor(img)
return img, target
# Create a custom transform class to resize the shorter side of the image using resize_shorter_side function and update the annotation dictionary accordingly
class ResizeTransform:
def __init__(self, short_side=600, max_side=1000):
self.short_side = short_side
self.max_side = max_side
def __call__(self, img, target):
return self.resize_shorter_side(img, target)
# resize fn to resize the shorter side of the image to a specified size while maintaining the aspect ratio, and also update the annotation dictionary with the new dimensions of the image.
def resize_shorter_side(self, img, target):
h, w = img.size
annotation_dict = copy.deepcopy(target)
scale = self.short_side / min(w, h)
if scale * max(w, h) > self.max_side:
scale = self.max_side / max(w, h)
new_w = int(w * scale)
new_h = int(h * scale)
annotation_dict["size"]["new_width"] = new_w
annotation_dict["size"]["new_height"] = new_h
return TF.resize(img, (new_h, new_w)), annotation_dict
# Create a composed transform class to apply multiple transformations sequentially
class ComposedTransform:
def __init__(self, transforms):
self.transforms = transforms
def __call__(self, img, target):
for transform in self.transforms:
img, target = transform(img, target)
return img, target
backbone_transform = ComposedTransform([
ResizeTransform(short_side=600, max_side=1000),
ToTensorTransform(),
])