tf.truncated_normal和tf.random_normal有什么区别?

53

tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 会输出来自于正态分布的随机值。

tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 会输出来自于截断正态分布的随机值。

我尝试谷歌搜索“截断正态分布”,但是并没有理解很多内容。

3个回答

80

文档已经说明了一切:

从指定的均值和标准差的正态分布中抽取值,舍弃并重新抽取任何距离均值超过两个标准差的样本。

可能最好通过绘制图形自行理解差异(%magic是因为我使用Jupyter Notebook):

import tensorflow as tf
import matplotlib.pyplot as plt

%matplotlib inline  

n = 500000
A = tf.truncated_normal((n,))
B = tf.random_normal((n,))
with tf.Session() as sess:
    a, b = sess.run([A, B])

现在

plt.hist(a, 100, (-4.2, 4.2));
plt.hist(b, 100, (-4.2, 4.2));

enter image description here


使用截断正态分布的目的是克服像sigmoid这样的函数饱和问题(当值太大/太小时,神经元停止学习)。


谢谢你的代码。它很棒。但是,我无法像下面显示的那样在电脑上打印出直方图。你知道为什么吗?,>>> plt.hist(b,100,(-4.2,4.2)); (array([ 3.00000000e+00, 6.00000000e+00, 9.00000000e+00, 4.00000000e+00, 1.60000000e+01, 8.00000000e+00, 3.864, 3.948, 4.032, 4.116, 4.2 ]), <a list of 100 Patch objects>) - Hong
@Hong 抱歉,我不知道为什么。看起来它已经被计算了,但由于某些原因没有被绘制出来。也许你可以提一个与matplotlib相关的问题。 - Salvador Dali
@SalvadorDali 随之而来的一个问题是,什么情况下使用其中一种比另一种更好?在我看来,truncated_normal 往往是首选。那么 random_normal 什么时候是一个有效的选择呢? - Carlos Jimenez Bermudez
7
很难预测哪种初始化方法可以带来最快的学习效果。在使用RELU激活函数时,可以考虑使用random_normal初始化方法。不使用random_normal的原因是sigmoid/tanh会饱和,但现在它们并不常用。 - Salvador Dali

25

tf.truncated_normal()会从一个均值接近0且范围在-0.1到0.1之间的正态分布中随机选取数字。它被称为截断的是因为你截掉了正态分布的尾巴。

tf.random_normal()会从一个均值接近0且范围在-2到2之间的正态分布中随机选取数字。

在实践中,机器学习通常希望权重接近于0。


1
在机器学习中,通常建议权重具有0的平均值、0.1或0.01的标准差,靠近0并具有均匀分布。您能准确说明为什么吗? - pravsels
@pravbeatle 我相信这篇文章可以帮到你,http://cs231n.github.io/neural-networks-2/。这些值是首选的,因为网络会更快地训练。 - Kenan
@pravbeatle 另一种关于 Sigmoid 链接权重饱和的解释:https://stats.stackexchange.com/questions/228670/what-is-the-benefit-of-the-truncated-normal-distribution-in-initializing-weights - weiheng

8

tf.truncated_normal() 的API文档描述了以下功能:

从截断正态分布中输出随机值。

生成的值遵循指定均值和标准差的正态分布,但其绝对值大于均值 2 个标准差的值将被丢弃并重新选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接