nystrom-ncut 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,14 +38,14 @@ def distance_from_features(
38
38
  elif distance == "euclidean":
39
39
  D = torch.cdist(features, features_B, p=2)
40
40
  elif distance == "rbf":
41
- D = torch.cdist(features, features_B, p=2) ** 2
41
+ D = 0.5 * torch.cdist(features, features_B, p=2) ** 2
42
42
 
43
43
  # Outlier-robust scale invariance using quantiles to estimate standard deviation
44
44
  c = 2.0
45
45
  p = torch.erf(torch.tensor((-c, c), device=features.device) * (2 ** -0.5))
46
46
  stds = torch.quantile(features, q=(p + 1) / 2, dim=0)
47
- stds = (stds[1] - stds[0]) / 2
48
- D = D / (2 * torch.linalg.norm(stds) ** 2)
47
+ stds = (stds[1] - stds[0]) / (2 * c)
48
+ D = D / (torch.linalg.norm(stds) ** 2)
49
49
  else:
50
50
  raise ValueError("distance should be 'cosine' or 'euclidean', 'rbf'")
51
51
  return D
@@ -98,8 +98,8 @@ class DistanceRealization(OnlineNystromSubsampleFit):
98
98
  def __init__(
99
99
  self,
100
100
  n_components: int = 100,
101
- sample_config: SampleConfig = SampleConfig(),
102
101
  distance: DistanceOptions = "cosine",
102
+ sample_config: SampleConfig = SampleConfig(),
103
103
  eig_solver: EigSolverOptions = "svd_lowrank",
104
104
  chunk_size: int = 8192,
105
105
  ):
@@ -1,3 +1,4 @@
1
+ import einops
1
2
  import torch
2
3
  import torch.nn.functional as Fn
3
4
 
@@ -21,10 +22,12 @@ class LaplacianKernel(OnlineKernel):
21
22
  self,
22
23
  affinity_focal_gamma: float,
23
24
  distance: DistanceOptions,
25
+ adaptive_scaling: bool,
24
26
  eig_solver: EigSolverOptions,
25
27
  ):
26
28
  self.affinity_focal_gamma = affinity_focal_gamma
27
29
  self.distance: DistanceOptions = distance
30
+ self.adaptive_scaling: bool = adaptive_scaling
28
31
  self.eig_solver: EigSolverOptions = eig_solver
29
32
 
30
33
  # Anchor matrices
@@ -53,13 +56,25 @@ class LaplacianKernel(OnlineKernel):
53
56
  self.a_r = torch.sum(self.A, dim=-1) # [n]
54
57
  self.b_r = torch.zeros_like(self.a_r) # [n]
55
58
 
56
- def update(self, features: torch.Tensor) -> torch.Tensor:
59
+ def _affinity(self, features: torch.Tensor) -> torch.Tensor:
57
60
  B = affinity_from_features(
58
61
  self.anchor_features, # [n x d]
59
62
  features, # [m x d]
60
63
  affinity_focal_gamma=self.affinity_focal_gamma,
61
64
  distance=self.distance,
62
65
  ) # [n x m]
66
+ if self.adaptive_scaling:
67
+ diagonal = (
68
+ einops.rearrange(B, "n m -> m 1 n") # [m x 1 x n]
69
+ @ self.Ainv # [n x n]
70
+ @ einops.rearrange(B, "n m -> m n 1") # [m x n x 1]
71
+ ).squeeze(1, 2) # [m]
72
+ adaptive_scale = diagonal ** -0.5 # [m]
73
+ B = B * adaptive_scale
74
+ return B # [n x m]
75
+
76
+ def update(self, features: torch.Tensor) -> torch.Tensor:
77
+ B = self._affinity(features) # [n x m]
63
78
  b_r = torch.sum(B, dim=-1) # [n]
64
79
  b_c = torch.sum(B, dim=-2) # [m]
65
80
  self.b_r = self.b_r + b_r # [n]
