Skip to content

data_modalities

data_modalities ¤

image_data(image_shape, region_graph='quad-graph', *, input_layer, num_input_units, sum_product_layer, num_sum_units, num_classes=1, input_params=None, sum_weight_param=None, use_mixing_weights=True) ¤

Constructs a symbolic circuit whose structure is tailored for image data sets.

Parameters:

Name Type Description Default
image_shape tuple[int, int, int]

The image shape (C, H, W), where C is the number of channels, H is the height of the images, and W is their width.

required
region_graph str

The name of the region graph to use. It can be one of the following: 'quad-tree-2' (the Quad-Tree with two splits per region node), 'quad-tree-4' (the Quad-Tree with four splits per region node), 'quad-graph' (the Quad-Graph region graph), 'random-binary-tree' (the random binary tree on flattened image pixels), 'poon-domingos' (the Poon-Domingos architecture).

'quad-graph'
input_layer str

The name of the input layer. It can be one of the following: 'categorical' (encoding a Categorical distribution over pixel channel values), 'binomial' (encoding a Binomial distribution over pixel channel values), 'embedding' (encoding an Embedding vector over pixel channel values).

required
num_input_units int

The number of input units per input layer.

required
sum_product_layer str

The name of the sum-product inner layer. It can be one of the following: 'cp' (the canonical decomposition layer, consisting of dense layers followed by a hadamard product layer), 'cpt' (the transposed canonical decomposition layer, consisting of a hadamard product layer followed by a single dense layer), 'tucker' (the Tucker decomposition layer, consisting of a kronecker product layer followed by a single dense layer).

required
num_classes int

The number of output classes (default=1).

1
num_sum_units int

The number of sum units in each sum layer, i.e., either dense or mixing layer.

required
input_params dict[str, Parameterization] | None

A dictionary mapping each name of a parameter of the input layer to its parameterization. If it is None, then the default parameterization of the chosen input layer will be chosen.

None
sum_weight_param Parameterization | None

The parameterization to use for sum layers parameters. If it None, then a softmax parameterization of the sum weights will be used.

None
use_mixing_weights bool

Whether to parameterize sum layers having arity > 1 in a way such that they compute a linear combinations of the input vectors, instead of computing a matrix-vector product where the vector is the concatenation of input vectors. Sum layers having this semantics are also sometimes referred to as "mixing" layers. Defaults to True.

True

Returns:

Name Type Description
Circuit Circuit

A symbolic circuit.

Raises:

Type Description
ValueError

If one of the arguments is not one of the specified allowed ones.

