Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/tensorboard/scalars_and_keras.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.

Escalares do TensorBoard: registro de métricas de treinamento no Keras

Visão geral

O aprendizado de máquina sempre envolve a compreensão sobre métricas fundamentais, como a perda, e como elas mudam ao longo do treinamento. Essas métricas podem ajudar você a entender, por exemplo, se está com overfitting ou treinando desnecessariamente por muito tempo. Você deve comparar essas métricas em diferentes execuções de treinamento para depurar e melhorar seu modelo.

O Painel de Controle Time Series (Série temporal) permite que você visualize essas métricas usando uma API simples com muito pouco esforço. Este tutorial apresenta exemplos bastante básicos para você aprender a usar essas APIs com o TensorBoard ao desenvolver seu modelo do Keras. Você aprenderá a usar a callback do TensorBoard para o Keras e as APIs Summary do TensorFlow para visualizar escalares padrão e personalizados.

Configuração

# Load the TensorBoard notebook extension. %load_ext tensorboard
from datetime import datetime from packaging import version import tensorflow as tf from tensorflow import keras import numpy as np print("TensorFlow version: ", tf.__version__) assert version.parse(tf.__version__).release[0] >= 2, \ "This notebook requires TensorFlow 2.0 or above."
TensorFlow version: 2.8.2
# Clear any logs from previous runs !rm -rf ./logs/

Configure os dados para uma regressão simples

Agora, você usará o Keras para calcular uma regressão, ou seja, encontrar a linha mais adequada para um dataset emparelhado. (Enquanto o uso das redes neurais e do método do gradiente descendente é excessivo para esse tipo de problema, é um exemplo de fácil compreensão.)

Você usará o TensorBoard para observar como a perda do treinamento e do teste muda nas épocas. Com sorte, você verá a perda do treinamento e do teste diminuir ao longo do tempo e depois permanecer estável.

Primeiro, gere 1000 pontos de dados perto da linha y = 0.5x + 2. Divida esses pontos de dados em datasets de treinamento e teste. Sua esperança é que a rede neural aprenda essa relação.

data_size = 1000 # 80% of the data is for training. train_pct = 0.8 train_size = int(data_size * train_pct) # Create some input data between -1 and 1 and randomize it. x = np.linspace(-1, 1, data_size) np.random.shuffle(x) # Generate the output data. # y = 0.5x + 2 + noise y = 0.5 * x + 2 + np.random.normal(0, 0.05, (data_size, )) # Split into test and train pairs. x_train, y_train = x[:train_size], y[:train_size] x_test, y_test = x[train_size:], y[train_size:]

Treinamento do modelo e registro da perda

Agora, você está pronto para definir, treinar e avaliar seu modelo.

Para registrar o escalar de perda ao treinar, faça o seguinte:

  1. Crie a callback do TensorBoard para o Keras

  2. Especifique um diretório de log

  3. Passe a callback do TensorBoard ao Model.fit() do Keras.

