Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/guide/basic_training_loops.ipynb
25115 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

Loops de treinamento básicos

Nos guias anteriores, você aprendeu sobre tensores, variáveis, fitas de gradiente e módulos. Neste guia, você usará tudo isso para treinar modelos.

O TensorFlow também inclui a API tf.Keras, uma API de redes neurais de alto nível que fornece abstrações úteis para reduzir o uso de código boilerplate. No entanto, neste guia, você usará classes básicas.

Configuração

import tensorflow as tf import matplotlib.pyplot as plt colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

Solucionando problemas de aprendizado de máquina

A resolução de um problema de aprendizado de máquina geralmente consiste nas seguintes etapas:

  • Obtenção de dados de treinamento.

  • Definição do modelo

  • Definição de uma função de perda

  • Percorrer os dados de treinamento, calculando a perda a partir do valor ideal

  • Calcular gradientes para essa perda e usar um otimizador para ajustar as variáveis ​​para que os dados caibam.

  • Avaliação dos resultados.

Para fins de ilustração, neste guia você desenvolverá um modelo linear simples, f(x)=xW+bf(x) = x * W + b, que possui duas variáveis: WW (pesos) e bb (bias).

Este é o mais básico dos problemas de aprendizado de máquina: dados xx e yy, tente encontrar a inclinação e o deslocamento de uma linha por meio da regressão linear simples.

Dados

O aprendizado supervisionado usa entradas (geralmente denotadas como x) e saídas (denotadas como y, geralmente chamadas de rótulos). O objetivo é aprender com entradas e saídas emparelhadas para que você possa prever o valor de uma saída a partir de uma entrada.

Cada entrada de dados, no TensorFlow, quase sempre é representada por um tensor e geralmente é um vetor. No treinamento supervisionado, a saída (ou valor que você gostaria de prever) também é um tensor.

Aqui estão alguns dados sintetizados pela adição de ruído gaussiano (normal) a pontos ao longo de uma linha.

# The actual line TRUE_W = 3.0 TRUE_B = 2.0 NUM_EXAMPLES = 201 # A vector of random x values x = tf.linspace(-2,2, NUM_EXAMPLES) x = tf.cast(x, tf.float32) def f(x): return x * TRUE_W + TRUE_B # Generate some noise noise = tf.random.normal(shape=[NUM_EXAMPLES]) # Calculate y y = f(x) + noise
# Plot all the data plt.plot(x, y, '.') plt.show()

Os tensores geralmente são reunidos em lotes ou grupos de entradas e saídas empilhadas. O lote pode conferir alguns benefícios ao treinamento e funciona bem com aceleradores e computação vetorizada. Dado o tamanho desse dataset, você pode tratar todo o dataset como um único lote.

Definição do modelo

Use tf.Variable para representar todos os pesos em um modelo. Um tf.Variable armazena um valor e o fornece na forma de tensor conforme necessário. Consulte o guia de variáveis ​​para mais detalhes.

Use tf.Module para encapsular as variáveis ​​e a computação. Você pode usar qualquer objeto Python, mas dessa forma ele pode ser salvo com facilidade.

Aqui, você define como variáveis tanto w como b.

class MyModel(tf.Module): def __init__(self, **kwargs): super().__init__(**kwargs) # Initialize the weights to `5.0` and the bias to `0.0` # In practice, these should be randomly initialized self.w = tf.Variable(5.0) self.b = tf.Variable(0.0) def __call__(self, x): return self.w * x + self.b model = MyModel() # List the variables tf.modules's built-in variable aggregation. print("Variables:", model.variables) # Verify the model works assert model(3.0).numpy() == 15.0

As variáveis ​​iniciais são definidas aqui de forma fixa, mas o Keras vem com diversos inicializadores que você pode usar, com ou sem o restante do Keras.

Definição de uma função de perda

Uma função de perda mede o quanto a saída de um modelo para uma determinada entrada corresponde à saída-alvo. O objetivo é minimizar essa diferença durante o treinamento. Defina a perda L2 padrão, também conhecida como erro "quadrado médio":

# This computes a single loss value for an entire batch def loss(target_y, predicted_y): return tf.reduce_mean(tf.square(target_y - predicted_y))

Antes de treinar o modelo, você pode prever o valor da perda plotando as previsões do modelo em vermelho e os dados de treinamento em azul:

plt.plot(x, y, '.', label="Data") plt.plot(x, f(x), label="Ground truth") plt.plot(x, model(x), label="Predictions") plt.legend() plt.show() print("Current loss: %1.6f" % loss(y, model(x)).numpy())

Definição de um loop de treinamento

O loop de treinamento consiste em fazer repetidamente três tarefas em ordem:

  • Enviar um lote de entradas através do modelo para gerar saídas

  • Calcular a perda comparando as saídas com a saída (ou rótulo)

  • Usar fitas de gradiente para encontrar os gradientes

  • Otimizar as variáveis ​​com esses gradientes

Para este exemplo, você pode treinar o modelo usando o método do gradiente descendente.

