Introdução às Variáveis

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 .