I want to write a function that can take small images and return a permutation of them, block-wise.
Basically I want to turn this:
Into this:
There was an excellent answer in Is there a function in Python that shuffle data by data blocks? that helped me write a solution. However for ~50,000 28×28 images this takes a long time to run.
JavaScript
x
15
15
1
# blocks of 7x7 shuffling
2
range1 = np.arange(4)
3
range2 = np.arange(4)
4
block_size = int(28 / 4)
5
print([[x[i*block_size:(i+1)*block_size].shape] for i in range1])
6
for x in x1:
7
np.random.shuffle(range1)
8
x[:] = np.block([[x[i*block_size:(i+1)*block_size]] for i in range1])
9
for a in x:
10
np.random.shuffle(range2)
11
a[:] = np.block([a[i*block_size:(i+1)*block_size] for i in range2])
12
13
print("x1", time.time() - begin)
14
begin = time.time()
15
Advertisement
Answer
Here’s one approach based on this post
–
JavaScript
1
10
10
1
def randomize_tiles_3D(x1, H, W):
2
# W,H are width and height of blocks
3
m,n,p = x1.shape
4
l1,l2 = n//H,p//W
5
combs = np.random.rand(m,l1*l2).argsort(axis=1)
6
r,c = np.unravel_index(combs,(l1,l2))
7
x1cr = x1.reshape(-1,l1,H,l2,W)
8
out = x1cr[np.arange(m)[:,None],r,:,c]
9
return out.reshape(-1,l1,l2,H,W).swapaxes(2,3).reshape(-1,n,p)
10
Sample run –
JavaScript
1
34
34
1
In [46]: x1
2
Out[46]:
3
array([[[ 0, 1, 2, 3, 4, 5],
4
[ 6, 7, 8, 9, 10, 11],
5
[12, 13, 14, 15, 16, 17],
6
[18, 19, 20, 21, 22, 23],
7
[24, 25, 26, 27, 28, 29],
8
[30, 31, 32, 33, 34, 35]],
9
10
[[36, 37, 38, 39, 40, 41],
11
[42, 43, 44, 45, 46, 47],
12
[48, 49, 50, 51, 52, 53],
13
[54, 55, 56, 57, 58, 59],
14
[60, 61, 62, 63, 64, 65],
15
[66, 67, 68, 69, 70, 71]]])
16
17
In [47]: np.random.seed(0)
18
19
In [48]: randomize_tiles_3D(x1, H=3, W=3)
20
Out[48]:
21
array([[[21, 22, 23, 0, 1, 2],
22
[27, 28, 29, 6, 7, 8],
23
[33, 34, 35, 12, 13, 14],
24
[18, 19, 20, 3, 4, 5],
25
[24, 25, 26, 9, 10, 11],
26
[30, 31, 32, 15, 16, 17]],
27
28
[[36, 37, 38, 54, 55, 56],
29
[42, 43, 44, 60, 61, 62],
30
[48, 49, 50, 66, 67, 68],
31
[39, 40, 41, 57, 58, 59],
32
[45, 46, 47, 63, 64, 65],
33
[51, 52, 53, 69, 70, 71]]])
34