-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodel.py
More file actions
71 lines (56 loc) · 2.27 KB
/
Copy pathmodel.py
File metadata and controls
71 lines (56 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import torch
import torch.nn as nn
from einops import rearrange
from torchvision.models.resnet import resnet18, resnet34, resnet50
class ResNetCls(nn.Module):
def __init__(self, num_classes, depth, pretrained=True, dropout=0., latent_dim=128, num_prototypes=2):
super(ResNetCls, self).__init__()
if depth == 18:
model = resnet18(pretrained=pretrained)
elif depth == 34:
model = resnet34(pretrained=pretrained)
else:
model = resnet50(pretrained=pretrained)
in_channel = model.fc.in_features
self.backbone = model
del self.backbone.fc
self.cls_head = nn.Sequential(
self.cls_block(in_channel, 256, dropout),
nn.Linear(256, latent_dim),
nn.InstanceNorm1d(latent_dim))
self.pool = nn.AdaptiveAvgPool2d((1, 1))
self.prototypes = nn.Embedding(num_classes * num_prototypes, latent_dim)
self.num_classes = num_classes
def cls_block(self, channel_in, channel_out, p):
block = nn.Sequential(
nn.Linear(channel_in, channel_out),
nn.ReLU(),
nn.Dropout(p),
)
return block
def get_logits(self, x, y):
logits = -1.0 * torch.sqrt(torch.sum(torch.square(x[:, None, :] - y), dim=-1))
logits = rearrange(logits, 'b (c p) -> b c p', c=self.num_classes)
logits, _ = torch.max(logits, dim=-1)
return logits
def forward(self, x):
feats = list()
feat = self.backbone.conv1(x)
feat = self.backbone.bn1(feat)
feat = self.backbone.relu(feat)
feat = self.backbone.maxpool(feat)
feats.append(self.pool(feat).flatten(1))
feat = self.backbone.layer1(feat)
feats.append(self.pool(feat).flatten(1))
feat = self.backbone.layer2(feat)
feats.append(self.pool(feat).flatten(1))
feat = self.backbone.layer3(feat)
feats.append(self.pool(feat).flatten(1))
feat = self.backbone.layer4(feat)
feat = self.backbone.avgpool(feat)
feat = torch.flatten(feat, 1)
feats.append(feat)
feat = self.cls_head(feat)
feats.append(feat)
logits = self.get_logits(feat, self.prototypes.weight)
return feats, logits