Основным объектом которым манипулируют в Tensorflow, является тензор. О том, что такое тензор, какие бывают тензоры, какие у них есть свойства и как ими манипулировать читайте в переводном руководстве с сайта tensorflow.org.
TensorFlow, как видно из названия, является платформой для определения и выполнения вычислений с использованием тензоров. Тензор — это обобщение векторов и матриц на более высокие измерения. Внутри TensorFlow тензоры представлены в виде n-мерных массивов базовых типов данных.
При написании программы TensorFlow основным объектом, которым вы манипулируете и передаете, является tf.Tensor
. Программы TensorFlow работают, сначала создавая граф объектов tf.Tensor
и подробно описывая, как вычисляется каждый тензор на основе других доступных тензоров, а затем запуская части этого графа для получения результатов вычисления.
tf.Tensor
обладает следующими параметрами:
- тип данных (
float32
,int32
, илиstring
, например) - размеры (shape)
Все элементы тензора имеют одинаковый тип данных, и он всегда известен. Размеры (количество измерений и размер каждого измерения) могут быть известны только частично. Результатом большинства операций являются тензоры с известными размерами, если размеры на входе также полностью известны, но в некоторых случаях узнать размеры тензора можно только во время исполнения графа.
Основные виды тензоров следующие:
tf.Variable
tf.constant
tf.placeholder
tf.SparseTensor
За исключением tf.Variable
, значение тензора неизменяемо, т.е. в контексте одного выполнения тензор может иметь только одно значение. Однако вычисление одного и того же тензора дважды может вернуть различные значения; например, тот же тензор может быть результатом чтения данных с диска, или генерации случайного числа.
Ранг
Ранг объекта tf.Tensor
это количество его измерений. Синонимами ранга являются порядок, степень, размерность. Обратите внимание, что ранг в TensorFlow это не то же самое, что и ранг матрицы в математике. Как показывает следующая таблица, каждый ранг в Tensorflow соответствует некоторой математической сущности:
Ранг | Математическая сущность |
---|---|
0 | Скаляр (только величина) |
1 | Вектор (величина и направление) |
2 | Матрица (таблица чисел) |
3 | 3-Тензор (куб чисел) |
n | n-Тензор (ну вы поняли идею) |
Ранг 0
Следующий фрагмент демонстрирует создание нескольких переменных ранга 0:
mammal = tf.Variable("Elephant", tf.string)
ignition = tf.Variable(451, tf.int16)
floating = tf.Variable(3.14159265359, tf.float64)
its_complicated = tf.Variable(12.3 - 4.85j, tf.complex64)
Замечание: Строка считается единым объектом в TensorFlow, а не последовательностью символов. Возможно иметь строковые скаляры, векторы строк и т.д.
Ранг 1
Для создания объекта tf.Tensor
ранга 1, вы можете передать список элементов в качестве начальных значений. Например:
mystr = tf.Variable(["Hello"], tf.string)
cool_numbers = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([12.3 - 4.85j, 7.5 - 6.23j], tf.complex64)
Ранги более высокого порядка
Ранг 2 объекта tf.Tensor
состоит как минимум из одной строки и одного столбца:
mymat = tf.Variable([[7],[11]], tf.int16)
myxor = tf.Variable([[False, True],[True, False]], tf.bool)
linear_squares = tf.Variable([[4], [9], [16], [25]], tf.int32)
squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
rank_of_squares = tf.rank(squarish_squares)
mymatC = tf.Variable([[7],[11]], tf.int32)
Тензоры более высокого ранга, аналогично, состоят из n-мерных массивов. Например, при обработке изображений используется много тензоров ранга 4, с размерностями соответствующими номеру примера в пакете, высоте изображения, ширине изображения, и цветовому каналу.
my_image = tf.zeros([10, 299, 299, 3]) # размер пакета x высота x ширина x количество цветовых каналов
Получение ранга объекта tf.Tensor
Для определения ранга объекта tf.Tensor
, вызовите метод tf.rank
. Например, следующий метод программно определяет ранг tf.Tensor
заданного выше:
r = tf.rank(my_image)
# После запуска графа, r станет равным 4.
Ссылки на срезы tf.Tensor
Поскольку tf.Tensor
это n-мерный массив ячеек, для получения доступа к одной ячейке в tf.Tensor
вам нужно указать n индексов.
Для тензоров ранга 0 (скаляров), индексы не нужны, поскольку это уже просто число.
Для тензора ранга 1 (вектор), передача единственного индекса даст вам доступ к числу:
my_scalar = my_vector[2]
Заметьте что индекс передаваемый в []
может сам быть скаляром tf.Tensor
, если вы хотите динамически выбрать элемент из вектора.
Для тензоров ранга 2 или выше ситуация интереснее. Для tf.Tensor
ранга 2, передача двух чисел возвращает как и ожидалось скаляр:
my_scalar = my_matrix[1, 2]
Передача одного числа, однако, возвращает подвектор матрицы следующим образом:
my_row_vector = my_matrix[2]
my_column_vector = my_matrix[:, 3]
Нотация :
в синтаксисе выделения подмассива в python используется как "оставьте это измерение в покое". Это полезно в тензорах высокого ранга, поскольку позволяет получить доступ к подвекторам, подматрицам и даже другим подтензорам.
Размеры
Размеры тензора это количество элементов в каждом измерении. Документация TensorFlow использует три условных обозначения для описания размерности тензора: ранг, размеры и количество измерений. Следующая таблица показывает как они соотносятся друг с другом:
Ранг | Размеры | Количество измерений | Пример |
---|---|---|---|
0 | [] | 0-D | 0-D тензор. Скаляр. |
1 | [D0] | 1-D | 1-D тензор размера [5]. |
2 | [D0, D1] | 2-D | 2-D тензор размера [3, 4]. |
3 | [D0, D1, D2] | 3-D | 3-D тензор размера [1, 4, 3]. |
n | [D0, D1,… Dn-1] | n-D | Тензор размера [D0, D1,… Dn-1]. |
Размеры могут быть представлены в виде списков Python/кортежей целых чисел, или с помощью
tf.TensorShape
.
Получение размера объекта tf.Tensor
Есть два способа получить размеры tf.Tensor
. При построении графа часто полезно спросить, что уже известно о размерах тензора. Это можно сделать, прочитав свойство shape
объекта tf.Tensor
. Этот метод возвращает объект TensorShape
, который является удобным способом
представления частично определенных размеров (поскольку при построении графа не все размеры могут быть полностью известны).
Также можно получить tf.Tensor
который представляет полностью определенные размеры другого tf.Tensor
во время выполнения. Это делается вызовом операции tf.shape
. Этим способом вы можете построить граф, который манипулирует размерами тензоров строя другие тензоры зависящие от динамических размеров входных tf.Tensor
.
Например, так можно сделать вектор нулей того же размера, что и число столбцов данной матрицы:
zeros = tf.zeros(my_matrix.shape[1])
Изменение размеров tf.Tensor
Количество элементов тензора это произведение всех его измерений. Количество элементов скаляра всегда равно 1
. Так как много разных размеров могут давать одно и то же число элементов часто удобно менять размеры tf.Tensor
, не изменяя его элементы. Это может быть сделано с помощью tf.reshape
.
Следующие примеры показывают как изменить размеры тензора:
rank_three_tensor = tf.ones([3, 4, 5])
matrix = tf.reshape(rank_three_tensor, [6, 10]) # Преобразование существущих данных
# в матрицу 6x10
matrixB = tf.reshape(matrix, [3, -1]) # Преобразование существующих данных в
# матрицу 3x20. -1 говорит reshape что нужно
# посчитать размер этого измерения.
matrixAlt = tf.reshape(matrixB, [4, 3, -1]) # Преобразование существующих данных в
# тензор 4x3x5
# Отметим, что число элементов в преобразованных тензорах должно совпадать
# с изначальным количеством. Поэтому следующий пример породит
# ошибку поскольку нет такого значения для последнего измерения
# при котором совпадет количество элементов.
yet_another = tf.reshape(matrixAlt, [13, 2, -1]) # ERROR!
Типы данных
В дополнение к размерности, у тензоров есть тип данных. У конкретного tf.Tensor
не может быть более одного типа данных. Однако, возможно сериализовать произвольные структуры данных в string
и хранить их в tf.Tensor
.
Можно преобразовать tf.Tensor
из одного типа данных в другой используя tf.cast
:
# Преобразование константного целочисленного тензора в тензор с плавающей запятой.
float_tensor = tf.cast(tf.constant([1, 2, 3]), dtype=tf.float32)
Чтобы посмотреть тип данных tf.Tensor
используйте свойство Tensor.dtype
.
При создании tf.Tensor
из объекта python вы можете опционально указать тип данных. Если вы этого не сделаете, TensorFlow выберет тип данных который может представлять ваши данные. TensorFlow преобразует целые числа Python в tf.int32
, а числа с плавающей запятой в tf.float32
. В других случаях TensorFlow использует те же правила что и numpy при конвертации массивов.
Оценка тензоров
Как только был построен вычислительный граф, вы можете запустить вычисление, которое
сгенерирует определенный tf.Tensor
и извлечь присвоенное ему значение. Это часто полезно для отладки, а также для работы большей части TensorFlow.
Самый простой способ оценить Tensor — использовать метод Tensor.eval
. Например:
constant = tf.constant([1, 2, 3])
tensor = constant * constant
print(tensor.eval())
Метод eval
работает только когда активна сессия по умолчанию tf.Session
. Tensor.eval
возвращает массив numpy с тем же содержанием что и тензор.
Иногда невозможно оценить tf.Tensor
без контекста, потому что его значение может зависеть от динамической информации, которая недоступна. Например, тензоры, зависящие от placeholder
, не могут быть оценены без предоставления значения для placeholder
.
p = tf.placeholder(tf.float32)
t = p + 1.0
t.eval() # Это не сработает, потому что placeholder не получил значение.
t.eval(feed_dict={p:2.0}) # Это сработает, потому что мы передает
# значение в placeholder.
Обратите внимание, что можно использовать любой tf.Tensor
, не только placeholder.
Конструкции других моделей могут усложнить оценивание tf.Tensor
. TensorFlow не может оценить напрямую tf.Tensor
определенные внутри функций или внутри конструкций потока управления. Если tf.Tensor
зависит от значения из очереди, оценка tf.Tensor
сработает только когда что-то поместят в очередь; в противном случае, оценка тензора зависнет. При работе с очередями, не забывайте вызвать tf.train.start_queue_runners
перед оценкой любого tf.Tensor
.
После проверки перевод появится также на сайте Tensorflow.org. Если вы хотите поучаствовать в переводе документации сайта Tensorflow.org на русский, обращайтесь в личку или комментарии. Любые исправления и замечания приветствуются.
Автор: stabuev