В чем разница между tf.placeholder и tf.Variable?

290

Я новичок в TensorFlow. Я запутался в разнице между tf.placeholderи tf.Variable. На мой взгляд, tf.placeholderиспользуется для ввода данных и tf.Variableиспользуется для хранения состояния данных. Это все, что я знаю.

Может ли кто-нибудь объяснить мне более подробно об их различиях? В частности, когда использовать tf.Variableи когда использовать tf.placeholder?

j.doe
источник
7
Интуитивно понятно, что вам нужны градиенты по отношению к Variables, но не к placeholders (значения которых всегда должны быть указаны).
Ибо Ян
Курс, подобный cs231n.stanford.edu, может помочь запутавшимся. Мне это очень понравилось! Очевидно, есть другие
Натан

Ответы:

175

Короче говоря, вы используете tf.Variableдля обучаемых переменных, таких как веса (W) и смещения (B) для вашей модели.

weights = tf.Variable(
    tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                    stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights')

biases = tf.Variable(tf.zeros([hidden1_units]), name='biases')

tf.placeholder используется для подачи реальных примеров обучения.

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

Вот как вы подаете обучающие примеры во время обучения:

for step in xrange(FLAGS.max_steps):
    feed_dict = {
       images_placeholder: images_feed,
       labels_placeholder: labels_feed,
     }
    _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)

Вы tf.variablesбудете обучены (изменены) в результате этого обучения.

Подробнее смотрите на https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Примеры взяты с веб-страницы.)

Сунг Ким
источник
2
Что, если я хочу предварительно обработать свое изображение перед подачей? (например, изменить масштаб контраста). Нужна ли мне переменная для этого? Если да, имеет ли это какие-либо последствия для памяти или скорости?
Бастиан
1
Любая предварительная обработка, которую вы делаете, происходит перед подачей данных в граф Tensorflow (то есть в сеть), так что техническая работа не требует каких-либо инструментов кода от Tensorflow. Например, переменная была бы ненужной 1. потому что это входные данные, которые передаются через tf.placeholder (не переменные) в графе и 2. Предварительная обработка происходит до того, как она загружается в заполнитель для текущего прохода через сеть ,
PaulG
Просто хотел отметить, насколько я ценю этот ответ. Тот факт , что есть гораздо меньше upvotes на этот ответ , чем на вопрос просто идет , чтобы показать , как мгновенное удовлетворение людей , может быть, и как модно теги нравится tensorflowи deep learningи AIесть.
Натан
70

Разница в том, что tf.Variableвы должны предоставить начальное значение при его объявлении. При этом tf.placeholderвам не нужно предоставлять начальное значение, и вы можете указать его во время выполнения с feed_dictаргументом внутриSession.run

fabrizioM
источник
63
-1. Хотя это правда, это упускает из виду. Более важным отличием является их роль в TensorFlow. Переменные обучаются с течением времени, заполнители - это входные данные, которые не меняются в зависимости от модели (например, входные изображения и метки классов для этих изображений). Как сказано в ответе Сунг Ким, вы используете переменные для весов и смещений в вашей модели (но не ограничиваясь этим - для передачи стиля вы оптимизируете изображение с течением времени).
Крис Андерсон
@ChrisAnderson мы можем сказать, что эта иллюстрация не так ?! youtu.be/MotG3XI2qSs?t=136
N0rA
@ChrisAnderson Почему важно, для чего он предназначен, если различия только в том, что требуется начальное значение?
Goldname
1
@Goldname Это не то, что «предназначено» для использования - это то, что возможно и не возможно. Это совершенно разные объекты. Они не являются взаимозаменяемыми, и различия больше, чем «нужно начальное значение».
Крис Андерсон
61

Так как вычисления Tensor составляют графы , лучше интерпретировать их в терминах графов.

Возьмем для примера простую линейную регрессию

WX+B=Y

где Wи Bобозначают веса и смещения, а также Xдля входов наблюдений иY наблюдений и выходные данные наблюдений.

Очевидно, Xи Yимеют одинаковую природу (явные переменные), которые отличаются от того, что Wи B(латентные переменные). Xи Yявляются значениями выборок (наблюдений) и, следовательно, нуждаются в месте для заполнения , в то время как Wи Bявляются весами и смещением, переменными (предыдущие значения влияют на последние) в графе, которые следует обучать, используя разные Xи Yпары. Мы размещаем различные образцы для заполнителей для обучения переменных .

