If you call model.eval(), the internal self.training flag will be set to False and e.g. the running estimates in batchnorm layers won’t be updated anymore but applied to the current batch.
Note that model.train() and model.eval() work recursively on all modules, so that you don’t have to reassign the model.
The training loop looks strange, as you are calling defeat.train with some arguments.
Are you using some high-level wrapper?
Also note that it looks as if you are storing the computation graph using running_loss += loss, which might increase your memory usage in each iteration.
If you would like to add the current loss to running_loss to print it later, use running_loss += loss.item() instead.