Özellikle makine öğrenmesinde kullanılan bu önemli tekniğe gelin bir göz atalım.
Vektörleştirme tekniği array operasyonlarında klasik programlama döngülerinin aksine her bir işlemi paralel bir şekilde yapmaktır.
Özellikle ML (Makine Öğrenmesi) alanında önemli bir rol oynayan bu teknik, işlem sürelerini ciddi oranda azaltmaktadır.
Bu yazıda bu işlemlerin kullanıldığı örnek kodları ve işlemlerin arasındaki farkı görmek adına işlem sürelerini de göreceksiniz.
Hadi başlayalım.
Çoğunlukla düşük boyutlu arraylerde çarpma, transpoz alma gibi işlemleri yaparken döngüleri kullanıyoruz. Fakat 50, 100 gibi düşük sayıda değil de 1.000.000 adet veri içeren bir array üzerinde bu şekilde işlem yapmak ne kadar doğru?
Döngüler ile işlem yaparken her bir iterasyonda döngü içindeki işlemler kadar işlem yapılır.
Numpy fonksiyonlarının C dilinde yazılmış olması ve döngü yerine vektör işlemleri kullanıldığı için işlemler en optimum şekilde ilerler. Ek olarak numpy, dizileri bellekte süreli bloklar halinde saklar. Bu ise bellek erişimlerini optimize etmesine olanak sağlar. Son olarak ‘slicing’ denilen dilimleme işlemleri ile veri kopyalamadan veriye doğrudan erişim sağlamaya yarar.
Bu gibi optimizasyon ve veri işleme algoritmalarını çok çekirdekli CPU’larda kullandğımız zaman yazdığımız kodları daha verimli ve hızlı çalıştırabiliyor oluyoruz.
Öncelikle basit işlemlerle başlayalım. İstisnasız en ufak kodda dahi kullandığımız toplama işlemini varsayalım. Bir arraydaki her bir değeri toplamak istersek nasıl olur?
for i in vary(1500000):
batuSalary += i
Örnek yukarıdaki kodda her bir maaş arttırma işlemi birim zamanda tek işlem olarak yapılır.
print(np.sum(np.arange(1500000))) #np.arange işlemi 1.5m adet verilik array oluşturmaya yarıyor
Bu kodda ise NumPy kütüphanesini (np) kullanarak her bir işlemi vektörize şekilde yapıyoruz.
Süre farkları :
Klasik for döngüsü : 75.00052452087402 ms
Vektörize şekilde : 9.056568145751953 ms
Yaklaşık 8 kattan fazla bir süre farkı görüyoruz.
Bu yapılacak işlemlerden en basitiydi, hadi daha zorlarına geçelim.
Matematiksel işlemler arasında en çok kullanılan bir diğer işlem olan ‘Dot Product’ olarak bildiğimiz nokta çarpım. Bu işlem iki farklı vektörün her bir i ninci elemanını birbirleriyle çarpıp, bu çarpımları toplayarak bir skaler sonuç üretir.
w = np.random.rand(1000000)
x = np.random.rand(1000000) #w ve x adında 1m veri bulunan arrayler ürettik#Vektörize kullanmadan
for i in vary(1000000):
c +=w[i]*x[i]
#Vektörize kullanarak
c = np.dot(w,x)
np.dot ifadesi numpyda nokta çarpım işlemini yapmamızı sağlar. Buradan şunu da çıkarabiliriz ki NumPy kullanımı yazdığımız kodları da kısaltıyor.
Süre farkları :
Klasik for döngüsü : 252.00414657592773 ms
Vektörize şekilde : 0.9920597076416016 ms
Aradaki uçurum gibi farkı hepimiz görüyoruz. Yaklaşık 250 kattan fazla bir hız farkı.
Bu örnek ve take a look at sayısına onlarca daha ekleyebileceğimiz işlem var elbette ama bu yazıda hepsine girmeyeceğiz. Meraklısı için diğer kullanımlara (örnek olarak gelişmiş makine öğrenmesi denklemleri) yönelik ayrı bir yazı yazabilirim.
Hem işlem süresini ciddi şekilde azaltan hem de kod yazımını kolaylaştıran vektörleştirme tekniğine beraber baktık. Özellikle C temelli ufuncları (bkz. Ufuncs) olmasıyla dikkat çeken NumPy ile bu tekniği makine öğrenmesi gibi önemli alanlarda kullanabiliyoruz.
Okuduğunuz için teşekkür ediyor, bol kodlamalı günler diliyorum.