अनुकूलन स्टेज # 1
एक broadcasting
को दीवाना कोड का एक सीधा अनुवाद का उपयोग अनुकूलन के मेरी पहली स्तर आधारित एक नया अक्ष शुरू करने पर है और इस तरह तो स्मृति कुशल नहीं एक के रूप में नीचे सूचीबद्ध के रूप में -
p1 = (-((X[:,None] - Y)**2)/c1)-c2
p11 = p1.sum(2)
p2 = np.exp(p11+c3)
out = np.log(p2.sum(0)).mean()
अनुकूलन स्टेज # 2
में मन में कुछ अनुकूलन रखने वें लाना
c10 = -c1
c20 = X.shape[1]*c2
subs = (X[:,None] - Y)**2
p00 = subs.sum(2)
p10 = p00/c10
p11 = p10-c20
p2 = np.exp(p11+c3)
out = np.log(p2.sum(0)).mean()
अनुकूलन स्टेज # 3
इसके साथ आगे जा रहे हैं और और स्थानों को देखने जहां संचालन किया जा सकता है - हम स्थिरांक पर कार्रवाई को अलग करने का इरादा रखते हैं पर, मैं निम्नलिखित के साथ समाप्त हो गया अनुकूलित, मैं Scipy's cdist
का उपयोग करके स्क्वायरिंग और sum-reduction
के भारी वजन वाले काम को प्रतिस्थापित करने के लिए समाप्त हुआ। यह सुंदर स्मृति कुशल हो सकता है और जैसा कि नीचे दिखाया हमें अंतिम कार्यान्वयन दिया, चाहिए -
प्रयास
from scipy.spatial.distance import cdist
# Setup constants
c10 = -c1
c20 = X.shape[1]*c2
c30 = c20-c3
c40 = np.exp(c30)
c50 = np.log(c40)
# Get stagewise operations corresponding to loopy ones
p1 = cdist(X, Y, 'sqeuclidean')
p2 = np.exp(p1/c10).sum(0)
out = np.log(p2).mean() - c50
रनटाइम परीक्षण -
def loopy_app(X, Y, sigma):
k, d = X.shape
m = Y.shape[0]
c1 = 2.0*sigma**2
c2 = 0.5*np.log(np.pi*c1)
c3 = np.log(1.0/k)
L_B = np.zeros((m,))
for i in xrange(m):
L_B[i] = np.log(np.sum(np.exp(np.sum(-np.divide(
np.power(X-Y[i,:],2), c1)-c2,1)+c3)))
return np.mean(L_B)
def vectorized_app(X, Y, sigma):
# Setup constants
k, d = D_A.shape
c1 = 2.0*sigma**2
c2 = 0.5*np.log(np.pi*c1)
c3 = np.log(1.0/k)
c10 = -c1
c20 = X.shape[1]*c2
c30 = c20-c3
c40 = np.exp(c30)
c50 = np.log(c40)
# Get stagewise operations corresponding to loopy ones
p1 = cdist(X, Y, 'sqeuclidean')
p2 = np.exp(p1/c10).sum(0)
out = np.log(p2).mean() - c50
return out
समय और सत्यापन -
In [294]: # Setup inputs with m(=D_B.shape[0]) being a large number
...: X = np.random.randint(0,9,(100,10))
...: Y = np.random.randint(0,9,(10000,10))
...: sigma = 2.34
...:
In [295]: np.allclose(loopy_app(X, Y, sigma),vectorized_app(X, Y, sigma))
Out[295]: True
In [296]: %timeit loopy_app(X, Y, sigma)
1 loops, best of 3: 225 ms per loop
In [297]: %timeit vectorized_app(X, Y, sigma)
10 loops, best of 3: 23.6 ms per loop
In [298]: # Setup inputs with m(=Y.shape[0]) being a much large number
...: X = np.random.randint(0,9,(100,10))
...: Y = np.random.randint(0,9,(100000,10))
...: sigma = 2.34
...:
In [299]: np.allclose(loopy_app(X, Y, sigma),vectorized_app(X, Y, sigma))
Out[299]: True
In [300]: %timeit loopy_app(X, Y, sigma)
1 loops, best of 3: 2.27 s per loop
In [301]: %timeit vectorized_app(X, Y, sigma)
1 loops, best of 3: 243 ms per loop
लगभग 10x
गतिशील वहाँ!
कमाल! 10x से अधिक! – xxx222
@ xxx222 आप अपने वास्तविक डेटासेट पर क्या गति प्राप्त कर रहे हैं? – Divakar
लगभग 20x या तो, क्योंकि मेरे पास एक बहुत बड़ा डेटासेट है इसलिए दूरी मैट्रिक्स की गणना करना मुश्किल हो जाता है। – xxx222