Come capire la forma statica e la forma dynamic in TensorFlow?

Nelle domande frequenti su TensorFlow , si dice:

In TensorFlow, un tensore ha sia una forma statica (dedotta) che una forma (vera) dynamic. La forma statica può essere letta usando il metodo tf.Tensor.get_shape (): questa forma è dedotta dalle operazioni che sono state utilizzate per creare il tensore e potrebbe essere parzialmente completa. Se la forma statica non è completamente definita, la forma dynamic di un tensore T può essere determinata valutando tf.shape (t).

Ma non riesco ancora a comprendere appieno la relazione tra forma statica e forma dynamic. Ci sono esempi che mostrano le loro differenze? Grazie.

A volte la forma di un tensore dipende da un valore che viene calcolato in fase di esecuzione. Prendiamo il seguente esempio, dove x è definito come vettore tf.placeholder() con quattro elementi:

 x = tf.placeholder(tf.int32, shape=[4]) print x.get_shape() # ==> '(4,)' 

Il valore di x.get_shape() è la forma statica di x , e il (4, ) significa che è un vettore di lunghezza 4. Ora applichiamo l’op tf.unique() a x

 y, _ = tf.unique(x) print y.get_shape() # ==> '(?,)' 

Il (?,) Significa che y è un vettore di lunghezza sconosciuta. Perché è sconosciuto? tf.unique(x) restituisce i valori univoci da x ei valori di x sono sconosciuti perché è un tf.placeholder() , quindi non ha un valore finché non lo si alimenta. Vediamo cosa succede se si alimentano due valori diversi:

 sess = tf.Session() print sess.run(y, feed_dict={x: [0, 1, 2, 3]}).shape # ==> '(4,)' print sess.run(y, feed_dict={x: [0, 0, 0, 0]}).shape # ==> '(1,)' 

Speriamo che questo chiarisca che un tensore può avere una diversa forma statica e dynamic. La forma dynamic è sempre completamente definita, non ha ? dimensioni – ma la forma statica può essere meno specifica. Questo è ciò che consente a TensorFlow di supportare operazioni come tf.unique() e tf.dynamic_partition() , che possono avere output di dimensioni variabili e vengono utilizzati in applicazioni avanzate.

Infine, l’op tf.shape() può essere usato per ottenere la forma dynamic di un tensore e usarlo in un calcolo TensorFlow:

 z = tf.shape(y) print sess.run(z, feed_dict={x: [0, 1, 2, 3]}) # ==> [4] print sess.run(z, feed_dict={x: [0, 0, 0, 0]}) # ==> [1]