![](/img/trans.png)
[英]When to use numpy.random.randn(…) and when numpy.random.rand(…)?
[英]Differences between numpy.random.rand vs numpy.random.randn in Python
numpy.random.rand
和numpy.random.randn
有什么区别?
从文档中,我知道它们之间的唯一区别是每个数字的概率分布,但整体结构(维度)和使用的数据类型(浮点数)是相同的。 因此,我很难调试神经网络。
具体来说,我正在尝试重新实现Michael Nielson 在《神经网络和深度学习》一书中提供的神经网络。 原始代码可以在这里找到。 我的实现和原来的一样; however, I instead defined and initialized weights and biases with numpy.random.rand
in the init
function, rather than the numpy.random.randn
function as shown in the original.
但是,我使用random.rand
初始化weights and biases
的代码不起作用。 网络不会学习,权重和偏差不会改变。
导致这种怪异的两个随机函数之间有什么区别?
首先,正如您从文档中看到的numpy.random.randn
从正态分布生成样本,而numpy.random.rand
从均匀分布(在 [0,1) 范围内)生成样本。
第二,为什么均匀分布不起作用? 主要原因是激活 function,尤其是在您使用 sigmoid function 的情况下。 sigmoid 的 plot 如下所示:
所以你可以看到,如果你的输入远离 0,function 的斜率下降得很快,结果你得到一个微小的梯度和微小的权重更新。 如果你有很多层 - 这些梯度在回传中会被多次相乘,所以即使是“正确”的梯度在乘法之后也会变小并且不再产生任何影响。 因此,如果您有很多权重将您的输入带到这些区域,那么您的网络很难训练。 这就是为什么通常的做法是在零值附近初始化网络变量。 这样做是为了确保您获得合理的梯度(接近 1)来训练您的网络。
但是,均匀分布并不是完全不可取的,您只需要将范围缩小并接近零。 一种好的做法是使用 Xavier 初始化。 在这种方法中,您可以使用以下方法初始化权重:
正态分布。 其中 mean 为 0 且var = sqrt(2. / (in + out))
,其中 in - 是神经元的输入数, out - 输出数。
范围内的均匀分布[-sqrt(6. / (in + out)), +sqrt(6. / (in + out))]
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()
哪个产品:
和
1) numpy.random.rand
来自统一(在 [0,1) 范围内)
2) numpy.random.randn
从正态分布生成样本
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.