Python 中 numpy.random.rand 与 numpy.random.randn 之间的区别

Posted

技术标签:

【中文标题】Python 中 numpy.random.rand 与 numpy.random.randn 之间的区别【英文标题】:Differences between numpy.random.rand vs numpy.random.randn in Python 【发布时间】:2018-04-24 17:12:59 【问题描述】:

numpy.random.randnumpy.random.randn 有什么区别?

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

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

但是,我使用random.rand 初始化weights and biases 的代码不起作用。网络不会学习,权重和偏差不会改变。

导致这种怪异的两个随机函数之间有什么区别?

【问题讨论】:

前者来自均匀分布,后者来自正态分布。 “为什么从正态分布中提取的初始权重在深度学习中效果更好”更适合Cross Validated。这与 numpy 或深度学习框架完全无关。 @ayhan 感谢您的评论。我认为这是一个 numpy 问题,而不是初始权重问题,因为即使我将权重初始化为零,我的性能也比使用 random.randn 初始化最差,但网络仍然可以学习。而如果我使用random.rand,网络只会一遍又一遍地重复初始结果,却什么也没学到。 【参考方案1】:

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

第二,为什么均匀分布不起作用?主要原因是激活函数,尤其是在您使用 sigmoid 函数的情况下。 sigmoid 的图如下所示:

因此,您可以看到,如果您的输入远离 0,则函数的斜率会非常快地减小,因此您会得到微小的梯度和微小的权重更新。如果你有很多层 - 这些梯度在回传中会被多次相乘,所以即使是“正确”的梯度在乘法之后也会变小并且不再产生任何影响。因此,如果您有很多权重将您的输入带到这些区域,那么您的网络很难训练。这就是为什么通常的做法是在零值附近初始化网络变量。这样做是为了确保您获得合理的梯度(接近 1)来训练您的网络。

但是,均匀分布并不是完全不受欢迎的,您只需要将范围缩小并接近零。一种好的做法是使用 Xavier 初始化。在这种方法中,您可以使用以下方法初始化权重:

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

    [-sqrt(6. / (in + out)), +sqrt(6. / (in + out))]范围内均匀分布

【讨论】:

谢谢。我知道梯度消失是一回事,但我从没想过从 random.randn 切换到 random.rand 会从一开始就使网络完全无用。 我认为这就是人们停止使用 sigmoid 作为激活函数的原因。顺便说一句,那本书是一个很棒的介绍!但我希望他已经编写了 ReLU。仍然因为早期的神经网络使用 Sigmoid,它确实有意义 用归一化输入、2-3 个 FC、ReLU 和 rand init 做了同样的实验,同样的行为,不收敛 @asakryukin 很好的答案!谢谢你的解释!【参考方案2】: np.random.rand 用于均匀分布(在半开区间[0.0, 1.0)np.random.randn 用于标准正态(又名高斯)分布(均值 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()

哪些产品:

【讨论】:

【参考方案3】:

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

2) numpy.random.randn正态分布

生成样本

【讨论】:

这并没有添加三年前没有说过的任何内容。

以上是关于Python 中 numpy.random.rand 与 numpy.random.randn 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

python中怎么重复打印

python中去除数组中inf

python中字典的问题

想象中的python,实际的python,希望的python

关于python中字典

python中= 和==的区别