コード例 #1
0
 def infer_shape(self, fgraph, node, in_shapes):
     shape_a = in_shapes[0]
     n = node.inputs[1]
     axis = node.inputs[2]
     if len(shape_a) == 1:
         return [(n, )]
     elif isinstance(axis, TensorConstant):
         out_shape = (list(shape_a[0:axis.data.item()]) + [n] +
                      list(shape_a[axis.data + 1:]))
     else:
         l = len(shape_a)
         shape_a = stack(shape_a)
         out_shape = concatenate((shape_a[0:axis], [n], shape_a[axis + 1:]))
         n_splits = [1] * l
         out_shape = split(out_shape, n_splits, l)
         out_shape = [a[0] for a in out_shape]
     return [out_shape]
コード例 #2
0
def kron(a, b):
    """Kronecker product.

    Same as scipy.linalg.kron(a, b).

    Parameters
    ----------
    a: array_like
    b: array_like

    Returns
    -------
    array_like with a.ndim + b.ndim - 2 dimensions

    Notes
    -----
    numpy.kron(a, b) != scipy.linalg.kron(a, b)!
    They don't have the same shape and order when
    a.ndim != b.ndim != 2.

    """
    a = as_tensor_variable(a)
    b = as_tensor_variable(b)
    if a.ndim + b.ndim <= 2:
        raise TypeError(
            "kron: inputs dimensions must sum to 3 or more. "
            f"You passed {int(a.ndim)} and {int(b.ndim)}."
        )
    o = atm.outer(a, b)
    o = o.reshape(at.concatenate((a.shape, b.shape)), a.ndim + b.ndim)
    shf = o.dimshuffle(0, 2, 1, *list(range(3, o.ndim)))
    if shf.ndim == 3:
        shf = o.dimshuffle(1, 0, 2)
        o = shf.flatten()
    else:
        o = shf.reshape(
            (o.shape[0] * o.shape[2], o.shape[1] * o.shape[3])
            + tuple(o.shape[i] for i in range(4, o.ndim))
        )
    return o
コード例 #3
0
def neibs2images(neibs, neib_shape, original_shape, mode="valid"):
    """
    Function :func:`neibs2images <aesara.sandbox.neighbours.neibs2images>`
    performs the inverse operation of
    :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`. It inputs
    the output of :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`
    and reconstructs its input.

    Parameters
    ----------
    neibs : 2d tensor
        Like the one obtained by
        :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`.
    neib_shape
        `neib_shape` that was used in
        :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`.
    original_shape
        Original shape of the 4d tensor given to
        :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`

    Returns
    -------
    object
        Reconstructs the input of
        :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`,
        a 4d tensor of shape `original_shape`.

    Notes
    -----
    Currently, the function doesn't support tensors created with
    `neib_step` different from default value. This means that it may be
    impossible to compute the gradient of a variable gained by
    :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>` w.r.t.
    its inputs in this case, because it uses
    :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>` for
    gradient computation.

    Examples
    --------
    Example, which uses a tensor gained in example for
    :func:`images2neibs <aesara.sandbox.neighbours.neibs2images>`:

    .. code-block:: python

        im_new = neibs2images(neibs, (5, 5), im_val.shape)
        # Aesara function definition
        inv_window = aesara.function([neibs], im_new)
        # Function application
        im_new_val = inv_window(neibs_val)

    .. note:: The code will output the initial image array.

    """
    neibs = as_tensor_variable(neibs)
    neib_shape = as_tensor_variable(neib_shape)
    original_shape = as_tensor_variable(original_shape)

    new_neib_shape = stack(
        [original_shape[-1] // neib_shape[1], neib_shape[1]])
    output_2d = images2neibs(neibs.dimshuffle("x", "x", 0, 1),
                             new_neib_shape,
                             mode=mode)

    if mode == "ignore_borders":
        # We use set_subtensor to accept original_shape we can't infer
        # the shape and still raise error when it don't have the right
        # shape.
        valid_shape = original_shape
        valid_shape = set_subtensor(
            valid_shape[2], (valid_shape[2] // neib_shape[0]) * neib_shape[0])
        valid_shape = set_subtensor(
            valid_shape[3], (valid_shape[3] // neib_shape[1]) * neib_shape[1])
        output_4d = output_2d.reshape(valid_shape, ndim=4)
        # padding the borders with zeros
        for d in (2, 3):
            pad_shape = list(output_4d.shape)
            pad_shape[d] = original_shape[d] - valid_shape[d]
            output_4d = concatenate([output_4d, zeros(pad_shape)], axis=d)
    elif mode == "valid":
        # TODO: we do not implement all mode with this code.
        # Add a check for the good cases.
        output_4d = output_2d.reshape(original_shape, ndim=4)
    else:
        raise NotImplementedError(f"neibs2images do not support mode={mode}")

    return output_4d
コード例 #4
0
 def _grad_helper(z):
     pre = aet.concatenate([[0.0], z])
     app = aet.concatenate([z, [0.0]])
     return pre - app