Jaka jest różnica między tf.placeholder a tf.Variable?

290

Jestem nowicjuszem w TensorFlow. Jestem zdezorientowany co do różnicy między tf.placeholderi tf.Variable. Moim zdaniem tf.placeholdersłuży do wprowadzania danych i tf.Variablesłuży do przechowywania stanu danych. To wszystko co wiem.

Czy ktoś mógłby mi bardziej szczegółowo wyjaśnić swoje różnice? W szczególności, kiedy tf.Variablei kiedy używać tf.placeholder?

J.Doe
źródło
7
Intuicyjnie będziesz potrzebować gradientów względem Variables, ale nie placeholders (których wartości należy zawsze podawać).
Yibo Yang,
Kurs taki jak cs231n.stanford.edu może pomóc tym zdezorientowanym. Bardzo to lubiłem! Oczywiście są inni
Nathan

Odpowiedzi:

175

W skrócie, używasz tf.Variablezmiennych , które można trenować, takich jak wagi (W) i odchylenia (B) dla swojego modelu.

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 służy do karmienia rzeczywistych przykładów szkoleń.

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

W ten sposób podajesz przykłady treningu podczas szkolenia:

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)

W tf.variableswyniku tego szkolenia zostaniesz przeszkolony (zmodyfikowany).

Zobacz więcej na https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Przykłady pochodzą ze strony internetowej.)

Sung Kim
źródło
2
Co jeśli chcę wstępnie przetworzyć mój obraz przed jego podaniem? (np. przeskaluj kontrast). Czy potrzebuję teraz do tego zmiennej? Jeśli tak, to czy ma to wpływ na pamięć lub szybkość?
Bastiaan
1
Każde wstępne przetwarzanie nastąpi przed wprowadzeniem danych do wykresu Tensorflow (tj. Sieci), aby praca nie wymagała technicznych narzędzi Tensorflow. Na przykład zmienna byłaby niepotrzebna 1., ponieważ jest to dane wejściowe, które są przekazywane przez tf.placeholder (nie zmienne) na wykresie i 2. Wstępne przetwarzanie następuje przed załadowaniem go do symbolu zastępczego dla bieżącego przejścia przez sieć .
PaulG
Chciałem tylko zauważyć, jak bardzo doceniam tę odpowiedź. Fakt, że istnieje o wiele mniej upvotes tą odpowiedź niż na pytanie tylko po to aby pokazać, jak ludzie natychmiastową gratyfikację może być i jak modny tagi podoba tensorflowi deep learningi AIsą.
Nathan
70

Różnica polega na tym, że wraz z tf.Variabledeklaracją musisz podać wartość początkową. Dzięki tf.placeholdernie musisz podawać wartości początkowej i możesz ją określić w czasie wykonywania z feed_dictargumentem w środkuSession.run

fabrizioM
źródło
63
-1. Chociaż jest to prawda, nie ma to sensu. Ważniejszą różnicą jest ich rola w TensorFlow. Zmienne są trenowane z biegiem czasu, symbole zastępcze są danymi wejściowymi, które nie zmieniają się w miarę trenowania modelu (takie jak obrazy wejściowe i etykiety klas dla tych obrazów). Jak mówi odpowiedź Sung Kima, używasz zmiennych do wag i odchyleń w swoim modelu (choć nie tylko - do transferu stylu optymalizujesz obraz w czasie).
Chris Anderson,
@ChrisAnderson czy moglibyśmy powiedzieć, że ta ilustracja jest błędna ?! youtu.be/MotG3XI2qSs?t=136
N0rA
@ChrisAnderson Dlaczego ma to znaczenie, do czego miało być użyte, jeśli różnice są tylko jedną wartością początkową?
Goldname
1
@Goldname To nie jest to, do czego „ma być” przeznaczone - jest to możliwe i niemożliwe. To są zupełnie różne przedmioty. Nie można ich zamieniać, a różnice są więcej niż „potrzebna jest wartość początkowa”.
Chris Anderson,
61

Ponieważ obliczenia Tensora składają się z wykresów , lepiej interpretować je w kategoriach wykresów.

Weźmy na przykład prostą regresję liniową

WX+B=Y

gdzie Wi Boznaczają wagi i stronniczość oraz Xdane wejściowe obserwacji i wyniki Yobserwacji.

Oczywiście Xi Ymają ten sam charakter (zmienne manifestacyjne), które różnią się od zmiennych Wi B(ukrytych zmiennych). Xi Ysą wartości próbek (obserwacje) i dlatego też potrzebują miejsca do obsadzenia , a Wi Bto masy i skośnym, zmienne (poprzednie wartości wpływa na drugi) na wykresie, które powinny zostać wyszkolony stosując różne Xi Ypary. Umieszczamy różne próbki dla symboli zastępczych w celu trenowania zmiennych .