Нам нужно только , чтобы сохранить или восстановить те переменные (на контрольно - пропускных пунктах) , чтобы сохранить или восстановить граф с кодом.

Заполнители в основном являются держателями для различных наборов данных (например, данных обучения или данных испытаний). Тем не менее, переменные обучаются в процессе обучения для конкретных задач, то есть, чтобы предсказать результат ввода или сопоставить входы с желаемыми метками. Они остаются такими же , пока вы не переучивать или тонкую настройку модели с использованием различных или же образцов для заполнения в Указатель место заполнения часто через Dict. Например:

 session.run(a_graph, dict = {a_placeholder_name : sample_values}) 

Заполнители также передаются в качестве параметров для установки моделей.

Если вы измените заполнители (добавьте, удалите, измените форму и т. Д.) Модели в середине обучения, вы все равно сможете перезагрузить контрольную точку без каких-либо других модификаций. Но если переменные сохраненной модели изменены, вам следует соответствующим образом настроить контрольную точку, чтобы перезагрузить ее и продолжить обучение (все переменные, определенные на графике, должны быть доступны в контрольной точке).

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

В некоторых интересных моделях, таких как модель передачи стиля , входные пиксели будут оптимизированы, и обычно называемые переменные модели фиксированы, тогда мы должны сделать ввод (обычно инициализированный случайным образом) как переменную, как реализовано в этой ссылке.

Для получения дополнительной информации, пожалуйста, сделайте вывод на этот простой и иллюстрирующий документ .

Лернер Чжан
источник
38

TL; DR

переменные

  • Для параметров, чтобы узнать
  • Ценности могут быть получены из обучения
  • Требуются начальные значения (часто случайные)

Заполнители

  • Выделенное хранилище для данных (например, для данных пикселей изображения во время подачи)
  • Начальные значения не обязательны (но могут быть установлены, см. tf.placeholder_with_default)
Джеймс
источник
34

Самая очевидная разница между tf.Variable и tf.placeholder заключается в том, что


Вы используете переменные для хранения и обновления параметров. Переменные - это буферы в памяти, содержащие тензоры. Они должны быть явно инициализированы и могут быть сохранены на диск во время и после тренировки. Позже вы можете восстановить сохраненные значения для тренировки или анализа модели.

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


С другой стороны, вы не можете обновить заполнитель. Они также не должны быть инициализированы, но, поскольку они обещают иметь тензор, вам необходимо ввести значение в них sess.run(<op>, {a: <some_val>}). И, наконец, по сравнению с переменной, заполнитель может не знать форму. Вы можете предоставить части размеров или вообще ничего не указывать.


Есть и другие отличия:

  • значения внутри переменной могут быть обновлены во время оптимизации
  • переменные могут быть общими и могут быть необучаемыми
  • значения внутри переменной могут быть сохранены после тренировки
  • при создании переменной на график добавляется 3 операции (переменная операция, операция инициализации, операция для начального значения)
  • заполнитель - это функция, переменная - это класс (отсюда и верхний регистр)
  • когда вы используете TF в распределенной среде, переменные хранятся в специальном месте ( сервер параметров ) и распределяются между рабочими.

Интересно, что кормить можно не только заполнителей. Вы можете передать значение переменной и даже константе.

Сальвадор Дали
источник
14

В дополнение к ответам других, они также очень хорошо объясняют это в этом уроке MNIST на веб-сайте Tensoflow:

Мы описываем эти взаимодействующие операции, манипулируя символическими переменными. Давайте создадим один:

x = tf.placeholder(tf.float32, [None, 784]),

xне конкретное значение. Это заполнитель, значение, которое мы введем, когда попросим TensorFlow выполнить вычисление. Мы хотим иметь возможность вводить любое количество изображений MNIST, каждое из которых сведено в 784-мерный вектор. Мы представляем это как двумерный тензор чисел с плавающей точкой с формой [None, 784]. (Здесь None означает, что измерение может иметь любую длину.)

Нам также нужны веса и уклоны для нашей модели. Мы могли бы представить себе , как обрабатывать эти дополнительные входы, но TensorFlow имеет еще лучший способ справиться с этим: Variable. A Variable- модифицируемый тензор, который живет в графе взаимодействующих операций TensorFlow. Он может быть использован и даже изменен при вычислении. Для приложений машинного обучения обычно используются параметры модели Variables.

