Ashish Mehta
Add data pipeline scripts and configuration files for Visual Genome processing
4687353
Raw
History Blame Contribute Delete
1.86 kB
from __future__ import annotations
from typing import List
import torch
from PIL import Image
from .encoders import ImageBackbone
class BaselineClassifier(torch.nn.Module):
def __init__(
self,
clip_backbone: ImageBackbone | None,
dino_backbone: ImageBackbone | None,
feature_dim: int,
hidden_dims: List[int],
dropout: float,
num_labels: int,
) -> None:
super().__init__()
self.clip_backbone = clip_backbone
self.dino_backbone = dino_backbone
layers: List[torch.nn.Module] = []
input_dim = feature_dim
for hidden in hidden_dims:
layers.append(torch.nn.Linear(input_dim, hidden))
layers.append(torch.nn.ReLU())
layers.append(torch.nn.Dropout(dropout))
input_dim = hidden
layers.append(torch.nn.Linear(input_dim, num_labels))
self.classifier = torch.nn.Sequential(*layers)
def encode(self, images: List[Image.Image], device: torch.device) -> torch.Tensor:
features = []
if self.clip_backbone is not None:
features.append(self.clip_backbone.forward_pil(images, device=device))
if self.dino_backbone is not None:
features.append(self.dino_backbone.forward_pil(images, device=device))
if len(features) == 1:
return features[0]
return torch.cat(features, dim=1)
def forward(self, images: List[Image.Image], device: torch.device) -> torch.Tensor:
feats = self.encode(images=images, device=device)
return self.classifier(feats)
def freeze_backbones(self) -> None:
for backbone in (self.clip_backbone, self.dino_backbone):
if backbone is None:
continue
for param in backbone.parameters():
param.requires_grad = False