Разница в реализации между переменной TensorFlow и тензором TensorFlow

Прежде всего, я знаю, что связанный с этим вопрос был задан здесь.

Однако этот вопрос касается внедрения и внутренних дел. Я читал статью " Тур по Тензорфлоу ". Оттуда цитируются следующие два пункта:

1.

Сам тензор не сохраняет или сохраняет значения в памяти, но предоставляет только интерфейс для извлечения значения, на которое ссылается тензор.

Это говорит мне о том, что Тензор - это объект, который просто сохраняет указатель на результат операции и, получая результат или значение тензора, это просто разыгрывает этот указатель.

2.

Переменные можно охарактеризовать как постоянные, изменяемые ручки для буферов в памяти, хранящих тензоры. Таким образом, переменные характеризуются определенной формой и фиксированным типом.

На этом я запутался, потому что, полагая, исходя из предыдущего пункта, тензоры просто хранят указатель. Если бы они были просто указателями, они также могли быть изменчивыми.

Если быть точным, это мои вопросы:

  1. В чем смысл "буферов в памяти"?
  2. В чем смысл "ручки"?
  3. Правильно ли мое первоначальное предположение о внутренности тензора?
  4. Какова существенная внутренняя разница в реализации между тензором и переменной? Почему они заявлены по-разному, и почему эта разница важна для TensorFlow?

Ответ 1

Прежде чем объяснять различие между тензорами и переменными, мы должны быть точными в отношении слова "тензор" в контексте TensorFlow:

  • В API Python объект tf.Tensor представляет собой символический результат операции TensorFlow. Например, в выражении t = tf.matmul(x, y) t - объект tf.Tensor представляющий результат умножения x и y (которые сами могут быть символическими результатами других операций, конкретные значения, такие как массивы NumPy, или переменные).

    В этом контексте "символический результат" более сложный, чем указатель на результат операции. Он более аналогичен объекту функции, который при вызове (т. tf.Session.run()) запускает необходимое вычисление для получения результата этой операции и возвращает его вам как конкретное значение (например, NumPy массив).

  • В API C++ объект tensorflow::Tensor представляет конкретное значение многомерного массива. Например, ядро MatMul принимает два двумерных tensorflow::Tensor objects в качестве входных данных и создает в качестве вывода один двумерный tensorflow::Tensor object.

Это различие немного запутанно, и мы можем выбрать разные имена, если мы начнем (в API других языков мы предпочитаем имя Output для символического результата и Tensor для конкретного значения).

Аналогичное различие существует для переменных. В API Python tf.Variable является символическим представлением переменной, которая имеет методы для создания операций, которые считывают текущее значение переменной и присваивают ей значения. В реализации C++ объект tensorflow::Var является оберткой вокруг общего, изменяемого tensorflow::Tensor.

Исходя из этого контекста, мы можем решить ваши конкретные вопросы:

  1. В чем смысл "буферов в памяти"?

    Буфер в памяти - это просто смежная область памяти, которая была распределена с помощью распределителя TensorFlow. tensorflow::Tensor Объекты tensorflow::Tensor содержат указатель на буфер памяти, в котором хранятся значения этого тензора. Буфер может находиться в памяти хоста (т.е. Доступен из ЦП) или памяти устройства (например, доступен только с графического процессора), а TensorFlow имеет операции перемещения данных между этими ячейками памяти.

  2. В чем смысл "ручки"?

    В объяснении в документе слово "дескриптор" используется несколькими разными способами, которые немного отличаются от того, как TensorFlow использует этот термин. В документе используется "символический дескриптор" для ссылки на объект tf.Tensor и "постоянный, изменяемый дескриптор" для ссылки на объект tf.Variable. Кодовая база TensorFlow использует "дескриптор" для обозначения имени объекта с сохранением состояния (например, tf.FIFOQueue или tf.TensorArray), который может передаваться без копирования всех значений (т. tf.FIFOQueue tf.TensorArray по ссылке).

  3. Верно ли мое первоначальное предположение о внутреннем тензоре?

    Ваше предположение наиболее близко соответствует определению тензорного потока (C++) tensorflow::Tensor. Объект tf.Tensor (Python) более сложный, поскольку он относится к функции вычисления значения, а не к самому значению.

  4. Какова существенная внутренняя разница в реализации между тензором и переменной?

    В C++ tensorflow::Tensor и tensorflow::Tensor tensorflow::Var очень похожи; единственное отличие заключается в том, что у tensorflow::Var также есть mutex который можно использовать для блокировки переменной при ее обновлении.

    В Python существенное различие заключается в том, что tf.Tensor реализуется как граф потока данных, и он tf.Session.run() только для чтения (т. tf.Session.run()). tf.Variable может считываться (т. tf.Variable его операцию чтения) и записывать (например, путем выполнения операции присваивания).

    Почему они заявлены по-разному, и почему эта разница важна для TensorFlow?

    Тензоры и переменные служат различным целям. tf.Tensor (tf.Tensor objects) могут представлять собой сложные композиции математических выражений, такие как функции потерь в нейронной сети или символические градиенты. Переменные представляют состояние, которое обновляется со временем, например, весовые матрицы и сверточные фильтры во время обучения. Хотя в принципе вы могли бы представить эволюционирующее состояние модели без переменных, вы получили бы очень большое (и повторяющееся) математическое выражение, поэтому переменные предоставляют удобный способ материализовать состояние модели и, например, долю это с другими машинами для параллельного обучения.