Funsors¶
基本 Funsors¶
- class Approximate(*args, **kwargs)[source]¶
基类:
Funsor
关于一组变量的解释器特定近似。
默认的 eager 解释器应该是精确的。用户接口是
Funsor.approximate()
方法。
- class Funsor(*args, **kwargs)[source]¶
基类:
object
不变函数式张量的抽象基类。
具体的派生类必须实现接受可哈希的
*args
参数且无可选**kwargs
关键字参数的__init__()
方法,以支持 cons 哈希。具有
.fresh
变量的派生类必须实现一个eager_subs()
方法。具有.bound
绑定变量的派生类必须实现一个_alpha_convert()
方法。- 参数
inputs (OrderedDict) – 从输入名称到域的映射。这可以被视为类型化上下文或从自由变量到域的映射。
output (Domain) – 一个输出域。
- property dtype¶
- property shape¶
- property requires_grad¶
- sample(sampled_vars, sample_inputs=None, rng_key=None)[source]¶
通过将
sampled_vars
的函数替换为Delta
来创建此 funsor 的 Monte Carlo 近似。结果是一个 Funsor,其
.inputs
和.output
与原始 funsor 相同(如果提供了sample_inputs
则加上),这样 self 可以在期望计算中被样本替换y = x.sample(sampled_vars) assert y.inputs == x.inputs assert y.output == x.output exact = (x.exp() * integrand).reduce(ops.add) approx = (y.exp() * integrand).reduce(ops.add)
如果提供了
sample_inputs
,这将创建一个批量样本。
- align(names)[source]¶
对齐此 funsor 以匹配给定的
names
。这主要用于准备提取funsor.tensor.Tensor
的.data
。
- eager_subs(subs)[source]¶
内部替换函数。这依赖于用户接口的
__call__()
方法将非 Funsor 强制转换为 Funsor。一旦所有输入都是 Funsor,eager_subs()
实现可以递归调用Subs
。
- class Independent(*args, **kwargs)[source]¶
基类:
Funsor
创建独立对角分布。
这等同于替换后进行归约
f = ... # a batched distribution assert f.inputs['x_i'] == Reals[4, 5] assert f.inputs['i'] == Bint[3] g = Independent(f, 'x', 'i', 'x_i') assert g.inputs['x'] == Reals[3, 4, 5] assert 'x_i' not in g.inputs assert 'i' not in g.inputs x = Variable('x', Reals[3, 4, 5]) g == f(x_i=x['i']).reduce(ops.add, 'i')
- 参数
- class Lambda(*args, **kwargs)[source]¶
基类:
Funsor
对
ops.getitem
的惰性逆操作。这对于通过将整数的高阶函数表示为数组来模拟它们很有用。
- 参数
var (Variable) – 一个要绑定的变量。
expr (funsor) – 一个 funsor。
- class Number(data, dtype=None)[source]¶
基类:
Funsor
由 Python 数字支持的 Funsor。
- 参数
data (numbers.Number) – 一个 python 数字。
dtype – 一个非负整数或字符串“real”。
- class Reduce(*args, **kwargs)[source]¶
基类:
Funsor
对多个变量进行惰性归约。
用户接口是
Funsor.reduce()
方法。- 参数
op (AssociativeOp) – 一个结合律操作符。
arg (funsor) – 要归约的参数。
reduced_vars (frozenset) – 一组用于归约的变量。
- class Scatter(*args, **kwargs)[source]¶
基类:
Funsor
对于内射 scatter 操作,这应满足方程
if destin = Scatter(op, subs, source, frozenset()) then source = Subs(destin, subs)
The
reduced_vars
is merely for computational efficiency, and could always be split out into a separate.reduce()
. For example in the following equation, the left hand side uses much less memory than the right hand sideScatter(op, subs, source, reduced_vars) == Scatter(op, subs, source, frozenset()).reduce(op, reduced_vars)
警告
这目前仅针对内射 scatter 操作实现。特别是,这不支持像 scatter-add 这样的累加行为。
注意
Scatter(ops.add, ...)
是numpy.add.at()
或torch.index_put()
或jax.lax.scatter_add()
的 funsor 对应物。对于内射替换,Scatter(ops.add, ...)
大致等价于张量操作result = zeros(...) # since zero is the additive unit result[subs] = source
- 参数
- class Subs(arg, subs)[source]¶
基类:
Funsor
形式为
x(u=y, v=z)
的惰性替换。- 参数
arg (Funsor) – 被替换的 funsor。
subs (tuple) – 一个
(name, value)
对的元组,其中name
是字符串,value
可以通过to_funsor()
强制转换为Funsor
。
- class Variable(*args, **kwargs)[source]¶
基类:
Funsor
表示单个自由变量的 Funsor。
- 参数
name (str) – 一个变量名称。
output (funsor.domains.Domain) – 一个域。
- to_data(x, name_to_dim=None, **kwargs)[source]¶
- to_data(x: Funsor, name_to_dim=None)
- to_data(x: Number, name_to_dim=None)
- to_data(x: Tensor, name_to_dim=None)
- to_data(funsor_dist: Distribution, name_to_dim=None)
- to_data(funsor_dist: Independent[Union[Independent, Distribution], str, str, str], name_to_dim=None)
- to_data(funsor_dist: Gaussian, name_to_dim=None)
- to_data(funsor_dist: Contraction[Union[LogaddexpOp, NullOp], AddOp, frozenset, Tuple[Union[Tensor, Number], Gaussian]], name_to_dim=None)
- to_data(funsor_dist: Multinomial, name_to_dim=None)
- to_data(funsor_dist: Delta, name_to_dim=None)
- to_data(expr: Unary[TransformOp, Union[Unary, Variable]], name_to_dim=None)
- to_data(x: Constant, name_to_dim=None)
从
Funsor
中提取 python 对象。如果剩余自由变量或 funsor 是惰性的,则引发
ValueError
错误。- 参数
x – 一个对象,可能是一个
Funsor
。name_to_dim (OrderedDict) – 可选的输入提示。
- 返回值
与
x
等价的非 funsor 对象。- 引发
如果剩余任何自由变量则引发 ValueError。
- 引发
如果 funsor 未完全评估则引发 PatternMissingError。
- to_funsor(x, output=None, dim_to_name=None, **kwargs)[source]¶
- to_funsor(x: Funsor, output=None, dim_to_name=None)
- to_funsor(name: str, output=None)
- to_funsor(x: Number, output=None, dim_to_name=None)
- to_funsor(s: slice, output=None, dim_to_name=None)
- to_funsor(args: tuple, output=None, dim_to_name=None)
- to_funsor(x: generic, output=None, dim_to_name=None)
- to_funsor(x: ndarray, output=None, dim_to_name=None)
- to_funsor(backend_dist: Beta, output=None, dim_to_name=None)
- to_funsor(backend_dist: Cauchy, output=None, dim_to_name=None)
- to_funsor(backend_dist: Chi2, output=None, dim_to_name=None)
- to_funsor(backend_dist: _PyroWrapper_BernoulliProbs, output=None, dim_to_name=None)
- to_funsor(backend_dist: _PyroWrapper_BernoulliLogits, output=None, dim_to_name=None)
- to_funsor(backend_dist: Binomial, output=None, dim_to_name=None)
- to_funsor(backend_dist: Categorical, output=None, dim_to_name=None)
- to_funsor(backend_dist: _PyroWrapper_CategoricalLogits, output=None, dim_to_name=None)
- to_funsor(pyro_dist: Delta, output=None, dim_to_name=None)
- to_funsor(backend_dist: Dirichlet, output=None, dim_to_name=None)
- to_funsor(backend_dist: DirichletMultinomial, output=None, dim_to_name=None)
- to_funsor(backend_dist: Exponential, output=None, dim_to_name=None)
- to_funsor(backend_dist: Gamma, output=None, dim_to_name=None)
- to_funsor(backend_dist: GammaPoisson, output=None, dim_to_name=None)
- to_funsor(backend_dist: Geometric, output=None, dim_to_name=None)
- to_funsor(backend_dist: Gumbel, output=None, dim_to_name=None)
- to_funsor(backend_dist: HalfCauchy, output=None, dim_to_name=None)
- to_funsor(backend_dist: HalfNormal, output=None, dim_to_name=None)
- to_funsor(backend_dist: Laplace, output=None, dim_to_name=None)
- to_funsor(backend_dist: Logistic, output=None, dim_to_name=None)
- to_funsor(backend_dist: LowRankMultivariateNormal, output=None, dim_to_name=None)
- to_funsor(backend_dist: Multinomial, output=None, dim_to_name=None)
- to_funsor(backend_dist: MultivariateNormal, output=None, dim_to_name=None)
- to_funsor(backend_dist: NonreparameterizedBeta, output=None, dim_to_name=None)
- to_funsor(backend_dist: NonreparameterizedDirichlet, output=None, dim_to_name=None)
- to_funsor(backend_dist: NonreparameterizedGamma, output=None, dim_to_name=None)
- to_funsor(backend_dist: NonreparameterizedNormal, output=None, dim_to_name=None)
- to_funsor(backend_dist: Normal, output=None, dim_to_name=None)
- to_funsor(backend_dist: Pareto, output=None, dim_to_name=None)
- to_funsor(backend_dist: Poisson, output=None, dim_to_name=None)
- to_funsor(backend_dist: StudentT, output=None, dim_to_name=None)
- to_funsor(backend_dist: Uniform, output=None, dim_to_name=None)
- to_funsor(backend_dist: VonMises, output=None, dim_to_name=None)
- to_funsor(backend_dist: ContinuousBernoulli, output=None, dim_to_name=None)
- to_funsor(backend_dist: FisherSnedecor, output=None, dim_to_name=None)
- to_funsor(backend_dist: NegativeBinomial, output=None, dim_to_name=None)
- to_funsor(backend_dist: OneHotCategorical, output=None, dim_to_name=None)
- to_funsor(backend_dist: RelaxedBernoulli, output=None, dim_to_name=None)
- to_funsor(backend_dist: Weibull, output=None, dim_to_name=None)
- to_funsor(tfm: Transform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(tfm: ExpTransform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(tfm: TanhTransform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(tfm: SigmoidTransform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(tfm: _InverseTransform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(tfm: ComposeTransform, output=None, dim_to_name=None, real_inputs=None)
- to_funsor(backend_dist: ExpandedDistribution, output=None, dim_to_name=None)
- to_funsor(backend_dist: Independent, output=None, dim_to_name=None)
- to_funsor(backend_dist: MaskedDistribution, output=None, dim_to_name=None)
- to_funsor(backend_dist: TransformedDistribution, output=None, dim_to_name=None)
- to_funsor(pyro_dist: Bernoulli, output=None, dim_to_name=None)
- to_funsor(x: ProvenanceTensor, output=None, dim_to_name=None)
- to_funsor(x: Tensor, output=None, dim_to_name=None)
- to_funsor(pyro_dist: FunsorDistribution, output=None, dim_to_name=None)
-
- 参数
x – 一个对象。
output (funsor.domains.Domain) – 可选的输出提示。
dim_to_name (OrderedDict) – 可选的从负批次维度到名称字符串的映射。
- 返回值
与
x
等效的 Funsor。- 返回类型
- 引发
ValueError
Delta¶
- class Delta(*args)[源代码]¶
基类:
Funsor
绑定多个变量的归一化 Delta 分布。
构建 Delta 支持以下三种语法
Delta(((name1, (point1, log_density1)), (name2, (point2, log_density2)), (name3, (point3, log_density3))))
或用于单个名称
Delta(name, point, log_density)
或用于默认
log_density == 0
Delta(name, point)
- 参数
terms (tuple) – 形式为
(name, (point, log_density))
的元组组成的元组。
Tensor¶
- Einsum(equation, *operands)[源代码]¶
用于操作实值 Funsors 的
torch.einsum()
或np.einsum()
的包装器。注意,这仅对 `output` 张量进行操作。要对命名维度执行和积收缩,请改用
+
和Reduce
。- 参数
equation (str) – 一个
torch.einsum()
或np.einsum()
方程。operands (tuple) – 输入 funsors 的元组。
- class Function(*args, **kwargs)[源代码]¶
基类:
Funsor
由原生的 PyTorch 或 NumPy 函数包装的 Funsor。
函数被假定支持广播,并且可以对具有整数类型自由变量(即批次维度)的 funsors 进行即时求值。
Function
通常通过function()
装饰器创建。
- class Tensor(data, inputs=None, dtype='real')[源代码]¶
基类:
Funsor
由 PyTorch Tensor 或 NumPy ndarray 支持的 Funsor。
这遵循
torch.distributions
的惯例,将命名的“批次”维度排列在左侧,其余“事件”维度排列在右侧。输出形状由所有剩余维度确定。例如:data = torch.zeros(5,4,3,2) x = Tensor(data, {"i": Bint[5], "j": Bint[4]}) assert x.output == Reals[3, 2]
像 `matmul` 和 `.sum()` 这样的操作符仅对输出形状进行操作,不会改变命名的输入。
- 参数
- property requires_grad¶
- align_tensor(new_inputs, x, expand=False)[源代码]¶
对张量进行排列和添加维度,以匹配期望的 `new_inputs`。
- 参数
new_inputs (OrderedDict) – 目标输入集合。
x (funsor.terms.Funsor) – 一个
Tensor
或Number
。expand (bool) – 如果为 False(默认),则将结果大小设置为 1,用于不在 `new_inputs` 中的任何 `x` 输入;如果为 True,则扩展到 `new_inputs` 大小。
- 返回值
一个数字或
torch.Tensor
或np.ndarray
,可以广播到具有给定 `new_inputs` 的其他张量。- 返回类型
int 或 float 或 torch.Tensor 或 np.ndarray
- align_tensors(*args, **kwargs)[源代码]¶
在应用广播操作之前,对多个张量进行排列。
这主要用于实现即时 funsor 操作。
- 参数
*args (funsor.terms.Funsor) – 多个
Tensor
和Number
。expand (bool) – 是否展开输入张量。默认为 False。
- 返回值
一对 `(inputs, tensors)`,其中 tensors 都是
torch.Tensor
或np.ndarray
,它们可以一起广播到具有给定 `inputs` 的单个数据。- 返回类型
- function(*signature)[源代码]¶
装饰器,用于包装 PyTorch/NumPy 函数,可以使用类型提示或显式类型注解。
示例
# Using type hints: @funsor.tensor.function def matmul(x: Reals[3, 4], y: Reals[4, 5]) -> Reals[3, 5]: return torch.matmul(x, y) # Using explicit type annotations: @funsor.tensor.function(Reals[3, 4], Reals[4, 5], Reals[3, 5]) def matmul(x, y): return torch.matmul(x, y) @funsor.tensor.function(Reals[10], Reals[10, 10], Reals[10], Real) def mvn_log_prob(loc, scale_tril, x): d = torch.distributions.MultivariateNormal(loc, scale_tril) return d.log_prob(x)
为了支持输出嵌套的张量元组的函数,请指定嵌套的输出类型 `Tuple`,例如
@funsor.tensor.function def max_and_argmax(x: Reals[8]) -> Tuple[Real, Bint[8]]: return torch.max(x, dim=-1)
- 参数
*signature – 输入域序列,后跟最终输出域或嵌套的输出域元组。
- tensordot(x, y, dims)[源代码]¶
用于操作实值 Funsors 的
torch.tensordot()
或np.tensordot()
的包装器。注意,这仅对 `output` 张量进行操作。要对命名维度执行和积收缩,请改用
+
和Reduce
。参数应满足
len(x.shape) >= dims len(y.shape) >= dims dims == 0 or x.shape[-dims:] == y.shape[:dims]
Gaussian¶
- class BlockMatrix(shape)[源代码]¶
基类:
object
与 Jit 兼容的辅助函数,用于构建分块矩阵。语法类似于
torch.zeros()
x = BlockMatrix((100, 20, 20)) x[..., 0:4, 0:4] = x11 x[..., 0:4, 6:10] = x12 x[..., 6:10, 0:4] = x12.transpose(-1, -2) x[..., 6:10, 6:10] = x22 x = x.as_tensor() assert x.shape == (100, 20, 20)
- class BlockVector(shape)[源代码]¶
基类:
object
与 Jit 兼容的辅助函数,用于构建分块向量。语法类似于
torch.zeros()
x = BlockVector((100, 20)) x[..., 0:4] = x1 x[..., 6:10] = x2 x = x.as_tensor() assert x.shape == (100, 20)
- class Gaussian(white_vec=None, prec_sqrt=None, inputs=None, *, mean=None, info_vec=None, precision=None, scale_tril=None, covariance=None)[源代码]¶
基类:
Funsor
表示批量高斯对数密度函数的 Funsor。
高斯是联合和条件多元正态分布以及多元正态似然的内部表示。从数学上讲,高斯表示二次对数密度函数
f(x) = -0.5 * || x @ prec_sqrt - white_vec ||^2 = -0.5 * < x @ prec_sqrt - white_vec | x @ prec_sqrt - white_vec > = -0.5 * < x | prec_sqrt @ prec_sqrt.T | x> + < x | prec_sqrt | white_vec > - 0.5 ||white_vec||^2
高斯内部使用平方根信息滤波器(SRIF)表示,该表示由精度矩阵 `prec_sqrt` 的平方根和白化空间中的向量 `white_vec` 组成。这种表示允许高效地构建具有不完全信息的高斯,即精度矩阵中具有零特征值。这些不完全对数密度出现在对高维隐状态进行低维观测时。采样和边缘化仅支持满秩高斯或满秩高斯子集。请参阅
rank()
和is_full_rank()
属性。注意
Gaussian
不是归一化的概率分布,而是被规范化使其在最大值处的对数密度为零:`f(prec_sqrt \ white_vec) = 0`。高斯不仅未归一化,而且可能秩亏和不可归一化,在这种情况下,采样和边缘化仅支持变量的满秩子集。- 参数
white_vec (torch.Tensor) – 批量白噪声向量,其中 `white_vec = prec_sqrt.T @ mean`。或者,您可以指定 kwargs `mean` 或 `info_vec` 中的一个,它们将被转换为 `white_vec`。
prec_sqrt (torch.Tensor) – 正半定精度矩阵的批量平方根。它不一定是方形的,通常具有形状 `prec_sqrt.shape == white_vec.shape[:-1] + (dim, rank)`,其中 `dim` 是实值输入的总展平大小,`rank = white_vec.shape[-1]`。或者,您可以指定 kwargs `precision`、`covariance` 或 `scale_tril` 中的一个,它们将被转换为 `prec_sqrt`。
inputs (OrderedDict) – 从名称到
Domain
的映射。
- compression_threshold = 2¶
- classmethod set_compression_threshold(threshold: float)[源代码]¶
用于设置秩压缩阈值的上下文管理器。
为了节省空间,高斯将宽 `prec_sqrt` 矩阵压缩成方形。然而,压缩使用了 QR 分解,这可能很昂贵,并且当结果精度矩阵秩亏时,其梯度不稳定。为了平衡空间、时间成本和数值稳定性,仅当 `prec_sqrt` 矩阵的宽度与高度之比大于 `threshold` 时,才会触发压缩。
- 参数
threshold (float) – 默认为 2。为了优化空间和确定性计算,设置 `threshold = 1`。为了优化最少的 QR 分解和数值稳定性,设置 `threshold = math.inf`。
- property rank¶
- property is_full_rank¶
Joint¶
Contraction¶
- class Contraction(*args, **kwargs)[源代码]¶
基类:
Funsor
有限和积运算的声明性表示。
通过 `normalize()` 解释进行归一化后,收缩将按类型规范化其项的顺序
Delta, Number, Tensor, Gaussian
- GaussianMixture¶
是
Contraction
的别名
积分¶
常量¶
- class Constant(const_inputs, arg)[source]¶
基类:
Funsor
相对于
const_inputs
是常量的 Funsor。Constant
可用于出处跟踪。示例
a = Constant(OrderedDict(x=Real, y=Bint[3]), Number(0)) a(y=1) # returns Constant(OrderedDict(x=Real), Number(0)) a(x=2, y=1) # returns Number(0) d = Tensor(torch.tensor([1, 2, 3]))["y"] a + d # returns Constant(OrderedDict(x=Real), d) c = Constant(OrderedDict(x=Bint[3]), Number(1)) c.reduce(ops.add, "x") # returns Number(3)
- 参数
const_inputs (dict) – 输入名称 (str) 到数据类型 (
funsor.domain.Domain
) 的映射。arg (funsor) – 一个相对于 const_inputs 是常量的 funsor。