def _oper_cpu(cls, x, in_shape, out_shape, karnel, stride, padding): col = im2col(x, out_shape[1:], karnel, stride, padding) n, ic, kh, kw, oh, ow = col.shape col = col.reshape(n, ic, kh * kw, oh, ow) value = np.mean(col, axis=2) ret = cls._create_node(value) ret.attrs._x = x ret.attrs._in_shape = in_shape ret.attrs._out_shape = out_shape ret.attrs._kernel = karnel ret.attrs._stride = stride ret.attrs._padding = padding return ret
def _backward_cpu(self, context, dy, **kwargs): col = im2col(dy, self.attrs._in_shape[1:], self.attrs._kernel, self.attrs._stride, self.attrs._padding) if isinstance(self.attrs._x, Node): dx = np.tensordot(col, self.attrs._w, ([1, 2, 3], [1, 2, 3])) dx = np.rollaxis(dx, 3, 1) self.attrs._x._update_diff(context, dx, **kwargs) if isinstance(self.attrs._w, Node): self.attrs._w._update_diff(context, np.tensordot( self.attrs._x, col, ([0, 2, 3], [0, 4, 5])), **kwargs) if isinstance(self.attrs._b, Node): self.attrs._b._update_diff(context, np.sum(dy, (0, 2, 3), keepdims=True), **kwargs)
def _oper_cpu(cls, x, w, b, in_shape, out_shape, kernel, stride, padding): col = im2col(to_value(x), out_shape[1:], kernel, stride, padding) value = np.rollaxis( np.tensordot(col, to_value(w), ([1, 2, 3], [1, 2, 3])), 3, 1) if b is not None: value += b ret = cls._create_node(value) ret.attrs._col = col ret.attrs._x = x ret.attrs._w = w ret.attrs._b = b ret.attrs._in_shape = in_shape ret.attrs._out_shape = out_shape ret.attrs._kernel = kernel ret.attrs._stride = stride ret.attrs._padding = padding return ret
def _oper_cpu(cls, x, w, b, in_shape, out_shape, kernel, stride, padding, dilation, groups): N, in_channels, in_h, in_w = x.shape k_h, k_w = kernel out_channels = w.shape[0] iCg = in_channels // groups oCg = out_channels // groups col = im2col(to_value(x), out_shape[1:], kernel, stride, padding, dilation) out_h, out_w = col.shape[-2:] col = col.transpose(1, 2, 3, 0, 4, 5) col = col.reshape(groups, iCg * k_h * k_w, N * out_h * out_w) w_new = w.reshape(groups, oCg, iCg * k_h * k_w) value = np.matmul(to_value(w_new), col) value = value.reshape(groups * oCg, N, out_h, out_w) value = value.transpose(1, 0, 2, 3) if b is not None: value += b.reshape(1, b.size, 1, 1) ret = cls._create_node(value) ret.attrs._col = col ret.attrs._x = x ret.attrs._w = w ret.attrs._b = b ret.attrs._in_shape = in_shape ret.attrs._out_shape = out_shape ret.attrs._kernel = kernel ret.attrs._stride = stride ret.attrs._padding = padding ret.attrs._dilation = dilation ret.attrs._groups = groups ret.attrs._iCg = iCg ret.attrs._oCg = oCg return ret