You have funny ideas of cleanliness – just like we all do.
More seriously:

There is nothing wrong with del. This is the method Python and PyTorch forsee for removing something.
Even just overwriting a module with another without explicit del is OK.
What does seem a lot less clean (to me, but I’ll admit that I fancy myself to have very good tastes in this and well aligned with PyTorch at that) is that you sometimes have self.relu be a module and sometimes a function. This is not good, as modules are superspecial to PyTorch. I would recommend to either use functions throughout (e.g. torch.nn.functional.relu) or stay with modules when changing.

Best regards
Thomas