Source code in cirkit/templates/data_modalities.py
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def image_data(
    image_shape: tuple[int, int, int],
    region_graph: str = "quad-graph",
    *,
    input_layer: str,
    num_input_units: int,
    sum_product_layer: str,
    num_sum_units: int,
    num_classes: int = 1,
    input_params: dict[str, Parameterization] | None = None,
    sum_weight_param: Parameterization | None = None,
    use_mixing_weights: bool = True,
) -> Circuit:
    """Constructs a symbolic circuit whose structure is tailored for image data sets.

    Args:
        image_shape: The image shape (C, H, W), where C is the number of channels, H is the height
            of the images, and W is their width.
        region_graph: The name of the region graph to use. It can be one of the following:
            'quad-tree-2' (the Quad-Tree with two splits per region node),
            'quad-tree-4' (the Quad-Tree with four splits per region node),
            'quad-graph'  (the Quad-Graph region graph),
            'random-binary-tree' (the random binary tree on flattened image pixels),
            'poon-domingos' (the Poon-Domingos architecture).
        input_layer: The name of the input layer. It can be one of the following:
            'categorical' (encoding a Categorical distribution over pixel channel values),
            'binomial' (encoding a Binomial distribution over pixel channel values),
            'embedding' (encoding an Embedding vector over pixel channel values).
        num_input_units: The number of input units per input layer.
        sum_product_layer: The name of the sum-product inner layer. It can be one of the following:
            'cp' (the canonical decomposition layer, consisting of dense layers followed by a
            hadamard product layer), 'cpt' (the transposed canonical decomposition layer, consisting
            of a hadamard product layer followed by a single dense layer), 'tucker' (the Tucker
            decomposition layer, consisting of a kronecker product layer followed by a single dense
            layer).
        num_classes: The number of output classes (default=1).
        num_sum_units: The number of sum units in each sum layer, i.e., either dense or mixing
            layer.
        input_params: A dictionary mapping each name of a parameter of the input layer to
            its parameterization. If it is None, then the default parameterization of the chosen
            input layer will be chosen.
        sum_weight_param: The parameterization to use for sum layers parameters. If it None,
            then a softmax parameterization of the sum weights will be used.
        use_mixing_weights: Whether to parameterize sum layers having arity > 1 in a way such
            that they compute a linear combinations of the input vectors, instead of computing
            a matrix-vector product where the vector is the concatenation of input vectors.
            Sum layers having this semantics are also sometimes referred to as "mixing" layers.
            Defaults to True.

    Returns:
        Circuit: A symbolic circuit.

    Raises:
        ValueError: If one of the arguments is not one of the specified allowed ones.
    """
    if region_graph not in [
        "quad-tree-2",
        "quad-tree-4",
        "quad-graph",
        "random-binary-tree",
        "poon-domingos",
    ]:
        raise ValueError(f"Unknown region graph called {region_graph}")
    if input_layer not in ["categorical", "binomial", "embedding", "gaussian"]:
        raise ValueError(f"Unknown input layer called {input_layer}")

    # Construct the image-tailored region graph
    image_hw = (image_shape[1], image_shape[2])
    match region_graph:
        case "quad-tree-2":
            rg = QuadTree(image_hw, num_patch_splits=2)
        case "quad-tree-4":
            rg = QuadTree(image_hw, num_patch_splits=4)
        case "quad-graph":
            rg = QuadGraph(image_hw)
        case "random-binary-tree":
            rg = RandomBinaryTree(np.prod(image_hw))
        case "poon-domingos":
            delta = max(np.ceil(image_hw[0] / 8), np.ceil(image_hw[1] / 8))
            rg = PoonDomingos(image_hw, delta=delta)
        case _:
            raise ValueError(f"Unknown region graph called {region_graph}")

    # Get the input layer factory
    input_kwargs: dict[str, Any]
    match input_layer:
        case "categorical":
            input_kwargs = {"num_categories": 256}
        case "binomial":
            input_kwargs = {"total_count": 255}
        case "embedding":
            input_kwargs = {"num_states": 256}
        case "gaussian":
            input_kwargs = {}
        case _:
            assert False
    if input_params is not None:
        input_kwargs.update(
            (name + "_factory", parameterization_to_factory(param))
            for name, param in input_params.items()
        )
    input_factory = name_to_input_layer_factory(input_layer, **input_kwargs)

    # Set the sum weight factory
    if sum_weight_param is None:
        sum_weight_param = Parameterization(activation="softmax", initialization="normal")
    sum_weight_factory = parameterization_to_factory(sum_weight_param)

    # Set the nary sum weight factory
    if use_mixing_weights:
        nary_sum_weight_factory = functools.partial(
            mixing_weight_factory, param_factory=sum_weight_factory
        )
    else:
        nary_sum_weight_factory = sum_weight_factory

    # Build and return the symbolic circuit
    return rg.build_circuit(
        input_factory=input_factory,
        sum_product=sum_product_layer,
        sum_weight_factory=sum_weight_factory,
        nary_sum_weight_factory=nary_sum_weight_factory,
        num_channels=image_shape[0],
        num_input_units=num_input_units,
        num_sum_units=num_sum_units,
        num_classes=num_classes,
        factorize_multivariate=True,
    )