Python中numpy.random.rand与numpy.random.randn之间的差异

时间:2017-11-11 16:42:54

标签: python numpy neural-network numpy-random

numpy.random.randnumpy.random.randn之间的所有差异是什么?

从文档中,我知道它们之间的唯一区别来自每个数字的概率分布,但总体结构(维度)和使用的数据类型(浮点数)是相同的。由于相信这一点,我很难调试神经网络。

具体来说,我正在尝试重新实现Neural Network and Deep Learning book by Michael Nielson中提供的神经网络。可以找到原始代码here。我的实现与原始实现相同,只是我在numpy.random.rand函数中使用init定义和初始化权重和偏差,而不是原始版本中的numpy.random.randn

但是,我使用random.rand初始化weights and biases的代码无法正常工作,因为网络不会学习,权重和偏见也不会改变。

两个随机函数之间的差异会导致这种奇怪吗?

3 个答案:

答案 0 :(得分:43)

首先,正如您从文档numpy.random.randn中看到的那样,从正态分布生成样本,而来自unifrom的numpy.random.rand(在范围[0,1)中)。

其次,为什么统一分配不起作用?其中的主要原因是激活功能,特别是在您使用sigmoid功能的情况下。 sigmoid的情节如下:

enter image description here

所以你可以看到,如果你的输入远离0,函数的斜率下降得非常快,结果你会得到一个小的渐变和微小的重量更新。如果你有很多层 - 那些渐变在后传中会多次增加,所以即使是#34;正确的"乘法后的梯度变小并停止产生任何影响。因此,如果您有很多权重可以将您的输入带到这些区域,那么您的网络难以训练。这就是为什么通常的做法是将网络变量初始化为零值。这样做是为了确保您获得合理的渐变(接近1)来训练您的网。

然而,均匀分布并非完全不合需要,您只需要使范围更小并且更接近零。正如一个好的做法是使用Xavier初始化。在这种方法中,您可以使用以下方法初始化权重:

1)正态分布。其中mean是0和var = sqrt(2. / (in + out)),其中in是神经元的输入数量和输出数量。

2)Unifrom分布范围[-sqrt(6. / (in + out)), +sqrt(6. / (in + out))]

答案 1 :(得分:1)

  • np.random.rand用于统一分发(在半开放间隔[0.0, 1.0)中)
  • np.random.randn用于标准正态(aka高斯)分布(均值0和方差1)

您可以很容易地从视觉上探索这两者之间的差异:

import numpy as np
import matplotlib.pyplot as plt

sample_size = 100000
uniform = np.random.rand(sample_size)
normal = np.random.randn(sample_size)

pdf, bins, patches = plt.hist(uniform, bins=20, range=(0, 1), density=True)
plt.title('rand: uniform')
plt.show()

pdf, bins, patches = plt.hist(normal, bins=20, range=(-4, 4), density=True)
plt.title('randn: normal')
plt.show()

哪种产品:

enter image description here

enter image description here

答案 2 :(得分:-3)

1)numpy.random.rand来自制服(在[0,1]范围内)

2)numpy.random.randn根据正态分布

生成样本