W = tf.Variable(tf.zeros([784, 10]))

b = tf.Variable(tf.zeros([10]))

Мы создаем эти Variables, задавая tf.Variableначальное значение Variable: в этом случае мы инициализируем оба Wи bкак тензоры, полные нулей. Так как мы будем учиться Wи b, это не имеет значения очень , что они изначально.

tagoma
источник
привет спасибо за ответ! В приведенном вами примере мы имеем xс формой [batch size, features], у нас есть веса, идущие от входа к первому слою размера [features, hidden units]и смещения [hidden units]. Итак, мой вопрос: как мы умножаем их вместе? Если мы это сделаем, tf.matmul(x, w)то получим, [batch size, hidden units]и не сможем b, потому что он имеет форму[hidden units]
Euler_Salter,
1
М.Горнер объясняет все это в своих слайд-шоу «Изучи TensorFlow и глубокое обучение, без докторской степени». лучше, чем я мог сделать здесь, в этом комментарии. Итак, позвольте мне сослаться на этот слайд: docs.google.com/presentation/d/…
tagoma
11

Tensorflow использует три типа контейнеров для хранения / выполнения процесса

  1. Константы: Константы содержат типичные данные.

  2. переменные: значения данных будут изменены с соответствующими функциями, такими как cost_function.

  3. заполнители: данные обучения / тестирования будут переданы на график.

Карнакар Редди
источник
10

Пример фрагмента:

import numpy as np
import tensorflow as tf

### Model parameters ###
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)

### Model input and output ###
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)

### loss ###
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares

### optimizer ###
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

### training data ###
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]

### training loop ###
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

Как следует из названия, заполнитель - это обещание предоставить значение позже, т.е.

Переменные - это просто параметры обучения ( W(матрица), b(смещение), такие же, как обычные переменные, которые вы используете в повседневном программировании, которые тренер обновляет / модифицирует при каждом запуске / шаге.

В то время как заполнитель не требует никакого начального значения, то, что когда вы создали xи yTF не выделил какую-либо память, вместо этого позже, когда вы подпишете заполнители в sess.run()использовании feed_dict, TensorFlow выделит для них память соответствующего размера ( xи y) - это без ограничений - Ness позволяет нам передавать данные любого размера и формы.


В двух словах :

Переменная - это параметр, который вы хотите, чтобы тренер (например, GradientDescentOptimizer) обновлял после каждого шага.

Демо- заполнитель -

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b  # + provides a shortcut for tf.add(a, b)

Исполнение:

print(sess.run(adder_node, {a: 3, b:4.5}))
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))

в результате на выходе

7.5
[ 3.  7.]

В первом случае 3 и 4.5 будут переданы в aи bсоответственно, а затем в adder_node outputting 7. Во втором случае есть список каналов, будут добавлены первые шаги 1 и 2, следующие 3 и 4 ( aи b).


Актуальные читает:

Набиль Ахмед
источник
7

переменные

Переменная TensorFlow - лучший способ представить общее постоянное состояние, управляемое вашей программой. Переменные обрабатываются с помощью класса tf.Variable. Внутренне переменная tf.Variable хранит постоянный тензор. Конкретные операции позволяют читать и изменять значения этого тензора. Эти изменения видны в нескольких сеансах tf.Session, поэтому несколько рабочих могут видеть одинаковые значения для переменной tf.Variable. Переменные должны быть инициализированы перед использованием.

Пример:

x = tf.Variable(3, name="x")
y = tf.Variable(4, name="y")
f = x*x*y + y + 2

Это создает граф вычислений. Переменные (x и y) могут быть инициализированы, а функция (f) оценена в сеансе тензорного потока следующим образом:

with tf.Session() as sess:
     x.initializer.run()
     y.initializer.run()
     result = f.eval()
print(result)
42

Заполнители

Заполнитель - это узел (такой же, как переменная), значение которого может быть инициализировано в будущем. Эти узлы в основном выводят значение, назначенное им во время выполнения. Узел-заполнитель можно назначить с помощью класса tf.placeholder (), которому вы можете предоставить аргументы, такие как тип переменной и / или ее форма. Заполнители широко используются для представления набора данных обучения в модели машинного обучения, так как набор данных обучения постоянно меняется.

