Introduzione ai tensori

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza l'origine su GitHub Scarica quaderno
import tensorflow as tf
import numpy as np

I tensori sono array multidimensionali con un tipo uniforme (chiamato dtype ). Puoi vedere tutti i dtypes supportati su tf.dtypes.DType .

Se hai familiarità con NumPy , i tensori sono (una specie di) come np.arrays .

Tutti i tensori sono immutabili come i numeri e le stringhe Python: non puoi mai aggiornare il contenuto di un tensore, ma crearne solo uno nuovo.

Nozioni di base

Creiamo alcuni tensori di base.

Ecco un tensore "scalare" o "rank-0". Uno scalare contiene un singolo valore e nessun "asse".

# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)

Un tensore "vettore" o "rank-1" è come un elenco di valori. Un vettore ha un asse:

# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)

Un tensore "matrice" o "rango 2" ha due assi:

# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
                             [3, 4],
                             [5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)
Uno scalare, forma: [] Un vettore, forma: [3] Una matrice, forma: [3, 2]
Uno scalare, il numero 4La riga con 3 sezioni, ciascuna contenente un numero.Una griglia 3x2, con ogni cella contenente un numero.

I tensori possono avere più assi; ecco un tensore con tre assi:

# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
  [[0, 1, 2, 3, 4],
   [5, 6, 7, 8, 9]],
  [[10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]],
  [[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29]],])

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Ci sono molti modi in cui potresti visualizzare un tensore con più di due assi.

Un tensore a 3 assi, forma: [3, 2, 5]

Puoi convertire un tensore in un array NumPy usando np.array o il metodo tensor.numpy :

np.array(rank_2_tensor)
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)

I tensori contengono spesso float e int, ma ne hanno molti altri tipi, tra cui:

  • numeri complessi
  • stringhe

La classe base tf.Tensor richiede che i tensori siano "rettangolari", ovvero, lungo ciascun asse, ogni elemento ha la stessa dimensione. Tuttavia, esistono tipi specializzati di tensori che possono gestire forme diverse:

Puoi eseguire calcoli di base sui tensori, tra cui addizione, moltiplicazione per elemento e moltiplicazione di matrici.

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # Could have also said `tf.ones([2,2])`

print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)
print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)

I tensori sono usati in tutti i tipi di operazioni (operazioni).

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])

# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105854e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

A proposito di forme

I tensori hanno forme. Un po' di vocabolario:

  • Forma : la lunghezza (numero di elementi) di ciascuno degli assi di un tensore.
  • Rango : Numero di assi tensoriali. Uno scalare ha rango 0, un vettore ha rango 1, una matrice ha rango 2.
  • Asse o dimensione : una particolare dimensione di un tensore.
  • Dimensione : il numero totale di elementi nel tensore, il vettore della forma del prodotto.

Tensor e oggetti tf.TensorShape hanno proprietà utili per l'accesso a questi:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Un tensore di grado 4, forma: [3, 2, 4, 5]
Una forma tensore è come un vettore.Un tensore a 4 assi
print("Type of every element:", rank_4_tensor.dtype)
print("Number of axes:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of axes: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5):  120

Sebbene gli assi siano spesso indicati dai loro indici, dovresti sempre tenere traccia del significato di ciascuno. Spesso gli assi sono ordinati da globale a locale: prima l'asse batch, seguito dalle dimensioni spaziali e infine dalle caratteristiche per ciascuna posizione. In questo modo i vettori di caratteristiche sono regioni di memoria contigue.

Ordine tipico degli assi
Tieni traccia di ciò che ogni asse è. Un tensore a 4 assi potrebbe essere: Batch, Larghezza, Altezza, Caratteristiche

Indicizzazione

Indicizzazione ad asse singolo

TensorFlow segue le regole di indicizzazione Python standard, simili all'indicizzazione di un elenco o di una stringa in Python e le regole di base per l'indicizzazione NumPy.

  • gli indici iniziano da 0
  • gli indici negativi contano alla rovescia dalla fine
  • i due punti, : , sono usati per le sezioni: start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 0  1  1  2  3  5  8 13 21 34]

L'indicizzazione con uno scalare rimuove l'asse:

print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
First: 0
Second: 1
Last: 34

L'indicizzazione con una : slice mantiene l'asse:

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy())
print("Reversed:", rank_1_tensor[::-1].numpy())
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]

Indicizzazione multiasse

I tensori di rango più alti vengono indicizzati passando più indici.

Le stesse regole identiche del caso ad asse singolo si applicano a ciascun asse in modo indipendente.

print(rank_2_tensor.numpy())
[[1. 2.]
 [3. 4.]
 [5. 6.]]

Passando un numero intero per ogni indice, il risultato è uno scalare.

# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0

Puoi indicizzare utilizzando qualsiasi combinazione di numeri interi e sezioni:

# Get row and column tensors
print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]]

