Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/Face-Recognition-with-ArcFace/backbone.py
3118 views
1
# Original code
2
# https://github.com/ZhaoJ9014/face.evoLVe.PyTorch/blob/master/backbone/model_irse.py
3
4
from collections import namedtuple
5
6
import torch
7
import torch.nn as nn
8
9
class bottleneck_IR(nn.Module):
10
def __init__(self, in_channel, depth, stride):
11
super(bottleneck_IR, self).__init__()
12
if in_channel == depth:
13
self.shortcut_layer = nn.MaxPool2d(1, stride)
14
else:
15
self.shortcut_layer = nn.Sequential(
16
nn.Conv2d(in_channel, depth, (1, 1), stride, bias=False),
17
nn.BatchNorm2d(depth),
18
)
19
self.res_layer = nn.Sequential(
20
nn.BatchNorm2d(in_channel),
21
nn.Conv2d(in_channel, depth, (3, 3), (1, 1), 1, bias=False),
22
nn.PReLU(depth),
23
nn.Conv2d(depth, depth, (3, 3), stride, 1, bias=False),
24
nn.BatchNorm2d(depth),
25
)
26
27
def forward(self, x):
28
shortcut = self.shortcut_layer(x)
29
res = self.res_layer(x)
30
return res + shortcut
31
32
33
class Bottleneck(namedtuple("Block", ["in_channel", "depth", "stride"])):
34
"""A named tuple describing a ResNet block."""
35
36
37
def get_block(in_channel, depth, num_units, stride=2):
38
return [Bottleneck(in_channel, depth, stride)] + [
39
Bottleneck(depth, depth, 1) for i in range(num_units - 1)
40
]
41
42
43
class Backbone(nn.Module):
44
def __init__(self, input_size):
45
super(Backbone, self).__init__()
46
assert input_size[0] in [
47
112,
48
224,
49
], "input_size should be [112, 112] or [224, 224]"
50
51
blocks = [
52
get_block(in_channel=64, depth=64, num_units=3),
53
get_block(in_channel=64, depth=128, num_units=4),
54
get_block(in_channel=128, depth=256, num_units=14),
55
get_block(in_channel=256, depth=512, num_units=3),
56
]
57
unit_module = bottleneck_IR
58
59
self.input_layer = nn.Sequential(
60
nn.Conv2d(3, 64, (3, 3), 1, 1, bias=False), nn.BatchNorm2d(64), nn.PReLU(64),
61
)
62
if input_size[0] == 112:
63
self.output_layer = nn.Sequential(
64
nn.BatchNorm2d(512),
65
nn.Dropout(),
66
nn.Flatten(),
67
nn.Linear(512 * 7 * 7, 512),
68
nn.BatchNorm1d(512),
69
)
70
else:
71
self.output_layer = nn.Sequential(
72
nn.BatchNorm2d(512),
73
nn.Dropout(),
74
nn.Flatten(),
75
nn.Linear(512 * 14 * 14, 512),
76
nn.BatchNorm1d(512),
77
)
78
79
modules = []
80
for block in blocks:
81
for bottleneck in block:
82
modules.append(
83
unit_module(
84
bottleneck.in_channel, bottleneck.depth, bottleneck.stride,
85
),
86
)
87
self.body = nn.Sequential(*modules)
88
89
def forward(self, x):
90
x = self.input_layer(x)
91
x = self.body(x)
92
x = self.output_layer(x)
93
return x
94
95