python पायथन में MATLAB के आईएम 2 कोल 'स्लाइडिंग' को लागू करना




performance python-2.7 (4)

मुझे नहीं लगता कि आप बेहतर कर सकते हैं स्पष्ट रूप से, आपको आकार का एक लूप चलाया जाना चाहिए

cols - block_size[1] * rows - block_size[0]

लेकिन आप अपने उदाहरण में 3, 3 पैच ले रहे हैं, नहीं 2, 2

प्रश्न: इसे कैसे गति दें?

नीचे प्रत्येक नं स्तंभ को लौटने की अतिरिक्त सुविधा के साथ, मैटलैब के आईएम 2 कोल 'स्लाइडिंग' का मेरा कार्यान्वयन किया गया है। फ़ंक्शन एक छवि (या कोई 2 मंद सरणी) और स्लाइड्स को बाएं से दाएं, ऊपर से नीचे, किसी भी आकार के प्रत्येक अतिव्यापी उप-छवि को चुनना और एक सरणी लौटते हैं जिनके स्तंभ उप-छवियाँ हैं

import numpy as np

def im2col_sliding(image, block_size, skip=1):

    rows, cols = image.shape
    horz_blocks = cols - block_size[1] + 1
    vert_blocks = rows - block_size[0] + 1

    output_vectors = np.zeros((block_size[0] * block_size[1], horz_blocks * vert_blocks))
    itr = 0
    for v_b in xrange(vert_blocks):
        for h_b in xrange(horz_blocks):
            output_vectors[:, itr] = image[v_b: v_b + block_size[0], h_b: h_b + block_size[1]].ravel()
            itr += 1

    return output_vectors[:, ::skip]

उदाहरण:

a = np.arange(16).reshape(4, 4)
print a
print im2col_sliding(a, (2, 2))  # return every overlapping 2x2 patch
print im2col_sliding(a, (2, 2), 4)  # return every 4th vector

रिटर्न:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
[[  0.   1.   2.   4.   5.   6.   8.   9.  10.]
 [  1.   2.   3.   5.   6.   7.   9.  10.  11.]
 [  4.   5.   6.   8.   9.  10.  12.  13.  14.]
 [  5.   6.   7.   9.  10.  11.  13.  14.  15.]]
[[  0.   5.  10.]
 [  1.   6.  11.]
 [  4.   9.  14.]
 [  5.  10.  15.]]

यह प्रदर्शन बहुत अच्छा नहीं है, खासकर मैं इस बात पर विचार कर रहा हूं कि क्या मैं im2col_sliding(big_matrix, (8, 8)) (62001 कॉलम) या im2col_sliding(big_matrix, (8, 8), 10) (6201 कॉलम; केवल हर 10 वीं सदिश रखते हुए) उसी समय का समय ले जाएगा [जहां big_matrix का आकार 256 x 256] है

मैं इसे बढ़ाने के लिए किसी भी विचार की तलाश कर रहा हूं


प्रदर्शन को बेहतर बनाने के लिए (उदाहरण के तौर पर रूपांतरण के लिए) हम विस्तारित कोड के आधार पर बैच के कार्यान्वयन का उपयोग भी कर सकते हैं, एम एलीया @ अंटार्कट मैटलैब के आईएम 2 कोल 'स्लाईडिंग' अजगर में , अर्थात

import numpy as np

A = np.arange(3*1*4*4).reshape(3,1,4,4)+1 # 3 Sample input array with 1 channel
B = [2,2] # Sample blocksize (rows x columns)
skip = [2,2]

# Parameters 
batch, D,M,N = A.shape
col_extent = N - B[1] + 1
row_extent = M - B[0] + 1

# Get batch block indices
batch_idx = np.arange(batch)[:, None, None] * D * M * N

# Get Starting block indices
start_idx = np.arange(B[0])[None, :,None]*N + np.arange(B[1])

# Generate Depth indeces
didx=M*N*np.arange(D)
start_idx=(didx[None, :, None]+start_idx.ravel()).reshape((-1,B[0],B[1]))

# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[None, :, None]*N + np.arange(col_extent)

# Get all actual indices & index into input array for final output
act_idx = (batch_idx + 
    start_idx.ravel()[None, :, None] + 
    offset_idx[:,::skip[0],::skip[1]].ravel())

out = np.take (A, act_idx)

नमूना चलाने का परीक्षण :

