Яка різниця між tf.placeholder і tf.Variable?


290

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

Чи міг би хтось детальніше пояснити мені їхні відмінності? Зокрема, коли користуватися tf.Variableта коли користуватися tf.placeholder?


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.placeholders (не змінні) в графі, і 2. Попередня обробка відбувається перед завантаженням у заповнювач для поточного проходу через мережу. .
PaulG

Просто хотів зазначити, наскільки я ціную цю відповідь. Той факт , що є набагато менше upvotes на цей відповідь , ніж на питання просто йде , щоб показати , як миттєве задоволення людей , може бути, і як модно теги подобається tensorflowі deep learningта AIє.
Натан

70

Різниця полягає в тому, що при оголошенні tf.Variableви повинні надати початкове значення. Оскільки tf.placeholderвам не потрібно вказувати початкове значення, і ви можете вказати його під час виконання feed_dictаргументу всерединіSession.run


63
-1. Хоча це правда, це не вистачає суті. Більш важлива відмінність полягає в їх ролі в TensorFlow. Змінні навчаються з часом, заповнювачі - це вхідні дані, які не змінюються під час поїздки вашої моделі (наприклад, вхідні зображення та мітки класів для цих зображень). Як йдеться у відповіді Сун Кім, ви використовуєте змінні для ваг і ухилів у вашій моделі (хоча це не обмежується - для передачі стилю ви оптимізуєте зображення з часом).
Кріс Андерсон

@ChrisAnderson чи можна сказати, що ця ілюстрація неправильна ?! youtu.be/MotG3XI2qSs?t=136
N0rA

@ChrisAnderson Чому не важливо, для чого він мав бути використаний, якщо відмінності потрібні лише для початкового значення?
Goldname

1
@Goldname Це не те, для чого "призначено" використовувати - це те, що можливо, а що не можна. Вони абсолютно різні об'єкти. Вони не взаємозамінні, і відмінності більше, ніж "одному потрібно початкове значення".
Кріс Андерсон

61

Оскільки обчислення Тензора складають графіки, то краще їх інтерпретувати в термінах графіків.

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

WX+B=Y

де Wі Bстоять для ваг та зміщення, а також Xдля даних спостережень та Yрезультатів спостережень.

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

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

Заповнювачі , в основному власники для різних наборів даних (наприклад навчальних даних або даних випробувань). Однак Змінні проходять підготовку в навчальному процесі для конкретних завдань, тобто передбачати результат введення або відображати введення даних на потрібні мітки. Вони залишаються тими ж, доки ви не перекваліфікуєте та не доопрацюєте модель, використовуючи різні чи однакові зразки, які часто заповнюються в заповнювачі через дикт. Наприклад:

 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()). Крім того, створюючи змінну, вам потрібно передати тензору як його початкове значення Variable()конструктору, і коли ви створюєте змінну, ви завжди знаєте її форму.


З іншого боку, ви не можете оновити заповнювач. Вони також не повинні бути ініціалізованими, але оскільки вони є обіцянкою мати тензор, вам потрібно ввести значення в них sess.run(<op>, {a: <some_val>}). І нарешті, порівняно зі змінною, заповнювач місця може не знати форми. Можна або надати частини розмірів, або взагалі нічого не забезпечити.


Є й інші відмінності:

Цікава частина полягає в тому, що годувати не тільки заповнювачів. Ви можете подати значення до змінної і навіть до постійної.


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, це не дуже важливо, якими вони є спочатку.


привіт дякую за вашу відповідь! У прикладі, який ви даєте, ми маємо xформу [batch size, features], у нас ваги переходять від вхідного до першого шару розміру [features, hidden units]та зміщення [hidden units]. Отже, моє запитання: як ми їх множимо разом? Якщо ми це зробимо, tf.matmul(x, w)ми дістанемося [batch size, hidden units]і не зможемо bзробити це, оскільки він має форму[hidden units]
Euler_Salter

1
М.Горнер пояснює все це у слайд-шоу "Навчимось тензором та глибоким навчанням, без кандидата наук". краще, ніж я міг коли-небудь зробити тут, у цьому коментарі. Тож дозвольте мені посилатися на цей слайд: 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 витіснення 7. У другому випадку є список каналів, додаються перший крок 1 і 2, наступні 3 і 4 ( aі b).


Відповідні записи:


7

Змінні

Змінна TensorFlow - найкращий спосіб представити спільне, стійке стан, яким маніпулює ваша програма. Змінні маніпулюють через клас tf.Variable. Всередині tf.Variable зберігає стійкий тензор. Конкретні операції дозволяють читати та змінювати значення цього тензора. Ці модифікації видно на декількох tf.Sessions, тому кілька працівників можуть бачити однакові значення для 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в tensorflow як звичайні змінні, які ми використовуємо в мовах програмування. Ми ініціалізуємо змінні, можемо також змінити їх згодом. Тоді placeholderяк початкове значення не вимагає. Заполнитель просто виділяє блок пам'яті для подальшого використання. Пізніше ми можемо використовувати feed_dictдля введення даних placeholder. За замовчуванням placeholderмає необмежену форму, що дозволяє подавати тензори різної форми в сеанс. Ви можете зробити обмежену форму, передавши необов'язковий аргумент -шапе, як я це зробив нижче.

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!!!")


3

Відповідь Tensorflow 2.0 : Концепція заповнювачів tf.placeholderне буде доступною Tensorflow 2.x (>= 2.0)за замовчуванням, оскільки режим виконання за замовчуванням - Eager Execution.

Однак ми можемо використовувати їх, якщо використовувати їх у Graph Mode( Disable Eager Execution).

Еквівалентною командою для заповнювача TF у версії 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.


2

Придумайте графік обчислень . У такому графіку нам потрібен вузол введення, щоб передати наші дані до графіка; ці вузли повинні бути визначені як заповнювач місця в tensorflow .

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.