Veja no TensorFlow.org | Executar no Google Colab | Ver fonte no GitHub | Baixar caderno |
Este é um tutorial introdutório do TensorFlow que mostra como:
- Importe o pacote necessário
- Criar e usar tensores
- Usar aceleração de GPU
- Demonstrar
tf.data.Dataset
Importar TensorFlow
Para começar, importe o módulo tensorflow
. A partir do TensorFlow 2, a execução antecipada é ativada por padrão. Isso permite um front-end mais interativo para o TensorFlow, cujos detalhes discutiremos muito mais tarde.
import tensorflow as tf
Tensores
Um tensor é uma matriz multidimensional. Semelhante aos objetos NumPy ndarray
, os objetos tf.Tensor
têm um tipo de dados e uma forma. Além disso, tf.Tensor
s pode residir na memória do acelerador (como uma GPU). O TensorFlow oferece uma rica biblioteca de operações ( tf.add , tf.matmul , tf.linalg.inv etc.) que consomem e produzem tf.Tensor
s. Essas operações convertem automaticamente os tipos nativos do Python, por exemplo:
print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))
# Operator overloading is also supported
print(tf.square(2) + tf.square(3))
tf.Tensor(3, shape=(), dtype=int32) tf.Tensor([4 6], shape=(2,), dtype=int32) tf.Tensor(25, shape=(), dtype=int32) tf.Tensor(6, shape=(), dtype=int32) tf.Tensor(13, shape=(), dtype=int32)
Cada tf.Tensor
tem uma forma e um tipo de dados:
x = tf.matmul([[1]], [[2, 3]])
print(x)
print(x.shape)
print(x.dtype)
tf.Tensor([[2 3]], shape=(1, 2), dtype=int32) (1, 2) <dtype: 'int32'>
As diferenças mais óbvias entre matrizes NumPy e tf.Tensor
s são:
- Os tensores podem ser apoiados pela memória do acelerador (como GPU, TPU).
- Os tensores são imutáveis.
Compatibilidade NumPy
Converter entre um TensorFlow tf.Tensor
um NumPy ndarray
é fácil:
- As operações do TensorFlow convertem automaticamente ndarrays NumPy em tensores.
- As operações NumPy convertem automaticamente Tensores em ndarrays NumPy.
Os tensores são explicitamente convertidos em ndarrays NumPy usando seu método .numpy()
. Essas conversões geralmente são baratas, pois o array e o tf.Tensor
compartilham a representação de memória subjacente, se possível. No entanto, compartilhar a representação subjacente nem sempre é possível, pois o tf.Tensor
pode ser hospedado na memória da GPU, enquanto os arrays NumPy são sempre suportados pela memória do host, e a conversão envolve uma cópia da GPU para a memória do host.
import numpy as np
ndarray = np.ones([3, 3])
print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor)
print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1))
print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
TensorFlow operations convert numpy arrays to Tensors automatically tf.Tensor( [[42. 42. 42.] [42. 42. 42.] [42. 42. 42.]], shape=(3, 3), dtype=float64) And NumPy operations convert Tensors to numpy arrays automatically [[43. 43. 43.] [43. 43. 43.] [43. 43. 43.]] The .numpy() method explicitly converts a Tensor to a numpy array [[42. 42. 42.] [42. 42. 42.] [42. 42. 42.]]
Aceleração da GPU
Muitas operações do TensorFlow são aceleradas usando a GPU para computação. Sem anotações, o TensorFlow decide automaticamente se deve usar a GPU ou a CPU para uma operação, copiando o tensor entre a memória da CPU e da GPU, se necessário. Tensores produzidos por uma operação são normalmente apoiados pela memória do dispositivo no qual a operação foi executada, por exemplo:
x = tf.random.uniform([3, 3])
print("Is there a GPU available: "),
print(tf.config.list_physical_devices("GPU"))
print("Is the Tensor on GPU #0: "),
print(x.device.endswith('GPU:0'))
Is there a GPU available: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')] Is the Tensor on GPU #0: True
Nomes de dispositivos
A propriedade Tensor.device
fornece um nome de string totalmente qualificado do dispositivo que hospeda o conteúdo do tensor. Esse nome codifica muitos detalhes, como um identificador do endereço de rede do host no qual esse programa está sendo executado e o dispositivo nesse host. Isso é necessário para a execução distribuída de um programa TensorFlow. A string termina com GPU:<N>
se o tensor for colocado na N
-th GPU no host.
Posicionamento explícito do dispositivo
No TensorFlow, o posicionamento refere-se a como as operações individuais são atribuídas (colocadas em) um dispositivo para execução. Conforme mencionado, quando não há orientação explícita fornecida, o TensorFlow decide automaticamente qual dispositivo executará uma operação e copia tensores para esse dispositivo, se necessário. No entanto, as operações do TensorFlow podem ser colocadas explicitamente em dispositivos específicos usando o gerenciador de contexto tf.device
, por exemplo:
import time
def time_matmul(x):
start = time.time()
for loop in range(10):
tf.matmul(x, x)
result = time.time()-start
print("10 loops: {:0.2f}ms".format(1000*result))
# Force execution on CPU
print("On CPU:")
with tf.device("CPU:0"):
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("CPU:0")
time_matmul(x)
# Force execution on GPU #0 if available
if tf.config.list_physical_devices("GPU"):
print("On GPU:")
with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("GPU:0")
time_matmul(x)
On CPU: 10 loops: 91.47ms On GPU: 10 loops: 388.16ms
Conjuntos de dados
Esta seção usa a API tf.data.Dataset
para criar um pipeline para alimentar dados em seu modelo. A API tf.data.Dataset
é usada para criar pipelines de entrada complexos e de alto desempenho a partir de peças simples e reutilizáveis que alimentarão os loops de treinamento ou avaliação do seu modelo.
Criar um conjunto de Dataset
de origem
Crie um conjunto de dados de origem usando uma das funções de fábrica como Dataset.from_tensors
, Dataset.from_tensor_slices
ou usando objetos que lêem arquivos como TextLineDataset
ou TFRecordDataset
. Consulte o guia do conjunto de dados do TensorFlow para obter mais informações.
ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])
# Create a CSV file
import tempfile
_, filename = tempfile.mkstemp()
with open(filename, 'w') as f:
f.write("""Line 1
Line 2
Line 3
""")
ds_file = tf.data.TextLineDataset(filename)
Aplicar transformações
Use as funções de transformação como map
, batch
e shuffle
para aplicar transformações aos registros do conjunto de dados.
ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)
ds_file = ds_file.batch(2)
Iterar
Os objetos tf.data.Dataset
suportam iteração para fazer um loop nos registros:
print('Elements of ds_tensors:')
for x in ds_tensors:
print(x)
print('\nElements in ds_file:')
for x in ds_file:
print(x)
Elements of ds_tensors: tf.Tensor([1 9], shape=(2,), dtype=int32) tf.Tensor([16 4], shape=(2,), dtype=int32) tf.Tensor([25 36], shape=(2,), dtype=int32) Elements in ds_file: tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string) tf.Tensor([b'Line 3' b' '], shape=(2,), dtype=string)