Exemplo n.º 1
0
def conditional_affine_autoregressive(input_dim,
                                      context_dim,
                                      hidden_dims=None,
                                      **kwargs):
    """
    A helper function to create an
    :class:`~pyro.distributions.transforms.ConditionalAffineAutoregressive` object
    that takes care of constructing a dense network with the correct input/output
    dimensions.

    :param input_dim: Dimension of input variable
    :type input_dim: int
    :param context_dim: Dimension of context variable
    :type context_dim: int
    :param hidden_dims: The desired hidden dimensions of the dense network. Defaults
        to using [10*input_dim]
    :type hidden_dims: list[int]
    :param log_scale_min_clip: The minimum value for clipping the log(scale) from
        the autoregressive NN
    :type log_scale_min_clip: float
    :param log_scale_max_clip: The maximum value for clipping the log(scale) from
        the autoregressive NN
    :type log_scale_max_clip: float
    :param sigmoid_bias: A term to add the logit of the input when using the stable
        tranform.
    :type sigmoid_bias: float
    :param stable: When true, uses the alternative "stable" version of the transform
        (see above).
    :type stable: bool

    """
    if hidden_dims is None:
        hidden_dims = [10 * input_dim]
    nn = ConditionalAutoRegressiveNN(input_dim, context_dim, hidden_dims)
    return ConditionalAffineAutoregressive(nn, **kwargs)
Exemplo n.º 2
0
    def __init__(self, input_dim, context_dim, hidden_dims,
                 activation=nn.ELU(), iaf_parametrization=False):
        super(MAF, self).__init__()
        self.arn = ConditionalAutoRegressiveNN(
            input_dim,
            context_dim,
            hidden_dims,
            nonlinearity=activation,
            skip_connections=False,
        )

        # This is a bit of a hack: it registers the perturbation attribute of
        # the ConditionalAutoregressiveNN as a buffer, so that it will be saved
        # when state_dict() is called. We call permutation explicitly below, so
        # this quantity needs to be saved.
        #
        # A less hacky approach would be to save each permutation as a
        # hyperparameter and then pass at build time. This is quicker though.

        perm = self.arn.permutation.clone().detach()
        del self.arn.permutation
        self.arn.register_buffer('permutation', perm)

        self.iaf_parametrization = iaf_parametrization
        self.initial_bias = 1.0
Exemplo n.º 3
0
    def _test_jacobian(self, input_dim, observed_dim, hidden_dim, param_dim):
        jacobian = torch.zeros(input_dim, input_dim)
        if observed_dim > 0:
            arn = ConditionalAutoRegressiveNN(input_dim, observed_dim, [hidden_dim], param_dims=[param_dim])
        else:
            arn = AutoRegressiveNN(input_dim, [hidden_dim], param_dims=[param_dim])

        def nonzero(x):
            return torch.sign(torch.abs(x))

        x = torch.randn(1, input_dim)
        y = torch.randn(1, observed_dim)

        for output_index in range(param_dim):
            for j in range(input_dim):
                for k in range(input_dim):
                    epsilon_vector = torch.zeros(1, input_dim)
                    epsilon_vector[0, j] = self.epsilon
                    if observed_dim > 0:
                        delta = (arn(x + 0.5 * epsilon_vector, y) - arn(x - 0.5 * epsilon_vector, y)) / self.epsilon
                    else:
                        delta = (arn(x + 0.5 * epsilon_vector) - arn(x - 0.5 * epsilon_vector)) / self.epsilon
                    jacobian[j, k] = float(delta[0, output_index, k])

            permutation = arn.get_permutation()
            permuted_jacobian = jacobian.clone()
            for j in range(input_dim):
                for k in range(input_dim):
                    permuted_jacobian[j, k] = jacobian[permutation[j], permutation[k]]

            lower_sum = torch.sum(torch.tril(nonzero(permuted_jacobian), diagonal=0))

            assert lower_sum == float(0.0)
 def loadConditionalIAFFlows(self,
                             num_iafs,
                             context_dims,
                             z_dim=100,
                             iaf_dim=320):
     ar = ConditionalAutoRegressiveNN(z_dim, context_dims,
                                      [iaf_dim, iaf_dim])
     flow_fn = lambda: CondInverseAutoregressiveFlowStable(ar)
     self.use_cond_flow = True
     self.loadFlows(num_iafs, flow_fn)
Exemplo n.º 5
0
def conditional_spline_autoregressive(input_dim,
                                      context_dim,
                                      hidden_dims=None,
                                      count_bins=8,
                                      bound=3.0,
                                      order="linear"):
    r"""
    A helper function to create a
    :class:`~pyro.distributions.transforms.ConditionalSplineAutoregressive` object
    that takes care of constructing an autoregressive network with the correct
    input/output dimensions.

    :param input_dim: Dimension of input variable
    :type input_dim: int
    :param context_dim: Dimension of context variable
    :type context_dim: int
    :param hidden_dims: The desired hidden dimensions of the autoregressive network.
        Defaults to using [input_dim * 10, input_dim * 10]
    :type hidden_dims: list[int]
    :param count_bins: The number of segments comprising the spline.
    :type count_bins: int
    :param bound: The quantity :math:`K` determining the bounding box,
        :math:`[-K,K]\times[-K,K]`, of the spline.
    :type bound: float
    :param order: One of ['linear', 'quadratic'] specifying the order of the spline.
    :type order: string

    """

    if hidden_dims is None:
        hidden_dims = [input_dim * 10, input_dim * 10]

    param_dims = [count_bins, count_bins, count_bins - 1, count_bins]
    arn = ConditionalAutoRegressiveNN(input_dim,
                                      context_dim,
                                      hidden_dims,
                                      param_dims=param_dims)
    return ConditionalSplineAutoregressive(input_dim,
                                           arn,
                                           count_bins=count_bins,
                                           bound=bound,
                                           order=order)
Exemplo n.º 6
0
def conditional_neural_autoregressive(input_dim,
                                      context_dim,
                                      hidden_dims=None,
                                      activation='sigmoid',
                                      width=16):
    """
    A helper function to create a
    :class:`~pyro.distributions.transforms.ConditionalNeuralAutoregressive` object
    that takes care of constructing an autoregressive network with the correct
    input/output dimensions.

    :param input_dim: Dimension of input variable
    :type input_dim: int
    :param context_dim: Dimension of context variable
    :type context_dim: int
    :param hidden_dims: The desired hidden dimensions of the autoregressive network.
        Defaults to using [3*input_dim + 1]
    :type hidden_dims: list[int]
    :param activation: Activation function to use. One of 'ELU', 'LeakyReLU',
        'sigmoid', or 'tanh'.
    :type activation: string
    :param width: The width of the "multilayer perceptron" in the transform (see
        paper). Defaults to 16
    :type width: int

    """

    if hidden_dims is None:
        hidden_dims = [3 * input_dim + 1]
    arn = ConditionalAutoRegressiveNN(input_dim,
                                      context_dim,
                                      hidden_dims,
                                      param_dims=[width] * 3)
    return ConditionalNeuralAutoregressive(arn,
                                           hidden_units=width,
                                           activation=activation)