Qual é a diferença entre tf.placeholder e tf.Variable?

290

Sou novato no TensorFlow. Estou confuso sobre a diferença entre tf.placeholdere tf.Variable. Na minha opinião, tf.placeholderé usado para dados de entrada e tf.Variableé usado para armazenar o estado dos dados. Isso é tudo o que eu sei.

Alguém poderia me explicar mais detalhadamente sobre suas diferenças? Em particular, quando usar tf.Variablee quando usar tf.placeholder?

J.Doe
fonte
7
Intuitivamente, você desejará gradientes em relação a Variables, mas não placeholders (cujos valores sempre devem ser fornecidos).
Yibo Yang
Um curso como cs231n.stanford.edu pode ajudar aqueles que estão confusos. Eu gosto muito disso! Obviamente, existem outros
Nathan

Respostas:

175

Em resumo, você usa tf.Variablepara variáveis ​​treináveis, como pesos (W) e desvios (B) para o seu modelo.

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 é usado para alimentar exemplos reais de treinamento.

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

É assim que você alimenta os exemplos de treinamento durante o treinamento:

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)

Seu tf.variables será treinado (modificado) como resultado deste treinamento.

Veja mais em https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Exemplos são retirados da página da web.)

Sung Kim
fonte
2
E se eu quiser pré-processar minha imagem antes de alimentá-la? (por exemplo, redimensionar o contraste). Agora eu preciso de uma variável para isso? Em caso afirmativo, isso tem implicações de memória ou velocidade?
Bastiaan
1
Qualquer pré-processamento que você fizer ocorrerá antes de alimentar os dados no gráfico do Tensorflow (ou seja, rede), para que o trabalho não exija tecnicamente nenhuma ferramenta de código do Tensorflow. Por exemplo, uma variável seria 1. desnecessária, porque são dados de entrada, passados ​​por tf.placeholders (não variáveis) no gráfico e 2. O pré-processamento ocorre antes de ser carregada em um espaço reservado para a passagem atual pela rede .
PaulG
Só queria observar o quanto eu aprecio essa resposta. O fato de que há muito menos upvotes sobre esta resposta do que sobre a questão só vai para mostrar como gratificação instantânea as pessoas podem ser, e como etiquetas de moda gosto tensorflowe deep learninge AIsão.
Nathan
70

A diferença é que tf.Variablevocê precisa fornecer um valor inicial quando o declara. Com tf.placeholdervocê, você não precisa fornecer um valor inicial e pode especificá-lo em tempo de execução com o feed_dictargumento dentroSession.run

fabrizioM
fonte
63
-1. Embora seja verdade, isso está errado. A diferença mais importante é o papel deles no TensorFlow. As variáveis ​​são treinadas ao longo do tempo, os espaços reservados são dados de entrada que não mudam conforme o modelo treina (como imagens de entrada e rótulos de classe para essas imagens). Como a resposta de Sung Kim diz, você usa variáveis ​​para pesos e vieses em seu modelo (embora não se limite a isso - para transferência de estilo, você otimiza uma imagem ao longo do tempo).
Chris Anderson
@ChrisAnderson, poderíamos dizer que esta ilustração está errada ?! youtu.be/MotG3XI2qSs?t=136
N0rA
@ChrisAnderson Por que importa para que serve? Se as diferenças são apenas uma, precisamos de um valor inicial?
Goldname 23/07/19
1
@ Goldname Não é para isso que "se destina" a ser usado - é o que é possível e não é possível. Eles são objetos totalmente diferentes. Eles não são intercambiáveis ​​e as diferenças são mais do que "é preciso um valor inicial".
Chris Anderson
61

Como os cálculos de tensores compõem gráficos , é melhor interpretar os dois em termos de gráficos.

Tomemos, por exemplo, a regressão linear simples

WX+B=Y

onde We Brepresentam os pesos e desvios e Xas entradas Ydas observações e os resultados das observações.