A = 
[[[[ 1  2  3  4]
   [ 5  6  7  8]
   [ 9 10 11 12]
   [13 14 15 16]]]


 [[[17 18 19 20]
   [21 22 23 24]
   [25 26 27 28]
   [29 30 31 32]]]


 [[[33 34 35 36]
   [37 38 39 40]
   [41 42 43 44]
   [45 46 47 48]]]] 


out = 
[[[ 1  2  3  9 10 11]
  [ 2  3  4 10 11 12]
  [ 5  6  7 13 14 15]
  [ 6  7  8 14 15 16]]

 [[17 18 19 25 26 27]
  [18 19 20 26 27 28]
  [21 22 23 29 30 31]
  [22 23 24 30 31 32]]

 [[33 34 35 41 42 43]
  [34 35 36 42 43 44]
  [37 38 39 45 46 47]
  [38 39 40 46 47 48]]]

अलग-अलग छवि चैनलों पर खिड़की स्लाइड करने के लिए, हम दिवाकर @ द्वारा प्रदान किए गए कोड के एक अद्यतन संस्करण का उपयोग कर सकते हैं MATLAB के im2col 'स्लाइडिंग' को पायथन में , अर्थात

import numpy as np
A = np.random.randint(0,9,(2,4,4)) # Sample input array
                    # Sample blocksize (rows x columns)
B = [2,2]
skip=[2,2]
# Parameters 
D,M,N = A.shape
col_extent = N - B[1] + 1
row_extent = M - B[0] + 1

# Get Starting block indices
start_idx = np.arange(B[0])[:,None]*N + np.arange(B[1])

# Generate Depth indeces
didx=M*N*np.arange(D)
start_idx=(didx[:,None]+start_idx.ravel()).reshape((-1,B[0],B[1]))

# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:,None]*N + np.arange(col_extent)

# Get all actual indices & index into input array for final output
out = np.take (A,start_idx.ravel()[:,None] + offset_idx[::skip[0],::skip[1]].ravel())

परीक्षण नमूना भागो

A=
[[[6 2 8 5]
[6 4 7 6]
[8 6 5 2]
[3 1 3 7]]

[[6 0 4 3]
[7 6 4 6]
[2 6 7 1]
[7 6 7 7]]]

out=
[6 8 8 5]
[2 5 6 2]
[6 7 3 3]
[4 6 1 7]
[6 4 2 7]
[0 3 6 1]
[7 4 7 7]
[6 6 6 7]

आप एम एलिया के जवाब में और अनुकूलन भी जोड़ सकते हैं (हालांकि यह महत्वपूर्ण नहीं है)

"आवेदन" करने के बजाय बहुत अंत में छोड़ दें, ऑफसेट एरे सृजन करते समय आप इसे लागू कर सकते हैं, इसके बदले:

# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:,None]*N + np.arange(col_extent)

# Get all actual indices & index into input array for final output
out = np.take (A,start_idx.ravel()[:,None] + offset_idx[::skip[0],::skip[1]].ravel())

आप numpy के क्रम फ़ंक्शन के चरण पैरामीटर का उपयोग करके रुक जाएंगे:

# Get offsetted indices across the height and width of input array and add skips
offset_idx = np.arange(row_extent, step=skip[0])[:, None] * N + np.arange(col_extent, step=skip[1])

और उसके बाद केवल [::] इंडेक्सिंग के बिना ओफ़सेट सरणी जोड़ें

# Get all actual indices & index into input array for final output

out = np.take(A, start_idx.ravel()[:, None] + offset_idx.ravel())

छोटे छोड़ मूल्यों पर यह बमुश्किल किसी भी समय बचाता है:

In[25]:
A = np.random.randint(0,9,(3, 1024, 1024))
B = [2, 2]
skip = [2, 2]

In[26]: %timeit im2col(A, B, skip)
10 loops, best of 3: 19.7 ms per loop

In[27]: %timeit im2col_optimized(A, B, skip)
100 loops, best of 3: 17.5 ms per loop

हालांकि बड़ा छोड़ मूल्यों के साथ यह थोड़ी अधिक समय बचाता है:

In[28]: skip = [10, 10]
In[29]: %timeit im2col(A, B, skip)
100 loops, best of 3: 3.85 ms per loop

In[30]: %timeit im2col_optimized(A, B, skip)
1000 loops, best of 3: 1.02 ms per loop

A = np.random.randint(0,9,(3, 2000, 2000))
B = [10, 10]
skip = [10, 10]

In[43]: %timeit im2col(A, B, skip)
10 loops, best of 3: 87.8 ms per loop

In[44]: %timeit im2col_optimized(A, B, skip)
10 loops, best of 3: 76.3 ms per loop






numpy