-
Notifications
You must be signed in to change notification settings - Fork 18
/
C2R.py
74 lines (64 loc) · 2.97 KB
/
C2R.py
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
import sys
import torch
import torch.nn as nn
from torchvision import models
sys.path.append('/')
class Vgg19(torch.nn.Module):
def __init__(self, requires_grad=False):
super(Vgg19, self).__init__()
vgg_pretrained_features = models.vgg19(pretrained=True).features
self.slice1 = torch.nn.Sequential()
self.slice2 = torch.nn.Sequential()
self.slice3 = torch.nn.Sequential()
self.slice4 = torch.nn.Sequential()
self.slice5 = torch.nn.Sequential()
for x in range(2):
self.slice1.add_module(str(x), vgg_pretrained_features[x])
for x in range(2, 7):
self.slice2.add_module(str(x), vgg_pretrained_features[x])
for x in range(7, 12):
self.slice3.add_module(str(x), vgg_pretrained_features[x])
for x in range(12, 21):
self.slice4.add_module(str(x), vgg_pretrained_features[x])
for x in range(21, 30):
self.slice5.add_module(str(x), vgg_pretrained_features[x])
if not requires_grad:
for param in self.parameters():
param.requires_grad = False
def forward(self, X):
h_relu1 = self.slice1(X)
h_relu2 = self.slice2(h_relu1)
h_relu3 = self.slice3(h_relu2)
h_relu4 = self.slice4(h_relu3)
h_relu5 = self.slice5(h_relu4)
return [h_relu1, h_relu2, h_relu3, h_relu4, h_relu5]
class C2R(nn.Module):
def __init__(self, ablation=False):
super(C2R, self).__init__()
self.vgg = Vgg19().cuda()
self.l1 = nn.L1Loss()
self.weights = [1.0 / 32, 1.0 / 16, 1.0 / 8, 1.0 / 4, 1.0]
self.ab = ablation
print('*******************use normal 6 neg clcr loss****************')
def forward(self, a, p, n1, n2, n3, n4, n5, n6, inp, weight):
a_vgg, p_vgg, n1_vgg, n2_vgg, n3_vgg, n4_vgg, n5_vgg, n6_vgg = self.vgg(a), self.vgg(p), self.vgg(n1), self.vgg(
n2), self.vgg(n3), self.vgg(n4), self.vgg(n5), self.vgg(n6)
inp_vgg = self.vgg(inp)
n1_weight, n2_weight, n3_weight, n4_weight, n5_weight, n6_weight, inp_weight = weight
loss = 0
for i in range(len(a_vgg)):
d_ap = self.l1(a_vgg[i], p_vgg[i].detach())
if not self.ab:
d_an1 = self.l1(a_vgg[i], n1_vgg[i].detach())
d_an2 = self.l1(a_vgg[i], n2_vgg[i].detach())
d_an3 = self.l1(a_vgg[i], n3_vgg[i].detach())
d_an4 = self.l1(a_vgg[i], n4_vgg[i].detach())
d_an5 = self.l1(a_vgg[i], n5_vgg[i].detach())
d_an6 = self.l1(a_vgg[i], n6_vgg[i].detach())
d_inp = self.l1(a_vgg[i], inp_vgg[i].detach())
contrastive = d_ap / (
d_an1 * n1_weight + d_an2 * n2_weight + d_an3 * n3_weight + d_an4 * n4_weight + d_an5 * n5_weight + d_an6 * n6_weight + d_inp * inp_weight + 1e-7)
else:
contrastive = d_ap
loss += self.weights[i] * contrastive
return loss