ONNX Nedir? Neden Öğrenmelisiniz?

Derin öğrenme modellerini her yerde kullanmanın en pratik yolu.

Mert Cobanov
7 min readOct 7, 2023

Bu yazıdaki tüm kodlara github repomdan ulaşabilirsiniz.

Bu Yazıyı Kimler Okumalı

ONNX’i kullanmayı öğrenmek muhakkak ki makine öğrenimi, derin öğrenme ve yapay zeka projelerine uzanan bir işiniz varsa işe yarayacaktır, günümüzde en basit uygulamalara bile sirayet eden yapay zeka projelerinde olur da işiniz düşerse nasıl kullanabileceğinizi merak ediyorsanız veya aşağıdaki listede size uygun bir durum söz konusuysa okumanızı tavsiye ederim.

  • Deep learning modelleriyle alakalı kısıtlı bilginiz varsa, web veya mobil geliştiriciyseniz
  • Farklı türden cihazlarda yapay zeka modellerinizi koşturmanız gerekiyorsa
  • Halihazırda kullandığınız modeller için optimizasyon yapmak istiyorsanız
  • Hızlıca hazır ve eğitilmiş yapay zeka modellerini kullanmanız gerekiyorsa
  • Birden fazla deep learning frameworkünü aynı uygulamada kullanmak zorundaysanız
  • Bir programlama dilinde model oluşturup, ardından tamamen farklı bir çalışma ortamında olmanız gerekiyorsa (örneğin, Python’da oluşturduğunuz modeli C# veya JS’de deployment yapacaksanız)
  • Muhtemelen aklıma gelmeyen fakat dökümantasyonda bulacağınız diğer konular

Bu Yazıda Neler Öğreneceksiniz

  • ONNX Nedir?
  • Hangi durumlarda ONNX’e ihtiyacınız olacak?
  • Örnek ONNX çalışmaları ve kodları
  • ONNX model zoo ile hızlıca modelleri nasıl kullanabilirsiniz?

ONNX Nedir?

https://upload.wikimedia.org/wikipedia/commons/c/c0/ONNX_logo_main.png

Tabii ki adettendir, ONNX’in ne olduğu ve ne yaptığı konusunda bir açıklama yapmadan önce Microsoft ve Facebook tarafından geliştirilmiştir, Linux Foundation bünyesinde birçok geliştirici tarafından desteklenmektedir gibi asla kullanmayacağınız trivial bilgileri hızlca geçip bu meretin ne yaptığını açıklamak istiyorum.

ONNX, PyTorch ve TensorFlow gibi bildiğimiz ve sevdiğimiz tüm deep learning frameworklerini kullanarak bir model oluşturmamıza ve çeşitli donanımlarda ve işletim sistemlerince desteklenen bir formatta paketlememize yarıyor. Aslında bu platformlar arası basit bir API gibi düşünebilirsiniz. Bulut, mobil, IoT artık aklınıza her neresi geliyorsa bu platformların tamamındaki problemlerimizi çözmeyi amaçlıyor.

https://media.licdn.com/dms/image/D4E12AQGqGhfNviyuWg/article-cover_image-shrink_600_2000/0/1665075477046?e=1701907200&v=beta&t=Uhtbm_x_FfDPJITKjQkOAJBG4fTmf5yXTYJ7acxw21o

ONNX, yani uzun adıyla “Open Neural Network Exchange” veya Türkçe adıyla “??Açık Sinir Ağı Değişimi??” derin öğrenme ve çeşitli makine öğrenmesi modelleri için geliştirilen bir standarttır. Bu standart, farklı derin öğrenme frameworkleri (örneğin, PyTorch, TensorFlow, Caffe2 vb.) tarafından geliştirilen yapay zeka modellerini taşınabilir (portable) ve birbirleriyle uyumlu (interoperable) hale getirir.

Yani, bir derin öğrenme modelini ONNX formatına dönüştürerek, bu modeli farklı frameworklerde sorunsuz bir şekilde kullanabilir, paylaşabilir ve çalıştırabilirsiniz. Bu da bize aslında bir esneklik sağlıyor ve farklı frameworklerde çalışan projeler arasında (mesela pytorch’tan tensorflow’a) veri ve model paylaşımını kolaylaştırmaya yarıyor.

Tek sihirbazlık yetenekleri de bu değil tabii ki, çalıştırmayı istediğiniz modeli istediğiniz cihazdan (CPU, GPU, FPGA veya TPU) bağımsız hale getirmeye çalışır (device-agnostic). Bununla birlikte, farklı donanımlarda optimizasyonu da ONNX’e bırakmış oluyorsunuz.

https://techcommunity.microsoft.com/t5/ai-machine-learning-blog/onnx-runtime-training-technical-deep-dive/ba-p/1398310

Buna ek olarak, makalenin ilerleyen kısımlarında bahsedeceğim model zoo, aynı Docker Hub gibi hazır eğitilmiş kullanıma hazır ONNX modellerini hızlıca ayağa kaldırmanızı sağlıyor. Ne demek istiyorum? Örneğin, YOLO ile nesne takibi yapmayı birkaç satırda halledebilir ve istediğiniz bir cihazda dakikalar içinde kullanıma hazır hale getirebilirsiniz, çünkü biri sizin için tüm sistemi hazırlayıp paketlemiş oluyor.

Detaylara geçmeden önce bir örnek gösterip kafanızda şekillendirmek istiyorum.

Olası Senaryolar

Diyelim ki fotoğraflardan çiçek türlerini tespit eden bir makine öğrenimi modeliniz var. Bu görevi bilgisayarınızdan bir fotoğraf yükleyerek tahminlemesini sağlıyorsunuz ve bu işlemi yaparken klasik x86 işlemcinizi veya Nvidia ekran kartınızı kullanıyorsunuz. Ancak bunu, A16 bionic çipli bir iPhone 15'te yapmak istediğinizde Apple sizi CoreML kullanmaya zorlayacak, çünkü bunu Neural Processing Unit (NPU) veya bilinen adıyla Apple Neural Engine’de yapmanız gerekiyor.

Kaynak: https://www.linkedin.com/pulse/what-onnx-machine-learning-model-why-should-you-care-bhattiprolu/

Bu makine öğrenme modelinizi CoreML modeline çevirme işlemini ONNX ile hızlıca yapabilirsiniz. `tf2onnx` kütüphanesini kullanarak Keras modelinizi ONNX’e dönüştüreceksiniz ve sonrasında `onnx-coreml` kütüphanesini kullanarak ONNX’i Core ML modeline dönüştüreceksiniz. CoreML’de deploy etmeye hazırsınız.

2. Edge Devicelarda TFLite

Bir PyTorch modeliniz var ve bunu edge cihazlarınızda çalışacak şekilde TFLite’a çevirmek istiyorsunuz. TFLite destekleyen IoT cihazlarınız veya akıllı telefonlarınız var. Modelinizin boyutunu düşürmek istiyorsunuz veya buna benzer farklı problemleriniz var.

https://medium.com/@zergtant/convert-pytorch-model-to-tf-lite-with-onnx-tf-232a3894657c

3. Diğer senaryolar

  • Web uygulamanızda yapay zeka modellerini kullanmanız gerekiyor
  • `onnxruntime-node` npm paketini kullanarak Node.js ortamında çalıştırmanız gereken bir projeniz var
  • AzureML veya diğer bulut sağlayıcılarda bu modelleri koşturmak istiyorsunuz
  • Hazır modelleri hızlıca model zoo’dan çekip kullanıma hazır hale getirmek istiyorsunuz. (Bundan daha detaylı bahsediyorum)

Örnek Çalışmalar

ONNX’in temelde iki konsepti oldukça ön plana çıkıyor. Birincisi, konvansiyonel makine öğrenme modellerinizi (örneğin, Scikit-Learn) ONNX formatında kaydedip sonrasında herhangi bir cihazda veya platformda kullanmak. İkincisi ise bir TensorFlow veya PyTorch modelini ONNX formatına çevirmek. Vakit kaybetmeden örneklerimize geçelim.

Örnek 1: scikitlearn & onnx

Temel bir dokümantasyon örneğini buraya getiriyorum ve parça parça sizinle inceleyelim.

Makine öğrenimi uzmanlarının milli veri seti olan Iris veri seti ve temel makine öğrenimi örneklerinin vazgeçilmez modeli olan Random Forest Classifier ile basit bir Scikit-Learn modeli kurmak için gerekli importları yapalım.

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

Modeli instantiate edip hızlıca modele fit edelim. Eğer zaten ONNX öğrenmek için geldiyseniz, bu temel kısımlarını hızlıca anlayacağınızı öngördüğümü yanlış bulmayacağınızı düşünüyorum.

iris = load_iris()

X, y = iris.data, iris.target
X = X.astype(np.float32)
X_train, X_test, y_train, y_test = train_test_split(X, y)

clr = RandomForestClassifier()
clr.fit(X_train, y_train)

Bu kod, Scikit-Learn ile eğitilmiş bir makine öğrenme modelini ONNX formatına dönüştürüp, bu dönüştürülmüş modeli “rf_iris.onnx” adlı bir dosyaya kaydediyor. ONNX formatı, modelin farklı platformlarda ve cihazlarda kullanılabilir olmasını sağlayacak.

from skl2onnx import to_onnx

onx = to_onnx(clr, X[:1])
with open("rf_iris.onnx", "wb") as f:
f.write(onx.SerializeToString())

ONNX formatındaki bir makine öğrenme modelini yükleyip, bu modeli kullanarak veriler üzerinde tahminleyip sonuçları elde edelim.

import onnxruntime as rt

sess = rt.InferenceSession("rf_iris.onnx", providers=["CPUExecutionProvider"])
input_name = sess.get_inputs()[0].name
label_name = sess.get_outputs()[0].name
pred_onx = sess.run([label_name], {input_name: X_test.astype(np.float32)})[0]

Örnek 2: TF & ONNX

Bu örnekte, TensorFlow veya Keras modelini ONNX formatına nasıl çevirebileceğinizi görebilirsiniz.

Peki, zaten TensorFlow modeli çalışırken neden ONNX’e çevirelim, buna neden ihtiyacımız olacak diye düşünüyorsanız, yukarıda bahsettiğim gibi bunu framework veya device agnostic hale getirmek istediğimiz için yapıyoruz. Aynı zamanda bir sonraki blog yazısında bahsedeceğim, bunu Azure, AWS gibi platformlarda veya bir mobil uygulama yapmak istiyorsanız kullanacaksınız.

import tensorflow as tf
import tf2onnx

tf_model = tf.keras.models.load_model('tf_model.h5')
onnx_model = tf2onnx.convert.from_keras(tf_model)

onnx_model_path = 'converted_model.onnx'
with open(onnx_model_path, 'wb') as f:
f.write(onnx_model.SerializeToString())

print("Model converted to ONNX and saved as:", onnx_model_path)

Daha Teknik Detaylar

ONNX modelinin halihazırda kullandığımız modelleri optimize ettiğinden bahsetmiştim. ONNX runtime size bazı performans avantajları sunuyor.

Bu tekniklerden biri JIT (Yani Sırası Geldiğinde Derleme), çekirdek birleştirme (kernel fusion) ve alt grafik bölümlendirme (subgraph partitioning) gibi tekniklerdir.

İkincil olarak, dağıtık sistemler için iş parçacığı havuzu (thread pooling) desteği de bulunmaktadır. Bu, daha büyük ölçekli deploymentlar yaparken işimize yarayabilecek özelliklerdir. Bunları basitçe anlatmanın pek bir yolu yok, aslında zten bunlar tamamen başka blogların konusu, fakat meraklıları için ilgili bağlantıları bırakıyorum.

http://www.xavierdupre.fr/app/onnxcustom/helpsphinx/onnxmd/onnx_docs/Hub.html

ONNX Model Zoo

ONNX Model Zoo, gönüllü geliştiricilerin ONNX formatında önceden eğittiği çeşitli modelleri topladığı bir platform ve bu modellerin yanında, model eğitimi ve eğitilen modelle çıkarım yapılması için Jupyter notebook örneklerini de ekliyorlar. Eğitimde kullanılan veri setleri ve model mimarisini açıklayan orijinal makalelere de referanslar ekleniyor. Bu sayede, bu modelleri tekerleği yeniden icat etmeden hızlıca alıp kullanabiliriz. Bu modelleri depolamak için Git LFS (Büyük Dosya Depolama) kullanılıyor.

import onnx
from onnx_tf.backend import prepare
import numpy as np
from PIL import Image
import json

# Load the ONNX model

# Use local model
model_path = './vgg19-7.onnx'
model = onnx.load(model_path)

## Download from hub
# model_path = 'vgg 19'
# model = onnx.hub.load(model_path)

# Prepare the ONNX model for TensorFlow
tf_model = prepare(model)

# Display input and output nodes of the model
print("Input nodes:", tf_model.inputs)
print("Output nodes:", tf_model.outputs)

# Load class labels from a JSON file
with open('labels.json', 'r') as json_file:
label_data = json.load(json_file)

# Load and preprocess the input image
input_image_path = 'frog.jpg'
input_image = Image.open(input_image_path).resize((224, 224))
input_image = np.asarray(input_image, dtype=np.float32)[np.newaxis, np.newaxis, :, :]
input_image = input_image.transpose(0, 1, 4, 2, 3)
input_image = input_image.reshape(1, 3, 224, 224) # Transform to Input Tensor

# Run inference on the input image
output = tf_model.run(input_image)[0][0]

# Find the top 5 class indices
top_indices = np.argpartition(output, -5)[-5:]

# Display the top 5 class labels and their scores
for i in top_indices:
class_label = label_data.get(str(i), "Unknown")
class_score = output[i]
print(f"Class: {class_label}, Score: {class_score:.4f}")
# Output

Class: American chameleon, anole, Anolis carolinensis, Score: 85.1076
Class: green lizard, Lacerta viridis, Score: 92.0642
Class: bullfrog, Rana catesbeiana, Score: 103.7489
Class: tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui, Score: 157.5779
Class: tree frog, tree-frog, Score: 186.0841

Sonuç

ONNX, yapay zeka ve makine öğrenme dünyasında son zamanlarda aşırı önemli bir rol oynamaya başladı ve bir standart oluşturuyor. Farklı derin öğrenme frameworkleri arasındaki problemleri çözüyor ve modellerin sorunsuz bir şekilde farklı platformlar ve cihazlar üzerinde çalışmasını ve dağıtılmasını sağlıyor.

Mert Cobanov

Twitter, Linkedin

Bu yazıdaki tüm kodlara github repomdan ulaşabilirsiniz.

Referanslar

--

--