@@ -75,12 +90,7 @@ class LaplacianKernel(OnlineKernel):
75
90
  B = self.A # [n x n]
76
91
  col_sum = row_sum # [n]
77
92
  else:
78
- B = affinity_from_features(
79
- self.anchor_features, # [n x d]
80
- features, # [m x d]
81
- affinity_focal_gamma=self.affinity_focal_gamma,
82
- distance=self.distance,
83
- ) # [n x m]
93
+ B = self._affinity(features)
84
94
  b_c = torch.sum(B, dim=-2) # [m]
85
95
  col_sum = b_c + B.mT @ self.Ainv @ self.b_r # [m]
86
96
  scale = (row_sum[:, None] * col_sum) ** -0.5 # [n x m]
@@ -94,8 +104,9 @@ class NCut(OnlineNystromSubsampleFit):
94
104
  self,
95
105
  n_components: int = 100,
96
106
  affinity_focal_gamma: float = 1.0,
97
- sample_config: SampleConfig = SampleConfig(),
98
107
  distance: DistanceOptions = "cosine",
108
+ adaptive_scaling: bool = True,
109
+ sample_config: SampleConfig = SampleConfig(),
99
110
  eig_solver: EigSolverOptions = "svd_lowrank",
100
111
  chunk_size: int = 8192,
101
112
  ):
@@ -104,16 +115,17 @@ class NCut(OnlineNystromSubsampleFit):
104
115
  n_components (int): number of top eigenvectors to return
105
116
  affinity_focal_gamma (float): affinity matrix temperature, lower t reduce the not-so-connected edge weights,
106
117
  smaller t result in more sharp eigenvectors.
118
+ distance (str): distance metric for affinity matrix, ['cosine', 'euclidean', 'rbf'].
119
+ adaptive_scaling (bool): whether to scale off-diagonal affinity vectors so extended diagonal equals 1
107
120
  sample_config (str): subgraph sampling, ['farthest', 'random'].
108
121
  farthest point sampling is recommended for better Nystrom-approximation accuracy
109
- distance (str): distance metric for affinity matrix, ['cosine', 'euclidean', 'rbf'].
110
122
  eig_solver (str): eigen decompose solver, ['svd_lowrank', 'lobpcg', 'svd', 'eigh'].
111
123
  chunk_size (int): chunk size for large-scale matrix multiplication
