Pure Swift Machine Learning Framework
Neural networks, classic ML algorithms, on-device training. No Python. No CoreML dependency. Just Swift + Accelerate.
Most ML frameworks for Apple platforms are either wrappers around Python (slow, bloated) or limited to CoreML inference (no training). SwiftAI is different:
- Pure Swift β every algorithm implemented from scratch
- On-device training β train models directly on iPhone/iPad/Mac
- Accelerate-optimized β SIMD vector ops via vDSP/BLAS for real performance
- Zero heavy dependencies β just swift-numerics, that's it
- scikit-learn API β familiar
.fit()/.predict()/.score()interface
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SwiftAI β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β π§ Neural Networks β π Classic ML β π§ Tools β
β βββββββββββββββββ β βββββββββββββ β ββββββββ β
β β’ Dense Layers β β’ Linear Regression β β’ Scalers β
β β’ Batch/Layer Norm β β’ Logistic Reg. β β’ Encoders β
β β’ Dropout β β’ Decision Trees β β’ Imputers β
β β’ Embedding β β’ Random Forests β β’ Metrics β
β β’ 10+ Activations β β’ K-Means β β’ CV Split β
β β’ 9+ Loss Functions β β’ KNN β β’ Export β
β β’ 5+ Optimizers β β’ SVM β β’ CoreML β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Swift Package Manager
dependencies: [
.package(url: "https://github.com/muhittincamdali/SwiftAI.git", from: "2.0.0")
]import SwiftAI
let network = NeuralNetwork()
.dense(784, 256, activation: .relu)
.batchNorm(256)
.dropout(0.3)
.dense(256, 128, activation: .relu)
.dropout(0.2)
.dense(128, 10, activation: .softmax)
network.compile(
optimizer: .adam,
loss: .crossEntropy,
learningRate: 0.001
)
let history = network.train(
x: trainData, y: trainLabels,
epochs: 50, batchSize: 32,
validationSplit: 0.2
)
let predictions = network.predict(testData)let model = LinearRegression()
model.fit(x: features, y: targets)
let predictions = model.predict(newData)
let r2 = model.score(x: testX, y: testY)
print("RΒ² Score: \(r2)") // 0.97let forest = RandomForestClassifier(
nEstimators: 100,
maxDepth: 10,
maxFeatures: .sqrt
)
forest.fit(x: trainX, y: trainY)
let accuracy = forest.score(x: testX, y: testY)
print("Accuracy: \(accuracy * 100)%")
// Feature importance
for (i, imp) in forest.featureImportances!.enumerated() {
print("Feature \(i): \(imp)")
}let kmeans = KMeans(nClusters: 5, initMethod: .kmeanspp)
kmeans.fit(data)
let labels = kmeans.predict(newData)
let score = silhouetteScore(x: data, labels: kmeans.labels!)
print("Silhouette: \(score)")let kfold = KFold(nSplits: 5, shuffle: true)
var scores = [Float]()
for (trainIdx, testIdx) in kfold.split(nSamples: data.count) {
let trainX = trainIdx.map { data[$0] }
let trainY = trainIdx.map { labels[$0] }
let testX = testIdx.map { data[$0] }
let testY = testIdx.map { labels[$0] }
let model = RandomForestClassifier(nEstimators: 50)
model.fit(x: trainX, y: trainY)
scores.append(model.score(x: testX, y: testY))
}
print("CV: \(scores.reduce(0,+) / Float(scores.count)) Β± \(standardDeviation(scores))")| Layer | Description | Parameters |
|---|---|---|
Dense |
Fully connected | inputSize, outputSize, useBias |
ActivationLayer |
Activation function | activation |
Dropout |
Regularization | rate |
BatchNorm |
Batch normalization | numFeatures, epsilon, momentum |
LayerNorm |
Layer normalization | normalizedShape, epsilon |
Embedding |
Token embedding | numEmbeddings, embeddingDim |
Flatten |
Flatten tensor | β |
relu Β· leakyRelu Β· elu Β· selu Β· sigmoid Β· tanh Β· softmax Β· swish Β· gelu Β· softplus
| Loss | Use Case |
|---|---|
mse |
Regression |
mae |
Regression (robust) |
huber |
Regression (outlier-resistant) |
bce |
Binary classification |
bceWithLogits |
Binary with raw logits |
crossEntropy |
Multi-class classification |
nll |
Negative log likelihood |
hinge |
SVM-style |
cosineEmbedding |
Similarity learning |
sgd (with momentum/nesterov) Β· adam Β· adamw Β· rmsprop Β· adagrad
| Algorithm | Type | Key Features |
|---|---|---|
LinearRegression |
Regression | OLS, L1/L2 regularization, SGD |
RidgeRegression |
Regression | L2 regularization |
LassoRegression |
Regression | L1 regularization |
ElasticNet |
Regression | L1 + L2 combined |
LogisticRegression |
Classification | Binary/Multinomial |
DecisionTreeClassifier |
Classification | Gini/Entropy splitting |
DecisionTreeRegressor |
Regression | MSE/MAE splitting |
RandomForestClassifier |
Classification | Bootstrap aggregating, OOB |
RandomForestRegressor |
Regression | Feature importance |
KMeans |
Clustering | K-means++ initialization |
KNeighborsClassifier |
Classification | KD-tree, distance weighting |
KNeighborsRegressor |
Regression | Distance-based |
SVC |
Classification | RBF/Linear/Poly/Sigmoid kernels |
SVR |
Regression | Epsilon-insensitive |
// Scalers
StandardScaler().fitTransform(data)
MinMaxScaler(featureRange: (0, 1)).fitTransform(data)
RobustScaler().fitTransform(data)
Normalizer(norm: .l2).transform(data)
// Encoders
LabelEncoder().fitTransform(labels)
OneHotEncoder().fitTransform(categories)
// Imputation
SimpleImputer(strategy: .mean).fitTransform(data)
// Splitting
let (trainX, testX, trainY, testY) = trainTestSplit(x: x, y: y, testSize: 0.2)// Classification
accuracyScore(yTrue: actual, yPred: predicted)
precisionRecallF1(yTrue: actual, yPred: predicted)
confusionMatrix(yTrue: actual, yPred: predicted)
rocAucScore(yTrue: actual, yScore: probabilities)
// Regression
meanSquaredError(yTrue: actual, yPred: predicted)
rootMeanSquaredError(yTrue: actual, yPred: predicted)
meanAbsoluteError(yTrue: actual, yPred: predicted)
r2Score(yTrue: actual, yPred: predicted)
// Clustering
silhouetteScore(x: data, labels: clusters)
daviesBouldinScore(x: data, labels: clusters)
adjustedRandScore(labelsTrue: true, labelsPred: pred)// Save/Load neural networks
try network.save(to: modelURL)
try network.load(from: modelURL)
// Export to CoreML-compatible JSON
try network.exportToCoreML(url: outputURL)
// Model quantization (8-bit)
let (quantized, scale, zp) = ModelCompressor.quantize(weights: params, bits: 8)Sources/SwiftAI/
βββ ML/
β βββ Core/
β β βββ Tensor.swift # SIMD-optimized via Accelerate
β β βββ Activations.swift # 10 activation functions + derivatives
β β βββ LossFunctions.swift # 9 loss functions + gradients
β β βββ Optimizers.swift # SGD, Adam, AdamW, RMSprop, Adagrad
β βββ Neural/
β β βββ Layers.swift # Dense, Dropout, BatchNorm, LayerNorm, Embedding
β β βββ NeuralNetwork.swift # Network builder, trainer, serialization
β βββ Algorithms/
β β βββ LinearRegression.swift # OLS + Ridge + Lasso + ElasticNet
β β βββ LogisticRegression.swift
β β βββ DecisionTree.swift # Classifier + Regressor
β β βββ RandomForest.swift # Classifier + Regressor
β β βββ KMeans.swift # K-Means + MiniBatch
β β βββ KNN.swift # Classifier + Regressor + KD-Tree
β β βββ SVM.swift # SVC + SVR (SMO algorithm)
β βββ Preprocessing/
β β βββ DataPreprocessing.swift # Scalers, encoders, imputers, CV
β βββ Evaluation/
β β βββ Metrics.swift # Classification, regression, clustering metrics
β βββ Export/
β βββ CoreMLExport.swift # JSON export, ONNX info, quantization
βββ SwiftAI.swift # Framework entry point
SwiftAI uses Apple's Accelerate framework under the hood:
| Operation | Method | Speedup vs Pure Swift |
|---|---|---|
| Matrix Multiply (1000Γ1000) | cblas_sgemm |
~70Γ |
| Vector Addition (1M) | vDSP_vadd |
~18Γ |
| Softmax (10K) | vvexpf |
~26Γ |
| Dot Product (1M) | vDSP_dotpr |
~15Γ |
| Feature | SwiftAI | CreateML | CoreML | TensorFlow |
|---|---|---|---|---|
| Pure Swift | β | β | β | β |
| Custom Neural Nets | β | β | β | β |
| On-Device Training | β | β | β | β |
| Classic ML (7 algos) | β | Partial | β | β |
| No Heavy Dependencies | β | β | β | β |
| Open Source | β | β | β | β |
| Preprocessing Pipeline | β | Limited | β | β |
| Model Serialization | β | β | β | β |
- Swift 5.9+
- iOS 15+ / macOS 12+ / tvOS 15+ / watchOS 8+
- Xcode 15+
Contributions welcome! Please read our Contributing Guide.
git clone https://github.com/muhittincamdali/SwiftAI.git
cd SwiftAI
swift build
swift testMIT License β see LICENSE for details.
Built with β€οΈ in Swift
Report Bug Β· Request Feature