Implement spectral normalization for a weight matrix. Spectral normalization constrains the spectral norm (largest singular value) of a weight matrix to 1, which stabilizes GAN training by enforcing Lipschitz continuity.
import numpy as np
def spectral_normalization(W: np.ndarray, num_iters: int = 1, u: np.ndarray = None) -> tuple[np.ndarray, np.ndarray]:
height = W.shape[0]
width = np.prod(W.shape[1:])
W_mat = W.reshape(height, width)
if u is None:
u = np.random.randn(height)
u = u / np.linalg.norm(u)
for _ in range(num_iters):
# Power iteration
v = W_mat.T @ u
v = v / np.linalg.norm(v)
u = W_mat @ v
u = u / np.linalg.norm(u)
sigma = u @ W_mat @ v
W_normalized = W / sigma
return W_normalized, uu vector so it can be reused across training steps for efficiency.