Existem muitas variantes do esquema do método do gradiente descendente que são capturadas em tf.keras.optimizers. Mas no espírito de construir a partir dos princípios básicos, aqui você mesmo vai implementar a matemática básica com a ajuda de tf.GradientTape para diferenciação automática e tf.assign_sub para decrementar um valor (que combina tf.assign e tf.sub):

# Given a callable model, inputs, outputs, and a learning rate... def train(model, x, y, learning_rate): with tf.GradientTape() as t: # Trainable variables are automatically tracked by GradientTape current_loss = loss(y, model(x)) # Use GradientTape to calculate the gradients with respect to W and b dw, db = t.gradient(current_loss, [model.w, model.b]) # Subtract the gradient scaled by the learning rate model.w.assign_sub(learning_rate * dw) model.b.assign_sub(learning_rate * db)

Para dar uma olhada no treinamento, você pode enviar o mesmo lote de x e y através do loop de treinamento e ver como W e b evoluem.

model = MyModel() # Collect the history of W-values and b-values to plot later weights = [] biases = [] epochs = range(10) # Define a training loop def report(model, loss): return f"W = {model.w.numpy():1.2f}, b = {model.b.numpy():1.2f}, loss={loss:2.5f}" def training_loop(model, x, y): for epoch in epochs: # Update the model with the single giant batch train(model, x, y, learning_rate=0.1) # Track this before I update weights.append(model.w.numpy()) biases.append(model.b.numpy()) current_loss = loss(y, model(x)) print(f"Epoch {epoch:2d}:") print(" ", report(model, current_loss))

Faça o treinamento

current_loss = loss(y, model(x)) print(f"Starting:") print(" ", report(model, current_loss)) training_loop(model, x, y)

Plote a evolução dos pesos ao longo do tempo:

plt.plot(epochs, weights, label='Weights', color=colors[0]) plt.plot(epochs, [TRUE_W] * len(epochs), '--', label = "True weight", color=colors[0]) plt.plot(epochs, biases, label='bias', color=colors[1]) plt.plot(epochs, [TRUE_B] * len(epochs), "--", label="True bias", color=colors[1]) plt.legend() plt.show()

Visualize o desempenho do modelo treinado

plt.plot(x, y, '.', label="Data") plt.plot(x, f(x), label="Ground truth") plt.plot(x, model(x), label="Predictions") plt.legend() plt.show() print("Current loss: %1.6f" % loss(model(x), y).numpy())

A mesma solução, mas com Keras

É útil comparar o código acima com o equivalente em Keras.

A definição do modelo parece exatamente igual se você usar uma subclasse de tf.keras.Model. Lembre-se que os modelos Keras herdam, em última instância, de module.

class MyModelKeras(tf.keras.Model): def __init__(self, **kwargs): super().__init__(**kwargs) # Initialize the weights to `5.0` and the bias to `0.0` # In practice, these should be randomly initialized self.w = tf.Variable(5.0) self.b = tf.Variable(0.0) def call(self, x): return self.w * x + self.b keras_model = MyModelKeras() # Reuse the training loop with a Keras model training_loop(keras_model, x, y) # You can also save a checkpoint using Keras's built-in support keras_model.save_weights("my_checkpoint")

Em vez de escrever novos loops de treinamento sempre que criar um modelo, você pode usar os recursos integrados do Keras como um atalho. Isso pode ser útil quando você não quiser escrever ou depurar loops de treinamento no Python.

Se fizer isso, você precisará usar model.compile() para definir os parâmetros e model.fit() para treinar. Pode ter menos código para usar as implementações Keras de perda de L2 e método do gradiente descendente, novamente como um atalho. As perdas e otimizadores do Keras também podem ser usados ​​fora dessas funções de conveniência, e o exemplo anterior poderia tê-los usado.

keras_model = MyModelKeras() # compile sets the training parameters keras_model.compile( # By default, fit() uses tf.function(). You can # turn that off for debugging, but it is on now. run_eagerly=False, # Using a built-in optimizer, configuring as an object optimizer=tf.keras.optimizers.SGD(learning_rate=0.1), # Keras comes with built-in MSE error # However, you could use the loss function # defined above loss=tf.keras.losses.mean_squared_error, )

O Keras fit espera dados em lote ou um dataset completo como um array NumPy. As matrizes NumPy são divididas em lotes e padronizadas para um tamanho de lote de 32.

Nesse caso, para corresponder ao comportamento do loop escrito à mão, você deve passar x como um único lote de tamanho 1000.

print(x.shape[0]) keras_model.fit(x, y, epochs=10, batch_size=1000)

Observe que Keras imprime a perda após o treinamento, não antes, então a primeira perda parece menor, mas, caso contrário, isso mostra essencialmente o mesmo desempenho de treinamento.

Próximos passos

Neste guia, você viu como usar as classes principais de tensores, variáveis, módulos e fitas de gradiente para construir e treinar um modelo e, além disso, como essas ideias são implementadas no Keras.

Este é, no entanto, um problema extremamente simples. Para uma introdução mais prática, consulte Passo a passo de treinamento personalizado.

Para saber mais sobre o uso de loops de treinamento integrados no Keras, consulte este guia. Para saber mais sobre loops de treinamento e Keras, consulte este guia. Para escrever loops de treinamento distribuídos personalizados, consulte este guia.