A volte la forma di un tensore dipende da un valore calcolato in fase di esecuzione. Prendiamo il seguente esempio, dove x
è definito come un tf.placeholder()
vettoriale con quattro elementi:
x = tf.placeholder(tf.int32, shape=[4])
print x.get_shape()
# ==> '(4,)'
Il valore x.get_shape()
è la forma statica di x
, e la (4,
) significa che è un vettore di lunghezza 4. ora applichiamo il tf.unique()
op per 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
e i 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 diversi valori:
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 rende chiaro che un tensore può avere una forma statica e dinamica diversa. La forma dinamica è 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 uscite di dimensioni variabili e vengono utilizzate in applicazioni avanzate.
Infine, il tf.shape()
op può essere utilizzato per ottenere la forma dinamica di un tensore e utilizzarlo 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]
posso utilizzare forme dinamiche con strati apprendibili? Cosa succederebbe ai pesi se uso un input più piccolo? – nouveau
In genere le forme dei parametri imparabili devono essere note staticamente, ma l'input può avere una dimensione batch variabile. – mrry