二项分布,及其用于dropout

来源:互联网 发布:sql server2014安装包 编辑:程序博客网 时间:2024/05/21 19:41

二项分布(binomial distribution): 

P(N)=(nN)pN(1p)nN

numpy给出的api是:

numpy.random.RandomState.binomial(n, p, size=None)
  • 1
  • 1

表示对一个二项分布进行采样(size表示采样的次数,draw samples from a binomial distribution.),参数中的n, p分别对应于公式中的n,p,函数的返回值表示n成功(success)的次数(也即N)。可能说起来比较抽象,我们以一个具体的实例进行阐释:

说野外正在进行9(n=9)口石油勘探井的发掘工作,每一口井能够开发出油的概率是0.1(p=0.1)。请问,最终所有的勘探井都勘探失败的概率?

如果手动计算的话,自然简单运用中学概率知识便可秒答,(nN)pN(1p)nN=(90)0.10(10.1)9=0.190.3874

因为np.random.binomial()进行的是采样工作,为了逼近这一概率,我们需要进行的是采用统计的方法进行对概率值的逼近。

>>> n, p = 9, .1>>> sum(np.random.binomial(n, p, size=20000)==0)/20000.0.38314999999999999                             # 不能使用整数相除
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

我们继续模拟,两枚硬币都是正面的概率:

>>> n, p = 2, .5            # 两枚都是正面>>> sum(np.random.binomial(n, p, size=20000)==2)/20000.0.25019999999999998         # 和我们的精确概率值相接近# 其中一个为反面>>> sum(np.random.binomial(n, p, size=20000)==1)/20000.0.49430000000000002# 两个都是反面 >>> n, p = 2, .5>>> sum(np.random.binomial(n, p, size=20000)==0)/20000.0.25054999999999999
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

再比如我们要随机地n个数中以概率p对其进行选择,我们可以先生成一个掩膜(mask)

mask = np.random.binomial(1, p, n)                    # 也即对这个n个数,分别以p进行确定其值为1(选中该值0),                    # 以(1-p)确定其值为0(也即是未选中该值)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在实际中参数p也未必一定是一个float类型的纯量,也可以是多个概率值组成的数组,此时需要满足size和p的shape相同,size中的每一个元素依p中的相应位的概率值进行取样,

>>> numpy.random.Random(23455).binomial(size=3, n=1, p=(.2, .8, .99))array([0, 1, 1])>>> numpy.random.Random(23455).binomial(size=3, n=1, p=(.2, .8, .99))array([0, 1, 1])>>> numpy.random.Random(23455).binomial(size=3, n=1, p=(.2, .8, .99))array([1, 1, 1])                    # 只需记住一点:                    # 每一次的概率取值,互相之间是独立的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

二项分布进行取样(选中为一,未选中为0)

p(hi=1|v)=σ(ci+Wiv)p(h=1|v)=σ(c+vTW)p(vj=1|h)=σ(bj+Wjh)p(v=1|h)=σ(b+hTW)

def propup(self, vis):    pre_sigmoid_activation = T.dot(vis, self.W)+self.v_bias    return [pre_sigmoid_activation, T.nnet.sigmoid(pre_sigmoid_activation)]def sample_h_given_x(self, v0_sample):    pre_sigmoid_h1, h1_mean = self.propup(v0_sample)    h1_sample = self.theano_rng.binomial(size=h1_mean, n=1, p=h1_mean, dtype=theano.config.floatX)    return [pre_sigmoid_h1, h1_mean, h1_sample]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

二项分布(生成掩码)机制在深度学习算法中的应用

主要是取n=1,用来生成MASK(掩码),然后将生成的掩码作用在原始输入上,获得需要的对网络结构的dropout或者对原始输入的corrupted

比如denoising autoencoder对原始输入的加噪机制这想法真的很酷,通过学习(特指监督学习)的方式,获得对含噪输入较强的鲁棒结果。

def get_corrupted_input(self, input, corruption_level):    return self.theano_rng.binomial(            size=input.shape, n=1,            p=1-corruption_level,            dtype=theano.config.floatX)*input
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

再比如避免overfitting的dropout机制(这时屏蔽的是神经网络的部分节点也就是神经元neuron):

def dropout_layer(layer, p_dropout):    mask = theano_rng.binomial(n=1, p=1-p_drop_out, size=layer.shape)    return layer*T.cast(mask, theano.config.floatX)