Musimy tylko zachować lub przywrócić do zmiennych (w punktach kontrolnych), aby zachować lub odbudować wykres z kodu.

Symbole zastępcze są najczęściej posiadaczami różnych zestawów danych (na przykład danych szkoleniowych lub danych testowych). Jednak Zmienne są przeszkoleni w procesie szkolenia do konkretnych zadań, czyli do przewidywania wyniku wejścia lub map wejść do wybranej etykiety. Pozostają takie same, dopóki nie dokonasz ponownego szkolenia lub dostrojenia modelu przy użyciu różnych lub tych samych próbek, aby często wypełniać symbole zastępcze za pomocą nagrania. Na przykład:

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

Symbole zastępcze są również przekazywane jako parametry do ustawiania modeli.

Jeśli zmienisz symbole zastępcze (dodasz, usuniesz, zmienisz kształt itp.) Modelu w trakcie treningu, nadal możesz ponownie załadować punkt kontrolny bez żadnych innych modyfikacji. Ale jeśli zmienne zapisane w modelu zostaną zmienione, należy odpowiednio dostosować punkt kontrolny, aby go ponownie załadować i kontynuować szkolenie (wszystkie zmienne zdefiniowane na wykresie powinny być dostępne w punkcie kontrolnym).

Podsumowując, jeśli wartości pochodzą z próbek (obserwacje, które już masz), bezpiecznie tworzysz symbol zastępczy, aby je zachować, a jeśli potrzebujesz trenowanego parametru, wykorzystaj Zmienną (po prostu ustaw, ustaw Zmienne dla żądanych wartości automatycznie korzystać z TF).

W niektórych interesujących modelach, takich jak model przenoszenia stylu , piksele wejściowe zostaną zoptymalizowane, a normalnie nazywane zmienne modelu zostaną naprawione, a następnie powinniśmy wprowadzić dane wejściowe (zwykle inicjowane losowo) jako zmienną zaimplementowaną w tym łączu.

Aby uzyskać więcej informacji, skorzystaj z tego prostego i ilustrującego dokumentu .

Lerner Zhang
źródło
38

TL; DR

Zmienne

  • Aby dowiedzieć się parametrów
  • Wartości można wyprowadzić ze szkolenia
  • Wymagane są wartości początkowe (często losowe)

Symbole zastępcze

  • Przydzielone miejsce na dane (takie jak dane pikseli obrazu podczas kanału)
  • Wartości początkowe nie są wymagane (ale można je ustawić, patrz tf.placeholder_with_default)
James
źródło
34

Najbardziej oczywistą różnicą między zmienną tf.Variable i tf.placeholder jest to


używasz zmiennych do przechowywania i aktualizowania parametrów. Zmienne są buforami w pamięci zawierającymi tensory. Muszą być wyraźnie zainicjowane i mogą być zapisywane na dysku podczas i po treningu. Możesz później przywrócić zapisane wartości w celu wykonania lub analizy modelu.

Inicjalizacja zmiennych odbywa się za pomocą sess.run(tf.global_variables_initializer()). Również podczas tworzenia zmiennej musisz przekazać konstruktorowi jego wartość początkową, Variable()a kiedy tworzysz zmienną, zawsze znasz jej kształt.


Z drugiej strony nie można zaktualizować symbolu zastępczego. Nie należy ich także inicjalizować, ale ponieważ są obietnicą posiadania tensora, należy do nich wprowadzić wartość sess.run(<op>, {a: <some_val>}). I w końcu, w porównaniu do zmiennej, symbol zastępczy może nie znać kształtu. Możesz podać części wymiarów lub w ogóle nic nie podać.


Istnieją inne różnice:

Ciekawe jest to, że można karmić nie tylko symbole zastępcze. Możesz podać wartość do zmiennej, a nawet stałej.

Salvador Dali
źródło
14

Dodając do odpowiedzi innych, wyjaśniają to również bardzo dobrze w tym samouczku MNIST na stronie internetowej Tensoflow:

Opisujemy te interakcje, manipulując zmiennymi symbolicznymi. Stwórzmy jeden:

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

xnie jest określoną wartością. Jest to symbol zastępczy, wartość, którą wprowadzimy, gdy poprosimy TensorFlow o uruchomienie obliczeń. Chcemy mieć możliwość wprowadzania dowolnej liczby obrazów MNIST, z których każdy jest spłaszczony do 784-wymiarowego wektora. Reprezentujemy to jako 2-D tensor liczb zmiennoprzecinkowych o kształcie [None, 784]. (Tutaj Brak oznacza, że ​​wymiar może mieć dowolną długość).