O TensorBoard lê os dados de log na hierarquia de diretório de logs. Nesse notebook, o diretório de log raiz é logs/scalars, com um subdiretório que inclui carimbo de data/hora como sufixo. Esse subdiretório permite identificar e selecionar execuções de treinamento conforme você usa o TensorBoard e itera seu modelo.

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir) model = keras.models.Sequential([ keras.layers.Dense(16, input_dim=1), keras.layers.Dense(1), ]) model.compile( loss='mse', # keras.losses.mean_squared_error optimizer=keras.optimizers.SGD(learning_rate=0.2), ) print("Training ... With default parameters, this takes less than 10 seconds.") training_history = model.fit( x_train, # input y_train, # output batch_size=train_size, verbose=0, # Suppress chatty output; use Tensorboard instead epochs=100, validation_data=(x_test, y_test), callbacks=[tensorboard_callback], ) print("Average test loss: ", np.average(training_history.history['loss']))
Training ... With default parameters, this takes less than 10 seconds. Average test loss: 0.042797307365108284

Análise da perda usando o TensorBoard

Agora, inicialize o TensorBoard, especificando o diretório de log raiz que você usou acima.

Aguarde alguns segundos para a interface do usuário do TensorBoard inicializar.

%tensorboard --logdir logs/scalars

Talvez você veja a mensagem "No dashboards are active for the current data set" (Nenhum painel de controle ativo para o dataset atual) no TensorBoard. Isso ocorre porque o registro de dados inicial ainda não foi salvo. Com o avanço do treinamento, o modelo Keras começará a registrar os dados. O TensorBoard atualizará periodicamente e mostrará suas métricas escalares. Se você estiver impaciente, toque na seta "Refresh" (Atualizar) no canto superior direito.

Ao observar o avanço do treinamento, note que ambas as perdas de treinamento e de validação diminuem rapidamente e depois permanecem estáveis. Na verdade, você poderia ter parado o treinamento após 25 épocas, porque ele não melhorou muito depois desse ponto.

Passe o cursor sobre o grafo para ver pontos de dados específicos. Você também pode tentar aumentar o zoom com o mouse ou selecionar parte deles para ver mais detalhes.

Observe o seletor "Runs" à esquerda. Uma "run", ou execução, representa um conjunto de logs de uma rodada de treinamento, nesse caso, o resultado de Model.fit(). Os desenvolvedores geralmente realizam muitas e muitas execuções, enquanto testam e desenvolvem o modelo ao longo do tempo.

Use o seletor "Runs" para escolher execuções específicas ou somente de treinamento/validação. A comparação de execuções ajudará você a avaliar qual versão do seu código soluciona melhor seu problema.

O grafo de perda do TensorBoard demonstra que a perda diminuiu consistentemente para ambos o treinamento e a validação e depois estabilizou. Isso significa que as métricas do modelo são provavelmente muito boas! Agora veja como o modelo realmente se comporta na vida real.

Com os dados de entrada (60, 25, 2), a linha y = 0.5x + 2 deve gerar (32, 14.5, 3). O modelo está de acordo?

print(model.predict([60, 25, 2])) # True values to compare predictions against: # [[32.0] # [14.5] # [ 3.0]]
[[32.148884 ] [14.562463 ] [ 3.0056725]]

Nada mal!

Registro de escalares personalizados

E se você quiser registrar valores personalizados, como uma taxa de aprendizado dinâmica? Para fazer isso, você precisa usar a API Summary do TensorFlow.

Treine novamente o modelo de regressão e registre uma taxa de aprendizado personalizada. Veja como:

  1. Crie um escritor de arquivo, usando tf.summary.create_file_writer().

  2. Defina uma função de taxa de aprendizado personalizada. Ela será passada à callback LearningRateScheduler do Keras.

  3. Dentro da função de taxa de aprendizado, use tf.summary.scalar() para registrar a taxa de aprendizado personalizada.

  4. Passe a callback LearningRateScheduler a Model.fit().

Em geral, para registrar um escalar personalizado, você precisa usar tf.summary.scalar() com um escritor de arquivo. O escritor de arquivo é responsável por escrever os dados para essa execução no diretório especificado e é usado de maneira implícita ao utilizar o tf.summary.scalar().

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") file_writer = tf.summary.create_file_writer(logdir + "/metrics") file_writer.set_as_default() def lr_schedule(epoch): """ Returns a custom learning rate that decreases as epochs progress. """ learning_rate = 0.2 if epoch > 10: learning_rate = 0.02 if epoch > 20: learning_rate = 0.01 if epoch > 50: learning_rate = 0.005 tf.summary.scalar('learning rate', data=learning_rate, step=epoch) return learning_rate lr_callback = keras.callbacks.LearningRateScheduler(lr_schedule) tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir) model = keras.models.Sequential([ keras.layers.Dense(16, input_dim=1), keras.layers.Dense(1), ]) model.compile( loss='mse', # keras.losses.mean_squared_error optimizer=keras.optimizers.SGD(), ) training_history = model.fit( x_train, # input y_train, # output batch_size=train_size, verbose=0, # Suppress chatty output; use Tensorboard instead epochs=100, validation_data=(x_test, y_test), callbacks=[tensorboard_callback, lr_callback], )

Vamos conferir o TensorBoard novamente.

%tensorboard --logdir logs/scalars

Usando o seletor "Runs" à esquerda, observe que você tem uma execução <timestamp>/metrics. Ao selecionar essa execução, aparece um grafo "taxa de aprendizado" que permite verificar a progressão da taxa de aprendizado durante a execução.

Você também pode comparar as curvas de perda de treinamento e validação dessa execução com as execuções anteriores. Além disso, talvez você perceba que o cronograma da taxa de aprendizado retornou valores discretos, dependendo da época, mas a plotagem da taxa de aprendizado parece suave. O TensorBoard tem um parâmetro de suavização que você pode precisar definir como zero para ver valores não suavizados.

Como é o desempenho desse modelo?

print(model.predict([60, 25, 2])) # True values to compare predictions against: # [[32.0] # [14.5] # [ 3.0]]
[[31.958094 ] [14.482997 ] [ 2.9993598]]

Registro no nível do lote

Primeiro, vamos carregar o dataset MNIST, normalizar os dados e escrever uma função que cria um modelo simples do Keras para classificar imagens em 10 classes.

mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 def create_model(): return tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax') ])
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 11493376/11490434 [==============================] - 0s 0us/step 11501568/11490434 [==============================] - 0s 0us/step

Registro instantâneo no nível do lote

O registro instantâneo de métricas no nível do lote pode nos mostrar o nível de oscilação entre lotes ao treinar cada época, o que pode ser útil para depuração.

Configure um escritor de resumo para um diretório de log diferente:

log_dir = 'logs/batch_level/' + datetime.now().strftime("%Y%m%d-%H%M%S") + '/train' train_writer = tf.summary.create_file_writer(log_dir)

Para ativar o registro no nível do lote, métricas tf.summary personalizadas devem ser definidas ao sobrepor train_step() na definição de classe do modelo e envolvidas em um contexto de escritor de resumo. Isso pode ser simplesmente combinado nas definições de modelo de subclasse ou ampliado para editar o modelo de API funcional anterior, conforme mostrado abaixo:

class MyModel(tf.keras.Model): def __init__(self, model): super().__init__() self.model = model def train_step(self, data): x, y = data with tf.GradientTape() as tape: y_pred = self.model(x, training=True) loss = self.compiled_loss(y, y_pred) mse = tf.keras.losses.mean_squared_error(y, K.max(y_pred, axis=-1)) self.optimizer.minimize(loss, self.trainable_variables, tape=tape) with train_writer.as_default(step=self._train_counter): tf.summary.scalar('batch_loss', loss) tf.summary.scalar('batch_mse', mse) return self.compute_metrics(x, y, y_pred, None) def call(self, x): x = self.model(x) return x # Adds custom batch-level metrics to our previous Functional API model model = MyModel(create_model()) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

Defina a callback do TensorBoard para registrar métricas no nível da época e do lote no diretório de log e chamar model.fit() com o batch_size selecionado:

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) model.fit(x=x_train, y=y_train, epochs=5, batch_size=500, validation_data=(x_test, y_test), callbacks=[tensorboard_callback])
Epoch 1/5 120/120 [==============================] - 5s 36ms/step - loss: 0.4379 - accuracy: 0.8788 - val_loss: 0.2041 - val_accuracy: 0.9430 Epoch 2/5 120/120 [==============================] - 4s 31ms/step - loss: 0.1875 - accuracy: 0.9471 - val_loss: 0.1462 - val_accuracy: 0.9591 Epoch 3/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1355 - accuracy: 0.9613 - val_loss: 0.1170 - val_accuracy: 0.9670 Epoch 4/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1058 - accuracy: 0.9694 - val_loss: 0.0954 - val_accuracy: 0.9723 Epoch 5/5 120/120 [==============================] - 3s 27ms/step - loss: 0.0872 - accuracy: 0.9752 - val_loss: 0.0843 - val_accuracy: 0.9749
<keras.callbacks.History at 0x7fce165a2fd0>

Abra o TensorBoard com o novo diretório de log e veja ambas as métricas no nível da época e do lote:

%tensorboard --logdir logs/batch_level

Registro cumulativo no nível do lote

O registro no nível do lote também pode ser implementado de maneira cumulativa, calculando a média das métricas de cada lote com a de lotes anteriores e resultando em uma curva de treinamento mais suave ao registrar métricas no nível do lote.

Configure um escritor de resumo para um diretório de log diferente:

log_dir = 'logs/batch_avg/' + datetime.now().strftime("%Y%m%d-%H%M%S") + '/train' train_writer = tf.summary.create_file_writer(log_dir)

Crie métricas stateful que podem ser registradas por lote:

batch_loss = tf.keras.metrics.Mean('batch_loss', dtype=tf.float32) batch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('batch_accuracy')

Como antes, adicione métricas tf.summary personalizadas no método train_step sobreposto. Para tornar o registro no nível do lote cumulativo, use as métricas stateful que definimos para calcular o resultado cumulativo a partir dos dados de cada passo do treinamento.

class MyModel(tf.keras.Model): def __init__(self, model): super().__init__() self.model = model def train_step(self, data): x, y = data with tf.GradientTape() as tape: y_pred = self.model(x, training=True) loss = self.compiled_loss(y, y_pred) self.optimizer.minimize(loss, self.trainable_variables, tape=tape) batch_loss(loss) batch_accuracy(y, y_pred) with train_writer.as_default(step=self._train_counter): tf.summary.scalar('batch_loss', batch_loss.result()) tf.summary.scalar('batch_accuracy', batch_accuracy.result()) return self.compute_metrics(x, y, y_pred, None) def call(self, x): x = self.model(x) return x # Adds custom batch-level metrics to our previous Functional API model model = MyModel(create_model()) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

Como antes, defina nossa callback do TensorBoard e chame model.fit() com nosso batch_size selecionado:

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) model.fit(x=x_train, y=y_train, epochs=5, batch_size=500, validation_data=(x_test, y_test), callbacks=[tensorboard_callback])
Epoch 1/5 120/120 [==============================] - 4s 27ms/step - loss: 0.4266 - accuracy: 0.8813 - val_loss: 0.2055 - val_accuracy: 0.9415 Epoch 2/5 120/120 [==============================] - 3s 26ms/step - loss: 0.1864 - accuracy: 0.9476 - val_loss: 0.1417 - val_accuracy: 0.9613 Epoch 3/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1352 - accuracy: 0.9614 - val_loss: 0.1148 - val_accuracy: 0.9665 Epoch 4/5 120/120 [==============================] - 3s 26ms/step - loss: 0.1066 - accuracy: 0.9702 - val_loss: 0.0932 - val_accuracy: 0.9716 Epoch 5/5 120/120 [==============================] - 3s 27ms/step - loss: 0.0859 - accuracy: 0.9749 - val_loss: 0.0844 - val_accuracy: 0.9754
<keras.callbacks.History at 0x7fce15c39f50>

Abra o TensorBoard com o novo diretório de log e veja ambas as métricas no nível da época e do lote:

%tensorboard --logdir logs/batch_avg

É isso! Agora você sabe como criar métricas de treinamento personalizadas no TensorBoard para uma ampla variedade de casos de uso.