If you’re interested in supervised neural networks, Keras, in my opinion, is the best option. You’d use CNTK, or more likely, TensorFlow for your Keras backend.
If you’re interested in unsupervised or semi-supervised neural networks, TensorFlow and PyTorch both work. However, they both have noteworthy issues.
Until eager execution was added to TensorFlow, TensorFlow models needed to be compiled. It was difficult to spice your network with dynamic behavior that couldn’t be easily constrained to a TensorFlow graph. Especially if you weren’t strong programming with common parallel primitives. Eager execution has made this easier, but it’s still more cumbersome than PyTorch’s execution methodology.
PyTorch sacrifices many of the benefits of compilation for usability and this is most obvious when deploying to, for example, the cloud or mobile devices. PyTorch, also, inexplicably, breaks many of the conventions present in the scientific Python ecosystem making it pretty cumbersome to integrate into existing workflows that rely on a package like scikit-image.
It’s complicated. In fact, I believe it’s way too complicated. Thankfully Keras solves most problems for most people in this area.