def _forward_grouped_convolution_xp(self, x, gy, xp): G = self.groups N, iC = x.shape[:2] oC = gy.shape[1] o_size = gy.shape[2:] o_size_prod = utils.size_of_shape(o_size) k_size = self.ksize dims = len(o_size) iCg = iC // G oCg = oC // G # Do not check iCg and oCg because this class is rarely used alone # (N, iC, k_size..., o_size...) x = conv_nd.im2col_nd(x, k_size, self.stride, self.pad, cover_all=self.cover_all, dilate=self.dilate) x = xp.rollaxis(x, 0, dims + 2) # (iC, k_size..., N, o_size...) mul_len = iCg * utils.size_of_shape(k_size) x = x.reshape(G, mul_len, N * o_size_prod) x = x.transpose(0, 2, 1) # (G, N*o_size, iCg*k_size) gy = xp.rollaxis(gy, 1) # (oC, N, o_size...) gy = gy.reshape(G, oCg, N * o_size_prod) # (G, oCg, iCg*k_size) = (G, oCg, N*o_size) @ (G, N*o_size, iCg*k_size) gW = convolution_2d._matmul(gy, x).astype(self.W_dtype, copy=False) gW = gW.reshape(oC, iCg, *k_size) return gW,
def _forward_grouped_convolution_xp(self, x, gy, xp): G = self.groups N, iC = x.shape[:2] oC = gy.shape[1] o_size = gy.shape[2:] o_size_prod = utils.size_of_shape(o_size) k_size = self.ksize dims = len(o_size) iCg = iC // G oCg = oC // G # Do not check iCg and oCg because this class is rarely used alone # (N, iC, k_size..., o_size...) x = conv_nd.im2col_nd(x, k_size, self.stride, self.pad, cover_all=self.cover_all, dilate=self.dilate) x = xp.rollaxis(x, 0, dims + 2) # (iC, k_size..., N, o_size...) mul_len = iCg * utils.size_of_shape(k_size) x = x.reshape(G, mul_len, N * o_size_prod) x = x.transpose(0, 2, 1) # (G, N*o_size, iCg*k_size) gy = xp.rollaxis(gy, 1) # (oC, N, o_size...) gy = gy.reshape(G, oCg, N * o_size_prod) # (G, oCg, iCg*k_size) = (G, oCg, N*o_size) @ (G, N*o_size, iCg*k_size) gW = convolution_2d._matmul(gy, x).astype(self.W_dtype, copy=False) gW = gW.reshape(oC, iCg, *k_size) return gW,
def check_im2col_nd(self, ksize, stride, pad, gpu): dims = self.dims if gpu: img = cuda.to_gpu(self.img) else: img = self.img col = conv_nd.im2col_nd(img, ksize, stride, pad) outs = tuple(conv_nd.get_conv_outsize(d, k, s, p) for (d, k, s, p) in zip(dims, ksize, stride, pad)) expected_shape = (2, 3) + ksize + outs self.assertEqual(col.shape, expected_shape) col = cuda.to_cpu(col) for n in moves.range(2): for c in moves.range(3): for xs in itertools.product( *[moves.range(out) for out in outs]): for dxs in itertools.product( *[moves.range(k) for k in ksize]): oxs = tuple(x * s - p + dx for (x, s, p, dx) in zip(xs, stride, pad, dxs)) if all(0 <= ox < d for (ox, d) in zip(oxs, dims)): col_index = (n, c) + dxs + xs img_index = (n, c) + oxs self.assertEqual( col[col_index], self.img[img_index]) else: col_index = (n, c) + dxs + xs self.assertEqual(col[col_index], 0)
def check_im2col_nd(self, ksize, stride, pad, gpu): dims = self.dims if gpu: img = cuda.to_gpu(self.img) else: img = self.img col = conv_nd.im2col_nd(img, ksize, stride, pad) outs = tuple(conv_nd.get_conv_outsize(d, k, s, p) for (d, k, s, p) in zip(dims, ksize, stride, pad)) expected_shape = (2, 3) + ksize + outs self.assertEqual(col.shape, expected_shape) col = cuda.to_cpu(col) for n in moves.range(2): for c in moves.range(3): for xs in itertools.product( *[moves.range(out) for out in outs]): for dxs in itertools.product( *[moves.range(k) for k in ksize]): oxs = tuple(x * s - p + dx for (x, s, p, dx) in zip(xs, stride, pad, dxs)) if all(0 <= ox < d for (ox, d) in zip(oxs, dims)): col_index = (n, c) + dxs + xs img_index = (n, c) + oxs self.assertEqual( col[col_index], self.img[img_index]) else: col_index = (n, c) + dxs + xs self.assertEqual(col[col_index], 0)
def divide_img(x, grid_size=32): b, c, x1, x2, x3 = x.shape kersize = grid_size # kernel size ssize = int(grid_size * 0.5) # stride size gl0 = int(x1 / ssize - 1) # grid length gl1 = int(x2 / ssize - 1) gl2 = int(x3 / ssize - 1) if type(x) == chainer.variable.Variable: h = im2col_nd(x.data, ksize=(kersize, kersize, kersize), stride=(ssize, ssize, ssize), pad=(0, 0, 0)) else: h = im2col_nd(x, ksize=(kersize, kersize, kersize), stride=(ssize, ssize, ssize), pad=(0, 0, 0)) h = F.reshape(h, (1, 4, kersize, kersize, kersize, gl0 * gl1 * gl2)) h = F.transpose(h, axes=(5, 1, 2, 3, 4, 0)) h = F.reshape(h, (gl0 * gl1 * gl2, 4, kersize, kersize, kersize)) return h
def _forward_grouped_convolution_xp(self, x, W, b, xp): # G: group count # N: batch size # iC: input channels # oC: output channels G = self.groups N, iC = x.shape[:2] oC = W.shape[0] k_size = W.shape[2:] iCg = iC // G oCg = oC // G dims = len(k_size) if iC % G != 0: raise TypeError('The number of groups must be ' 'a divisor of that of input channels') if oC % G != 0: raise TypeError('The number of groups must be ' 'a divisor of that of output channels') xp = backend.get_array_module(x) # (N, iC, k_size..., o_size...) x = conv_nd.im2col_nd(x, k_size, self.stride, self.pad, cover_all=self.cover_all, dilate=self.dilate) o_size = x.shape[-dims:] x = xp.rollaxis(x, 0, dims + 2) # (iC, k_size..., N, o_size...) mul_len = iCg * utils.size_of_shape(k_size) x = x.reshape(G, mul_len, N * utils.size_of_shape(o_size)) W = W.reshape(G, oCg, mul_len) # (G, oCg, N*o_size) = (G, oCg, iCg*k_size) @ (G, iCg*k_size, N*o_size) y = convolution_2d._matmul(W, x).astype(x.dtype, copy=False) y = y.reshape(oC, N, *o_size) y = xp.rollaxis(y, 1) # (N, oC, o_size...) if b is not None: y += b.reshape(1, b.size, *((1, ) * dims)) return y,
def _forward_grouped_convolution_xp(self, x, W, b, xp): # G: group count # N: batch size # iC: input channels # oC: output channels G = self.groups N, iC = x.shape[:2] oC = W.shape[0] k_size = W.shape[2:] iCg = iC // G oCg = oC // G dims = len(k_size) if iC % G != 0: raise TypeError('The number of groups must be ' 'a divisor of that of input channels') if oC % G != 0: raise TypeError('The number of groups must be ' 'a divisor of that of output channels') xp = backend.get_array_module(x) # (N, iC, k_size..., o_size...) x = conv_nd.im2col_nd(x, k_size, self.stride, self.pad, cover_all=self.cover_all, dilate=self.dilate) o_size = x.shape[-dims:] x = xp.rollaxis(x, 0, dims + 2) # (iC, k_size..., N, o_size...) mul_len = iCg * utils.size_of_shape(k_size) x = x.reshape(G, mul_len, N * utils.size_of_shape(o_size)) W = W.reshape(G, oCg, mul_len) # (G, oCg, N*o_size) = (G, oCg, iCg*k_size) @ (G, iCg*k_size, N*o_size) y = convolution_2d._matmul(W, x).astype(x.dtype, copy=False) y = y.reshape(oC, N, *o_size) y = xp.rollaxis(y, 1) # (N, oC, o_size...) if b is not None: y += b.reshape(1, b.size, *((1,) * dims)) return y,