繁体   English   中英

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

[英]Differences between numpy.random.rand vs numpy.random.randn in Python

numpy.random.randnumpy.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 初始化。 在这种方法中,您可以使用以下方法初始化权重:

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

  2. 范围内的均匀分布[-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM