Skip to main content

TensorFlow and Spectral Clustering

TensorFlow 2.21.0 has linear-algebra primitives but does not provide a maintained high-level spectral-clustering estimator. Recreating the full algorithm in eager tensor code adds substantial numerical responsibility. Here TensorFlow builds the affinity and scikit-learn performs the clustering.

1. Generate deterministic data​

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn.cluster import SpectralClustering
from sklearn.datasets import make_moons
from sklearn.metrics import adjusted_rand_score

X, reference = make_moons(n_samples=240, noise=0.05, random_state=42)
X_tensor = tf.convert_to_tensor(X, dtype=tf.float64)

2. Build the RBF affinity​

gamma = 15.0
deltas = X_tensor[:, None, :] - X_tensor[None, :, :]
squared_distances = tf.reduce_sum(tf.square(deltas), axis=2)
affinity_tensor = tf.exp(-gamma * squared_distances)
np.testing.assert_allclose(affinity_tensor.numpy(), affinity_tensor.numpy().T)
affinity = affinity_tensor.numpy()

3. Cluster and verify the known toy partition​

model = SpectralClustering(
n_clusters=2,
affinity="precomputed",
assign_labels="cluster_qr",
random_state=42,
)
labels = model.fit_predict(affinity)
assert adjusted_rand_score(reference, labels) > 0.95
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap="viridis", s=24)
plt.title("Spectral clustering from a TensorFlow-built affinity")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.close()

The conversion to NumPy is explicit because scikit-learn owns the estimator. A differentiable affinity does not make the discrete clustering differentiable, and the dense matrix retains quadratic memory cost.