Potrzebujemy również wag i odchyleń dla naszego modelu. Możemy sobie wyobrazić, traktując je jak dodatkowe wejścia, ale TensorFlow ma nawet lepszy sposób sobie z tym poradzić: Variable. A Variablejest modyfikowalnym tensorem, który żyje na wykresie interakcji TensorFlow. Może być używany, a nawet modyfikowany przez obliczenia. W przypadku aplikacji uczenia maszynowego parametrami modelu na ogół są Variables.

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

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

Tworzymy je Variable, podając tf.Variablewartość początkową Variable: w tym przypadku inicjujemy oba Wi bjako tensory pełne zer. Ponieważ będziemy się uczyć Wi bnie ma większego znaczenia, jakie są początkowo.

tagoma
źródło
cześć dziękuję za odpowiedź! W podanym przez ciebie przykładzie mamy xkształt [batch size, features], mamy wagi od wejścia do pierwszej warstwy wielkości [features, hidden units]i odchylenia [hidden units]. Moje pytanie brzmi: w jaki sposób je pomnożymy? Jeśli to zrobimy tf.matmul(x, w), dostaniemy [batch size, hidden units]i nie możemy tego bzrobić, ponieważ ma kształt[hidden units]
Euler_Salter,
1
M.Gorner wyjaśnia to wszystko w swoich pokazach slajdów „Naucz się TensorFlow i głębokiego uczenia się, bez doktoratu”. lepiej niż mogłem zrobić tutaj w tym komentarzu. Pozwólcie, że odsyłam do tego slajdu: docs.google.com/presentation/d/…
tagoma,
11

Tensorflow wykorzystuje trzy typy kontenerów do przechowywania / wykonywania procesu

  1. Stałe: Stałe przechowują typowe dane.

  2. zmienne: Wartości danych zostaną zmienione wraz z odpowiednimi funkcjami, takimi jak funkcja koszt.

  3. symbole zastępcze: dane szkoleniowe / testowe zostaną przekazane do wykresu.

Karnakar Reddy
źródło
10

Przykładowy fragment:

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})

Jak sama nazwa mówi, symbol zastępczy jest obietnicą dostarczenia wartości później, tj

Zmienne to po prostu parametry treningu ( W(matryca), b(stronniczość) takie same jak normalne zmienne używane w codziennym programowaniu, które trener aktualizuje / modyfikuje przy każdym uruchomieniu / kroku.

Podczas gdy symbol zastępczy nie wymaga żadnej wartości początkowej, że gdy utworzysz, xa yTF nie przydzieli pamięci, zamiast tego, gdy podasz symbole zastępcze w sess.run()użyciu feed_dict, TensorFlow przydzieli im odpowiednią wielkość pamięci ( xi y) - to nieograniczone - ness pozwala nam podawać dane o dowolnym rozmiarze i kształcie.


W skrócie :

Zmienna - jest parametrem, który trener (tj. GradientDescentOptimizer) ma aktualizować po każdym kroku.

Demo zastępcze -

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

Wykonanie:

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

co daje wynik

7.5
[ 3.  7.]

W pierwszym przypadku, 3 i 4,5 będą przekazywane do ai b, odpowiednio, a następnie adder_node ouputting 7. W drugim przypadku nie jest to lista kanałów, pierwszy etap 1 i 2 zostanie dodana, przy 3 i 4 ( aa b).


Odpowiednie czyta:

Nabeel Ahmed
źródło
7

Zmienne

Zmienna TensorFlow jest najlepszym sposobem reprezentowania wspólnego, trwałego stanu, którym manipuluje twój program. Zmienne są przetwarzane za pośrednictwem klasy tf.Variable. Wewnętrznie tf.Variable przechowuje trwały tensor. Określone operacje pozwalają na odczyt i modyfikację wartości tego tensora. Te modyfikacje są widoczne w wielu sesjach TF, więc wielu pracowników może zobaczyć te same wartości dla zmiennej TF. Przed użyciem należy zainicjować zmienne.

Przykład:

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

Spowoduje to utworzenie wykresu obliczeniowego. Zmienne (xiy) można zainicjować, a funkcję (f) ocenić w sesji tensorflow w następujący sposób:

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

Symbole zastępcze

Symbol zastępczy to węzeł (taki sam jak zmienna), którego wartość można zainicjować w przyszłości. Te węzły generują w zasadzie wartość przypisaną do nich podczas działania. Węzeł zastępczy można przypisać za pomocą klasy tf.placeholder (), do której można podać argumenty, takie jak typ zmiennej i / lub jej kształt. Symbole zastępcze są szeroko stosowane do reprezentowania zestawu danych szkoleniowych w modelu uczenia maszynowego, gdy zestaw danych szkoleniowych ciągle się zmienia.

Przykład:

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

Uwaga: „Brak” dla wymiaru oznacza „dowolny rozmiar”.

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.]]