Ecco un esempio con un tensore a 3 assi:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)
Selezione dell'ultima caratteristica in tutte le posizioni in ogni esempio nel batch
Un tensore 3x2x5 con tutti i valori all'indice-4 dell'ultimo asse selezionato.I valori selezionati racchiusi in un tensore a 2 assi.

Leggi la guida allo slicing del tensore per scoprire come applicare l'indicizzazione per manipolare i singoli elementi nei tuoi tensori.

Manipolare le forme

Rimodellare un tensore è di grande utilità.

# Shape returns a `TensorShape` object that shows the size along each axis
x = tf.constant([[1], [2], [3]])
print(x.shape)
(3, 1)
# You can convert this object into a Python list, too
print(x.shape.as_list())
[3, 1]

Puoi rimodellare un tensore in una nuova forma. L'operazione tf.reshape è veloce ed economica in quanto non è necessario duplicare i dati sottostanti.

# You can reshape a tensor to a new shape.
# Note that you're passing in a list
reshaped = tf.reshape(x, [1, 3])
print(x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)

Il dato mantiene il suo layout in memoria e viene creato un nuovo tensore, con la forma richiesta, che punta agli stessi dati. TensorFlow utilizza l'ordinamento della memoria "row-major" in stile C, in cui l'incremento dell'indice più a destra corrisponde a un singolo passaggio in memoria.

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Se appiattisci un tensore puoi vedere quale ordine è disposto in memoria.

# A `-1` passed in the `shape` argument says "Whatever fits".
print(tf.reshape(rank_3_tensor, [-1]))
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)

In genere l'unico uso ragionevole di tf.reshape è combinare o dividere assi adiacenti (o aggiungere/rimuovere 1 s).

Per questo tensore 3x2x5, rimodellare a (3x2)x5 o 3x(2x5) sono entrambe cose ragionevoli da fare, poiché le fette non si mescolano:

print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -1]))
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]], shape=(6, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)
Alcuni buoni rimodellamenti.
Un tensore 3x2x5Gli stessi dati sono stati rimodellati in (3x2)x5Gli stessi dati sono stati rimodellati a 3x(2x5)

Il rimodellamento "funziona" per qualsiasi nuova forma con lo stesso numero totale di elementi, ma non servirà a nulla se non si rispetta l'ordine degli assi.

Lo scambio di assi in tf.reshape non funziona; hai bisogno di tf.transpose per quello.

# Bad examples: don't do this

# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n") 

# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")

# This doesn't work at all
try:
  tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

 [[15 16 17 18 19]
  [20 21 22 23 24]
  [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) 

InvalidArgumentError: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]
Alcuni brutti rimodellamenti.
Non puoi riordinare gli assi, usa tf.transpose per quelloTutto ciò che mescola insieme le fette di dati è probabilmente sbagliato.La nuova forma deve adattarsi esattamente.

Potresti imbatterti in forme non completamente specificate. O la forma contiene un None (una lunghezza dell'asse è sconosciuta) o l'intera forma è None (il rango del tensore è sconosciuto).

Fatta eccezione per tf.RaggedTensor , tali forme si verificheranno solo nel contesto delle API simboliche per la creazione di grafici di TensorFlow:

Altro su DTypes

Per controllare il tipo di dati di un tf.Tensor , utilizzare la proprietà Tensor.dtype .

Quando si crea un tf.Tensor da un oggetto Python è possibile specificare facoltativamente il tipo di dati.

In caso contrario, TensorFlow sceglie un tipo di dati che può rappresentare i tuoi dati. TensorFlow converte i numeri interi Python in tf.int32 e i numeri in virgola mobile Python in tf.float32 . In caso contrario, TensorFlow utilizza le stesse regole che NumPy usa durante la conversione in array.

Puoi trasmettere da un tipo all'altro.

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)

Trasmissione

La trasmissione è un concetto preso in prestito dalla funzionalità equivalente in NumPy . In breve, in determinate condizioni, i tensori più piccoli vengono "allungati" automaticamente per adattarsi a tensori più grandi quando si eseguono operazioni combinate su di essi.

Il caso più semplice e comune è quando si tenta di moltiplicare o aggiungere un tensore a uno scalare. In tal caso, lo scalare viene trasmesso per avere la stessa forma dell'altro argomento.

x = tf.constant([1, 2, 3])

y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)

Allo stesso modo, gli assi con lunghezza 1 possono essere allungati per abbinare gli altri argomenti. Entrambi gli argomenti possono essere allungati nello stesso calcolo.

In questo caso una matrice 3x1 viene moltiplicata per elemento per una matrice 1x4 per produrre una matrice 3x4. Nota come l'iniziale 1 è facoltativo: la forma di y è [4] .

# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
 [2]
 [3]], shape=(3, 1), dtype=int32) 

tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) 

tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)
Una aggiunta trasmessa: a [3, 1] volte a [1, 4] dà un [3,4]
Aggiungendo una matrice 3x1 a una matrice 4x1 si ottiene una matrice 3x4

