Is it
optimizer.zero_grad()
out = model(batch_X)
loss = loss_fn(out, batch_y)
loss.backward()
optimizer.step()

or
out = model(batch_X)
loss = loss_fn(out, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()

I use the second one, as I belive just before the gradients are calculated, I need to zero out the existing ones.
But, my project reviewer on Udacity says to use the first one.
The model is LSTM.
Also, I think both are the same, isn’t it?