Veja no TensorFlow.org | Executar no Google Colab | Ver fonte no GitHub | Baixar caderno |
Uma variável do TensorFlow é a maneira recomendada de representar o estado compartilhado e persistente que seu programa manipula. Este guia aborda como criar, atualizar e gerenciar instâncias de tf.Variable
no TensorFlow.
As variáveis são criadas e rastreadas por meio da classe tf.Variable
. Uma tf.Variable
representa um tensor cujo valor pode ser alterado executando operações nele. Operações específicas permitem que você leia e modifique os valores desse tensor. Bibliotecas de nível superior como tf.keras
usam tf.Variable
para armazenar parâmetros de modelo.
Configurar
Este notebook discute o posicionamento variável. Se você quiser ver em qual dispositivo suas variáveis estão colocadas, descomente esta linha.
import tensorflow as tf
# Uncomment to see where your variables get placed (see below)
# tf.debugging.set_log_device_placement(True)
Criar uma variável
Para criar uma variável, forneça um valor inicial. A tf.Variable
terá o mesmo dtype
que o valor de inicialização.
my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
my_variable = tf.Variable(my_tensor)
# Variables can be all kinds of types, just like tensors
bool_variable = tf.Variable([False, False, False, True])
complex_variable = tf.Variable([5 + 4j, 6 + 1j])
Uma variável parece e age como um tensor e, na verdade, é uma estrutura de dados apoiada por um tf.Tensor
. Como os tensores, eles têm um dtype
e uma forma e podem ser exportados para NumPy.
print("Shape: ", my_variable.shape)
print("DType: ", my_variable.dtype)
print("As NumPy: ", my_variable.numpy())
Shape: (2, 2) DType: <dtype: 'float32'> As NumPy: [[1. 2.] [3. 4.]]
A maioria das operações de tensor funciona em variáveis como esperado, embora as variáveis não possam ser reformuladas.
print("A variable:", my_variable)
print("\nViewed as a tensor:", tf.convert_to_tensor(my_variable))
print("\nIndex of highest value:", tf.argmax(my_variable))
# This creates a new tensor; it does not reshape the variable.
print("\nCopying and reshaping: ", tf.reshape(my_variable, [1,4]))
A variable: <tf.Variable 'Variable:0' shape=(2, 2) dtype=float32, numpy= array([[1., 2.], [3., 4.]], dtype=float32)> Viewed as a tensor: tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float32) Index of highest value: tf.Tensor([1 1], shape=(2,), dtype=int64) Copying and reshaping: tf.Tensor([[1. 2. 3. 4.]], shape=(1, 4), dtype=float32)
Como observado acima, as variáveis são apoiadas por tensores. Você pode reatribuir o tensor usando tf.Variable.assign
. Chamar assign
não aloca (geralmente) um novo tensor; em vez disso, a memória do tensor existente é reutilizada.
a = tf.Variable([2.0, 3.0])
# This will keep the same dtype, float32
a.assign([1, 2])
# Not allowed as it resizes the variable:
try:
a.assign([1.0, 2.0, 3.0])
except Exception as e:
print(f"{type(e).__name__}: {e}")
ValueError: Cannot assign to variable Variable:0 due to variable shape (2,) and value shape (3,) are incompatible
Se você usar uma variável como um tensor em operações, geralmente operará no tensor de apoio.
A criação de novas variáveis a partir de variáveis existentes duplica os tensores de apoio. Duas variáveis não compartilharão a mesma memória.
a = tf.Variable([2.0, 3.0])
# Create b based on the value of a
b = tf.Variable(a)
a.assign([5, 6])
# a and b are different
print(a.numpy())
print(b.numpy())
# There are other versions of assign
print(a.assign_add([2,3]).numpy()) # [7. 9.]
print(a.assign_sub([7,9]).numpy()) # [0. 0.]
[5. 6.] [2. 3.] [7. 9.] [0. 0.]
Ciclos de vida, nomenclatura e observação
No TensorFlow baseado em Python, a instância tf.Variable
tem o mesmo ciclo de vida de outros objetos Python. Quando não há referências a uma variável, ela é desalocada automaticamente.
As variáveis também podem ser nomeadas, o que pode ajudá-lo a rastreá-las e depurá-las. Você pode dar a duas variáveis o mesmo nome.
# Create a and b; they will have the same name but will be backed by
# different tensors.
a = tf.Variable(my_tensor, name="Mark")
# A new variable with the same name, but different value
# Note that the scalar add is broadcast
b = tf.Variable(my_tensor + 1, name="Mark")
# These are elementwise-unequal, despite having the same name
print(a == b)
tf.Tensor( [[False False] [False False]], shape=(2, 2), dtype=bool)
Os nomes das variáveis são preservados ao salvar e carregar modelos. Por padrão, as variáveis nos modelos adquirirão nomes de variáveis exclusivos automaticamente, portanto, você não precisa atribuí-las você mesmo, a menos que queira.
Embora as variáveis sejam importantes para a diferenciação, algumas variáveis não precisarão ser diferenciadas. Você pode desativar os gradientes de uma variável definindo trainable
como falso na criação. Um exemplo de variável que não precisaria de gradientes é um contador de passos de treinamento.
step_counter = tf.Variable(1, trainable=False)
Colocando variáveis e tensores
Para um melhor desempenho, o TensorFlow tentará colocar tensores e variáveis no dispositivo mais rápido compatível com seu dtype
. Isso significa que a maioria das variáveis são colocadas em uma GPU, se houver uma disponível.
No entanto, você pode substituir isso. Neste trecho, coloque um tensor flutuante e uma variável na CPU, mesmo que uma GPU esteja disponível. Ao ativar o registro de posicionamento do dispositivo (consulte Configuração ), você pode ver onde a variável é colocada.
Se você executar este notebook em diferentes back-ends com e sem uma GPU, verá um registro diferente. Observe que o posicionamento do dispositivo de registro deve ser ativado no início da sessão.
with tf.device('CPU:0'):
# Create some tensors
a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)
print(c)
tf.Tensor( [[22. 28.] [49. 64.]], shape=(2, 2), dtype=float32)
É possível definir a localização de uma variável ou tensor em um dispositivo e fazer o cálculo em outro dispositivo. Isso introduzirá atraso, pois os dados precisam ser copiados entre os dispositivos.
Você pode fazer isso, no entanto, se tiver vários trabalhadores de GPU, mas quiser apenas uma cópia das variáveis.
with tf.device('CPU:0'):
a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.Variable([[1.0, 2.0, 3.0]])
with tf.device('GPU:0'):
# Element-wise multiply
k = a * b
print(k)
tf.Tensor( [[ 1. 4. 9.] [ 4. 10. 18.]], shape=(2, 3), dtype=float32)
Para saber mais sobre treinamento distribuído, consulte nosso guia .
Próximos passos
Para entender como as variáveis são normalmente usadas, consulte nosso guia sobre diferenciação automática .