Ecco la stessa operazione senza trasmettere:

x_stretch = tf.constant([[1, 1, 1, 1],
                         [2, 2, 2, 2],
                         [3, 3, 3, 3]])

y_stretch = tf.constant([[1, 2, 3, 4],
                         [1, 2, 3, 4],
                         [1, 2, 3, 4]])

print(x_stretch * y_stretch)  # Again, operator overloading
tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

La maggior parte delle volte, la trasmissione è efficiente sia in termini di tempo che di spazio, poiché l'operazione di trasmissione non materializza mai i tensori espansi in memoria.

Puoi vedere come appare la trasmissione usando tf.broadcast_to .

print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
 [1 2 3]
 [1 2 3]], shape=(3, 3), dtype=int32)

A differenza di un'operazione matematica, ad esempio, broadcast_to non fa nulla di speciale per risparmiare memoria. Qui stai materializzando il tensore.

Può diventare ancora più complicato. Questa sezione del libro di Jake VanderPlas Python Data Science Handbook mostra più trucchi di trasmissione (di nuovo in NumPy).

tf.convert_to_tensor

La maggior parte delle operazioni, come tf.matmul e tf.reshape , accetta argomenti di classe tf.Tensor . Tuttavia, noterai che nel caso precedente sono accettati oggetti Python a forma di tensore.

La maggior parte, ma non tutte, le operazioni chiamano convert_to_tensor su argomenti non tensoriali. Esiste un registro delle conversioni e la maggior parte delle classi di oggetti come NumPy's ndarray , TensorShape , Python lists e tf.Variable verranno tutte convertite automaticamente.

Vedi tf.register_tensor_conversion_function per maggiori dettagli e, se hai il tuo tipo, vorresti convertire automaticamente in un tensore.

Tensori irregolari

Un tensore con numero variabile di elementi lungo un asse è detto "frastagliato". Usa tf.ragged.RaggedTensor per dati irregolari.

Ad esempio, questo non può essere rappresentato come un tensore regolare:

A tf.RaggedTensor , forma: [4, None]
Un tensore irregolare a 2 assi, ogni riga può avere una lunghezza diversa.
ragged_list = [
    [0, 1, 2, 3],
    [4, 5],
    [6, 7, 8],
    [9]]
try:
  tensor = tf.constant(ragged_list)
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.

Invece crea un tf.RaggedTensor usando tf.ragged.constant :

ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>

La forma di un tf.RaggedTensor conterrà alcuni assi con lunghezze sconosciute:

print(ragged_tensor.shape)
(4, None)

Tensori di stringhe

tf.string è un dtype , vale a dire che puoi rappresentare i dati come stringhe (array di byte a lunghezza variabile) in tensori.

Le stringhe sono atomiche e non possono essere indicizzate come le stringhe Python. La lunghezza della corda non è uno degli assi del tensore. Vedere tf.strings per le funzioni per manipolarli.

Ecco un tensore di stringa scalare:

# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)

E un vettore di stringhe:

Un vettore di stringhe, forma: [3,]
La lunghezza della corda non è uno degli assi del tensore.
# If you have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
                                 "Quick brown fox",
                                 "Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)

Nella stampa sopra il prefisso b indica che tf.string dtype non è una stringa unicode, ma una stringa di byte. Vedere il tutorial Unicode per ulteriori informazioni sull'utilizzo del testo unicode in TensorFlow.

Se passi i caratteri Unicode, sono codificati in utf-8.

tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>

Alcune funzioni di base con le stringhe possono essere trovate in tf.strings , incluso tf.strings.split .

# You can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)
# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>
Tre corde divise, forma: [3, None]
La divisione di più stringhe restituisce un tf.RaggedTensor

E tf.string.to_number :

text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([  1.  10. 100.], shape=(3,), dtype=float32)

Sebbene non sia possibile utilizzare tf.cast per trasformare un tensore di stringa in numeri, è possibile convertirlo in byte e quindi in numeri.

byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117  99 107], shape=(4,), dtype=uint8)
# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")

print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)
Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)

Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)

Unicode values: tf.Tensor([ 12450  12498  12523     32 129414], shape=(5,), dtype=int32)

Il tf.string tf.string viene utilizzato per tutti i dati di byte non elaborati in TensorFlow. Il modulo tf.io contiene funzioni per la conversione di dati da e verso byte, inclusa la decodifica di immagini e l'analisi di CSV.

Tensori sparsi

A volte, i tuoi dati sono scarsi, come uno spazio di incorporamento molto ampio. TensorFlow supporta tf.sparse.SparseTensor e le operazioni correlate per archiviare dati sparsi in modo efficiente.

A tf.SparseTensor , forma: [3, 4]
Una griglia 3x4, con valori solo in due delle celle.
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
                                       values=[1, 2],
                                       dense_shape=[3, 4])
print(sparse_tensor, "\n")

# You can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) 

tf.Tensor(
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]], shape=(3, 4), dtype=int32)