112
124
  """
113
125
  OnlineNystromSubsampleFit.__init__(
114
126
  self,
115
127
  n_components=n_components,
116
- kernel=LaplacianKernel(affinity_focal_gamma, distance, eig_solver),
128
+ kernel=LaplacianKernel(affinity_focal_gamma, distance, adaptive_scaling, eig_solver),
117
129
  distance=distance,
118
130
  sample_config=sample_config,
119
131
  eig_solver=eig_solver,
@@ -82,4 +82,7 @@ def fpsample(
82
82
  U, S, V = torch.pca_lowrank(features, q=config.fps_dim)
83
83
  features = U * S
84
84
 
85
- return sample_farthest_points(features[None], K=config.num_sample)[1][0]
85
+ try:
86
+ return sample_farthest_points(features[None], K=config.num_sample)[1][0]
87
+ except RuntimeError:
88
+ return sample_farthest_points(features[None].cpu(), K=config.num_sample)[1][0].to(features.device)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nystrom_ncut
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Normalized Cut and Nyström Approximation
5
5
  Author-email: Huzheng Yang <huze.yann@gmail.com>, Wentinn Liao <wentinn.liao@gmail.com>
6
6
  Project-URL: Documentation, https://github.com/JophiArcana/Nystrom-NCUT/
@@ -0,0 +1,15 @@
1
+ __init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ nystrom_ncut/__init__.py,sha256=HifrTcqX2-hYjBDe6xIThHvuIBYMPBA3EzjR8-qPMUM,512
3
+ nystrom_ncut/common.py,sha256=_PGJoImSk_Fb_5Ri-e_IsFoCcSfbGS8CxYUUHVoNM50,2036
4
+ nystrom_ncut/distance_utils.py,sha256=p-pYdpRrJsIhzxM_IxUqja7N8okngx52WGXD9pu_Aec,3129
5
+ nystrom_ncut/sampling_utils.py,sha256=oMmhFcd_N_D15Ht7F0rCGPSgLeitJszAKMD3ICKwHNU,3105
6
+ nystrom_ncut/visualize_utils.py,sha256=RsQVjPhxoIdxDOQ2PI7ifFDuEL23YXpZBdJ0wjjafek,22970
7
+ nystrom_ncut/nystrom/__init__.py,sha256=4EpxD3Cmc8Fif4vo8DG-6FpTfCnNanD5zCZxK3WrMwQ,121
8
+ nystrom_ncut/nystrom/distance_realization.py,sha256=YaKEzuiiJfS6tdOTuJ4Ce1jqOWIfrVGb8ilvhzKeW9w,5789
9
+ nystrom_ncut/nystrom/normalized_cut.py,sha256=N-M5wkTo59vpbBfIx8evkSQBxlo4j80qCtuoifxQa_A,7578
10
+ nystrom_ncut/nystrom/nystrom_utils.py,sha256=Wq364xlxBhr74lqyCkPWLBxq5YSt2zr-DSfYUHpYfgE,12989
11
+ nystrom_ncut-0.1.5.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
12
+ nystrom_ncut-0.1.5.dist-info/METADATA,sha256=7gO_GxpjbitbEBB9juaha7W4e7SWs-hYqgkYfaGmuIg,6058
13
+ nystrom_ncut-0.1.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
+ nystrom_ncut-0.1.5.dist-info/top_level.txt,sha256=gM8IWWHYysIRTCvCTcdS4RShOyl9pxpylgSwPUZR2XM,22
15
+ nystrom_ncut-0.1.5.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- __init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- nystrom_ncut/__init__.py,sha256=HifrTcqX2-hYjBDe6xIThHvuIBYMPBA3EzjR8-qPMUM,512
3
- nystrom_ncut/common.py,sha256=_PGJoImSk_Fb_5Ri-e_IsFoCcSfbGS8CxYUUHVoNM50,2036
4
- nystrom_ncut/distance_utils.py,sha256=xSMKL-sFGrz0EL106vhVx0qSk3iSdSLRFhGL0KmAOnU,3121
5
- nystrom_ncut/sampling_utils.py,sha256=7zCneqmkaA_fUkaZcykFjHtn7pxdZdsjAbKxJplegc0,2960
6
- nystrom_ncut/visualize_utils.py,sha256=RsQVjPhxoIdxDOQ2PI7ifFDuEL23YXpZBdJ0wjjafek,22970
7
- nystrom_ncut/nystrom/__init__.py,sha256=4EpxD3Cmc8Fif4vo8DG-6FpTfCnNanD5zCZxK3WrMwQ,121
8
- nystrom_ncut/nystrom/distance_realization.py,sha256=9GX_XSISTvsEWUu8bG5AxtlkYYNItFspcH5wXiwSOKY,5789
9
- nystrom_ncut/nystrom/normalized_cut.py,sha256=ZxFV8Sckp6wtpNyoA15DS7Vfu9QLvzNpwrwY0n9_GNs,6953
10
- nystrom_ncut/nystrom/nystrom_utils.py,sha256=Wq364xlxBhr74lqyCkPWLBxq5YSt2zr-DSfYUHpYfgE,12989
11
- nystrom_ncut-0.1.3.dist-info/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
12
- nystrom_ncut-0.1.3.dist-info/METADATA,sha256=tK9gbt1b0c5mGNm2e0OdAKQm7rFUWCuhn9myh_Vf408,6058
13
- nystrom_ncut-0.1.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
- nystrom_ncut-0.1.3.dist-info/top_level.txt,sha256=gM8IWWHYysIRTCvCTcdS4RShOyl9pxpylgSwPUZR2XM,22
15
- nystrom_ncut-0.1.3.dist-info/RECORD,,