Obviamente Xe Ysão da mesma natureza (variáveis ​​manifestas) que diferem da de We B(variáveis ​​latentes). Xe Ysão valores das amostras (observações) e, portanto, precisam de um local a ser preenchido , enquanto We Bsão os pesos e desvios, variáveis (os valores anteriores afetam os últimos) no gráfico que devem ser treinados usando pares Xe diferentes Y. Colocamos amostras diferentes para os espaços reservados para treinar as variáveis .

Só precisamos salvar ou restaurar as variáveis (nos pontos de verificação) para salvar ou reconstruir o gráfico com o código.

Os marcadores de posição são principalmente titulares dos diferentes conjuntos de dados (por exemplo, dados de treinamento ou dados de teste). No entanto, as variáveis são treinadas no processo de treinamento para tarefas específicas, ou seja, para prever o resultado da entrada ou mapear as entradas para os rótulos desejados. Eles permanecem os mesmos até você treinar ou ajustar o modelo usando amostras diferentes ou iguais para preencher os espaços reservados frequentemente com o ditado. Por exemplo:

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

Os espaços reservados também são passados ​​como parâmetros para definir modelos.

Se você alterar espaços reservados (adicionar, excluir, alterar a forma etc.) de um modelo no meio do treinamento, ainda poderá recarregar o ponto de verificação sem outras modificações. Mas se as variáveis ​​de um modelo salvo forem alteradas, você deve ajustar o ponto de verificação de acordo para recarregá-lo e continuar o treinamento (todas as variáveis ​​definidas no gráfico devem estar disponíveis no ponto de verificação).

Para resumir, se os valores são das amostras (observações que você já possui), você cria um espaço reservado para segurá-las, enquanto que se precisar de um parâmetro a ser treinado, utiliza uma variável (basta colocar, defina as variáveis para os valores desejados para usar o TF automaticamente).

Em alguns modelos interessantes, como um modelo de transferência de estilo , os pixes de entrada serão otimizados e as variáveis ​​de modelo normalmente chamadas serão corrigidas; então, devemos fazer a entrada (geralmente inicializada aleatoriamente) como uma variável conforme implementada nesse link.

Para mais informações, deduza a este documento simples e ilustrativo .

Lerner Zhang
fonte
38

TL; DR

Variáveis

  • Para parâmetros para aprender
  • Valores podem ser derivados do treinamento
  • Valores iniciais são necessários (geralmente aleatórios)

Espaços reservados

  • Armazenamento alocado para dados (como dados de pixel de imagem durante um feed)
  • Os valores iniciais não são necessários (mas podem ser definidos, consulte tf.placeholder_with_default)
James
fonte
34

A diferença mais óbvia entre o tf.Variable e o tf.placeholder é que


você usa variáveis ​​para manter e atualizar parâmetros. Variáveis ​​são buffers na memória contendo tensores. Eles devem ser explicitamente inicializados e podem ser salvos no disco durante e após o treinamento. Posteriormente, você pode restaurar os valores salvos para exercitar ou analisar o modelo.

A inicialização das variáveis ​​é feita com sess.run(tf.global_variables_initializer()). Além disso, ao criar uma variável, você precisa passar um tensor como seu valor inicial para o Variable()construtor e, ao criar uma variável, sempre conhece sua forma.


Por outro lado, você não pode atualizar o espaço reservado. Eles também não devem ser inicializados, mas como prometem ter um tensor, é necessário alimentar o valor neles sess.run(<op>, {a: <some_val>}). E, finalmente, em comparação com uma variável, o espaço reservado pode não conhecer a forma. Você pode fornecer partes das dimensões ou não fornecer absolutamente nada.


Existem outras diferenças:

Parte interessante é que não apenas os espaços reservados podem ser alimentados. Você pode alimentar o valor para uma variável e até para uma constante.

Salvador Dalí
fonte
14

Além das respostas de outras pessoas, elas também explicam muito bem neste tutorial do MNIST no site da Tensoflow:

Descrevemos essas operações de interação manipulando variáveis ​​simbólicas. Vamos criar um:

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

xnão é um valor específico. É um espaço reservado, um valor que inseriremos quando pedirmos ao TensorFlow para executar um cálculo. Queremos poder inserir qualquer número de imagens MNIST, cada uma achatada em um vetor de 784 dimensões. Representamos isso como um tensor 2D de números de ponto flutuante, com uma forma [Nenhum, 784]. (Aqui, None significa que uma dimensão pode ter qualquer comprimento.)

