Quiero aplicar un algoritmo de descomposición parcial de Tucker para minimizar el conjunto de datos del tensor de imagen MNIST de (60000,28,28), para conservar sus características al aplicar otro algoritmo de máquina después como SVM. Tengo este código que minimiza la segunda y tercera dimensión del tensor.
i = 16 j = 10 core, factors = partial_tucker(train_data_mnist, modes=[1,2],tol=10e-5, rank=[i,j]) train_datapartial_tucker = tl.tenalg.multi_mode_dot(train_data_mnist, factors, modes=modes, transpose=True) test_data_partial_tucker = tl.tenalg.multi_mode_dot(test_data_mnist, factors, modes=modes, transpose=True) ¿Cómo encontrar el mejor rango [i,j] cuando estoy usando partial_tucker parcial que dará la mejor reducción de dimensión para la imagen mientras conserva la mayor cantidad de datos?
Al igual que el análisis de componentes principales, la descomposición parcial de Tucker dará mejores resultados a medida que aumentemos el rango, en el sentido de que el residuo cuadrático medio óptimo de la reconstrucción es menor.
En general, las características (el tensor core ) que permiten reconstrucciones precisas de los datos originales se pueden usar para hacer predicciones similares (dado cualquier modelo, podemos anteponer una transformación que reconstruya los datos originales a partir de las características core ).
import mxnet as mx import numpy as np import tensorly as tl import matplotlib.pyplot as plt import tensorly.decomposition # Load data mnist = mx.test_utils.get_mnist() train_data = mnist['train_data'][:,0] err = np.zeros([28,28]) # here I will save the errors for each rank batch = train_data[::100] # process only 1% of the data to go faster for i in range(1,28): for j in range(1,28): if err[i,j] == 0: # Decompose the data core, factors = tl.decomposition.partial_tucker( batch, modes=[1,2], tol=10e-5, rank=[i,j]) # Reconstruct data from features c = tl.tenalg.multi_mode_dot(core, factors, modes=[1,2]); # Calculate the RMS error and save err[i,j] = np.sqrt(np.mean((c - batch)**2)); # Plot the statistics plt.figure(figsize=(9,6)) CS = plt.contour(np.log2(err), levels=np.arange(-6, 0)); plt.clabel(CS, CS.levels, inline=True, fmt='$2^{%d}$', fontsize=16) plt.xlabel('rank 2') plt.ylabel('rank 1') plt.grid() plt.title('Reconstruction RMS error'); Por lo general, obtiene mejores resultados con un rango equilibrado, es decir, i y j no muy diferentes entre sí.
A medida que aumentamos el error, podemos obtener una mejor compresión, podemos clasificar (i,j) por el error y trazar solo donde el error es mínimo para una dimensión de característica determinada i * j , como este
X = np.zeros([28, 28]) X[...] = np.nan; p = 28 * 28; for e,i,j in sorted([(err[i,j], i, j) for i in range(1, 28) for j in range(1, 28)]): if p < i * j: # we can achieve this error with some better compression pass else: p = i * j; X[i,j] = e; plt.imshow(X)En cualquier lugar de la región blanca que esté desperdiciando recursos, la elección
Entonces, si observa el código fuente de los enlaces tensoriales aquí , puede ver que la documentación de la función en partial_tucker tensorly :
""" Partial tucker decomposition via Higher Order Orthogonal Iteration (HOI) Decomposes 'tensor' into a Tucker decomposition exclusively along the provided modes. Parameters ---------- tensor: ndarray modes: int list list of the modes on which to perform the decomposition rank: None, int or int list size of the core tensor, if int, the same rank is used for all modes """El propósito de esta función es brindarle la aproximación que conserva la mayor cantidad de datos posible para un rango determinado . No puedo darle qué rango "dará la mejor reducción de dimensión para la imagen conservando la mayor cantidad de datos", porque el equilibrio óptimo entre la reducción de dimensionalidad y la pérdida de precisión es algo que no tiene una respuesta objetivamente "correcta" en abstracto, ya que dependerá en gran medida de los objetivos específicos de su proyecto y los recursos computacionales disponibles para lograr esos objetivos.
Si le dijera que hiciera "el mejor rango", eliminaría el propósito de esta descomposición aproximada en primer lugar, porque "el mejor rango" será el rango que no da "pérdida", que ya no es una aproximación de fijo rango y tipo de hace que el término aproximación no tenga sentido. Pero hasta qué punto desviarse de este "mejor rango" para obtener una reducción de la dimensionalidad no es una pregunta que nadie más pueda responder por usted de manera objetiva. Ciertamente se podría dar una opinión, pero esta opinión dependería de mucha más información de la que tengo de usted en este momento. Si está buscando una perspectiva más profunda sobre esta compensación y qué compensación le conviene más, le sugiero que publique una pregunta con más detalles sobre su situación en un sitio de la red Stack más centrado en los fundamentos matemáticos/estadísticos de la dimensionalidad. reducción y menos en los aspectos de programación en los que Stack Overflow se enfoca más, como Stack Exhange Cross Validated o quizás Stack Exhange Data Science .
Fuentes/Referencias/Lecturas adicionales: