La descomposición de valores singulares, también conocida como SVD, es una de las muchas técnicas de descomposición de arrays que descompone una array en 3 subarrays, a saber, U, S, V, donde U es el vector propio izquierdo, S es una array diagonal de valores singulares y V se denomina vector propio derecho. Podemos reconstruir SVD de una imagen usando el método linalg.svd() del módulo NumPy.
Sintaxis:
linalg.svd(array, arrays_completas=Verdadero, computar_uv=Verdadero, hermitian=Falso)
Parámetros:
- array : Una array real o compleja de tamaño > 2.
- full_arrays: si es verdadero, el tamaño de las arrays u y v es mxn, si es falso, entonces la forma de las arrays u y v es mxk, donde k es solo valores distintos de cero.
- compute_uv: toma un valor booleano para calcular las arrays u y v junto con la array s.
- hermitian: por defecto, se supone que la array es hermitiana si contiene valores reales, esto se usa internamente para calcular de manera eficiente los valores singulares.
Imagen utilizada:
Python3
# import module import requests import cv2 import numpy as np import matplotlib.pyplot as plt # assign and open image url = 'https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210401173418/Webp-compressed.jpg' response = requests.get(url, stream=True) with open('image.png', 'wb') as f: f.write(response.content) img = cv2.imread('image.png') # Converting the image into gray scale for faster # computation. gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Calculating the SVD u, s, v = np.linalg.svd(gray_image, full_matrices=False) # inspect shapes of the matrices print(f'u.shape:{u.shape},s.shape:{s.shape},v.shape:{v.shape}')
Producción:
u.shape:(3648, 3648),s.shape:(3648,),v.shape:(3648, 5472)
Explicación:
La forma de salida anterior indica que hay 3648 vectores propios linealmente independientes en esta imagen.
Ahora veamos gráficamente la varianza de la imagen utilizada sobre un vector singular:
Python3
# import module import seaborn as sns var_explained = np.round(s**2/np.sum(s**2), decimals=6) # Variance explained top Singular vectors print(f'variance Explained by Top 20 singular values:\n{var_explained[0:20]}') sns.barplot(x=list(range(1, 21)), y=var_explained[0:20], color="dodgerblue") plt.title('Variance Explained Graph') plt.xlabel('Singular Vector', fontsize=16) plt.ylabel('Variance Explained', fontsize=16) plt.tight_layout() plt.show()
Producción:
Explicación: El gráfico anterior de varianza explicada muestra claramente que alrededor del 99,77 % de la información se explica por el primer vector propio y sus propios valores propios correspondientes. Por lo tanto, es muy recomendable reconstruir la imagen con solo los primeros vectores propios.
En el siguiente programa basado en la discusión anterior, reconstruimos la imagen usando SVD:
Python3
# plot images with different number of components comps = [3648, 1, 5, 10, 15, 20] plt.figure(figsize=(12, 6)) for i in range(len(comps)): low_rank = u[:, :comps[i]] @ np.diag(s[:comps[i]]) @ v[:comps[i], :] if(i == 0): plt.subplot(2, 3, i+1), plt.imshow(low_rank, cmap='gray'), plt.title(f'Actual Image with n_components = {comps[i]}') else: plt.subplot(2, 3, i+1), plt.imshow(low_rank, cmap='gray'), plt.title(f'n_components = {comps[i]}')
Producción:
Explicación:
- Aunque el primer vector propio contiene el 99,77% de la información, la reconstrucción de una imagen únicamente a partir de él no ofrece una imagen clara.
- El uso de los 15 vectores principales para la reconstrucción de la imagen proporciona una aproximación bastante buena. También de 3648 vectores, que es una disminución masiva en el cálculo y también comprime la imagen.
Publicación traducida automáticamente
Artículo escrito por arun singh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA