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:

Rappresentazione di un tensore
Rappresentazione di un tensore

TensorFlow rappresenta questa matrice come:

[[1, 2, 3], 
   [4, 5, 6]]

Se creiamo una matrice tridimensionale con valori da 1 a 8, abbiamo:

Rappresentazione di un tensore

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)

Crea un tensore di n-dimensione

# 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:

Grafico

TensorFlow creerà un grafico per eseguire la funzione. Il grafico si presenta così:

Esempio di grafico TensorFlow

Esempio di grafico TensorFlow

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:

  1. calcolare e:
  2. aggiungere 1) insieme
  3. aggiungi a 2)
  4. 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: