Keras e épocas, batches, taxas de aprendizado, etc1. Intro2. Controle manual pelo usuárioa) Número de épocas (epochs
) e tamanho do batch (batch_size
)b) Quando o backpropagation é executado?3. Ajuste automático de hiperparâmetrosa) Taxa de aprendizado (learning rate) adaptativaMétodo de Adam (Adaptative Moment Estimation)FuncionamentoComo a Taxa de Aprendizado 𝛼 é Adaptada?Referência BibliográficaReferências Adicionais RecentesImplementação no KerasResumo (do método Adam)b) Momentum adaptativoRMSprop (Detalhes)Funcionamento do RMSprop no KerasMomentum no RMSprop?A Taxa de Aprendizado é ajustada automáticamente no RMSprop? Parâmetros Controláveis pelo Usuário no RMSprop (Keras)Referências Bibliográficas (RMSprop) Resumo das Características do RMSprop4. Early stopping automáticoMais DetalhesO que acontece?Usando ModelCheckpointMais Referências5. Como o Keras decide com base nos dados?6. Funcionalidades avançadas (Keras + TensorFlow)7. Como o Keras tenta evitar Overfitting1. Early Stopping2. Regularização Integrada 3. Dropout 4. Validação MonitoradaO Que Depende do Usuário?Exemplo de Boa Prática no KerasResumoDicas FinaisMaterial Extra1. Controle do Early Stopping no Keras2. Como restore_best_weights=True
Funciona?Exemplo Prático3. Como Acompanhar a Função Loss em Tempo Real com Gráficos?Opção 1: Usando History
+ MatplotlibOpção 2: Gráfico em Tempo Real com LambdaCallback
4. Referências Bibliográficas5. ResumoDiferença entre Conjunto de Validação vs Conjunto de Teste1. Papel de Cada Conjunto de Dados2. Por Que o Conjunto de Teste é Intocável?Exemplo Prático3. Quando o Conjunto de Validação é Usado?Fluxo "Correto" (esperado) no Keras:4. E Se Não Houver Conjunto de Validação?5. Referências Bibliográficas6. Resumo
O Keras (agora integrado ao TensorFlow como tf.keras
) oferece várias formas de controlar os parâmetros de treinamento, incluindo épocas, batch size, e até a execução do backpropagation. Além disso, ele possui funcionalidades para ajuste automático de hiperparâmetros e early stopping.
A página Épocas, batches e mini-batches introduz mais informações à respeto do seja uma "época", o que são batches, definição do tamanho dos batches e atualizações dos parãmetros de treinamento da rede.
epochs
) e tamanho do batch (batch_size
)No Keras, você define esses parramentos diretamente no método .fit()
:
model.fit(
x_train, y_train,
epochs=50, # Número de épocas
batch_size=32, # Tamanho do mini-batch (backpropagation a cada 32 amostras)
validation_data=(x_val, y_val) # Dados de validação
)
O Keras adota mini-batch gradient descent por padrão, ou seja:
batch_size
.Se você quiser um comportamento diferente (ex.: atualização apenas ao final da época), teria que implementar um otimizador personalizado ou usar Batch Gradient Descent
(definindo batch_size=len(x_train)
).
O Keras oferece mecanismos para adaptar dinamicamente certos parâmetros durante o treinamento:
Otimizadores com scheduling embutido:
tf.keras.optimizers.Adam(learning_rate=0.001)
(usa adaptação automática por padrão).tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
(momento pode ser ajustado).Redução automática da taxa de aprendizado (learning rate decay):
xfrom keras.callbacks import LearningRateScheduler
def lr_schedule(epoch):
return 0.001 * 0.9 ** epoch # Reduz a taxa a cada época
model.fit(..., callbacks=[LearningRateScheduler(lr_schedule)])
No caso do exemplo de código acima, a taxa de aprendizado desceria da seguinte forma:
XXXXXX
O método de "Adam" (Adaptive Moment Estimation) (Kingma & Ba, 2015), para atualização da taxa de aprendizado, consite num otimizador adaptativo que combina os benefícios do RMSprop (adaptação por média móvel dos gradientes ao quadrado) e do momentum (média móvel dos gradientes). A principal característica do Adam é que ele ajusta individualmente a taxa de aprendizado para cada parâmetro da rede neural, com base nas estimativas de primeiro e segundo momentos dos gradientes.
Passo a Passo da Atualização no Adam:
Seja o parâmetro no tempo , o gradiente em , e a taxa de aprendizado inicial.
Calcula-se o gradiente (backpropagation).
Estima-se o primeiro momento (média móvel dos gradientes - momentum):
Estima-se o segundo momento (média móvel dos gradientes ao quadrado - adaptação por magnitude):
Correção de viés (importante nas primeiras iterações):
Atualiza-se os parâmetros:
Sobre a taxa :
O termo age como um fator de escala adaptativo:
Resultado: Parâmetros com gradientes irregulares têm taxas menores, enquanto parâmetros com gradientes estáveis avançam mais rapidamente.
O artigo original que introduziu o Adam é o mais citado e recomendado para referência:
Kingma, D. P. and Ba, J. (2015) Adam: A method for stochastic optimization. arXiv preprint arXiv:1412.6980. Disponível em: https://arxiv.org/abs/1412.6980.
Reddi, S. J. et al. (2018) On the convergence of Adam and beyond. International Conference on Learning Representations (ICLR).
Loshchilov, I. and Hutter, F. (2019) Decoupled weight decay regularization. ICLR.
No Keras/TensorFlow, o Adam já inclui todas as adaptações descritas:
xxxxxxxxxx
from tensorflow.keras.optimizers import Adam
optimizer = Adam(
learning_rate=0.001, # Taxa inicial (alpha)
beta_1=0.9, # Decaimento do 1º momento (beta_1)
beta_2=0.999, # Decaimento do 2º momento (beta_2)
epsilon=1e-8 # Termo de estabilização
)
Característica | Efeito na Taxa de Aprendizado |
---|---|
Momentum () | Suaviza oscilações em gradientes ruidosos, mantendo direção consistente. |
Adaptação () | Reduz a taxa efetiva para parâmetros com gradientes grandes/instáveis (ex.: ruídos). |
Correção de viés | Garante que e não sejam subestimados no início do treino. |
O Adam é amplamente usado em redes profundas por sua eficiência em problemas com gradientes esparsos ou ruidosos (ex.: NLP, GANs). Para problemas onde ele oscila demais, variantes como AdamW ou NAdam podem ser melhores.
O RMSprop (Root Mean Square Propagation) é um método de otimização adaptativo que ajusta a taxa de aprendizado para cada parâmetro individualmente, com base na magnitude média dos gradientes recentes. Diferentemente do Adam, o RMSprop não usa momentum tradicional, mas pode ser combinado com momentum (uma variante chamada RMSprop com momentum).
Passo a Passo do RMSprop: Seja:
Calcula-se o gradiente (via backpropagation).
Atualiza-se a média móvel dos gradientes ao quadrado (adaptação da taxa de aprendizado):
Atualiza-se os parâmetros:
O termo ajusta a taxa de aprendizado individualmente para cada parâmetro:
O RMSprop puro não inclui momentum, mas o Keras permite adicioná-lo via parâmetro momentum
:
xxxxxxxxxx
from tensorflow.keras.optimizers import RMSprop
optimizer = RMSprop(
learning_rate=0.001, # Taxa de aprendizado base
rho=0.9, # Equivalente a γ (decaimento da média móvel)
momentum=0.0, # Se > 0, adiciona momentum clássico
epsilon=1e-8
)
Se momentum > 0
, o update passa a incluir um termo de momentum:
Sim e não:
Parâmetro | Descrição | Valor Típico |
---|---|---|
learning_rate | Taxa de aprendizado inicial (). | 0.001 |
rho | Fator de decaimento da média móvel (). | 0.9 |
momentum | Se , adiciona momentum clássico ao RMSprop. | 0.0 (sem momentum) |
epsilon | Termo de estabilização para evitar divisão por zero. | 1e-8 |
Artigo Original do RMSprop: Tieleman, T. and Hinton, G. (2012) Lecture 6.5-rmsprop: Divide the gradient by a running average of its recent magnitude. COURSERA: Neural Networks for Machine Learning.
Referências Recentes sobre Otimização Adaptativa:
Ruder, S. (2016) An overview of gradient descent optimization algorithms. arXiv preprint arXiv:1609.04747.
Reddi, S. J. et al. (2018) On the convergence of Adam and beyond. International Conference on Learning Representations (ICLR).
Zhang, J. et al. (2020) Why gradient clipping accelerates training: A theoretical justification for adaptivity. ICLR.
Feature | RMSprop Puro | RMSprop + Momentum |
---|---|---|
Taxa de aprendizado | Ajustada por parâmetro | Ajustada por parâmetro |
Momentum | Não | Sim |
Uso típico | RNNs, problemas com gradientes instáveis | CNNs, problemas mais complexos |
O RMSprop é especialmente útil em redes recorrentes (RNNs) e problemas onde os gradientes variam muito em magnitude. Para problemas modernos, muitas vezes é substituído pelo Adam, que combina RMSprop e momentum.
O Keras inclui um callback pronto para parar o treinamento quando o modelo para de melhorar no conjunto de validação (não no conjunto de teste!):
xxxxxxxxxx
from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(
monitor='val_loss', # Métrica monitorada (erro no validação)
patience=5, # Número de épocas sem melhoria antes de parar
restore_best_weights=True # Restaura os melhores pesos encontrados
)
model.fit(
x_train, y_train,
validation_data=(x_val, y_val),
callbacks=[early_stopping] # Adiciona o callback
)
Monitoramento Contínuo:
val_loss
) melhorou em relação ao melhor valor histórico.Critério de Parada (patience
):
patience
épocas consecutivas, o treinamento é interrompido.Onde os Pesos São Armazenados?
Memória RAM: O Keras mantém apenas dois conjuntos de pesos na RAM:
Obs.: Nenhum arquivo em disco é gerado por padrão (a menos que você use ModelCheckpoint
).
No caso do exemplo anterior:
patience=5
;val_loss
ocorreu na époica 20;Neste caso o treinamento continua até a época 25 (sem melhoras) e então para.
Na época 20 os pesos foram copiados para a variável best_weigths
(em RAM).
Entre as épocas 21 à 25 os pesos foram atualizados, mas best_weights
não foi alterado (pois vai_loss
não melhorou).
Finalmente, o Keras descarta os pesos da época 25 e restaura best_weights
(da época 20).
Se for desejado gravar arquivos de pesos da rede, temporários em disco, pode-se usar o método ModelCheckpoint
para gerá-los (formato .h5
ou .keras
) refletindo os melhores pesos:
xxxxxxxxxx
from keras.callbacks import ModelCheckpoint
checkpoint = ModelCheckpoint(
filepath='melhores_pesos.h5',
monitor='val_loss',
save_best_only=True, # Salva apenas se val_loss melhorar
mode='min'
)
model.fit(..., callbacks=[early_stopping, checkpoint])
Desta forma, um arquivo melhores_pesos.h5
é gerado no disco, cada vez que val_loss
atingir um novo mínimo. Pode-se ajustar ModelCheckpoint
para gerar nomes de arquivos dinâmicos (ex.: pesos_epoch_{epoch:02d}.h5
).
Conjunto de dados | Finalidade |
---|---|
Treino | Calcula gradientes e atualiza pesos. |
Validação | Monitora desempenho para early stopping, ajuste de LR, etc. Nunca afeta os pesos. |
Teste | Avaliação final (após o treinamento). Não influencia o modelo. |
Hiperparâmetros automáticos: Usando keras-tuner
ou integração com TensorFlow Extended (TFX)
.
Callbacks úteis:
ReduceLROnPlateau
: Reduz a taxa de aprendizado se a validação estagnar.ModelCheckpoint
: Salva os melhores pesos durante o treino.O Keras oferece mecanismos robustos para evitar overfitting, mas é crucial saber usá-los corretamente. Vamos reforçar os pontos-chave que garantem um treinamento equilibrado:
val_loss
para de cair por patience=5
épocas, o treinamento para e restaura os melhores pesos. Camadas como Dense
e Conv2D
aceitam parâmetros de regularização:
xxxxxxxxxx
Dense(64, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(0.01))
Isso penaliza pesos muito grandes, evitando ajustes extremos aos dados de treino.
Obs.: Redes muito complexas sem Dropout
ou L2
podem memorizar os dados.
"Desliga" neurônios aleatoriamente durante o treino, forçando a rede a não depender de poucos caminhos:
xxxxxxxxxx
tf.keras.layers.Dropout(0.5) # 50% de chance de zerar um neurônio
Obs.: Redes muito complexas sem Dropout
ou L2
podem memorizar os dados.
val_loss
e val_accuracy
são calculadas sem backpropagation, dando uma visão realista do desempenho. Escolha dos hiperparâmetros:
patience
muito baixo pode parar o treino cedo demais. batch_size
e learning_rate
afetam diretamente a generalização. Separação dos dados:
xxxxxxxxxx
model = Sequential([
Dense(64, activation='relu', kernel_regularizer=l2(0.01)),
Dropout(0.3),
Dense(1)
])
model.compile(
optimizer=RMSprop(learning_rate=0.001),
loss='mse'
)
history = model.fit(
x_train, y_train,
validation_data=(x_val, y_val),
epochs=100,
callbacks=[
EarlyStopping(patience=10, restore_best_weights=True),
ModelCheckpoint('melhor_modelo.keras', save_best_only=True)
]
)
model.fit(epochs=..., batch_size=...)
.callbacks
, monitorando validação.Se precisar de mais flexibilidade, você pode criar otimizadores personalizados ou usar subclasses de tf.keras.callbacks.Callback
.
Sempre visualize loss
vs val_loss
(usando TensorBoard/Matplotlib). Se as curvas divergirem, é sinal de overfitting:
loss
continua caindo. val_loss
estagna ou sobe. Combinando as técnicas acima, seu modelo terá alta performance sem overfitting!
O EarlyStopping
no Keras não é controlado apenas pelo parâmetro patience
. Ele possui outros parâmetros importantes:
Parâmetros Principais do EarlyStopping
:
Parâmetro | Descrição | Valor Padrão |
---|---|---|
monitor | Métrica monitorada (ex.: 'val_loss' , 'val_accuracy' ). | 'val_loss' |
patience | Número de épocas sem melhoria antes de parar. | 0 |
min_delta | Melhoria mínima exigida para considerar "progresso" (ex.: 0.001 ). | 0 |
restore_best_weights | Restaura os pesos da época com melhor métrica (monitor ). | False |
mode | Define se a métrica deve ser minimizada ('min' ) ou maximizada ('max' ). | 'auto' |
Exemplo de uso avançado:
xxxxxxxxxx
early_stopping = EarlyStopping(
monitor='val_loss',
patience=10, # Espera 10 épocas sem melhorar val_loss
min_delta=0.001, # Melhoria mínima exigida
restore_best_weights=True, # Volta aos melhores pesos encontrados
mode='min' # Minimizar val_loss
)
restore_best_weights=True
Funciona?Quando ativado, o Keras:
val_loss
) a cada época. patience
épocas não houver melhora, o treinamento é interrompido. val_loss
tenha o menor valor na época 15, mas o treinamento vai até a época 25 (por causa do patience=10
). restore_best_weights=True
, o modelo final ignora os pesos da época 25 e usar os da época 15. Sem restore_best_weights
:
Você pode usar callbacks do Keras para plotar gráficos dinâmicos durante o treinamento. Duas abordagens comuns:
History
+ Matplotlibxxxxxxxxxx
import matplotlib.pyplot as plt
history = model.fit(
x_train, y_train,
validation_data=(x_val, y_val),
epochs=100,
callbacks=[early_stopping]
)
# Plotar loss e val_loss após o treino
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.legend()
plt.show()
LambdaCallback
xxxxxxxxxx
from keras.callbacks import LambdaCallback
import matplotlib.pyplot as plt
import numpy as np
# Listas para armazenar os valores
train_losses = []
val_losses = []
# Callback para atualizar o gráfico a cada época
plot_callback = LambdaCallback(
on_epoch_end=lambda epoch, logs: (
train_losses.append(logs['loss']),
val_losses.append(logs['val_loss']),
plt.clf(),
plt.plot(train_losses, label='Train Loss'),
plt.plot(val_losses, label='Validation Loss'),
plt.legend(),
plt.pause(0.001) # Pausa para atualizar o gráfico
)
)
model.fit(..., callbacks=[early_stopping, plot_callback])
Observação: Para gráficos interativos e/ou mais avançados, use bibliotecas como Plotly ou TensorBoard. O TensorBoard é a ferramenta recomendada pelo Keras para visualização em tempo real.
Para saber mais sobre TensorBoard:
Chollet, F. (2021) Deep Learning with Python. 2nd ed. Manning Publications.
Documentação Oficial:
Dúvida | Resposta |
---|---|
Como EarlyStopping funciona? | Monitora uma métrica (ex.: val_loss ) e para após patience épocas sem melhoria. |
restore_best_weights ? | Restaura os pesos da época onde a métrica monitorada foi ótima. |
Como plotar loss em tempo real? | Usar History + Matplotlib ou LambdaCallback para atualização dinâmica. |
Ponto crucial! Vamos esclarecer a diferença entre conjunto de validação e conjunto de teste, e por que o Keras (e boas práticas em ML) nunca usam o teste durante o treinamento.
Conjunto | Finalidade | Quando é Usado? |
---|---|---|
Treino | Ajustar os pesos da rede (backpropagation). | Durante todo o treinamento. |
Validação | Monitorar desempenho para early stopping, ajuste de hiperparâmetros e seleção de modelos. | Durante o treinamento, mas não afeta os pesos. |
Teste | Avaliação final do modelo, simulando cenários do mundo real. | Apenas uma vez, após o treinamento. |
Objetivo do teste: Simular como o modelo se comportará com dados nunca vistos antes (como em produção).
Se você usar o teste para decisões de treino (ex.: parar o treinamento quando o erro no teste melhora):
Suponha que você:
O conjunto de validação é o substituto seguro do teste durante o treinamento. Ele permite:
xxxxxxxxxx
model.fit(
x_train, y_train,
validation_data=(x_val, y_val), # Usado para monitorar desempenho
callbacks=[EarlyStopping(monitor='val_loss')] # Para se val_loss piorar
)
# Avaliação FINAL (após treino)
test_loss = model.evaluate(x_test, y_test) # Só aqui o teste é usado!
Algumas abordagens usam apenas treino e teste, mas isso é arriscado:
Goodfellow, I., Bengio, Y. and Courville, A. (2016) Deep Learning. MIT Press.
Raschka, S. (2020) Model evaluation, model selection, and algorithm selection in machine learning. arXiv:1811.12808.
Conjunto | Uso | Quando |
---|---|---|
Treino: | Ajuste de pesos | → Backpropagation |
Validação: | Monitoramento | → Early stopping, ajuste de LR |
Teste: | Avaliação final | → Só no fim! |
.fit()
, a menos que você cometa um erro (ex.: passar x_test
como validation_data
). Se você usar o teste para tomar decisões durante o treino, estará superestimando o desempenho real do modelo. A validação existe justamente para evitar isso!
Fernando Passold, em 10/06/2025