Эта статья переведена с:«Понимание статических и динамических форм», Если есть какое-либо нарушение, пожалуйста, свяжитесь, чтобы удалить его, только для академических обменов, пожалуйста, не используйте его в коммерческих целях. Если есть какие-либо ошибки, пожалуйста, свяжитесь, чтобы указать.
Тензоры в TensorFlow имеют свойство статической формы, которое определяется при построении графа. Статические формы могут быть неопределенными. Например, мы можем определить тензор формы [None, 128]:
import tensorflow as tf
a = tf.placeholder(tf.float32, [None, 128])
Это означает, что первое измерение может быть любого размера и будет вSession.run()
Период определяется динамически. Вы можете запросить статическую форму тензора следующим образом:
static_shape = a.shape.as_list() # returns [None, 128]
Чтобы получить динамическую форму тензора, вы можете вызватьtf.shape
метод, который возвращает форму, представленную данным тензором:
dynamic_shape = tf.shape(a)
можно использоватьTensor.set_shape()
Метод задает статическую форму тензора:
a.set_shape([32, 128]) # static shape of a is [32, 128]
a.set_shape([None, 128]) # first dimension of a is determined dynamically
ты можешь использовать этоtf.reshape
Функция динамически изменяет заданный тензор:
a = tf.reshape(a, [32, 128])
Было бы удобно иметь функцию, которая возвращает статическую форму, когда она доступна, и динамическую форму, когда она недоступна. Лучшая реализация программы выглядит следующим образом:
def get_shape(tensor):
static_shape = tensor.shape.as_list()
dynamic_shape = tf.unstack(tf.shape(tensor))
dims = [s[1] if s[0] is None else s[0]
for s in zip(static_shape, dynamic_shape)]
return dims
Теперь предположим, что мы хотим преобразовать 3D-тензор в 2D-тензор, объединив второе и третье измерения в одно. мы можем использоватьget_shape()
функция для этого:
b = tf.placeholder(tf.float32, [None, 10, 32])
shape = get_shape(b)
b = tf.reshape(b, [shape[0], shape[1] * shape[2]])
Стоит отметить, что это работает независимо от того, задана ли форма статически или нет.
На самом деле, мы можем написать общийreshape()
функция, чтобы свернуть любой список измерений:
import tensorflow as tf
import numpy as np
def reshape(tensor, dims_list):
shape = get_shape(tensor)
dims_prod = []
for dims in dims_list:
if isinstance(dims, int):
dims_prod.append(shape[dims])
elif all([isinstance(shape[d], int) for d in dims]):
dims_prod.append(np.prod([shape[d] for d in dims]))
else:
dims_prod.append(tf.prod([shape[d] for d in dims]))
tensor = tf.reshape(tensor, dims_prod)
return tensor
Затем свернуть второе измерение становится очень просто:
b = tf.placeholder(tf.float32, [None, 10, 32])
b = reshape(b, [0, [1, 2]])