Veja no TensorFlow.org | Executar no Google Colab | Ver fonte no GitHub | Baixar caderno |
Este guia fornece uma visão geral rápida dos conceitos básicos do TensorFlow . Cada seção deste documento é uma visão geral de um tópico maior - você pode encontrar links para guias completos no final de cada seção.
O TensorFlow é uma plataforma de ponta a ponta para aprendizado de máquina. Ele suporta o seguinte:
- Computação numérica baseada em matriz multidimensional (semelhante a NumPy .)
- GPU e processamento distribuído
- Diferenciação automática
- Construção, treinamento e exportação de modelos
- E mais
Tensores
O TensorFlow opera em matrizes ou tensores multidimensionais representados como objetos tf.Tensor
. Aqui está um tensor bidimensional:
import tensorflow as tf
x = tf.constant([[1., 2., 3.],
[4., 5., 6.]])
print(x)
print(x.shape)
print(x.dtype)
tf.Tensor( [[1. 2. 3.] [4. 5. 6.]], shape=(2, 3), dtype=float32) (2, 3) <dtype: 'float32'>
Os atributos mais importantes de um tf.Tensor
são sua shape
e dtype
:
-
Tensor.shape
: informa o tamanho do tensor ao longo de cada um de seus eixos. -
Tensor.dtype
: informa o tipo de todos os elementos no tensor.
O TensorFlow implementa operações matemáticas padrão em tensores, bem como muitas operações especializadas para aprendizado de máquina.
Por exemplo:
x + x
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ 2., 4., 6.], [ 8., 10., 12.]], dtype=float32)>
5 * x
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ 5., 10., 15.], [20., 25., 30.]], dtype=float32)>
x @ tf.transpose(x)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy= array([[14., 32.], [32., 77.]], dtype=float32)>
tf.concat([x, x, x], axis=0)
<tf.Tensor: shape=(6, 3), dtype=float32, numpy= array([[1., 2., 3.], [4., 5., 6.], [1., 2., 3.], [4., 5., 6.], [1., 2., 3.], [4., 5., 6.]], dtype=float32)>
tf.nn.softmax(x, axis=-1)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[0.09003057, 0.24472848, 0.6652409 ], [0.09003057, 0.24472848, 0.6652409 ]], dtype=float32)>
tf.reduce_sum(x)
<tf.Tensor: shape=(), dtype=float32, numpy=21.0>
A execução de grandes cálculos na CPU pode ser lenta. Quando configurado corretamente, o TensorFlow pode usar hardware acelerador, como GPUs, para executar operações muito rapidamente.
if tf.config.list_physical_devices('GPU'):
print("TensorFlow **IS** using the GPU")
else:
print("TensorFlow **IS NOT** using the GPU")
TensorFlow **IS** using the GPU
Consulte o guia Tensor para obter detalhes.
Variáveis
Objetos tf.Tensor
normais são imutáveis. Para armazenar pesos de modelo (ou outro estado mutável) no TensorFlow, use um tf.Variable
.
var = tf.Variable([0.0, 0.0, 0.0])
var.assign([1, 2, 3])
<tf.Variable 'UnreadVariable' shape=(3,) dtype=float32, numpy=array([1., 2., 3.], dtype=float32)>
var.assign_add([1, 1, 1])
<tf.Variable 'UnreadVariable' shape=(3,) dtype=float32, numpy=array([2., 3., 4.], dtype=float32)>
Consulte o guia Variáveis para obter detalhes.
Diferenciação automática
A descida de gradiente e os algoritmos relacionados são a base do aprendizado de máquina moderno.
Para habilitar isso, o TensorFlow implementa a diferenciação automática (autodiff), que usa cálculo para calcular gradientes. Normalmente, você usará isso para calcular o gradiente do erro ou perda de um modelo em relação a seus pesos.
x = tf.Variable(1.0)
def f(x):
y = x**2 + 2*x - 5
return y
f(x)
<tf.Tensor: shape=(), dtype=float32, numpy=-2.0>
Em x = 1.0
, y = f(x) = (1**2 + 2*1 - 5) = -2
.
A derivada de y
é y' = f'(x) = (2*x + 2) = 4
. O TensorFlow pode calcular isso automaticamente:
with tf.GradientTape() as tape:
y = f(x)
g_x = tape.gradient(y, x) # g(x) = dy/dx
g_x
<tf.Tensor: shape=(), dtype=float32, numpy=4.0>
Este exemplo simplificado leva apenas a derivada em relação a um único escalar ( x
), mas o TensorFlow pode calcular o gradiente em relação a qualquer número de tensores não escalares simultaneamente.
Consulte o guia Autodiff para obter detalhes.
Gráficos e tf.function
Embora você possa usar o TensorFlow interativamente como qualquer biblioteca Python, o TensorFlow também fornece ferramentas para:
- Otimização de desempenho : para acelerar o treinamento e a inferência.
- Exportar : para que você possa salvar seu modelo quando terminar o treinamento.
Eles exigem que você use tf.function
para separar seu código Pure-TensorFlow do Python.
@tf.function
def my_func(x):
print('Tracing.\n')
return tf.reduce_sum(x)
A primeira vez que você executa o tf.function
, embora ele seja executado em Python, ele captura um gráfico completo e otimizado representando os cálculos do TensorFlow feitos dentro da função.
x = tf.constant([1, 2, 3])
my_func(x)
Tracing. <tf.Tensor: shape=(), dtype=int32, numpy=6>
Nas chamadas subsequentes, o TensorFlow executa apenas o gráfico otimizado, ignorando todas as etapas não relacionadas ao TensorFlow. Abaixo, observe que my_func
não imprime rastreamento , pois print
é uma função do Python, não uma função do TensorFlow.
x = tf.constant([10, 9, 8])
my_func(x)
<tf.Tensor: shape=(), dtype=int32, numpy=27>
Um gráfico pode não ser reutilizável para entradas com uma assinatura diferente ( shape
e dtype
), portanto, um novo gráfico é gerado:
x = tf.constant([10.0, 9.1, 8.2], dtype=tf.float32)
my_func(x)
Tracing. <tf.Tensor: shape=(), dtype=float32, numpy=27.3>
Esses gráficos capturados fornecem dois benefícios:
- Em muitos casos, eles fornecem uma aceleração significativa na execução (embora não neste exemplo trivial).
- Você pode exportar esses gráficos, usando
tf.saved_model
, para executar em outros sistemas como um servidor ou um dispositivo móvel , sem necessidade de instalação do Python.
Consulte Introdução aos gráficos para obter mais detalhes.
Módulos, camadas e modelos
tf.Module
é uma classe para gerenciar seus objetos tf.Variable
e os objetos tf.function
que operam neles. A classe tf.Module
é necessária para dar suporte a dois recursos significativos:
- Você pode salvar e restaurar os valores de suas variáveis usando
tf.train.Checkpoint
. Isso é útil durante o treinamento, pois é rápido salvar e restaurar o estado de um modelo. - Você pode importar e exportar os valores
tf.Variable
e os gráficostf.function
usandotf.saved_model
. Isso permite que você execute seu modelo independentemente do programa Python que o criou.
Aqui está um exemplo completo de exportação de um objeto tf.Module
simples:
class MyModule(tf.Module):
def __init__(self, value):
self.weight = tf.Variable(value)
@tf.function
def multiply(self, x):
return x * self.weight
mod = MyModule(3)
mod.multiply(tf.constant([1, 2, 3]))
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([3, 6, 9], dtype=int32)>
Salve o Module
:
save_path = './saved'
tf.saved_model.save(mod, save_path)
INFO:tensorflow:Assets written to: ./saved/assets 2022-01-19 02:29:48.135588: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
O SavedModel resultante é independente do código que o criou. Você pode carregar um SavedModel do Python, outras associações de linguagem ou TensorFlow Serving . Você também pode convertê-lo para ser executado com TensorFlow Lite ou TensorFlow JS .
reloaded = tf.saved_model.load(save_path)
reloaded.multiply(tf.constant([1, 2, 3]))
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([3, 6, 9], dtype=int32)>
As classes tf.keras.layers.Layer
e tf.keras.Model
construídas no tf.Module
, fornecendo funcionalidades adicionais e métodos convenientes para construir, treinar e salvar modelos. Algumas delas são demonstradas na próxima seção.
Consulte Introdução aos módulos para obter detalhes.
Loops de treinamento
Agora junte tudo isso para construir um modelo básico e treiná-lo do zero.
Primeiro, crie alguns dados de exemplo. Isso gera uma nuvem de pontos que segue vagamente uma curva quadrática:
import matplotlib
from matplotlib import pyplot as plt
matplotlib.rcParams['figure.figsize'] = [9, 6]
x = tf.linspace(-2, 2, 201)
x = tf.cast(x, tf.float32)
def f(x):
y = x**2 + 2*x - 5
return y
y = f(x) + tf.random.normal(shape=[201])
plt.plot(x.numpy(), y.numpy(), '.', label='Data')
plt.plot(x, f(x), label='Ground truth')
plt.legend();
Crie um modelo:
class Model(tf.keras.Model):
def __init__(self, units):
super().__init__()
self.dense1 = tf.keras.layers.Dense(units=units,
activation=tf.nn.relu,
kernel_initializer=tf.random.normal,
bias_initializer=tf.random.normal)
self.dense2 = tf.keras.layers.Dense(1)
def call(self, x, training=True):
# For Keras layers/models, implement `call` instead of `__call__`.
x = x[:, tf.newaxis]
x = self.dense1(x)
x = self.dense2(x)
return tf.squeeze(x, axis=1)
model = Model(64)
plt.plot(x.numpy(), y.numpy(), '.', label='data')
plt.plot(x, f(x), label='Ground truth')
plt.plot(x, model(x), label='Untrained predictions')
plt.title('Before training')
plt.legend();
Escreva um loop de treinamento básico:
variables = model.variables
optimizer = tf.optimizers.SGD(learning_rate=0.01)
for step in range(1000):
with tf.GradientTape() as tape:
prediction = model(x)
error = (y-prediction)**2
mean_error = tf.reduce_mean(error)
gradient = tape.gradient(mean_error, variables)
optimizer.apply_gradients(zip(gradient, variables))
if step % 100 == 0:
print(f'Mean squared error: {mean_error.numpy():0.3f}')
Mean squared error: 16.123 Mean squared error: 0.997 Mean squared error: 0.964 Mean squared error: 0.946 Mean squared error: 0.932 Mean squared error: 0.921 Mean squared error: 0.913 Mean squared error: 0.907 Mean squared error: 0.901 Mean squared error: 0.897
plt.plot(x.numpy(),y.numpy(), '.', label="data")
plt.plot(x, f(x), label='Ground truth')
plt.plot(x, model(x), label='Trained predictions')
plt.title('After training')
plt.legend();
Isso está funcionando, mas lembre-se de que implementações de utilitários de treinamento comuns estão disponíveis no módulo tf.keras
. Portanto, considere usá-los antes de escrever o seu próprio. Para começar, os métodos Model.compile
e Model.fit
implementam um loop de treinamento para você:
new_model = Model(64)
new_model.compile(
loss=tf.keras.losses.MSE,
optimizer=tf.optimizers.SGD(learning_rate=0.01))
history = new_model.fit(x, y,
epochs=100,
batch_size=32,
verbose=0)
model.save('./my_model')
INFO:tensorflow:Assets written to: ./my_model/assets
plt.plot(history.history['loss'])
plt.xlabel('Epoch')
plt.ylim([0, max(plt.ylim())])
plt.ylabel('Loss [Mean Squared Error]')
plt.title('Keras training progress');
Consulte Loops de treinamento básico e o guia Keras para obter mais detalhes.