This repository has been archived by the owner on Feb 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
glimpseSensor.py
74 lines (54 loc) · 2.62 KB
/
glimpseSensor.py
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from chainer import cuda
from chainer import function
import numpy as np
class GlimpseSensor(function.Function):
def __init__(self, center, output_size,depth=1, scale=2, using_conv = False, ):
if type(output_size) is not tuple:
self.output_size = output_size
else:
assert output_size[0] == output_size[1],"Output dims must be same"
self.output_size = output_size[0]
self.center = center
self.depth = depth
self.scale = scale
self.using_conv = using_conv
def forward(self, images):
xp = cuda.get_array_module(*images)
n, c, h_i, w_i = images[0].shape
assert h_i == w_i, "Image should be square"
size_i = h_i
size_o = self.output_size
# [-1, 1]^2 -> [0, size_i - 1]x[0, size_i - 1]
center = (0.5 * (self.center + 1) * (size_i - 1)).data # center:shape -> [n X 2]
y = xp.zeros(shape=(n, c*self.depth, size_o, size_o), dtype=xp.float32)
xmin = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
ymin = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
xmax = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
ymax = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
xstart = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
ystart = xp.zeros(shape=(self.depth, n), dtype=xp.int32)
for depth in range(self.depth):
xmin[depth] = xp.clip(xp.rint(center[:, 0]) - (0.5 * size_o * (np.power(self.scale,depth))), 0., size_i).astype(xp.int32)
ymin[depth] = xp.clip(xp.rint(center[:, 1]) - (0.5 * size_o * (np.power(self.scale,depth))), 0., size_i).astype(xp.int32)
xmax[depth] = xp.clip(xp.rint(center[:, 0]) + (0.5 * size_o * (np.power(self.scale,depth))), 0., size_i).astype(xp.int32)
ymax[depth] = xp.clip(xp.rint(center[:, 1]) + (0.5 * size_o * (xp.power(self.scale,depth))), 0., size_i).astype(xp.int32)
xstart[depth] = xmin[depth] - (xp.rint(center[:, 0]) - (0.5 * size_o * (np.power(self.scale,depth))))
ystart[depth] = ymin[depth] - (xp.rint(center[:, 1]) - (0.5 * size_o * (np.power(self.scale,depth))))
for i in range(n):
for j in range(self.depth):
cropped = images[0][i][:,xmin[j][i]:xmax[j][i], ymin[j][i]:ymax[j][i]]
# TODO: resize images
y[i][c*j: (c*j)+c, xstart[j][i]: xstart[j][i] + xmax[j][i] - xmin[j][i] ,
ystart[j][i]: ystart[j][i] + ymax[j][i] - ymin[j][i]] += cropped
if self.using_conv:
return y,
else:
return y.reshape(n,-1),
def backward(self, images, gy):
#return zero grad
xp = cuda.get_array_module(*images)
n, c_in ,h_i, w_i = images[0].shape
gx = xp.zeros(shape=(n, c_in, h_i, w_i), dtype=xp.float32)
return gx,
def getGlimpses(x, center, size, depth=1, scale=2, using_conv = False):
return GlimpseSensor(center, size, depth, scale)(x)