def augment(V, crop, grayscale=False): # note assumes square outputs of size crop x crop # randomly sample a crop in the input volume if crop == V.sx: return V dx = randi(0, V.sx - crop) dy = randi(0, V.sy - crop) W = Vol(crop, crop, V.depth) for x in xrange(crop): for y in xrange(crop): if x + dx < 0 or x + dx >= V.sx or \ y + dy < 0 or y + dy >= V.sy: continue for d in xrange(V.depth): W.set(x, y, d, V.get(x + dx, y + dy, d)) if grayscale: #flatten into depth=1 array G = Vol(crop, crop, 1, 0.0) for i in xrange(crop): for j in xrange(crop): G.set(i, j, 0, W.get(i, j, 0)) W = G return W
def forward(self, V, is_training): self.in_act = V N = self.out_depth V2 = Vol(self.out_sx, self.out_sy, self.out_depth, 0.0) if self.out_sx == 1 and self.out_sy == 1: for i in xrange(N): offset = i * self.group_size m = max(V.w[offset:]) index = V.w[offset:].index(m) V2.w[i] = m self.switches[i] = offset + index else: switch_counter = 0 for x in xrange(V.sx): for y in xrange(V.sy): for i in xrange(N): ix = i * self.group_size elem = V.get(x, y, ix) elem_i = 0 for j in range(1, self.group_size): elem2 = V.get(x, y, ix + j) if elem2 > elem: elem = elem2 elem_i = j V2.set(x, y, i, elem) self.switches[i] = ix + elem_i switch_counter += 1 self.out_act = V2 return self.out_act
def load_data(crop, gray, training=True): filename = './data/cifar10_' if training: filename += 'train.npz' else: filename += 'test.npz' data = numpy.load(filename) xs = data['x'] ys = data['y'] for i in xrange(len(xs)): V = Vol(32, 32, 3, 0.0) for d in xrange(3): for x in xrange(32): for y in xrange(32): px = xs[i][x * 32 + y, d] / 255.0 - 0.5 V.set(x, y, d, px) if crop: V = augment(V, 24, gray) y = ys[i] yield V, y
def forward(self, V, is_training): self.in_act = V A = Vol(self.out_sx, self.out_sy, self.out_depth, 0.0) switch_counter = 0 for d in xrange(self.out_depth): x = -self.pad y = -self.pad for ax in xrange(self.out_sx): y = -self.pad for ay in xrange(self.out_sy): # convolve centered at this particular location max_a = -99999 win_x, win_y = -1, -1 for fx in xrange(self.sx): for fy in xrange(self.sy): off_x = x + fx off_y = y + fy if off_y >= 0 and off_y < V.sy \ and off_x >= 0 and off_x < V.sx: v = V.get(off_x, off_y, d) # max pool if v > max_a: max_a = v win_x = off_x win_y = off_y self.switch_x[switch_counter] = win_x self.switch_y[switch_counter] = win_y switch_counter += 1 A.set(ax, ay, d, max_a) y += self.stride x += self.stride self.out_act = A return self.out_act
def forward(self, V, is_training): self.in_act = V A = Vol(self.out_sx, self.out_sy, self.out_depth, 0.0) v_sx = V.sx v_sy = V.sy xy_stride = self.stride for d in xrange(self.out_depth): f = self.filters[d] x = -self.pad y = -self.pad for ay in xrange(self.out_sy): x = -self.pad for ax in xrange(self.out_sx): # convolve centered at this particular location sum_a = 0.0 for fy in xrange(f.sy): off_y = y + fy for fx in xrange(f.sx): # coordinates in the original input array coordinates off_x = x + fx if off_y >= 0 and off_y < V.sy and off_x >= 0 and off_x < V.sx: for fd in xrange(f.depth): sum_a += f.w[((f.sx * fy) + fx) * f.depth + fd] \ * V.w[((V.sx * off_y) + off_x) * V.depth + fd] sum_a += self.biases.w[d] A.set(ax, ay, d, sum_a) x += xy_stride y += xy_stride self.out_act = A return self.out_act