Machine Learning at the edge – Training Neural Networks on the phone



Neural Network Training on handwritten characters
Training a neural network to recognise handwritten digits using SNNetwork.swift

You may not consider training your machine learning model on a mobile phone a very likely or viable approach. After all, a phone is a pretty limited computer, both in memory and processing capacity.

For some applications, where the size of say – a neural network – is limited, it could however, be extremely useful. Incremental improvements to a model that is specific to the individual user, could be made on the fly without incurring network overhead or the latency or cost from centralised processing. (The alternative would be to upload the data to the cloud, do the training there and re-download the trained model.)

To test this out we have implemented a classic neural network as a Swift class – SNNetwork.swift and powered it by our Matrix library (see this post). We have packaged SNNetwork with two other classes you will need – SMatrix.swift and MLGenerics.swift in a ‘try-it’ application; NNTester.

Please feel free to download and unzip NNTester. (171 downloads)


NNTester runs in Xcode on your Mac. It uses example data from MNIST for character recognition.


Each character is a 20 x 20 pixel matrix, unrolled into a 400 element vector where each pixel’s grayscale value is a Double. When you check out startTraining() in the MasterViewController class in NNTester, you will see that the neural network is created with a 400 (rather than 784 as in the illustration above) node input layer and a 10 node output layer.

Once trained, the neural network will take a 400 element input vector and produce a 10 element output, where the element with the highest value between 0 and 1 is interpreted as having the highest probability of being the input digit.

So if for instance, a handwritten digit is input as a 400 element pixel vector and the output vector is [0.01, 0.2, 0.05, 0.01, 0.005, 0.7, 0.003, 0.008, 0.004, 0.01], the element with the highest probability is the 6th, and the classifier would conclude that the input vector corresponds to a 6. Running a trained network in ‘feed-forward’ mode like this is done with a simple function call. If snnetwork is an instance of SNNetwork, then snnetwork.h(inputVector x : [Double]) -> [Double] will give you the ouput vector or ‘hypothesis’ given the x input vector.

Finally – don’t be confused by the fact that NNTester is a Mac application. By including SNNetwork.swift, SMatrix.swift and MLGenerics.swift in your iOS projects, you can start training or using pre-trained neural networks on the phone. SNNetwork contains code to save trained networks and read them in again, so you can also choose to train on the desktop and deploy the trained network to the phone.

The software is free for you to use as you please – we have released it under the GNU Lesser public license. If you want support from us – we are happy to provide that on commercial terms. Or if you would like to tell us how you have used the code, we would love to hear from you.  Get in touch on

Happy Coding!

Bjørn Taale