added training function and some optimizations