Almost completely implemented training function