Machine Learning Apps with Swift as Backend & Python ML Models
There has been demand of apps consuming Machine Learning Models to predict results. Apple & Android have been evolving their base day by day to provide better experience to Developers & End Users both. There has been several challanges in consumption of Trained Models in apps —
- Hardware & OS compatibility
- Duplicate development efforts in Apps Development to consume same trained models
- Separate Trained Models for different OS — High maintenance cost
App Developers world has been evolving day by day with improved tech stack. In this article — I have come up with one of unique combination for better results.
Swift as Backend — using Vapor
- Swift 5.5
- Vapor 4
- Python3
AWS
- Ubuntu 20.04
- t2.large instance
Machine Learning (trained) Model — SAV (python)
Native / Cross Platform Apps — consuming the APIs — Hope we already know this ;-)
Lets get started! XCode Vapor Project — On Mac Machine
Create a Swift Package Project using Vapor. Install Vapor on your Mac Machine. Follow below documentation —
Install Python3 on Mac machine. Mac machines generally has two python versions -
python — v2.7python3 — v3.8 (or any other version of python v3)
Execute below command on Mac Machine to update to latest version of Python
brew install python
This updates python3 mapping of usr/bin to brew installed python. Add ENV variable in your .bash_profile / .zshrc / .profile / .zprofile
export PYTHON_LIBRARY=/usr/bin/python3
In terminal — source your profile file where you added ENV variable
source ~/.zshrc
Machine Learning Model — SAV (python)
Check your python sample code — accessing the same ML Model, install the required “import” libraries. Generally, below are the tools needed by PythonML Models
joblib
pip3 install joblib
pandas
pip3 install pandas
scikit-learn
pip3 install -U scikit-learn scipy matplotlib
XCode Vapor Project
Add PythonKit to package file dependencies
.package(url: “https://github.com/pvieito/PythonKit.git", .branch(“master”))
Add python models — SAV files — in Project Sources > App
Add SAV models in resources section of package.swift file — path is relative to App Folder inside sources
resources: [.copy(“Python/HeartRiskModel.sav”)],
Now, in Swift File follow the below —
import PythonKitclass HeartRiskPythonModel {/// URL of model assuming it was installed in the same bundle as this class class var urlOfModelInThisBundle : String { let _ = Bundle(for: self) return Bundle.module.path(forResource: “HeartRiskModel”, ofType:”sav”)! }}
In Routes file, or the target file, where you want to use ML Model — load model classes as class level variables, using below
let joblib = Python.import(“joblib”)let heartModelPath = HeartRiskPythonModel.urlOfModelInThisBundlelet heartRiskModel = joblib.load(heartModelPath)
Now, in your target method, use below —
let user_data = [[body.age, body.sex, body.cp, body.trestbps, body.chol, body.fbs, body.restecg, body.thalach, body.exang, body.oldpeak, body.slope, body.ca, body.thal]]let predection = heartRiskModel.predict(user_data)let predection_prob = heartRiskModel.predict_proba(user_data)
You can obviously achieve the same Using CoreML library of Apple, which is straight forward BUT that comes up with other restrictions-
- You need to set-up Mac Instance on AWS — which is expensive
- You always need to map Python Models into CoreML models
Lets GO LIVE! — On AWS, login using credentials and SetUp new EC2 OR user your existing one — make sure you are having t2.large instance as minimum for this.
Using Root User — Install Swift following below commands — Swift Version Download link in step 4 of below — can be found at https://www.swift.org/download/
sudo apt updatesudo apt upgradesudo apt install binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev pkg-config tzdata zlib1g-devwget https://swift.org/builds/swift-5.3.3-release/ubuntu2004/swift-5.3.3-RELEASE/swift-5.3.3-RELEASE-ubuntu20.04.tar.gztar xzf swift-5.3.3-RELEASE-ubuntu20.04.tar.gzsudo mv swift-5.3.3-RELEASE-ubuntu20.04 /usr/share/swiftecho "export PATH=/usr/share/swift/usr/bin:$PATH" >> ~/.bashrcsource ~/.bashrcswift --version
Install Vapor using below documentation — (I preferred toolbox approach)
Install Python & Required dependencies on AWS too, using the same commands as stated above.
Git Clone your Vapor Porject — move to code directory and run project using below — (I did this using root user only)
vapor run serve — hostname 0.0.0.0 — port 80
All SET!! You can now consume the API on both iOS & Android Apps.