Também precisamos dos pesos e preconceitos para o nosso modelo. Poderíamos imaginar tratar estes como entradas adicionais, mas TensorFlow tem uma maneira ainda melhor de lidar com isso: Variable. A Variableé um tensor modificável que vive no gráfico de operações de interação do TensorFlow. Pode ser usado e até modificado pelo cálculo. Para aplicativos de aprendizado de máquina, geralmente os parâmetros do modelo são Variables.

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

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

Criamos esses Variables, fornecendo tf.Variableo valor inicial de Variable: nesse caso, inicializamos ambos We bcomo tensores cheios de zeros. Desde que vamos aprender We b, não importa muito o que eles são inicialmente.

tagoma
fonte
Oi, obrigado pela sua resposta! No exemplo que você dá, temos xa forma [batch size, features], temos os pesos que vão da entrada à primeira camada de tamanho [features, hidden units]e os vieses [hidden units]. Então, minha pergunta é: como os multiplicamos juntos? Se o fizermos tf.matmul(x, w), então nós vamos chegar [batch size, hidden units]e não podemos ba ela, uma vez que tem forma[hidden units]
Euler_Salter
1
M.Gorner explica tudo isso em suas apresentações de slides "Aprenda TensorFlow e aprendizado profundo, sem doutorado". melhor do que eu jamais poderia fazer aqui neste comentário. Portanto, permita-me consultar este slide: docs.google.com/presentation/d/…
tagoma
11

O Tensorflow usa três tipos de contêineres para armazenar / executar o processo

  1. Constantes: Constantes mantém os dados típicos.

  2. variáveis: os valores dos dados serão alterados, com as respectivas funções como cost_function.

  3. espaços reservados: os dados de treinamento / teste serão transmitidos para o gráfico.

Karnakar Reddy
fonte
10

Fragmento de exemplo:

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

Como o nome diz, o espaço reservado é uma promessa de fornecer um valor posteriormente, ou seja

