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

Phu*_* Le 40 python numpy neural-network numpy-random

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

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

具体来说,我试图重新实现Michael Nielson神经网络和深度学习书中提供的神经网络.原始代码可以在这里找到.我的实现与原始实现相同,除了我numpy.random.randinit函数中定义和初始化权重和偏差,而不是numpy.random.randn在原始中.

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

两个随机函数之间的差异会导致这种奇怪吗?

asa*_*kin 58

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

第二,为什么统一分配不起作用?其中的主要原因是激活功能,特别是在您使用sigmoid功能的情况下.sigmoid的情节如下:

在此输入图像描述

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

然而,均匀分布并非完全不合需要,您只需要使范围更小并且更接近零.正如一个好的做法是使用Xavier初始化.在这种方法中,您可以使用以下方法初始化权重:

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

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

  • 谢谢.我知道消失渐变是一件事,但我从未想过只需从`random.randn`切换到`random.rand`就可以使网络从一开始就完全没用. (3认同)

YaO*_*OzI 6

  • np.random.rand用于均匀分布(在半开放时间间隔内[0.0, 1.0)
  • np.random.randn 适用于标准正态(aka高斯)分布(均值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()
Run Code Online (Sandbox Code Playgroud)

哪个产生:

在此处输入图片说明

在此处输入图片说明