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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47240308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:05:48  来源:igfitidea点击:

Differences between numpy.random.rand vs numpy.random.randn in Python

pythonnumpyneural-networknumpy-random

提问by Phúc Lê

What are all the differences between numpy.random.randand numpy.random.randn?

numpy.random.rand和之间有什么区别numpy.random.randn

From the docs, I know that the only difference among them are from the probabilistic distribution each number is drawn from, but the overall structure (dimension) and data type used (float) are the same. I have a hard time debugging a neural network because of believing this.

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

Specifically, I am trying to re-implement the Neural Network provided in the Neural Network and Deep Learning book by Michael Nielson. The original code can be found here. My implementation was the same as the original one, except that I defined and initialized weights and biases with numpy.random.randin initfunction, rather than numpy.random.randnas in the original.

具体来说,我正在尝试重新实现Michael NielsonNeural Network and Deep Learning 一书中提供的神经网络。原始代码可以在这里找到。我的实现与原始实现相同,除了我使用numpy.random.randininit函数定义和初始化权重和偏差,而不是numpy.random.randn在原始实现中。

However, my code that use random.randto initialize weights and biasesdoesn't work because the network won't learn and the weights and biases are will not change.

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

What difference(s) among two random functions cause this weirdness?

两个随机函数之间的什么差异导致了这种怪异?

回答by asakryukin

First, as you see from the documentation numpy.random.randngenerates samples from the normal distribution, while numpy.random.randfrom unifrom (in range [0,1)).

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

Second, why uniform distribution didn't work? The main reason in this is activation function, especially in your case where you use sigmoid function. The plot of the sigmoid looks like following:

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

enter image description here

在此处输入图片说明

So you can see that if your input is away from 0, the slope of the function decreases quite fast and as a result you get a tiny gradient and tiny weight update. And if you have many layers - those gradients get multiplied many times in the back pass, so even "proper" gradients after multiplications become small and stop making any influence. So if you have a lot of weights which bring your input to those regions you network is hardly trainable. That's why it is a usual practice to initialize network variables around zero value. This is done to ensure that you get reasonable gradients (close to 1) to train your net.

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

However, uniform distribution is not something completely undesirable, you just need to make the range smaller and closer to zero. As one of good practices is using Xavier initialization. In this approach you can initialize your weights with:

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

1) Normal distribution. Where mean is 0 and var = sqrt(2. / (in + out)), where in - is the number of inputs to the neurons and out - number of outputs.

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

2)Unifrom distribution in range [-sqrt(6. / (in + out)), +sqrt(6. / (in + out))]

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

回答by YaOzI

  • np.random.randis for Uniform distribution (in the half-open interval [0.0, 1.0))
  • np.random.randnis for Standard Normal (aka. Gaussian) distribution (mean 0 and variance 1)
  • np.random.rand是均匀分布(在半开区间[0.0, 1.0)
  • np.random.randn适用于标准正态(又名高斯)分布(均值为 0 和方差为 1)

You can visually explore the differences between these two very easily:

您可以非常轻松地直观地探索这两者之间的差异:

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()

Which produce:

其中产生:

enter image description here

在此处输入图片说明

and

enter image description here

在此处输入图片说明