def backward(self, indices, grad_outputs):
        xvar, Wvar = self.get_retained_inputs()
        x = xvar.data
        W = Wvar.data
        gyvar, = grad_outputs
        gy = gyvar.data
        xp = backend.get_array_module(x, W)
        stride_row, stride_col = self.sy, self.sx
        output_row, output_col = W.shape[1], W.shape[2]
        ret = []
        if 0 in indices:
            gx = xp.zeros_like(x)
            for i in moves.range(output_row):
                for j in moves.range(output_col):
                    slice_row = slice(i * stride_row,
                                      i * stride_row + W.shape[4])
                    slice_col = slice(j * stride_col,
                                      j * stride_col + W.shape[5])
                    # ochans * ichans * krows * kcols
                    W_slice = W[:, i, j, ...]
                    # nsamps * ochans
                    gy_slice = gy[..., i, j]
                    # -> nsamps * ichans * krows * kcols
                    gx[:, :, slice_row,
                       slice_col] += xp.tensordot(gy_slice,
                                                  W_slice,
                                                  axes=[(1, ), (0, )])
            ret.append(
                chainer.functions.cast(variable.as_variable(gx), x.dtype))
        if 1 in indices:
            gW = xp.empty_like(W)
            for i in moves.range(output_row):
                for j in moves.range(output_col):
                    slice_row = slice(i * stride_row,
                                      i * stride_row + W.shape[4])
                    slice_col = slice(j * stride_col,
                                      j * stride_col + W.shape[5])
                    # nsamps * inchans * krows * kcols
                    x_slice = x[:, :, slice_row, slice_col]
                    # nsamps * outchans * 1 * 1
                    gy_slice = gy[:, :, i, j]
                    gW[:, i, j, :, :, :] = xp.tensordot(gy_slice,
                                                        x_slice,
                                                        axes=[(0, ), (0, )])
            ret.append(
                chainer.functions.cast(variable.as_variable(gW), W.dtype))
        if 2 in indices:
            gb = chainer.functions.sum(gyvar, axis=0)
            ret.append(gb)

        return ret
    def backward(self, indices, grad_outputs):
        xvar, Wvar = self.get_retained_inputs()
        x = xvar.data
        W = Wvar.data
        gyvar, = grad_outputs
        gy = gyvar.data
        xp = backend.get_array_module(x, W)
        stride_row, stride_col = self.sy, self.sx
        output_row, output_col = W.shape[1], W.shape[2]
        ret = []
        if 0 in indices:
            gx = xp.zeros_like(x)
            for i in moves.range(output_row):
                for j in moves.range(output_col):
                    slice_row = slice(i * stride_row,
                                      i * stride_row + W.shape[4])
                    slice_col = slice(j * stride_col,
                                      j * stride_col + W.shape[5])
                    # ochans * ichans * krows * kcols
                    W_slice = W[:, i, j, ...]
                    # nsamps * ochans
                    gy_slice = gy[..., i, j]
                    # -> nsamps * ichans * krows * kcols
                    gx[:, :, slice_row, slice_col] += xp.tensordot(
                        gy_slice, W_slice, axes=[(1,), (0,)]
                    )
            ret.append(chainer.functions.cast(variable.as_variable(gx),
                                              x.dtype))
        if 1 in indices:
            gW = xp.empty_like(W)
            for i in moves.range(output_row):
                for j in moves.range(output_col):
                    slice_row = slice(i * stride_row,
                                      i * stride_row + W.shape[4])
                    slice_col = slice(j * stride_col,
                                      j * stride_col + W.shape[5])
                    # nsamps * inchans * krows * kcols
                    x_slice = x[:, :, slice_row, slice_col]
                    # nsamps * outchans * 1 * 1
                    gy_slice = gy[:, :, i, j]
                    gW[:, i, j, :, :, :] = xp.tensordot(
                        gy_slice, x_slice, axes=[(0,), (0,)]
                    )
            ret.append(chainer.functions.cast(variable.as_variable(gW),
                                              W.dtype))
        if 2 in indices:
            gb = chainer.functions.sum(gyvar, axis=0)
            ret.append(gb)

        return ret
Exemple #3
0
    def backward(self, indexes, grad_outputs):
        if self.grad is None:
            grad = (self.xp.ones(self.input_shape, self.input_dtype), )
        else:
            grad = self.grad

        return tuple(None if g is None else variable.as_variable(g)
                     for g in grad)
Exemple #4
0
    def backward(self, inputs, grad_outputs):
        grad = self.grad

        return tuple(None if g is None else variable.as_variable(g)
                     for g in grad)
Exemple #5
0
    def backward(self, inputs, grad_outputs):
        grad = self.grad

        return tuple(
            None if g is None else variable.as_variable(g)
            for g in grad)