Estou treinando uma auto-encoder
rede com Adam
otimizador (with amsgrad=True
) e MSE loss
para a tarefa de separação de fonte de áudio de canal único. Sempre que decai a taxa de aprendizado por um fator, a perda de rede aumenta bruscamente e depois diminui até a próxima queda na taxa de aprendizado.
Estou usando o Pytorch para implementação e treinamento de rede.
Following are my experimental setups:
Setup-1: NO learning rate decay, and
Using the same Adam optimizer for all epochs
Setup-2: NO learning rate decay, and
Creating a new Adam optimizer with same initial values every epoch
Setup-3: 0.25 decay in learning rate every 25 epochs, and
Creating a new Adam optimizer every epoch
Setup-4: 0.25 decay in learning rate every 25 epochs, and
NOT creating a new Adam optimizer every time rather
using PyTorch's "multiStepLR" and "ExponentialLR" decay scheduler
every 25 epochs
Estou obtendo resultados muito surpreendentes para as configurações 2, 3 e 4 e não consigo explicar nenhuma explicação. A seguir estão meus resultados:
Setup-1 Results:
Here I'm NOT decaying the learning rate and
I'm using the same Adam optimizer. So my results are as expected.
My loss decreases with more epochs.
Below is the loss plot this setup.
Trama-1:
optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)
for epoch in range(num_epochs):
running_loss = 0.0
for i in range(num_train):
train_input_tensor = ..........
train_label_tensor = ..........
optimizer.zero_grad()
pred_label_tensor = model(train_input_tensor)
loss = criterion(pred_label_tensor, train_label_tensor)
loss.backward()
optimizer.step()
running_loss += loss.item()
loss_history[m_lr].append(running_loss/num_train)
Setup-2 Results:
Here I'm NOT decaying the learning rate but every epoch I'm creating a new
Adam optimizer with the same initial parameters.
Here also results show similar behavior as Setup-1.
Because at every epoch a new Adam optimizer is created, so the calculated gradients
for each parameter should be lost, but it seems that this doesnot affect the
network learning. Can anyone please help on this?
Trama-2:
for epoch in range(num_epochs):
optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)
running_loss = 0.0
for i in range(num_train):
train_input_tensor = ..........
train_label_tensor = ..........
optimizer.zero_grad()
pred_label_tensor = model(train_input_tensor)
loss = criterion(pred_label_tensor, train_label_tensor)
loss.backward()
optimizer.step()
running_loss += loss.item()
loss_history[m_lr].append(running_loss/num_train)
Setup-3 Results:
As can be seen from the results in below plot,
my loss jumps every time I decay the learning rate. This is a weird behavior.
If it was happening due to the fact that I'm creating a new Adam
optimizer every epoch then, it should have happened in Setup #1, #2 as well.
And if it is happening due to the creation of a new Adam optimizer with a new
learning rate (alpha) every 25 epochs, then the results of Setup #4 below also
denies such correlation.
Trama-3:
decay_rate = 0.25
for epoch in range(num_epochs):
optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)
if epoch % 25 == 0 and epoch != 0:
lr *= decay_rate # decay the learning rate
running_loss = 0.0
for i in range(num_train):
train_input_tensor = ..........
train_label_tensor = ..........
optimizer.zero_grad()
pred_label_tensor = model(train_input_tensor)
loss = criterion(pred_label_tensor, train_label_tensor)
loss.backward()
optimizer.step()
running_loss += loss.item()
loss_history[m_lr].append(running_loss/num_train)
Setup-4 Results:
In this setup, I'm using Pytorch's learning-rate-decay scheduler (multiStepLR)
which decays the learning rate every 25 epochs by 0.25.
Here also, the loss jumps everytime the learning rate is decayed.
Como sugerido por @Dennis nos comentários abaixo, tentei com ambas ReLU
e 1e-02 leakyReLU
não - linearidades. Mas, os resultados parecem se comportar de maneira semelhante e a perda primeiro diminui, depois aumenta e depois satura em um valor mais alto do que o que eu obteria sem diminuir a taxa de aprendizado.
O gráfico 4 mostra os resultados.
Trama-4:
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer=optimizer, milestones=[25,50,75], gamma=0.25)
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.95)
scheduler = ......... # defined above
optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)
for epoch in range(num_epochs):
scheduler.step()
running_loss = 0.0
for i in range(num_train):
train_input_tensor = ..........
train_label_tensor = ..........
optimizer.zero_grad()
pred_label_tensor = model(train_input_tensor)
loss = criterion(pred_label_tensor, train_label_tensor)
loss.backward()
optimizer.step()
running_loss += loss.item()
loss_history[m_lr].append(running_loss/num_train)
EDITAR% S:
- Conforme sugerido nos comentários e respostas abaixo, fiz alterações no meu código e treinei o modelo. Eu adicionei o código e os gráficos para o mesmo.
- Tentei com vários
lr_scheduler
inPyTorch (multiStepLR, ExponentialLR)
e plotagens para o mesmo estão listadosSetup-4
como sugerido por @Dennis nos comentários abaixo. - Tentando com leakyReLU como sugerido por @Dennis nos comentários.
Qualquer ajuda. obrigado
fonte
Respostas:
Não vejo razão para que as taxas de aprendizado decadentes criem os tipos de saltos nas perdas que você está observando. Ele deve "desacelerar" a rapidez com que você "se move", o que, no caso de uma perda que, de outra forma, diminui consistentemente, deve, na pior das hipóteses, levar a um platô nas suas perdas (em vez daqueles saltos).
A primeira coisa que observo no seu código é que você recria o otimizador do zero a cada época. Ainda não trabalhei o suficiente com o PyTorch para ter certeza, mas isso não destrói o estado / memória interna do otimizador sempre? Eu acho que você deve criar o otimizador apenas uma vez, antes do ciclo através das épocas. Se esse é realmente um bug no seu código, também deve ser um bug no caso em que você não usa o declínio da taxa de aprendizado ... mas talvez você simplesmente tenha sorte lá e não tenha os mesmos efeitos negativos do erro.
Para diminuir a taxa de aprendizado, recomendo usar a API oficial para isso , em vez de uma solução manual. No seu caso particular, convém instanciar um agendador StepLR , com:
optimizer
= o otimizador do ADAM, que você provavelmente deve instanciar apenas uma vez.step_size = 25
gamma = 0.25
Você pode simplesmente chamar
scheduler.step()
no início de cada época (ou talvez no final - o exemplo no link da API o chama no início de cada época).Se, após as alterações acima, você ainda enfrentar o problema, também seria útil executar cada um de seus experimentos várias vezes e traçar resultados médios (ou traçar linhas para todos os experimentos). Teoricamente, seus experimentos devem ser idênticos durante as primeiras 25 épocas, mas ainda vemos grandes diferenças entre as duas figuras, mesmo durante as primeiras 25 épocas em que não ocorre uma queda na taxa de aprendizado (por exemplo, uma figura começa com uma perda de ~ 28K, a outra começa com uma perda de ~ 40K). Isso pode ser simplesmente devido a diferentes inicializações aleatórias; portanto, seria bom calcular a média de que os resultados não são determinados por seus gráficos.
fonte