numaralı telefonu arayarak şu anda bir makine öğrenme projesi üzerinde çalışıyorum - bir veri matrisi Z
ve bir vektör rho
- verilen değer ve eğimini hesaplamak zorundayım rho
'da logistic loss function. Hesaplama, temel taşma-vektör çarpımını ve log/exp işlemlerini içerir, sayısal taşmayı önlemek için bir numara (bu previous post sayılı belgede açıklanmıştır).Python'da matris-vektör çarpma ve üssüasyonun hızlandırılması, muhtemelen C/C++
Şu anda bunu aşağıda gösterildiği gibi Python'da NumPy kullanarak yapıyorum (başvuru olarak bu kod 0,2s'de çalışır). Bu iyi çalışıyor olsa da, kodumda birden çok kez işlevi çağırdığımdan hızlandırmak istiyorum (ve projemde yer alan hesaplamanın% 90'ından fazlasını temsil ediyor).
Paralel olmadan bu kodun çalışma zamanını iyileştirmenin herhangi bir yolunu arıyorum (örn. Sadece 1 CPU). Python'da herkese açık olan bir paketi kullanmaktan veya C veya C++ 'yı aradığımdan (bu durumun çalışma zamanlarını büyüklük sırasına göre iyileştirdiğini duyduğumdan) mutluyum. Veri matrisi Z
'un ön işlemlerinin yapılması da Tamam olur. Daha iyi hesaplaması için yararlanılabilir Bazı şeyler vektör rho
(girişler = 0 yaklaşık% 50 ile), genellikle seyrek ve kadar fazla satır
(çoğu durumda
n_cols <= 100
olarak) sütunlardan daha genelde bulunmamasıdır BLAS ailesinin kitaplıkları, en iyi performans için zaten çoktan ayarlanmış durumdadır.
import time
import numpy as np
np.__config__.show() #make sure BLAS/LAPACK is being used
np.random.seed(seed = 0)
#initialize data matrix X and label vector Y
n_rows, n_cols = 1e6, 100
X = np.random.random(size=(n_rows, n_cols))
Y = np.random.randint(low=0, high=2, size=(n_rows, 1))
Y[Y==0] = -1
Z = X*Y # all operations are carried out on Z
def compute_logistic_loss_value_and_slope(rho, Z):
#compute the value and slope of the logistic loss function in a way that is numerically stable
#loss_value: (1 x 1) scalar = 1/n_rows * sum(log(1 .+ exp(-Z*rho))
#loss_slope: (n_cols x 1) vector = 1/n_rows * sum(-Z*rho ./ (1+exp(-Z*rho))
#see also: https://stackoverflow.com/questions/20085768/
scores = Z.dot(rho)
pos_idx = scores > 0
exp_scores_pos = np.exp(-scores[pos_idx])
exp_scores_neg = np.exp(scores[~pos_idx])
#compute loss value
loss_value = np.empty_like(scores)
loss_value[pos_idx] = np.log(1.0 + exp_scores_pos)
loss_value[~pos_idx] = -scores[~pos_idx] + np.log(1.0 + exp_scores_neg)
loss_value = loss_value.mean()
#compute loss slope
phi_slope = np.empty_like(scores)
phi_slope[pos_idx] = 1.0/(1.0 + exp_scores_pos)
phi_slope[~pos_idx] = exp_scores_neg/(1.0 + exp_scores_neg)
loss_slope = Z.T.dot(phi_slope - 1.0)/Z.shape[0]
return loss_value, loss_slope
#initialize a vector of integers where more than half of the entries = 0
rho_test = np.random.randint(low=-10, high=10, size=(n_cols, 1))
set_to_zero = np.random.choice(range(0,n_cols), size =(np.floor(n_cols/2), 1), replace=False)
rho_test[set_to_zero] = 0.0
start_time = time.time()
loss_value, loss_slope = compute_logistic_loss_value_and_slope(rho_test, Z)
print "total runtime = %1.5f seconds" % (time.time() - start_time)
1'den fazla CPU'yu neden hariç tutuyorsunuz? Her ne kadar Python VM temelde tek bir iş parçacığı olsa da, verileri daha çok iş parçacığı dostu bir veri yapısına kopyaladıktan sonra bir C uzantısından POSIX iş parçacığı çağırabilirsiniz.Birden fazla CPU kullanmamanın başka nedenleri olabilir, ancak C. – rts1
@rts'e kaçarsanız bu kısıtlama ile sınırlı değilsiniz. Bu durumda, 'compute_logistic_loss_function' işlevini çağıran kod aslında paralelleştirilmiş olduğundan, 1 CPU'yla sınırlandırmam gerekiyor ... Bu yüzden işlev çağrıldığında yalnızca 1 CPU kullanılabilir. –
Büyük 'n' için çalışma zamanı,' Z' ile aynı boyuta yayın yapan loss_slope = Z * (phi_slope - 1.0) 'ile baskın görünüyor. Sıra üzeri satırları aldığınız için, bunu bir nokta ürün olarak yeniden yazabilirim. ZTdot (phi_slope) .T/Z.shape [0] ', bu da benim için 4'lük bir hız artışı sağlar. makinesi. –