Иногда форма тензора зависит от значения, которое вычисляется во время выполнения. Давайте рассмотрим следующий пример, где x
определяется как tf.placeholder()
вектор с четырьмя элементами:
x = tf.placeholder(tf.int32, shape=[4])
print x.get_shape()
# ==> '(4,)'
Значение x.get_shape()
является статическая форма x
и (4,
) означает, что вектор длины 4. Теперь давайте применим tf.unique()
оп к x
y, _ = tf.unique(x)
print y.get_shape()
# ==> '(?,)'
(?,)
означает, что y
вектор неизвестной длины. Почему это неизвестно? tf.unique(x)
возвращает уникальные значения от x
, а значения x
неизвестны, так как это tf.placeholder()
, поэтому он не имеет значения до его подачи. Давайте посмотрим, что произойдет, если вы кормите два различных значения:
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,)'
Надеюсь, это ясно показывает, что тензор может иметь различную статическую и динамическую форму. Динамическая форма всегда полностью определена — у нее нет ?
размеры —, но статическая форма может быть менее конкретной. Это позволяет TensorFlow поддерживать такие операции, как tf.unique()
и tf.dynamic_partition()
, которые могут иметь выходы переменного размера и используются в расширенных приложениях.
Наконец, tf.shape()
оп может быть использовано, чтобы получить динамическую форму тензора и использовать его в вычислениях 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]
можно использовать динамические формы с изучаемыми слоями? Что произойдет с весами, если я использую меньший вход? – nouveau
Обычно формы обучаемых параметров должны быть известны статически, но вход может иметь переменный размер партии. – mrry