• PyTorch随机生成一个布尔型张量


    一、 50 % 50\% 50% 概率

    先考虑一个最简单的情形,即生成的布尔型张量中,每个元素等于 True 的概率都为 50 % 50\% 50%

    思路很简单,我们只需创建两个形状相同的整型张量,里面的元素非 0 0 0 1 1 1,然后判断它们是否相等:

    def randbool(*size):
        return torch.randint(2, size) == torch.randint(2, size)
    
    • 1
    • 2

    例如:

    print(randbool(3, 3))
    # tensor([[False, False, False],
    #         [False,  True,  True],
    #         [ True, False,  True]])
    
    • 1
    • 2
    • 3
    • 4

    这是因为,对于每一个元素,它在第一个张量中的取值只有两种可能: 0 0 0 1 1 1,在第二个张量中的取值也只有两种可能: 0 0 0 1 1 1,因此共有四种情形:

    0 = = 0 ⇒    True 0 = = 1 ⇒    False 1 = = 0 ⇒    False 1 = = 1 ⇒    True 0==0True0==1False1==0False1==1True

    0==00==11==01==1TrueFalseFalseTrue

    可以看出 True 的概率为 2 / 4 = 0.5 2/4=0.5 2/4=0.5

    我们还可以通过程序来验证 True 的概率:

    s = 0
    for i in range(10 ** 5):
        s += randbool(4, 4).sum().item()
    s = s / 10 ** 5
    print(s / 16)
    # 0.499908125
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    将其封装成函数便于之后使用

    def true_prob(fun):
        s = 0
        for i in range(10 ** 6):
            s += fun(10, 10).sum().item()
        return s / 10 ** 8
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、 1 / 3 1/3 1/3 概率

    再来考虑一个也比较简单的情形,即生成的布尔型张量中,每个元素等于 True 的概率都为 1 / 3 1/3 1/3

    假设对于每一个元素,它在第一个张量中的取值只有两种可能: 0 , 1 0,1 0,1,但在第二个张量中的取值有三种可能: 0 , 1 , 2 0,1,2 0,1,2,因此共有六种情形:

    0 = = 0 ⇒    True 0 = = 1 ⇒    False 0 = = 2 ⇒    False 1 = = 0 ⇒    False 1 = = 1 ⇒    True 1 = = 2 ⇒    False 0==0True0==1False0==2False1==0False1==1True1==2False

    0==00==10==21==01==11==2TrueFalseFalseFalseTrueFalse

    可以看出 True 的概率为 2 / 6 = 1 / 3 2/6=1/3 2/6=1/3

    代码实现如下:

    def randbool(*size):
        return torch.randint(2, size) == torch.randint(3, size)
    
    • 1
    • 2

    验证:

    print(true_prob(randbool))
    # 0.33325818
    
    • 1
    • 2

    三、任意概率

    有没有可能指定 True 的概率为任意概率 p p p 呢?

    答案是可以的,不过我们先来解释一下为什么之前的方法会行不通。

    假设第一个张量的取值范围为 0 , 1 , ⋯   , m − 1 0,1,\cdots,m-1 0,1,,m1,第二个张量的取值范围为 0 , 1 , ⋯   , n − 1 0,1,\cdots,n-1 0,1,,n1,则总共会产生 m n mn mn 个判断条件,而这 m n mn mn 个判断条件里只有 min ⁡ ( m , n ) \min(m,n) min(m,n) 个为 True,因此 True 的概率为

    P ( True ) = min ⁡ ( m , n ) m n = { 1 n , m ≤ n 1 m , m > n = 1 max ⁡ ( m , n ) P(\text{True})=\frac{\min(m,n)}{mn}= {1n,mn1m,m>n

    =\frac{1}{\max(m,n)} P(True)=mnmin(m,n)={n1,m1,mnm>n=max(m,n)1

    ∀ p ∈ ( 0 , 1 ) \forall p\in(0,1) p(0,1),令 P ( True ) = p P(\text{True})=p P(True)=p,则有 max ⁡ ( m , n ) = 1 p \max(m,n)=\frac1p max(m,n)=p1,左边是整数,右边是浮点数,因此无法建立相等关系。即使对右边取整,我们也无法良好地去逼近这个概率 p p p

    例如,取 p = 0.7 p=0.7 p=0.7,则 1 p ≈ 1.428 \frac1p\approx 1.428 p11.428,对其取整后为 1 1 1 2 2 2,此时令 max ⁡ ( m , n ) \max(m,n) max(m,n) 1 1 1 2 2 2,则 P ( True ) P(\text{True}) P(True) 0.5 0.5 0.5 1 1 1,与真实的 0.7 0.7 0.7 相差甚远。

    对于以上情形,只有当 p p p 充分小时才能良好地近似 p p p,而我们希望的是 ∀ p ∈ ( 0 , 1 ) \forall p\in(0,1) p(0,1) 都能有良好的近似。为此考虑不再将张量中每个元素的值限定为整数,而是将其放松至 ( 0 , 1 ) (0,1) (0,1) 区间内的浮点数。对于每个元素,如果其值小于 p p p,则将该元素设置为 True,否则为 False,如下:

    def randbool(size, p=0.5):
        return torch.rand(*size) < p
    
    
    def true_prob(fun):
        s = 0
        for i in range(10 ** 6):
            s += fun((10, 10), 0.7).sum().item()
        return s / 10 ** 8
    
    
    print(true_prob(randbool))
    # 0.69995753
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    python解析xml遇到的问题分享(命名空间有关)
    官网子域名网站发布流程
    什么是分卷压缩
    C语言每日一题(10) 回形矩阵
    【FreeRTOS】多任务创建
    使用html+css+js实现一个静态页面(含源码)
    AI:86-基于深度学习的街景图像地理位置识别
    ET-B32C如何让屏幕常亮(屏幕不熄灭或待机状态)
    自动化部署 YYDS
    代码随想录训练营二刷第四十四天 | 01背包问题 416. 分割等和子集
  • 原文地址:https://blog.csdn.net/raelum/article/details/126541057