-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModel.py
More file actions
118 lines (87 loc) · 3.42 KB
/
Copy pathModel.py
File metadata and controls
118 lines (87 loc) · 3.42 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import torch
import torch.nn as nn
import torch.nn.functional as F
from Constants import K
class Head(nn.Module):
def __init__(self, c_last_layer):
super().__init__()
self.lin1 = nn.Linear(8 * 8 * c_last_layer, 32 * c_last_layer)
self.lin2 = nn.Linear(32 * c_last_layer, 8 * c_last_layer)
self.lin3 = nn.Linear(8 * c_last_layer, 3)
def forward(self, x):
x = F.relu(self.lin1(x))
x = F.relu(self.lin2(x))
x = self.lin3(x)
return x
class Model(nn.Module):
def __init__(self, k=K):
super().__init__()
c1 = 1*k
c2 = 2*k
c3 = 4*k
self.conv1 = nn.Conv2d(4, c1, 3, padding="same")
self.conv2 = nn.Conv2d(c1, c1, 3, padding="same")
self.conv3 = nn.Conv2d(c1, c2, 3, padding="same")
self.conv4 = nn.Conv2d(c2, c2, 3, padding="same")
self.conv5 = nn.Conv2d(c2, c3, 3, padding="same")
self.conv6 = nn.Conv2d(c3, c3, 3, padding="same")
self.conv7 = nn.Conv2d(c3, c3, 3, padding="same")
self.conv8 = nn.Conv2d(c3, c3, 3, padding="same")
self.conv9 = nn.Conv2d(c3, c3, 3, padding="same")
self.conv10 = nn.Conv2d(c3, c3, 3, padding="same")
self.pool = nn.MaxPool2d(2, stride=2)
self.head_shift = Head(c3)
self.head_scale = Head(c3)
self.head_rotate = Head(c3)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.relu(self.conv2(x))
x = self.pool(x)
x = F.relu(self.conv3(x))
x = F.relu(self.conv4(x))
x = self.pool(x)
x = F.relu(self.conv5(x))
x = F.relu(self.conv6(x))
x = self.pool(x)
x = F.relu(self.conv7(x))
x = F.relu(self.conv8(x))
x = self.pool(x)
x = F.relu(self.conv9(x))
x = F.relu(self.conv10(x))
x = self.pool(x)
x = torch.flatten(x, start_dim=1)
x_shift = self.head_shift(x) # [N,3]
x_scale = self.head_scale(x) # [N,3]
x_rotate = self.head_rotate(x) # [N,3]
x = torch.cat([x_shift, x_scale, x_rotate],dim=1) # [N,9]
bb = self.create_bb(x) # [N,8,3]
return bb
def create_bb(self, y): # [N,9]
# 0. BASE OF BOUNDING BOX
bb = torch.tensor([[-0.5,-0.5,-0.5],[-0.5,0.5,-0.5],[0.5,0.5,-0.5],[0.5,-0.5,-0.5],
[-0.5,-0.5,0.5],[-0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,-0.5,0.5]],
dtype = torch.float, device=y.device)
bb = bb[None,:,:] # [N,8,3]
# 1. SCALE
size = y[:,None, 3:6] # [N,1,3]
size = F.softplus(size)
bb = bb * size # [N,8,3]
# 2. ROTATE
angles = (torch.tanh(y[:,6:9])) * (torch.pi/4) # [N,3]
cx, cy, cz = torch.cos(angles[:,0]), torch.cos(angles[:,1]), torch.cos(angles[:,2]) # [N]
sx, sy, sz = torch.sin(angles[:,0]), torch.sin(angles[:,1]), torch.sin(angles[:,2]) # [N]
R = torch.zeros((y.shape[0], 3, 3),device=y.device) # [N,3,3]
R[:,0,0] = cy * cz
R[:,0,1] = cz * sx * sy - cx * sz
R[:,0,2] = cx * cz * sy + sx * sz
R[:,1,0] = cy * sz
R[:,1,1] = cx * cz + sx * sy * sz
R[:,1,2] = -cz * sx + cx * sy * sz
R[:,2,0] = -sy
R[:,2,1] = cy * sx
R[:,2,2] = cx * cy
bb = torch.matmul(bb, R.transpose(1,2)) # [N,8,3]=[N,8,3]*[N,3,3]
# 3. SHIFT
center = y[:,None,0:3] # [N,1,3]
bb = bb + center
return bb # [N,8,3]