Пример:

A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5

Примечание: «Нет» для измерения означает «любой размер».

with tf.Session as sess:
    B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})
    B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})

print(B_val_1)
[[6. 7. 8.]]
print(B_val_2)
[[9. 10. 11.]
 [12. 13. 14.]]

Ссылки:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: практическое машинное обучение с Scikit-Learn & Tensorflow
Анкита Мишра
источник
6

Думайте о Variableтензорном потоке как о обычных переменных, которые мы используем в языках программирования. Мы инициализируем переменные, мы можем изменить это позже. Принимая во внимание, placeholderчто не требует начальной стоимости. Заполнитель просто выделяет блок памяти для будущего использования. Позже мы можем использовать feed_dictдля подачи данных в placeholder. По умолчанию placeholderимеет неограниченную форму, что позволяет подавать тензоры разных форм в сеансе. Вы можете создать ограниченную форму, передав необязательный аргумент -shape, как я сделал ниже.

x = tf.placeholder(tf.float32,(3,4))
y =  x + 2

sess = tf.Session()
print(sess.run(y)) # will cause an error

s = np.random.rand(3,4)
print(sess.run(y, feed_dict={x:s}))

При выполнении задачи машинного обучения большую часть времени мы не знаем о количестве строк, но (предположим) мы знаем количество элементов или столбцов. В этом случае мы можем использовать None.

x = tf.placeholder(tf.float32, shape=(None,4))

Теперь во время выполнения мы можем кормить любую матрицу 4 столбцами и любым количеством строк.

Кроме того, заполнители используются для входных данных (они являются своего рода переменными, которые мы используем для подачи нашей модели), где в качестве переменных используются такие параметры, как веса, которые мы тренируем с течением времени.

Мухаммед Усман
источник
4

Заполнитель:

  1. Заполнитель - это просто переменная, которой мы назначим данные позже. Это позволяет нам создавать наши операции и строить наш график вычислений, не требуя данных. В терминологии TensorFlow мы затем подаем данные в граф через эти заполнители.

  2. Начальные значения не обязательны, но могут иметь значения по умолчанию с tf.placeholder_with_default)

  3. Мы должны предоставить значение во время выполнения, как:

    a = tf.placeholder(tf.int16) // initialize placeholder value
    b = tf.placeholder(tf.int16) // initialize placeholder value
    
    use it using session like :
    
    sess.run(add, feed_dict={a: 2, b: 3}) // this value we have to assign at runtime

Переменная:

  1. Переменная TensorFlow - лучший способ представить общее постоянное состояние, управляемое вашей программой.
  2. Переменные обрабатываются с помощью класса tf.Variable. Переменная tf.Variable представляет тензор, значение которого можно изменить, запустив на нем операции ops.

Пример : tf.Variable("Welcome to tensorflow!!!")

jitsm555
источник
3

Ответ, совместимый с Tensorflow 2.0 : Концепция заполнителей tf.placeholderне будет доступна Tensorflow 2.x (>= 2.0)по умолчанию, поскольку режимом исполнения по умолчанию является «Стремительное выполнение».

Тем не менее, мы можем использовать их, если они используются в Graph Mode( Disable Eager Execution).

Эквивалентная команда для TF Placeholder в версии 2.x есть tf.compat.v1.placeholder.

Эквивалентная команда для переменной TF в версии 2.x есть, tf.Variableи если вы хотите перенести код с 1.x на 2.x, эквивалентная команда

tf.compat.v2.Variable,

Пожалуйста, обратитесь к этой странице Tensorflow для получения дополнительной информации о Tensorflow версии 2.0.

Пожалуйста, обратитесь к Руководству по миграции для получения дополнительной информации о миграции с версий 1.x до 2.x.

Поддержка Tensorflow
источник
2

Подумайте о графике вычислений . В таком графе нам нужен входной узел для передачи наших данных в граф, эти узлы должны быть определены как Placeholder в тензорном потоке .

Не думайте, что это обычная программа на Python. Вы можете написать программу на Python и делать все те вещи, которые ребята объяснили в других ответах только с помощью переменных, но для вычислительных графов в тензорном потоке, чтобы подать ваши данные в граф, вам нужно определить эти узлы как заполнители.

Али Салехи
источник