Lo que cuesta guardar cada núcleo
- CP guarda R·ΣIₙ números: lineal en R.
- Tucker guarda ΠRₙ + ΣIₙRₙ: el producto del núcleo es lo que más crece. Un modo que se deja entero (Rₙ = Iₙ) no guarda factor.
def cp_numbers(shape, rank):
return rank * sum(shape)
def tucker_numbers(shape, ranks):
core = int(np.prod(ranks))
factors = sum(n * r for n, r in zip(shape, ranks) if r < n)
return core + factors
Sobre un kernel de convolución de 256 × 256 × 3 × 3 con rango 100, CP guarda 51 800 números (518R) y Tucker-2 con (100, 100, 3, 3) guarda 141 200 (512R + 9R²), unas 2.7 veces más. 90 000 de ellos son entradas del núcleo.
Pero comparar a igual rango es un error: a igual rango Tucker ajusta al menos igual de bien. Un conteo dice el precio de un modelo, no lo que compra.