伯努利随机数生成器

17

我不理解怎么在numpy中使用的Bernoulli随机数生成器计算,希望能有一些解释。例如:

np.random.binomial(size=3, n=1, p= 0.5)

Results:
[1 0 0]

n = 实验次数

p = 出现的概率

size = 实验数量

如何确定生成的数字/结果为“0”或“1”?

=================================更新==================================

我创建了一个受限玻尔兹曼机,尽管在多次代码执行中它是“随机”的,但总是呈现相同的结果。 随机化使用了np.random.seed(10)

import numpy as np

np.random.seed(10)

def sigmoid(u):
    return 1/(1+np.exp(-u))

def gibbs_vhv(W, hbias, vbias, x):
    f_s = sigmoid(np.dot(x, W) + hbias)
    h_sample = np.random.binomial(size=f_s.shape, n=1, p=f_s)

    f_u = sigmoid(np.dot(h_sample, W.transpose())+vbias)
    v_sample = np.random.binomial(size=f_u.shape, n=1, p=f_u)
    return [f_s, h_sample, f_u, v_sample]

def reconstruction_error(f_u, x):
    cross_entropy = -np.mean(
        np.sum(
            x * np.log(sigmoid(f_u)) + (1 - x) * np.log(1 - sigmoid(f_u)),
            axis=1))
    return cross_entropy


X = np.array([[1, 0, 0, 0]])

#Weight to hidden
W = np.array([[-3.85, 10.14, 1.16],
              [6.69, 2.84, -7.73],
              [1.37, 10.76, -3.98],
              [-6.18, -5.89, 8.29]])

hbias = np.array([1.04, -4.48, 2.50]) #<= 3 bias for 3 neuron in hidden
vbias = np.array([-6.33, -1.68, -1.25, 3.45]) #<= 4 bias for 4 neuron in input


k = 2
v_sample = X
for i in range(k):
    [f_s, h_sample, f_u, v_sample] = gibbs_vhv(W, hbias, vbias, v_sample)
    start = v_sample
    if i < 2:
        print('f_s:', f_s)
        print('h_sample:', h_sample)
        print('f_u:', f_u)
        print('v_sample:', v_sample)
    print(v_sample)
    print('iter:', i, ' h:', h_sample, ' x:', v_sample, ' entropy:%.3f'%reconstruction_error(f_u, v_sample))

结果:

[[1 0 0 0]]
f_s: [[ 0.05678618  0.99652957  0.97491304]]
h_sample: [[0 1 1]]
f_u: [[ 0.99310473  0.00139984  0.99604968  0.99712837]]
v_sample: [[1 0 1 1]]
[[1 0 1 1]]
iter: 0  h: [[0 1 1]]  x: [[1 0 1 1]]  entropy:1.637

f_s: [[  4.90301318e-04   9.99973278e-01   9.99654440e-01]]
h_sample: [[0 1 1]]
f_u: [[ 0.99310473  0.00139984  0.99604968  0.99712837]]
v_sample: [[1 0 1 1]]
[[1 0 1 1]]
iter: 1  h: [[0 1 1]]  x: [[1 0 1 1]]  entropy:1.637

@kazemakase 当我使用函数 np.random.binomial(size=3, n=1, p= 0.5) 时,结果是 [1 0 0]。然而,我不理解 numpy 是如何得出这些结果的,希望能够得到解释。 - WhiteSolstice
你是在询问产生这些数字的算法如何工作,还是结果与输入参数之间的关系如何? - MB-F
我想了解算法是如何生成这些数字的。 - WhiteSolstice
随着更新,这实际上是一个新问题。除非您想使现有答案无效,否则应考虑将其作为单独的问题提出...进一步提示:显示所有相关代码。输出指示迭代,但您的代码中没有迭代的迹象。看到在同一上下文中提到seeditersame result这些词让我警觉起来 :)(在循环中重新播种?)。因此,请确切地显示您如何重复调用binomial函数以及播种发生的确切位置。 - MB-F
通过收敛于[0, 1, 1],您的意思是伯努利分布有极高的概率得到[0, 1, 1],因为概率是[0.057, 0.997, 0.975]?因此,其他结果不太可能出现。如果是这样,我尝试将值硬编码为[0.3, 0.5, 0.7],但仍然没有“随机”值的迹象,因为它给出了一个恒定的结果[1, 0, 1]。提前致谢! - WhiteSolstice
显示剩余4条评论
2个回答

21
我正在了解算法如何生成这些数字。- WhiteSolstice 35分钟前
非技术说明:
如果将n = 1传递给二项式分布,则相当于伯努利分布。在这种情况下,该函数可以模拟抛硬币。 size = 3告诉它抛三次硬币,p = 0.5使其成为等概率的公平硬币,正面(1)或反面(0)的可能性相等。
[1 0 0]的结果意味着硬币正面向上一次,反面向上两次。这是随机的,因此再次运行会产生不同的序列,如[1 1 0],[0 1 0],甚至可能是[1 1 1]。虽然你不能在三次运行中获得相同数量的1和0,但平均而言,你会得到相同的数量。
技术说明:
Numpy用C实现随机数生成。二项式分布的源代码可以在here中找到。实际上实现了两种不同的算法。
  • 如果 n * p <= 30,则使用逆变换抽样
  • 如果 n * p > 30,则使用(Kachitvichyanukul和Schmeiser 1988)的BTPE算法。(该出版物不免费。)

我认为这两种方法,尤其是逆变换抽样,都依赖于随机数生成器产生均匀分布的随机数。 Numpy内部使用梅森旋转器伪随机数生成器。 然后将均匀随机数转换为所需的分布。


哦,我明白了,一度我以为有一种方法可以准确地确定/计算这些值。实际上,我创建了一个受限玻尔兹曼机,使用np.random.binomial的值总是相同的。我已经更新了问题,希望您能看一下。 - WhiteSolstice

1
一个二项式分布的随机变量有两个参数np,可以被认为是当抛掷一个有偏向的硬币n次时得到正面的数量的分布,其中每次抛掷得到正面的概率是p。(更正式地说,它是具有参数p的独立伯努利随机变量之和。)
例如,如果n=10p=0.5,则可以通过抛掷一个公平的硬币10次并计算硬币正面朝上的次数来模拟从Bin(10, 0.5)中抽取。
除了上面描述的参数np之外,np.random.binomial还有一个额外的参数size。如果size=1np.random.binomial会计算从二项分布中抽取一次样本。如果size=k,其中k是整数,则会计算相同二项分布的k个独立抽样。size也可以是索引数组,在这种情况下,将用来自二项分布的独立样本填充具有给定size的完整np.array

请注意,二项分布是伯努利分布的一种推广 - 在n=1的情况下,Bin(n,p)Ber(p)具有相同的分布。

有关二项分布的更多信息,请参见:https://en.wikipedia.org/wiki/Binomial_distribution


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接