tahamajs's picture
download
raw
3.45 kB
# models.py - Model definitions
import torch
import torch.nn as nn
import torchvision.models as models
def get_resnet50(num_classes):
model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
# Modify the final layer for Re-ID (classification)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, num_classes)
return model
class MHSA(nn.Module):
""" Multi-Head Self-Attention for 2D Images """
def __init__(self, n_dims, width, height, heads=4):
super(MHSA, self).__init__()
self.heads = heads
self.query = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.key = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.value = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.rel_h = nn.Parameter(torch.randn([1, heads, n_dims // heads, 1, height]), requires_grad=True)
self.rel_w = nn.Parameter(torch.randn([1, heads, n_dims // heads, width, 1]), requires_grad=True)
self.softmax = nn.Softmax(dim=-1)
def forward(self, x):
n_batch, C, width, height = x.size()
# 1. Projections
q = self.query(x).view(n_batch, self.heads, C // self.heads, -1)
k = self.key(x).view(n_batch, self.heads, C // self.heads, -1)
v = self.value(x).view(n_batch, self.heads, C // self.heads, -1)
# 2. Content-Content Attention
content_content = torch.matmul(q.permute(0, 1, 3, 2), k)
# 3. Positional Embeddings (Relative) -> Simplified for this assignment
# In a full BotNet, you add relative position encodings here.
# For simplicity, we calculate basic attention:
energy = content_content
attention = self.softmax(energy) # Save this for visualization later!
self.last_attention_map = attention # Hook for Q1.5
# 4. Aggregation
out = torch.matmul(v, attention.permute(0, 1, 3, 2))
out = out.view(n_batch, C, width, height)
return out
class BotNet50(nn.Module):
def __init__(self, num_classes, resolution=(256, 128)):
super(BotNet50, self).__init__()
# Load backbone
resnet = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
# Extract initial layers
self.stem = nn.Sequential(resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool)
self.layer1 = resnet.layer1
self.layer2 = resnet.layer2
self.layer3 = resnet.layer3
# Replace Layer 4 Convolutions with MHSA blocks
# Note: In a real BotNet, you replace the 3x3 conv inside the Bottleneck with MHSA.
# Ideally, iterate through resnet.layer4 and replace conv2 with MHSA.
self.layer4 = resnet.layer4
# Example: Replacing the final spatial processing with a global MHSA before pooling
# (Simplified version for assignment feasibility)
# H, W at stage 4 for 256x128 input is usually 16x8
self.mhsa = MHSA(2048, width=resolution[1]//32, height=resolution[0]//32)
self.avgpool = resnet.avgpool
self.fc = nn.Linear(2048, num_classes)
def forward(self, x):
x = self.stem(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
# Apply Attention
x = self.mhsa(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x

Xet Storage Details

Size:
3.45 kB
·
Xet hash:
361db2a5a04f2dfab156476a851a7a5e40bba7444b82a29783e0596902afc85d

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.