The outputs tensor is created by your model and represents the output of the forward method.
Usually it would contain e.g. class logits for your use case.
The loss_function calculates the loss, which will be used to compute the gradients of this loss w.r.t. all parameters of the model during the loss.backward() call. The optimizer.step() uses the gradients (and internal estimates depending which optimizer is used) to update all passed parameters.
I would recommend to take a look at some courses e.g. FastAI, which might be a good starter.