Descripción common del contenido
- Tensores escasos en tensorflow
- Creación de un tf.sparse.sparsetensor
- Manipulación de tensores dispersos
- Usando tf.sparse.sparsetensor con otras API TensorFlow
- tf.keras
- tf.information
- tf.prepare.instance
- tf.función
- Más lecturas y recursos
Cuando se trabaja con tensores que contienen muchos valores cero, es importante almacenarlos de manera que sea eficiente en el espacio y el tiempo. Los tensores dispersos permiten un almacenamiento y procesamiento eficientes de tensores que contienen muchos valores cero. Los tensores dispersos se usan ampliamente en esquemas de codificación como TF-IDF como parte del preprocesamiento de datos en aplicaciones de PNL y para el procesamiento de imágenes de preprocesamiento con muchos píxeles oscuros en aplicaciones de visión por computadora.
Tensores escasos en tensorflow
TensorFlow representa tensores escasos a través del tf.sparse.SparseTensor
objeto. Actualmente, los tensores dispersos en TensorFlow están codificados utilizando el formato de la lista de coordenadas (COO). Este formato de codificación está optimizado para matrices de hiper-sparse, como incrustaciones.
La codificación de COO para tensores dispersos se compone de:
values
: Un tensor 1D con forma[N]
que contiene todos los valores distantes de cero.indices
: Un tensor 2D con forma[N, rank]
que contiene los índices de los valores distintivos.dense_shape
: Un tensor 1D con forma[rank]
especificando la forma del tensor.
A cero cero valor en el contexto de un tf.sparse.SparseTensor
es un valor que no está codificado explícitamente. Es posible incluir explícitamente valores cero en el values
de una matriz escasa de COO, pero estos “ceros explícitos” generalmente no se incluyen cuando se refieren a valores distintivos en un tensor escaso.
Nota: tf.sparse.SparseTensor
No requiere que los índices/valores estén en un orden en explicit, pero varios OPS suponen que están en el orden de mayúsculas. Usar tf.sparse.reorder
Para crear una copia del tensor disperso que se clasifica en el orden canónico de la fila.
Creando un tf.sparse.SparseTensor
Construir tensores dispersos especificando directamente su values
, indices
y dense_shape
.
import tensorflow as tf
2024-10-25 01:24:09.202320: E exterior/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT manufacturing facility: Making an attempt to register manufacturing facility for plugin cuFFT when one has already been registered
WARNING: All log messages earlier than absl::InitializeLog() is known as are written to STDERR
E0000 00:00:1729819449.223893 16549 cuda_dnn.cc:8310] Unable to register cuDNN manufacturing facility: Making an attempt to register manufacturing facility for plugin cuDNN when one has already been registered
E0000 00:00:1729819449.230517 16549 cuda_blas.cc:1418] Unable to register cuBLAS manufacturing facility: Making an attempt to register manufacturing facility for plugin cuBLAS when one has already been registered
st1 = tf.sparse.SparseTensor(indices=[[0, 3], [2, 4]],
values=[10, 20],
dense_shape=[3, 10])
W0000 00:00:1729819451.911465 16549 gpu_device.cc:2344] Can not dlopen some GPU libraries. Please be certain the lacking libraries talked about above are put in correctly if you want to make use of GPU. Comply with the information at for the best way to obtain and setup the required libraries in your platform.
Skipping registering GPU units...
Cuando usas el print()
Función para imprimir un tensor escaso, muestra el contenido de los tres tensores de componentes:
print(st1)
SparseTensor(indices=tf.Tensor(
[[0 3]
[2 4]], form=(2, 2), dtype=int64), values=tf.Tensor([10 20], form=(2,), dtype=int32), dense_shape=tf.Tensor([ 3 10], form=(2,), dtype=int64))
Es más fácil entender el contenido de un tensor escaso si el distinto de cero values
están alineados con su correspondiente indices
. Defina una función auxiliar de tensores dispersos bastante impresos de modo que cada valor distinto de cero se muestre en su propia línea.
def pprint_sparse_tensor(st):
s = ""
print(pprint_sparse_tensor(st1))
You can also construct sparse tensors from dense tensors by using tf.sparse.from_dense
, and convert them back to dense tensors by using tf.sparse.to_dense
.
st2 = tf.sparse.from_dense([[1, 0, 0, 8], [0, 0, 0, 0], [0, 0, 3, 0]]) print (pPrint_sparse_tensor (ST2))
st3 = tf.sparse.to_dense(st2)
print(st3)
tf.Tensor(
[[1 0 0 8]
[0 0 0 0]
[0 0 3 0]]forma = (3, 4), dtype = int32)
Manipulación de tensores dispersos
Use las utilidades en el tf.sparse
Paquete para manipular tensores dispersos. Ops como tf.math.add
que puede usar para la manipulación aritmética de tensores densos no funcionan con tensores dispersos.
Agregue tensores dispersos de la misma forma usando tf.sparse.add
.
st_a = tf.sparse.SparseTensor(indices=[[0, 2], [3, 4]],
values=[31, 2],
dense_shape=[4, 10])
st_b = tf.sparse.SparseTensor(indices=[[0, 2], [3, 0]],
values=[56, 38],
dense_shape=[4, 10])
st_sum = tf.sparse.add(st_a, st_b)
print(pprint_sparse_tensor(st_sum))
Usar tf.sparse.sparse_dense_matmul
para multiplicar tensores dispersos con matrices densas.
st_c = tf.sparse.SparseTensor(indices=([0, 1], [1, 0], [1, 1]),
values=[13, 15, 17],
dense_shape=(2,2))
mb = tf.fixed([[4], [6]])
product = tf.sparse.sparse_dense_matmul(st_c, mb)
print(product)
tf.Tensor(
[[ 78]
[162]], form=(2, 1), dtype=int32)
Poner tensores escasos usando usando tf.sparse.concat
y desarmarlos usando usando tf.sparse.slice
.
sparse_pattern_A = tf.sparse.SparseTensor(indices = [[2,4], [3,3], [3,4], [4,3], [4,4], [5,4]],
values = [1,1,1,1,1,1],
dense_shape = [8,5])
sparse_pattern_B = tf.sparse.SparseTensor(indices = [[0,2], [1,1], [1,3], [2,0], [2,4], [2,5], [3,5],
[4,5], [5,0], [5,4], [5,5], [6,1], [6,3], [7,2]],
values = [1,1,1,1,1,1,1,1,1,1,1,1,1,1],
dense_shape = [8,6])
sparse_pattern_C = tf.sparse.SparseTensor(indices = [[3,0], [4,0]],
values = [1,1],
dense_shape = [8,6])
sparse_patterns_list = [sparse_pattern_A, sparse_pattern_B, sparse_pattern_C]
sparse_pattern = tf.sparse.concat(axis=1, sp_inputs=sparse_patterns_list)
print(tf.sparse.to_dense(sparse_pattern))
tf.Tensor(
[[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0]
[0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0]
[0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0]
[0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]], form=(8, 17), dtype=int32)
sparse_slice_A = tf.sparse.slice(sparse_pattern_A, begin = [0,0], dimension = [8,5])
sparse_slice_B = tf.sparse.slice(sparse_pattern_B, begin = [0,5], dimension = [8,6])
sparse_slice_C = tf.sparse.slice(sparse_pattern_C, begin = [0,10], dimension = [8,6])
print(tf.sparse.to_dense(sparse_slice_A))
print(tf.sparse.to_dense(sparse_slice_B))
print(tf.sparse.to_dense(sparse_slice_C))
tf.Tensor(
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 1]
[0 0 0 1 1]
[0 0 0 1 1]
[0 0 0 0 1]
[0 0 0 0 0]
[0 0 0 0 0]], form=(8, 5), dtype=int32)
tf.Tensor(
[[0]
[0]
[1]
[1]
[1]
[1]
[0]
[0]], form=(8, 1), dtype=int32)
tf.Tensor([], form=(8, 0), dtype=int32)
Si está utilizando TensorFlow 2.4 o superior, use tf.sparse.map_values
para operaciones de elementos en valores distintos de cero en tensores dispersos.
st2_plus_5 = tf.sparse.map_values(tf.add, st2, 5)
print(tf.sparse.to_dense(st2_plus_5))
tf.Tensor(
[[ 6 0 0 13]
[ 0 0 0 0]
[ 0 0 8 0]], form=(3, 4), dtype=int32)
Tenga en cuenta que solo se modificaron los valores distintivos: los valores cero se mantienen cero.
De manera equivalente, puede seguir el patrón de diseño a continuación para versiones anteriores de TensorFlow:
st2_plus_5 = tf.sparse.SparseTensor(
st2.indices,
st2.values + 5,
st2.dense_shape)
print(tf.sparse.to_dense(st2_plus_5))
tf.Tensor(
[[ 6 0 0 13]
[ 0 0 0 0]
[ 0 0 8 0]], form=(3, 4), dtype=int32)
Usando tf.sparse.SparseTensor
con otras API tensorflow
Los tensores dispersos funcionan transparentemente con estas API de flujo tensor:
tf.keras
tf.information
tf.Prepare.Instance
protobuftf.operate
tf.while_loop
tf.cond
tf.id
tf.forged
tf.print
tf.saved_model
tf.io.serialize_sparse
tf.io.serialize_many_sparse
tf.io.deserialize_many_sparse
tf.math.abs
tf.math.unfavorable
tf.math.signal
tf.math.sq.
tf.math.sqrt
tf.math.erf
tf.math.tanh
tf.math.bessel_i0e
tf.math.bessel_i1e
Los ejemplos se muestran a continuación para algunas de las API anteriores.
tf.keras
Un subconjunto de la tf.keras
La API admite tensores escasos sin costosas operaciones de fundición o conversión. La API de Keras le permite pasar tensores dispersos como entradas a un modelo Keras. Colocar sparse=True
Al llamar tf.keras.Enter
o tf.keras.layers.InputLayer
. Puede pasar tensores dispersos entre las capas de Keras, y también hacer que los modelos Keras los devuelvan como salidas. Si usa tensores dispersos en tf.keras.layers.Dense
Capas En su modelo, generarán tensores densos.
El siguiente ejemplo le muestra cómo pasar un tensor escaso como entrada a un modelo Keras si usa solo capas que admiten entradas dispersas.
x = tf.keras.Enter(form=(4,), sparse=True)
y = tf.keras.layers.Dense(4)(x)
mannequin = tf.keras.Mannequin(x, y)
sparse_data = tf.sparse.SparseTensor(
indices = [(0,0),(0,1),(0,2),
(4,3),(5,0),(5,1)],
values = [1,1,1,1,1,1],
dense_shape = (6,4)
)
mannequin(sparse_data)
mannequin.predict(sparse_data)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step
array([[ 1.8707037e-02, 7.7025330e-01, 2.2425324e-01, -1.9139588e+00],
[ 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
[ 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
[ 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
[-6.2435389e-02, -4.5783034e-01, 1.2970567e-03, -1.8046319e-01],
[-8.0019468e-01, 9.0452707e-01, 2.1884918e-02, -1.3622781e+00]],
dtype=float32)
tf.information
El tf.information
API le permite construir tuberías de entrada complejas a partir de piezas simples y reutilizables. Su estructura de datos del núcleo es tf.information.Dataset
que representa una secuencia de elementos en los que cada elemento consta de uno o más componentes.
Construyendo conjuntos de datos con tensores escasos
Construir conjuntos de datos a partir de tensores dispersos utilizando los mismos métodos que se utilizan para construirlos a partir de tf.Tensor
s o matrices numpy, como tf.information.Dataset.from_tensor_slices
. Este OP preserva la escasez (o naturaleza escasa) de los datos.
dataset = tf.information.Dataset.from_tensor_slices(sparse_data)
for aspect in dataset:
print(pprint_sparse_tensor(aspect))
Conjuntos de datos por lotes y desacelerar con tensores escasos
Puede lotes (combinar elementos consecutivos en un solo elemento) y dejar de desgarrar conjuntos de datos con tensores dispersos utilizando el Dataset.batch
y Dataset.unbatch
métodos respectivamente.
batched_dataset = dataset.batch(2)
for aspect in batched_dataset:
print (pprint_sparse_tensor(aspect))
unbatched_dataset = batched_dataset.unbatch()
for element in unbatched_dataset:
print (pprint_sparse_tensor(element))
También puedes usar tf.information.experimental.dense_to_sparse_batch
a los elementos del conjunto de datos por lotes de formas variables en tensores dispersos.
Transformar conjuntos de datos con tensores escasos
Transformar y crear tensores escasos en conjuntos de datos utilizando Dataset.map
.
transform_dataset = dataset.map(lambda x: x*2)
for i in transform_dataset:
print(pprint_sparse_tensor(i))
tf.prepare.instance
tf.prepare.Instance
es una codificación de protoBUF estándar para datos de flujo de tensor. Al usar tensores dispersos con tf.prepare.Instance
puede:
- Leer datos de longitud variable en un
tf.sparse.SparseTensor
usandotf.io.VarLenFeature
. Sin embargo, debe considerar usartf.io.RaggedFeature
en cambio. - Leer datos escasos arbitrarios en un
tf.sparse.SparseTensor
usandotf.io.SparseFeature
que utiliza tres teclas de características separadas para almacenar elindices
,values
ydense_shape
.
tf.operate
El tf.operate
El decorador precompuesta gráficos de tensorflow para funciones de Python, que pueden mejorar sustancialmente el rendimiento de su código de flujo tensor. Los tensores escasos funcionan transparentemente con ambos tf.operate
y funciones concretas.
@tf.operate
def f(x,y):
return tf.sparse.sparse_dense_matmul(x,y)
a = tf.sparse.SparseTensor(indices=[[0, 3], [2, 4]],
values=[15, 25],
dense_shape=[3, 10])
b = tf.sparse.to_dense(tf.sparse.transpose(a))
c = f(a,b)
print(c)
tf.Tensor(
[[225 0 0]
[ 0 0 0]
[ 0 0 625]], form=(3, 3), dtype=int32)
Distinguir los valores faltantes de los valores cero
La mayoría de las operaciones en tf.sparse.SparseTensor
S trata los valores faltantes y los valores cero explícitos de manera idéntica. Esto es por diseño – un tf.sparse.SparseTensor
se supone que actúa como un tensor denso.
Sin embargo, hay algunos casos en los que puede ser útil distinguir los valores cero de los valores faltantes. En explicit, esto permite una forma de codificar datos faltantes/desconocidos en sus datos de entrenamiento. Por ejemplo, considere un caso de uso en el que tenga un tensor de puntajes (que puede tener algún valor de punto flotante de -inf a +inf), con algunos puntajes faltantes. Puede codificar este tensor utilizando un tensor disperso donde los ceros explícitos son puntajes cero conocidos, pero los valores cero implícitos en realidad representan datos faltantes y no cero.
Nota: Este generalmente no es el uso previsto de tf.sparse.SparseTensor
s; Y es posible que también desee considerar otras técnicas para codificar esto, como por ejemplo, usar un tensor de máscara separado que identifica las ubicaciones de los valores conocidos/desconocidos. Sin embargo, ejercer precaución mientras usa este enfoque, ya que la mayoría de las operaciones escasas tratarán de manera idéntica valores cero explícitos e implícitos.
Tenga en cuenta que a algunas operaciones les gusta tf.sparse.reduce_max
No trate los valores faltantes como si fueran cero. Por ejemplo, cuando ejecuta el bloque de código a continuación, la salida esperada es 0
. Sin embargo, debido a esta excepción, la salida es -3
.
print(tf.sparse.reduce_max(tf.sparse.from_dense([-5, 0, -3])))
tf.Tensor(-3, form=(), dtype=int32)
En contraste, cuando aplicas tf.math.reduce_max
Para un tensor denso, la salida es 0 como se esperaba.
print(tf.math.reduce_max([-5, 0, -3]))
tf.Tensor(0, form=(), dtype=int32)
Más lecturas y recursos
- Consulte la Guía del tensor para aprender sobre tensores.
- Lea la guía de tensor irregular para aprender a trabajar con tensores irregulares, un tipo de tensor que le permite trabajar con datos no uniformes.
- Echa un vistazo a este modelo de detección de objetos en el Modelo de TensorFlow Backyard que usa tensores dispersos en un
tf.Instance
decodificador de datos.
Publicado originalmente en el