-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsimilarity.py
117 lines (79 loc) · 2.36 KB
/
similarity.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
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
import torch
from torchmetrics.functional import pearson_corrcoef
import tensorly as tl
from tensorly import unfold
tl.set_backend('pytorch')
cos = torch.nn.CosineSimilarity(dim=0)
def cosine(a, b):
"""Caculate cosine similarity
"""
return cos(torch.flatten(a), torch.flatten(b))
def Euclide(a, b):
"""Caculate Euclide distance
"""
return torch.dist(a, b)
def Manhattan(a, b):
"""Caculate Manhattan similarity
"""
return torch.dist(a, b, 1)
def Pearson(a, b):
"""Caculate Pearson similarity
"""
return pearson_corrcoef(torch.flatten(a), torch.flatten(b))
def SNR(signal, noise):
"""Caculate signal to noise ratio
"""
return torch.var(signal-noise) / torch.var(signal)
def VBD(a, b):
"""Caculate variance based distance
"""
vbd = torch.var(a-b) / (torch.var(a) + torch.var(b))
return vbd
def get_u_svd(x):
"""Perform SVD, return 1st column of u
"""
u, _, _ = torch.linalg.svd(x, full_matrices=False)
return u[:, 0]
def svd_cos(x, y):
"""Caculate absolute value of cosine of 2 matrix
x, y: 2d matrix (unfoled from 3d tensor)
"""
return abs(cos(get_u_svd(x), get_u_svd(y)))
def svd(x, y):
"""Caculate cosine similarity through SVD
x, y: 3d filter
First unfold x, y then return cosine
"""
ufx = unfold(x, 0)
ufy = unfold(y, 0)
return svd_cos(ufx, ufy)
def hosvd(x, y):
"""Caculate cosine similarity through HOSVD
x, y: 3d filter
First unfold x, y in each dim
Then return averaged cosine
"""
sum = 0
ufx = [0, 0, 0]
ufy = [0, 0, 0]
for i in range(3):
ufx[i] = unfold(x, i)
ufy[i] = unfold(y, i)
sum += svd_cos(ufx[i], ufy[i])
return sum/3
def similarity(a, b, criterion):
"""Calculate similarity based on criterion
a, b: tensor 1d or 3d
"""
if criterion == 'cosine_sim':
return abs(cosine(a, b))
elif criterion == 'Euclide_dis':
return Euclide(a, b)
elif criterion == 'Manhattan_dis':
return Manhattan(a, b)
elif criterion == 'Pearson_sim':
return Pearson(a, b)
elif criterion == 'SNR_dis':
return SNR(a, b)
elif criterion == 'VBD_dis':
return VBD(a, b)