在python中生成随机对称张量

问题描述 投票:0回答:2

我想生成一个关于轴的所有排列对称的随机(高斯)张量。最后,我希望所有条目具有相同的分布,因此对所有排列求和并通过 sqrt(k!) 重新缩放(其中 k 是我的张量的阶数)之类的技巧不起作用。例如:

import numpy as np
from itertools import permutations

noise_buffer = np.random.normal(size=n*n*n).reshape(n,n,n)/np.sqrt(6);
noise = np.zeros([n,n,n]);
for i in permutations([0,1,2]):
    noise += np.transpose(noise_buffer,axes=list(i))

我可以遍历所有坐标(-1)并适当地重新缩放,但这很耗时。

您知道有哪个图书馆实现了这一点吗?或者你知道有什么快速实施方法吗?

python random tensorflow tensor symmetric
2个回答
1
投票

您可以使用相当简单的元素明智方法,在时间上与张量大小呈线性关系(

d^n
,避免生成所有排列的阶乘开销),这也可以直接让您选择条目分布:

import itertools
import collections
import numpy as np

def random_symmetric(d, ndim, seed=None):
    rng = np.random.default_rng(seed)
    # choose your desired distribution here
    value_store = collections.defaultdict(rng.normal)
    x = np.empty((d,) * ndim, dtype=np.float64)
    for coo in itertools.product(range(d), repeat=ndim):
        key = [0] * d
        for i in coo:
            key[i] += 1
        key = tuple(key)
        x[coo] = value_store[key]
    return x

解释一下,您只需访问每个元素及其坐标,将坐标“散列”到其各自的排列组中,然后生成或检索该排列组的随机值。例如,坐标

(0, 1, 0, 1, 2, 0, 1)
将具有键
(3, 3, 1)
,因为它有 3 个零、3 个一和 1 个二。生成的独特元素总数将为
comb(ndim + d - 1, d - 1)

x = random_symmetric(3, 12)
>1/2 百万个条目大约需要 0.3 秒。 cython/numba 版本应该非常容易适应并且可能更快。


0
投票

其实,你提出的方法是有效的;它只需要一个小小的修改。

利用正态随机变量之和是另一个正态随机变量的方差之和的事实,例如看这里

问题似乎是您希望噪声条目来自某个分布,但如果您从该分布中获取noise_buffer,那么噪声将具有不同的分布。

解决方案是对noise_buffer使用不同的分布(具体来说,正态分布,标准差减少1/sqrt(k!)),那么噪声将具有正确的分布。

© www.soinside.com 2019 - 2024. All rights reserved.