WithStackedVariables¶
Context inside of which each Random Draw node behaves like a stack of N independent draws, indexed by a subscript, and where each draw appears stacked along a new axis.
This is analogous to a "plate" context in graphical models (see also URL at bottom), wherein each random variable inside the plate area behaves like a stack of N subscripted variables that are conditionally independent (conditional on the parameters of the distribution). This is an alternative to relying on the replicated axis being present in either the like input of Random Draw nodes or in parameters of the underlying distributions. While the latter have the same effect of causing the draw to be "batched" or broadcast across the additional axis, the plate notation can be more explicit and make the model easier to interpret or follow. Which form is preferable depends on the specific use case: plates are very useful for implementing published models that often come already specified in plate notation, while the implicit approach can result in a more compact graph with fewer nodes or interactions. The node is configured by specifying an axis type for the new axis (which can also have a label) and a repeat count that is either given as an integer, or one may pass data into the node's like input, whose length along the given axis is used as the count (the latter is preferred when the data has the desired axis, which is often the case). An important feature of this node is that it optionally allows for random subsampling of the index range (along the axis) during the inference, analogous to "mini-batch" updates in stochastic gradient descent. This can greatly speed up inference when the index range is large as with long time series or many data instances, but it can also introduce noise (variance) into the inference. The batch size is specified via the "subsample to" argument. When concrete data (independent or dependent variables) enters the plate context and interacts with random draws therein, the subsampling has to be applied to the data, along the correct axis; this is conveniently done using the At Subscripts node, which automatically detects the enclosing plate contexts and applies the correct index to the right axes of the data. For this reason it is recommended to use the At Subscripts node whenever subsampling is used, and for this to work the node needs to be downstream of the placeholder that receives the subscript (from the innermost plate context if nesting is used), usually via an update-update edge. The manual alternative to this is to use a Select Range node that has the subscript Placeholder wired into its selection range input, and which has the correct axis set (and to do that separately for each applicable nesting level), but this is more error-prone and less convenient. See also the documentation for the "plate body [subscript name]" setting in the node for more intuition on structuring the portion of the graph that shall be nested inside the plate. The user may notice that the presence of a With Stacked Variables node will cause the affected axis to move into a specific position in the output of each contained Random Draw. This is not an error but a side effect of the underlying implementation, where each such context uses a different dimension index. The index can also be overridden via the "stacking dimension" argument, but this is difficult to use correctly by hand since it is relative to the event space dimensions of each random variable (e.g., multivariate normal or certain discrete distributions). It is possible to use plates, random draws, distributions, and at subscript without axes (i.e., using plain arrays for everything), in which case guarantees that axes will be lined up correctly do not apply and the user needs to pre-plan the shapes of all arrays and distributions and work through the respective broadcasting semantics (there is an article on "How Dimensions get Managed by the With Stacked Variables Node, Distributions, and Random Draws" with further details on this use case). This is however not a recommended path since it is extremely error-prone and quite difficult to debug for all but the simplest model. More Info... Version 0.9.1
Ports/Properties¶
like¶
Data whose axis should be indexed by the plate.
- verbose name: Like
- default value: None
- port type: DataPort
- value type: AnyNumeric (can be None)
- data direction: IN
body¶
Plate body.
- verbose name: Plate Body
- default value: None
- port type: GraphPort
- value type: Graph
body__signature¶
Name of the index variable (subscript) passed to the plate body. The usage of this node is somewhat analogous to how one would use a For Each loop node, where there is a loop body that is to be repeated N times, and which begins with a Placeholder node that receives the loop variable (e..g, i). Then any nodes downstream of this placeholder implicitly becomes part of the loop body and will be evaluated N times (in parallel), and the result of the body (final node's output) is wired back into the "body" input of the loop node. That node then outputs the results stacked along a new array axis.
The fully accurate mental model is that any Random Draw nodes that are directly or indirectly downstream of this placeholder (e.g., connected to it via an update-update edge) behave as if each of them was really a stack of N independent copies of the random draw, as suggested by the node icon. These operations are vectorized and it still the same random draw node that now simply returns an array with an extra axis of length N of a specified position and type (and can also accept arrays with an axis of this type). This makes the plate a "batching" context that is used to model an array of (conditionally) independent random draws. This context only directly affects a small set of Bayesian nodes, including Random Draw, At Subscript, and Optimizable Parameter -- but note that the batched nature of data carries forward through any subsequent array operations, so that the entire computation downstream of the batched draws also tends to becomes batched. By (shift+)control clicking on the edge going into the "plate body" port of the node (which shows in dotted style in UIs) one can see the full set of nodes that are formally part of the plate context (and nested contexts therein).
See main documentation of this node for additional background and the At Subscripts node on how to handle concrete data (independent or dependent variables) that need to interact with any of the batched random variables.
- verbose name: Plate Body [Subscript Name]
- default value: (i)
- port type: Port
- value type: object (can be None)
values¶
Stacked results of the random draws.
- verbose name: Values
- default value: None
- port type: DataPort
- value type: object (can be None)
- data direction: OUT
is_training¶
Whether we're in a training context.
- verbose name: Is Training
- default value: None
- port type: DataPort
- value type: bool (can be None)
- data direction: INOUT
axis¶
Named axis to which the subscript and plate indexing applies. This uniquely associates the replicated dimension of the plate with a named axis of the given type in all data and any distribution or random draw node that interacts with the plate context. This in turn guarantees that axes line up correctly between observable data, distribution parameters, and the new dimension introduced by the plate. When using the At Subscripts node, this also ensures that the data is correctly subsampled along this axis. This can be left unspecified when the node is used with plain arrays, but then it is the user's responsibility to ensure consistent axis alignment across all nodes in the plate context (in such cases it can also help to override the stacking dimension argument to achieve the desired shape of the randomly drawn arrays, which is otherwise not necessary).
- verbose name: Data Axis
- default value: unspecified
- port type: ComboPort
- value type: str (can be None)
count¶
Number of times the random variables will be replicated. If this value is not specified, some data must be wired into the "like" input, and an axis must be specified; the length of the data along that axis is then used as the count. Random draws occurring in the stacked body will be independently replicated this many times, conceptually yielding N subscripted instances of the random variable. This is also the length of the resulting outcome array(s) along the stacked axis.
- verbose name: Repeat Count
- default value: None
- port type: IntPort
- value type: int (can be None)
stack_dim¶
The array dimension index along which the outcome array(s) returned by any Random Draw nodes will be stacked. This option is mainly for use with statistical models that are formulated in terms of plain arrays, where the axes are not explicitly named, but note that this is an error-prone way to work with statistical models and not a recommended workflow. When working with plain arrays it is relatively easy to end up with shape conflicts between dimensions that the plates allocate, that the observed data has, and that the distributions were parameterized with or generate, or that the random draw was parameterized with (via its shape argument); in such cases this parameter allows for fine tuning of which exact dimension offsets (relative to the event space dimensions of each random draw) will be used for stacking by this plate. For additional technical details on the internal default behavior (when this is not specified), see the document on "How Dimensions get Managed by the With Stacked Variables Node, Distributions, and Random Draws".
- verbose name: Stacking Dimension
- default value: None
- port type: IntPort
- value type: int (can be None)
subsample_to¶
Batch size to which to subsample the indices along the plate dimension to speed up inference. This is useful for very large collections of indexed variables, where subsampling is analogous to mini-batch updates in stochastic inference or deep learning. However, note that this can introduce noise (i.e., additional posterior variance) into the inference process depending on the specifics of the inference algorithm. When using subsampling, any data that interacts with any random draws in the plate context must also be subsampled along the correct axis, which is conveniently done using the At Subscripts node (see node for more details).
- verbose name: Subsample To
- default value: None
- port type: IntPort
- value type: int (can be None)
no_subsample_when_predicting¶
Whether to disable subsampling at prediction time. This is typically desirable since otherwise only a random subset of the data would be used for prediction.
- verbose name: No Subsample When Predicting
- default value: True
- port type: BoolPort
- value type: bool (can be None)
set_breakpoint¶
Set a breakpoint on this node. If this is enabled, your debugger (if one is attached) will trigger a breakpoint.
- verbose name: Set Breakpoint (Debug Only)
- default value: False
- port type: BoolPort
- value type: bool (can be None)
metadata¶
User-definable meta-data associated with the node. Usually reserved for technical purposes.
- verbose name: Metadata
- default value: {}
- port type: DictPort
- value type: dict (can be None)