Sinir Ağları ve Derin Öğrenme — VIII : Vektörizasyon

Eren Bozarık
SMLR CENTER
Published in
3 min readSep 5, 2019

Daha önce ki yazılarda da belirttiğim gibi derin öğrenme işlemlerinde veriminizi arttırmak istiyorsanız elinizde verinin çok olması lazım. Ne kadar “büyük veri” o kadar “kaliteli sonuç” diyebiliriz. Fakat bu büyük veriyi hızlı işlememiz gerekli. Sonuç çok kısa bir süre içerisinde elde edilmeli.

Burada w ve x ifadeleri kolon vektörüdür.

şeklinde tanımlanır. Özellikler ne kadar fazlaysa vektörlerde o kadar büyüktür. Vektörize edilmemiş bir şekilde w ve x değerlerini hesaplamaya çalışırsanız çok zamanınızı alır. Bir demo yapalım.

import numpy as np
import time
a=np.random.rand(1000000)
b=np.random.rand(1000000)

tic=time.time()
c=np.dot(a,b)
toc=time.time()
print(c)
print("Vectorize versiyon :" + str(1000*(toc-tic)) + "ms")

c=0
tic=time.time()
for i in range(1000000):
c+=a[i]*b[i]
toc = time.time()
print(c)
print ("For döngüsü :" + str(1000*(toc-tic)) + "ms")
249820.043348
Vectorize versiyon :4.001140594482422ms
249820.043348
For döngüsü :529.984712600708ms

Görüldüğü üzere aynı a ve b verileri vektörize edildiğinde derlenme hızında gözle büyük bir değişim var. Vektörize edilmiş bir veri daha hızlı derlenmektedir. Burada Numpy kütüphanesinin paralel hesaplama işleminde ne kadar iyi olduğunuda görebilirsiniz. Bu teknik SIMD (Single Instruction Multiple Data / Tek İşlem, Çoklu Veri) olarakta geçmektedir. Bilimsel uygulamaların yüksek performanslı çalışmasının gerektirdiği zamanlarda işlemcinin vektör işlemlerini yapabilmesini, daha doğrusu hafıza bölgesindeki veri kümelerini blok halinde bir kerede alıp üzerinde işlem gerçekleştirilmesini sağlayan tekniğe verilen addır. SIMD kullanarak tek bir cekirdek ayni anda birden fazla islemi gerceklestirebilir. GPU ve CPU’lar vektörel işlemler için SIMD birimlerini kullanırlar.

Mümkün olduğu kadar for döngülerinden kaçının.

Elimizde A ve v vektörleri olduğunu kabul edelim. Ve bunların çarpımını istiyoruz. İki matrisin çarpımının algoritması şu şekildedir.

Biz bu hesabı numpy kullanarak çok basit bir şekilde yapabiliriz. Bu işlem aşağıda ki kod satırı ile yapabilirsiniz.

u=np.dot(A,v)

İşlemi Deneyebilmeniz İçin Başka Bir Örnek

import numpy as np
import time
A=np.random.random((4, 4))
v=np.random.random((4, 4))
tic=time.time()
u=np.dot(A,v)
toc=time.time()
print(u)

print("\n Derleme Hızı:" + str(1000*(toc-tic)) + "ms\n")

tic1=time.time()
s=(4,4)
result=np.zeros(s)
for i in range(len(A)):

for j in range(len(v[0])):

for k in range(len(v)):
result[i][j] += A[i][k] * v[k][j]
toc1=time.time()

for r in result:
print(r)
print("\n Derleme Hızı:" + str(1000*(toc1-tic1)) + "ms\n")

Matrislerin boyutunu arttırdıkça farkı daha net göreceksiniz.

Bir matriste ki her eleman için aşağıda ki gibi üstel işlemi yapacağımızı varsayalım

Bu işlemi for döngüsü ile yapmak için uygulayacağınız kod satırları şu şekildedir.

u=np.zeros((1,n))
for i in range (n):
u[i]=math.exp(v[i])
print(u[i])

Bu işlemi numpy ile çok daha kolay bir şekilde yapabilirsiniz.

u=np.exp(v)

--

--

Eren Bozarık
SMLR CENTER

Sr. Data Scientist & SWE | Galatasaray University