Nozioni di base su TensorFlow: tensore, forma, tipo, sessioni e OperaTors
Cos'è un tensore?
Il nome di Tensorflow deriva direttamente dal suo framework principale: Tensor. In Tensorflow, tutti i calcoli coinvolgono tensori. Un tensore è un vettore o matrice di n dimensioni che rappresenta tutti i tipi di dati. Tutti i valori in un tensore contengono un tipo di dati identico con una forma nota (o parzialmente nota). La forma dei dati è la dimensionalità della matrice o dell'array.
Un tensore può essere originato dai dati di input o dal risultato di un calcolo. In TensorFlow, tutte le operazioni vengono condotte all'interno di un grafico. Il grafico è un insieme di calcoli che avvengono successivamente. Ogni operazione è chiamata nodo operativo e sono collegate tra loro.
Il grafico delinea le operazioni e le connessioni tra i nodi. Tuttavia, non visualizza i valori. Il bordo dei nodi è il tensore, cioè un modo per popolare l'operazione con i dati.
Nel Machine Learning, i modelli vengono alimentati con un elenco di oggetti chiamati vettori di funzionalità. Un vettore di caratteristiche può essere di qualsiasi tipo di dati. Il vettore delle caratteristiche sarà solitamente l'input principale per popolare un tensore. Questi valori confluiranno in un nodo operativo attraverso il tensore e il risultato di questa operazione/calcolo creerà un nuovo tensore che a sua volta verrà utilizzato in una nuova operazione. Tutte queste operazioni possono essere visualizzate nel grafico.
Rappresentazione di un tensore
In TensorFlow, un tensore è una raccolta di vettori di caratteristiche (cioè array) di n dimensioni. Ad esempio, se abbiamo una matrice 2×3 con valori da 1 a 6, scriviamo:
TensorFlow rappresenta questa matrice come:
[[1, 2, 3], [4, 5, 6]]
Se creiamo una matrice tridimensionale con valori da 1 a 8, abbiamo:
TensorFlow rappresenta questa matrice come:
[ [[1, 2], [[3, 4], [[5, 6], [[7,8] ]
Nota: Un tensore può essere rappresentato con uno scalare oppure può avere una forma a più di tre dimensioni. È semplicemente più complicato visualizzare il livello di dimensione superiore.
Tipi di tensore
In TensorFlow, tutti i calcoli passano attraverso uno o più tensori. Un tf.tensor è un oggetto con tre proprietà:
- Un'etichetta univoca (nome)
- Una dimensione (forma)
- Un tipo di dati (dtype)
Ogni operazione che eseguirai con TensorFlow prevede la manipolazione di un tensore. Esistono quattro tipi principali di tensori che è possibile creare:
- tf.Variabile
- tf.costante
- tf.segnaposto
- tf.SparseTensor
In questo tutorial imparerai come creare un tf.constant e un tf.Variable.
Prima di seguire il tutorial, assicurati di attivare l'ambiente conda con TensorFlow. Abbiamo chiamato questo ambiente ciao-tf.
Per gli utenti MacOS:
source activate hello-tf
Per Windows utente:
activate hello-tf
Dopo averlo fatto, sei pronto per importare tensorflow
# Import tf import tensorflow as tf
Crea un tensore di n dimensione
Inizi con la creazione di un tensore con una dimensione, vale a dire uno scalare.
Per creare un tensore, puoi utilizzare tf.constant() come mostrato nell'esempio di forma del tensore TensorFlow riportato di seguito:
tf.constant(value, dtype, name = "") arguments - `value`: Value of n dimension to define the tensor. Optional - `dtype`: Define the type of data: - `tf.string`: String variable - `tf.float32`: Float variable - `tf.int16`: Integer variable - "name": Name of the tensor. Optional. By default, `Const_1:0`
Per creare un tensore di dimensione 0, eseguire il seguente codice
## rank 0 # Default name r1 = tf.constant(1, tf.int16) print(r1)
Uscita
Tensor("Const:0", shape=(), dtype=int16)
# Named my_scalar r2 = tf.constant(1, tf.int16, name = "my_scalar") print(r2)
Uscita
Tensor("my_scalar:0", shape=(), dtype=int16)
Ogni tensore viene visualizzato con il nome del tensore. Ogni oggetto tensore è definito con attributi tensoriali come un'etichetta univoca (nome), una dimensione (forma) e tipi di dati TensorFlow (dtype).
È possibile definire un tensore con valori decimali o con una stringa modificando il tipo di dati.
# Decimal r1_decimal = tf.constant(1.12345, tf.float32) print(r1_decimal) # String r1_string = tf.constant("Guru99", tf.string) print(r1_string)
Uscita
Tensor("Const_1:0", shape=(), dtype=float32) Tensor("Const_2:0", shape=(), dtype=string)
Un tensore di dimensione 1 può essere creato come segue:
## Rank 1r1_vector = tf.constant([1,3,5], tf.int16) print(r1_vector) r2_boolean = tf.constant([True, True, False], tf.bool) print(r2_boolean)
Uscita
Tensor("Const_3:0", shape=(3,), dtype=int16) Tensor("Const_4:0", shape=(3,), dtype=bool)
Puoi notare che la forma TensorFlow è composta solo da 1 colonna.
Per creare un array di 2 dimensioni tensoriali, è necessario chiudere le parentesi dopo ogni riga. Controlla l'esempio di forma del tensore Keras qui sotto
## Rank 2 r2_matrix = tf.constant([ [1, 2], [3, 4] ],tf.int16) print(r2_matrix)
Uscita
Tensor("Const_5:0", shape=(2, 2), dtype=int16)
La matrice ha 2 righe e 2 colonne riempite con i valori 1, 2, 3, 4.
Una matrice a 3 dimensioni si costruisce aggiungendo un altro livello tramite le parentesi.
## Rank 3 r3_matrix = tf.constant([ [[1, 2], [3, 4], [5, 6]] ], tf.int16) print(r3_matrix)
Uscita
Tensor("Const_6:0", shape=(1, 3, 2), dtype=int16)
La matrice assomiglia all'immagine due.
Forma del tensore
Quando stampi il tensore, TensorFlow indovina la forma. Tuttavia, puoi ottenere la forma del tensore con la proprietà forma TensorFlow.
Di seguito, costruisci una matrice riempita con un numero da 10 a 15 e controlli la forma di m_shape
# Shape of tensor m_shape = tf.constant([ [10, 11], [12, 13], [14, 15] ] ) m_shape.shape
Uscita
TensorShape([Dimension(3), Dimension(2)])
La matrice ha 3 righe e 2 colonne.
TensorFlow dispone di comandi utili per creare un vettore o una matrice riempita con 0 o 1. Ad esempio, se desideri creare un tensore 1-D con una forma specifica di 10, riempita con 0, puoi eseguire il codice seguente:
# Create a vector of 0 print(tf.zeros(10))
Uscita
Tensor("zeros:0", shape=(10,), dtype=float32)
La proprietà funziona anche per Matrix. Qui crei una matrice 10×10 riempita con 1
# Create a vector of 1 print(tf.ones([10, 10]))
Uscita
Tensor("ones:0", shape=(10, 10), dtype=float32)
Puoi usare la forma di una matrice data per creare un vettore di unità. La matrice m_shape è una dimensione 3×2. Puoi creare un tensore con 3 righe riempite da unità con il seguente codice:
# Create a vector of ones with the same number of rows as m_shape print(tf.ones(m_shape.shape[0]))
Uscita
Tensor("ones_1:0", shape=(3,), dtype=float32)
Se passi il valore 1 nella parentesi, puoi costruire un vettore di uno uguale al numero di colonne nella matrice m_shape.
# Create a vector of ones with the same number of column as m_shape print(tf.ones(m_shape.shape[1]))
Uscita
Tensor("ones_2:0", shape=(2,), dtype=float32)
Infine, puoi creare una matrice 3×2 con solo uno
print(tf.ones(m_shape.shape))
Uscita
Tensor("ones_3:0", shape=(3, 2), dtype=float32)
Tipo di dati
La seconda proprietà di un tensore è il tipo di dati. Un tensore può avere solo un tipo di dati alla volta. Un tensore può avere solo un tipo di dati. È possibile restituire il tipo con la proprietà dtype.
print(m_shape.dtype)
Uscita
<dtype: 'int32'>
In alcune occasioni, potresti voler cambiare il tipo di dati. In TensorFlow, è possibile con il metodo tf.cast.
Esempio
Di seguito, un tensore float viene convertito in numero intero utilizzando il metodo cast.
# Change type of data type_float = tf.constant(3.123456789, tf.float32) type_int = tf.cast(type_float, dtype=tf.int32) print(type_float.dtype) print(type_int.dtype)
Uscita
<dtype: 'float32'> <dtype: 'int32'>
TensorFlow sceglie automaticamente il tipo di dati quando l'argomento non viene specificato durante la creazione del tensore. TensorFlow indovinerà quali sono i tipi di dati più probabili. Ad esempio, se passi un testo, indovinerà che è una stringa e lo convertirà in stringa.
Operatore di creazione
Alcuni operatori utili di TensorFlow
Sai come creare un tensore con TensorFlow. È tempo di imparare come eseguire operazioni matematiche.
TensorFlow contiene tutte le operazioni di base. Puoi iniziare con uno semplice. Utilizzerai il metodo TensorFlow per calcolare il quadrato di un numero. Questa operazione è semplice perché è richiesto un solo argomento per costruire il tensore.
Il quadrato di un numero è costruito con tf.sqrt(x) con x come numero mobile.
x = tf.constant([2.0], dtype = tf.float32) print(tf.sqrt(x))
Uscita
Tensor("Sqrt:0", shape=(1,), dtype=float32)
Nota: L'output ha restituito un oggetto tensore e non il risultato del quadrato di 2. Nell'esempio si stampa la definizione del tensore e non la valutazione effettiva dell'operazione. Nella sezione successiva imparerai come funziona TensorFlow per eseguire le operazioni.
Di seguito è riportato un elenco di operazioni comunemente utilizzate. L'idea è la stessa. Ogni operazione richiede uno o più argomenti.
- tf.add(a, b)
- tf.substract(a, b)
- tf.moltiplica(a, b)
- tf.div(a, b)
- tf.pow(a, b)
- tf.exp(a)
- tf.sqrt(a)
Esempio
# Add tensor_a = tf.constant([[1,2]], dtype = tf.int32) tensor_b = tf.constant([[3, 4]], dtype = tf.int32) tensor_add = tf.add(tensor_a, tensor_b)print(tensor_add)
Uscita
Tensor("Add:0", shape=(1, 2), dtype=int32)
Spiegazione del codice
Crea due tensori:
- un tensore con 1 e 2
- un tensore con 3 e 4
Sommi entrambi i tensori.
Preavviso: che entrambi i tensori devono avere la stessa forma. Puoi eseguire una moltiplicazione tra i due tensori.
# Multiply tensor_multiply = tf.multiply(tensor_a, tensor_b) print(tensor_multiply)
Uscita
Tensor("Mul:0", shape=(1, 2), dtype=int32)
Variabili
Finora hai creato solo tensori costanti. Non è di grande utilità. I dati arrivano sempre con valori diversi, per catturarli puoi utilizzare la classe Variable. Rappresenterà un nodo in cui i valori cambiano sempre.
Per creare una variabile, puoi utilizzare il metodo tf.get_variable()
tf.get_variable(name = "", values, dtype, initializer) argument - `name = ""`: Name of the variable - `values`: Dimension of the tensor - `dtype`: Type of data. Optional - `initializer`: How to initialize the tensor. Optional If initializer is specified, there is no need to include the `values` as the shape of `initializer` is used.
Ad esempio, il codice seguente crea una variabile bidimensionale con due valori casuali. Per impostazione predefinita, TensorFlow restituisce un valore casuale. Dai un nome alla variabile var
# Create a Variable ## Create 2 Randomized values var = tf.get_variable("var", [1, 2]) print(var.shape)
Uscita
(1, 2)
Nel secondo esempio crei una variabile con una riga e due colonne. È necessario utilizzare [1,2] per creare la dimensione della variabile
I valori iniziali di questo tensore sono zero. Ad esempio, quando si addestra un modello, è necessario disporre di valori iniziali per calcolare il peso delle funzionalità. Di seguito, imposti questi valori iniziali su zero.
var_init_1 = tf.get_variable("var_init_1", [1, 2], dtype=tf.int32, initializer=tf.zeros_initializer) print(var_init_1.shape)
Uscita
(1, 2)
È possibile passare i valori di un tensore costante in una variabile. Crei un tensore costante con il metodo tf.constant(). Si utilizza questo tensore per inizializzare la variabile.
I primi valori della variabile sono 10, 20, 30 e 40. Il nuovo tensore avrà una forma di 2×2.
# Create a 2x2 matrixtensor_const = tf.constant([[10, 20], [30, 40]]) # Initialize the first value of the tensor equals to tensor_const var_init_2 = tf.get_variable("var_init_2", dtype=tf.int32, initializer=tensor_const) print(var_init_2.shape)
Uscita
(2, 2)
segnaposto
Un segnaposto ha lo scopo di alimentare il tensore. Il segnaposto viene utilizzato per inizializzare i dati in modo che scorrano all'interno dei tensori. Per fornire un segnaposto è necessario utilizzare il metodo feed_dict. Il segnaposto verrà alimentato solo all'interno di una sessione.
Nel prossimo esempio vedrai come creare un segnaposto con il metodo tf.placeholder. Nella prossima sessione imparerai ad alimentare un segnaposto con il valore tensore effettivo.
La sintassi è:
tf.placeholder(dtype,shape=None,name=None ) arguments: - `dtype`: Type of data - `shape`: dimension of the placeholder. Optional. By default, shape of the data - `name`: Name of the placeholder. Optional data_placeholder_a = tf.placeholder(tf.float32, name = "data_placeholder_a") print(data_placeholder_a)
Uscita
Tensor("data_placeholder_a:0", dtype=float32)
Sessione
TensorFlow funziona attorno a 3 componenti principali:
- Grafico
- tensore
- Sessione
Componenti | Descrizione |
---|---|
Grafico | Il grafico è fondamentale in TensorFlow. Tutte le operazioni matematiche (ops) vengono eseguite all'interno di un grafico. Puoi immaginare un grafico come un progetto in cui vengono eseguite tutte le operazioni. I nodi rappresentano queste operazioni, possono assorbire o creare nuovi tensori. |
tensore | Un tensore rappresenta i dati che avanzano tra le operazioni. Hai visto in precedenza come inizializzare un tensore. La differenza tra una costante e una variabile è che i valori iniziali di una variabile cambieranno nel tempo. |
Sessione | Una sessione eseguirà l'operazione dal grafico. Per alimentare il grafico con i valori di un tensore è necessario aprire una sessione. All'interno di una sessione è necessario eseguire un operatore per creare un output. |
Grafici e sessioni sono indipendenti. Puoi eseguire una sessione e ottenere i valori da usare in seguito per ulteriori calcoli.
Nell'esempio seguente, dovrai:
- Crea due tensori
- Creare un'operazione
- Apri una sessione
- Stampa il risultato
Passo 1) Crei due tensori x e y
## Create, run and evaluate a session x = tf.constant([2]) y = tf.constant([4])
Passo 2) Crei l'operatore moltiplicando xey
## Create operator multiply = tf.multiply(x, y)
Passo 3) Apri una sessione. Tutti i calcoli avverranno all'interno della sessione. Al termine, è necessario chiudere la sessione.
## Create a session to run the code sess = tf.Session()result_1 = sess.run(multiply) print(result_1) sess.close()
Uscita
[8]
Spiegazione del codice
- tf.Session(): apre una sessione. Tutte le operazioni confluiranno all'interno delle sessioni
- esegui(moltiplica): esegue l'operazione creata nel passaggio 2.
- print(risultato_1): infine, puoi stampare il risultato
- close(): chiude la sessione
Il risultato mostra 8, che è la moltiplicazione di xey.
Un altro modo per creare una sessione è all'interno di un blocco. Il vantaggio è che chiude automaticamente la sessione.
with tf.Session() as sess: result_2 = multiply.eval() print(result_2)
Uscita
[8]
In un contesto di sessione, è possibile utilizzare il metodo eval() per eseguire l'operazione. È equivalente a run(). Rende il codice più leggibile.
Puoi creare una sessione e vedere i valori all'interno dei tensori che hai creato finora.
## Check the tensors created before sess = tf.Session() print(sess.run(r1)) print(sess.run(r2_matrix)) print(sess.run(r3_matrix))
Uscita
1 [[1 2] [3 4]] [[[1 2] [3 4] [5 6]]]
Le variabili sono vuote per impostazione predefinita, anche dopo aver creato un tensore. È necessario inizializzare la variabile se si desidera utilizzare la variabile. L'oggetto tf.global_variables_initializer() deve essere chiamato per inizializzare i valori di una variabile. Questo oggetto inizializzerà esplicitamente tutte le variabili. Ciò è utile prima di addestrare un modello.
Puoi controllare i valori delle variabili che hai creato prima. Tieni presente che è necessario utilizzare run per valutare il tensore
sess.run(tf.global_variables_initializer()) print(sess.run(var)) print(sess.run(var_init_1)) print(sess.run(var_init_2))
Uscita
[[-0.05356491 0.75867283]] [[0 0]] [[10 20] [30 40]]
Puoi utilizzare il segnaposto creato in precedenza e alimentarlo con il valore reale. È necessario passare i dati nel metodo feed_dict.
Ad esempio, prenderai la potenza di 2 del segnaposto data_placeholder_a.
import numpy as np power_a = tf.pow(data_placeholder_a, 2) with tf.Session() as sess: data = np.random.rand(1, 10) print(sess.run(power_a, feed_dict={data_placeholder_a: data})) # Will succeed.
Spiegazione del codice
- importa numpy come np: importa biblioteca insensata per creare i dati
- tf.pow(data_placeholder_a, 2): crea le operazioni
- np.random.rand(1, 10): crea un array casuale di dati
- feed_dict={data_placeholder_a: data}: alimenta il segnaposto con i dati
Uscita
[[0.05478134 0.27213147 0.8803037 0.0398424 0.21172127 0.01444725 0.02584014 0.3763949 0.66022706 0.7565559 ]]
Grafico
TensorFlow dipende da un approccio geniale per rendere l'operazione. Tutti i calcoli sono rappresentati con uno schema di flusso di dati. Il grafico del flusso di dati è stato sviluppato per verificare le dipendenze dei dati tra le singole operazioni. La formula matematica o l'algoritmo sono costituiti da una serie di operazioni successive. Un grafico è un modo conveniente per visualizzare come sono coordinati i calcoli.
Il grafico mostra a nodo e bordo. Il nodo è la rappresentazione di un'operazione, cioè l'unità di calcolo. Il bordo è il tensore, può produrre un nuovo tensore o consumare i dati di input. Dipende dalle dipendenze tra le singole operazioni.
La struttura del grafico collega tra loro le operazioni (ovvero i nodi) e come queste vengono alimentate. Si noti che il grafico non mostra l'output delle operazioni, aiuta solo a visualizzare la connessione tra le singole operazioni.
Vediamo un esempio.
Immagina di voler valutare la seguente funzione:
TensorFlow creerà un grafico per eseguire la funzione. Il grafico si presenta così:
Puoi facilmente vedere il percorso che i tensori seguiranno per raggiungere la destinazione finale.
Ad esempio, puoi vedere che l'operazione add non può essere eseguita prima e . Il grafico spiega che:
- calcolare e:
- aggiungere 1) insieme
- aggiungi a 2)
- aggiungere 3) a
x = tf.get_variable("x", dtype=tf.int32, initializer=tf.constant([5])) z = tf.get_variable("z", dtype=tf.int32, initializer=tf.constant([6])) c = tf.constant([5], name = "constant")square = tf.constant([2], name = "square") f = tf.multiply(x, z) + tf.pow(x, square) + z + c
Spiegazione del codice
- x: inizializza una variabile chiamata x con un valore costante pari a 5
- z: inizializza una variabile chiamata z con un valore costante pari a 6
- c: inizializza un tensore costante chiamato c con un valore costante pari a 5
- quadrato: inizializza un tensore costante chiamato quadrato con un valore costante pari a 2
- f: Costruisci l'operatore
In questo esempio, scegliamo di mantenere fissi i valori delle variabili. Abbiamo anche creato un tensore costante chiamato c che è il parametro costante nella funzione f. Prende un valore fisso pari a 5. Nel grafico puoi vedere questo parametro nel tensore chiamato costante.
Abbiamo anche costruito un tensore costante per la potenza nell'operatore tf.pow(). Non è necessario. Lo abbiamo fatto in modo che tu possa vedere il nome del tensore nel grafico. È il cerchio chiamato quadrato.
Dal grafico si può capire cosa accadrà ai tensori e come potrà restituire un output pari a 66.
Il codice seguente valuta la funzione in una sessione.
init = tf.global_variables_initializer() # prepare to initialize all variables with tf.Session() as sess: init.run() # Initialize x and y function_result = f.eval() print(function_result)
Uscita
[66]
Sommario
TensorFlow funziona intorno a:
- Grafico: Ambiente computazionale contenente le operazioni e i tensori
- Tensori: Rappresenta i dati (o valore) che fluiranno nel grafico. È il bordo del grafico
- Sessioni: Consentire l'esecuzione delle operazioni
Crea un tensore costante
costante | oggetto |
---|---|
D0 | tf.costante(1, tf.int16) |
D1 | tf.costante([1,3,5], tf.int16) |
D2 | tf.costante([ [1, 2], [3, 4] ],tf.int16) |
D3 | tf.costante([ [[1, 2],[3, 4], [5, 6]] ], tf.int16) |
Creare un operatore
Creare un operatore | Oggetto |
---|---|
a + b | tf.add(a, b) |
a * b | tf.moltiplica(a, b) |
Creare un tensore variabile
Crea una variabile | oggetto |
---|---|
valore randomizzato | tf.get_variable(“var”, [1, 2]) |
primo valore inizializzato | tf.get_variable(“var_init_2”, dtype=tf.int32, inizializzatore=[ [1, 2], [3, 4] ]) |
Apri una sessione
Sessione | oggetto |
---|---|
Crea una sessione | tf.Sessione() |
Esegui una sessione | tf.Session.run() |
Valutare un tensore | nome_variabile.eval() |
Chiudere una sessione | sess.close() |
Sessione per blocco | con tf.Session() come sess: |