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.rand
和numpy.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 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章