Variáveis são simplesmente os parâmetros de treinamento ( W(matriz), b(viés) iguais às variáveis ​​normais que você usa em sua programação diária, que o treinador atualiza / modifica em cada corrida / etapa.

Embora o espaço reservado não exija nenhum valor inicial, que quando você criou xe yTF não alocou nenhuma memória, mais tarde, quando você alimenta os espaços reservados no sess.run()uso feed_dict, o TensorFlow alocará a memória de tamanho apropriado para eles ( xe y) - isso sem restrições - nos permite alimentar qualquer tamanho e forma de dados.


Em poucas palavras :

Variável - é um parâmetro que você deseja que o treinador (por exemplo, GradientDescentOptimizer) atualize após cada etapa.

Demonstração de espaço reservado -

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

Execução:

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

resultando na saída

7.5
[ 3.  7.]

No primeiro caso, 3 e 4.5 serão passados ​​para ae brespectivamente e , em seguida, para adder_node ouputting 7. No segundo caso, há uma lista de feeds, os primeiros passos 1 e 2 serão adicionados, os próximos 3 e 4 ( ae b).


Leituras relevantes:

Nabeel Ahmed
fonte
7

Variáveis

Uma variável TensorFlow é a melhor maneira de representar o estado persistente e compartilhado manipulado pelo seu programa. As variáveis ​​são manipuladas através da classe tf.Variable. Internamente, uma variável tf.Variable armazena um tensor persistente. Operações específicas permitem ler e modificar os valores desse tensor. Essas modificações são visíveis em várias tf.Sessions, para que vários trabalhadores possam ver os mesmos valores para uma tf.Variable. As variáveis ​​devem ser inicializadas antes do uso.

Exemplo:

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

Isso cria um gráfico de computação. As variáveis ​​(x e y) podem ser inicializadas e a função (f) avaliada em uma sessão de fluxo tensor da seguinte maneira:

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

Espaços reservados

Um espaço reservado é um nó (igual a uma variável) cujo valor pode ser inicializado no futuro. Esses nós basicamente emitem o valor atribuído a eles durante o tempo de execução. Um nó de espaço reservado pode ser atribuído usando a classe tf.placeholder () à qual você pode fornecer argumentos como o tipo da variável e / ou sua forma. Os espaços reservados são usados ​​extensivamente para representar o conjunto de dados de treinamento em um modelo de aprendizado de máquina, pois o conjunto de dados de treinamento continua mudando.

Exemplo:

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

Nota: 'Nenhum' para uma dimensão significa 'qualquer tamanho'.

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

Referências:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: aprendizado prático de máquina com o Scikit-Learn e Tensorflow
Ankita Mishra
fonte
6

Pense Variableno tensorflow como variáveis ​​normais que usamos nas linguagens de programação. Inicializamos variáveis, também podemos modificá-lo mais tarde. Considerando placeholderque não requer valor inicial. O espaço reservado simplesmente aloca bloco de memória para uso futuro. Mais tarde, podemos usar feed_dictpara alimentar os dados placeholder. Por padrão, placeholderpossui uma forma sem restrições, que permite alimentar tensores de diferentes formas em uma sessão. Você pode criar uma forma restrita passando o argumento opcional -shape, como fiz abaixo.

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

Ao executar a tarefa de aprendizado de máquina, na maioria das vezes não temos conhecimento do número de linhas, mas (vamos assumir) sabemos o número de recursos ou colunas. Nesse caso, podemos usar None.

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

Agora, no tempo de execução, podemos alimentar qualquer matriz com 4 colunas e qualquer número de linhas.

Além disso, os marcadores de posição são usados ​​para dados de entrada (são tipos de variáveis ​​que usamos para alimentar nosso modelo), onde variáveis ​​são parâmetros como pesos que treinamos ao longo do tempo.

Muhammad Usman
fonte
4

Espaço reservado:

  1. Um espaço reservado é simplesmente uma variável à qual atribuiremos os dados posteriormente. Ele nos permite criar nossas operações e construir nosso gráfico de computação, sem precisar dos dados. Na terminologia do TensorFlow, alimentamos os dados no gráfico através desses espaços reservados.

  2. Os valores iniciais não são necessários, mas podem ter valores padrão com tf.placeholder_with_default)

  3. Temos que fornecer valor em tempo de execução como:

    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

Variável :

  1. Uma variável TensorFlow é a melhor maneira de representar o estado persistente e compartilhado manipulado pelo seu programa.
  2. As variáveis ​​são manipuladas através da classe tf.Variable. Uma variável tf.Variable representa um tensor cujo valor pode ser alterado executando ops nele.

Exemplo: tf.Variable("Welcome to tensorflow!!!")

jitsm555
fonte
3

Resposta compatível com Tensorflow 2.0 : O conceito de espaços reservados, tf.placeholdernão estará disponível Tensorflow 2.x (>= 2.0)por padrão, pois o modo de execução padrão é a execução ansiosa.

No entanto, podemos usá-los se usados ​​em Graph Mode( Disable Eager Execution).

Comando equivalente para TF Placeholder na versão 2.x é tf.compat.v1.placeholder.

O comando equivalente para a variável TF na versão 2.x é tf.Variablee se você deseja migrar o código de 1.x para 2.x, o comando equivalente é

tf.compat.v2.Variable.

Consulte esta página do Tensorflow para obter mais informações sobre o Tensorflow versão 2.0.

Consulte o Guia de migração para obter mais informações sobre migração das versões 1.x para 2.x.

Suporte ao Tensorflow
fonte
2

Pense em um gráfico de computação . Nesse gráfico, precisamos de um nó de entrada para passar nossos dados para o gráfico; esses nós devem ser definidos como Espaço reservado no fluxo tensor .

Não pense como um programa geral em Python. Você pode escrever um programa Python e fazer todas as coisas que os caras explicaram em outras respostas apenas por Variáveis, mas para gráficos de computação em fluxo tensor, para alimentar seus dados com o gráfico, você precisa definir esses acenos como espaços reservados.

Ali Salehi
fonte