Bibliografia:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: Praktyczne uczenie maszynowe dzięki Scikit-Learn i Tensorflow
Ankita Mishra
źródło
6

Myśl o Variabletensorflow jako o normalnych zmiennych, których używamy w językach programowania. Inicjujemy zmienne, możemy je również później modyfikować. Natomiast placeholdernie wymaga wartości początkowej. Symbol zastępczy po prostu przydziela blok pamięci do wykorzystania w przyszłości. Później możemy użyć feed_dictdo wprowadzenia danych placeholder. Domyślnie placeholderma nieograniczony kształt, co pozwala na podawanie tensorów o różnych kształtach w sesji. Możesz stworzyć ograniczony kształt, przekazując opcjonalny argument -shape, jak zrobiłem poniżej.

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}))

Podczas wykonywania zadania uczenia maszynowego przez większość czasu nie jesteśmy świadomi liczby wierszy, ale (załóżmy) znamy liczbę funkcji lub kolumn. W takim przypadku możemy użyć opcji Brak.

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

Teraz w czasie wykonywania możemy karmić dowolną macierz 4 kolumnami i dowolną liczbą wierszy.

Również symbole zastępcze są używane do danych wejściowych (są rodzajem zmiennych, których używamy do zasilania naszego modelu), gdzie jako zmienne są parametry, takie jak wagi, które trenujemy w czasie.

Muhammad Usman
źródło
4

Symbol zastępczy:

  1. Symbol zastępczy to po prostu zmienna, do której przypiszemy dane w późniejszym terminie. Pozwala nam to tworzyć nasze operacje i budować wykres obliczeniowy bez potrzeby korzystania z danych. W terminologii TensorFlow za pomocą tych symboli zastępczych wprowadzamy dane do wykresu.

  2. Wartości początkowe nie są wymagane, ale mogą mieć wartości domyślne z tf.placeholder_with_default)

  3. W czasie wykonywania musimy zapewnić wartość, taką jak:

    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

Zmienna:

  1. Zmienna TensorFlow jest najlepszym sposobem reprezentowania wspólnego, trwałego stanu, którym manipuluje twój program.
  2. Zmienne są przetwarzane za pośrednictwem klasy tf.Variable. Zmienna tf. Reprezentuje tensor, którego wartość można zmienić, uruchamiając na nim operacje.

Przykład: tf.Variable("Welcome to tensorflow!!!")

jitsm555
źródło
3

Odpowiedź zgodna z Tensorflow 2.0 : Koncepcja symboli zastępczych tf.placeholdernie będzie Tensorflow 2.x (>= 2.0)domyślnie dostępna, ponieważ domyślnym trybem wykonania jest Szybka realizacja.

Możemy ich jednak użyć, jeśli zostaną użyte w Graph Mode( Disable Eager Execution).

Odpowiednikiem polecenia dla symbolu zastępczego TF w wersji 2.x jest tf.compat.v1.placeholder.

Poleceniem równoważnym dla zmiennej TF w wersji 2.x jest tf.Variablei jeśli chcesz migrować kod z 1.x do 2.x, równoważne polecenie to

tf.compat.v2.Variable.

Więcej informacji na temat Tensorflow w wersji 2.0 można znaleźć na tej stronie Tensorflow.

Więcej informacji na temat migracji z wersji 1.x do 2.x można znaleźć w Przewodniku migracji.

Obsługa Tensorflow
źródło
2

Pomyśl o grafie obliczeniowym . Na takim wykresie potrzebujemy węzła wejściowego, aby przekazać nasze dane do wykresu. Węzły te należy zdefiniować jako symbol zastępczy w przepływie tensorowym .

Nie myśl jako ogólny program w Pythonie. Możesz napisać program w języku Python i robić wszystkie te rzeczy, które faceci wyjaśnili w innych odpowiedziach tylko przez Zmienne, ale w przypadku wykresów obliczeniowych w przepływie tensorowym, aby wprowadzić dane do wykresu, musisz zdefiniować te węzły jako symbole zastępcze.

Ali Salehi
źródło