随机产生函数种子seed、numpy.random.seed()、tf.set_random_seed()、tf.random_uniform()、tf.random_normal()学习
神经网络代码中,随机产生函数几乎都会出现在最开头的位置,足以说明其重要性。
我们得保证,每次代码产生的随机数是相同的,要不然每次运行出的数据都是不同的,不利于我们的研究分析
1.种子是什么
了解种子是什么,首先得了解随机数产生机制。
在numpy中,seed函数的作用为 Seed the random number generator(为随机生成函数生成种子),而seed函数中的参数seed可以理解成为了获取每次产生随机数时的 “开始位置”的数值。
我们可以把seed看作一个映射函数的输入,输入不同的值,都会有唯一对应的数值( “开始位置”)。
至于随机数,是一些顺序已经固定的序列。
通过seed得到的 “开始位置”,就能在固定随机序列中找到位置,进行输出。
至于tensorflow中的seed和numpy相似,可以进行类比。
2.numpy.random.seed() 函数
random_sample() : Uniformly distributed floats over [0, 1) ( 随机产生 [0,1)之间的均匀分布浮点数)
random() : Alias for random_sample() (random_sample 的别称)
可以看到random_sample() 和 random() 其实是同一个函数,都是随机生成[0,1)之间的均匀分布浮点数
seed() 函数上面提到,是对随机生成函数指定随机 “开始位置”
接下来,我们进行具体实验,来看看numpy.random.seed()的具体效果
import numpy as np#numpy seed只限制一层for k in range(3):np.random.seed(123)for i in range(5):print( np.random.random() )print('\n')for k in range(3):for i in range(5):np.random.seed(123)print( np.random.random() )print('\n')np.random.seed(123)
for k in range(3):for i in range(5):print( np.random.random() )print('\n')
第一个循环结果
三次相同的五个不同随机数
第二个循环结果
三次输出完全相同五个随机数
第三个循环结果
三次完全不同的五个随机数int
总结输出结果,numpy.random.seed()只是针对某一层进行约束,不是全局约束
3.tf.random_uniform()、tf.random_normal()、tf.set_random_seed()
tensorflow中随机数生成分为两种层次
操作级 tf.random_uniform(shape,seed)、tf.random_normal(shape,seed)
保证每个操作每次生成相同的随机数
图级(全局) tf.set_random_seed()
保证整个图每次生成相同随机数
----------------------------------------------------------------------------------------------------
tf.random_uniform(shape,seed) :随机生成[0,1)之间的均匀分布数
tf.random_normal(shape,seed): 随机生成正态分布值,平均值不大于2
上述的shape,表示生成随机数的形状,可以是单个数值 [int]表示,也可以是矩阵类型[a,b]表示,高维度的也可以生成
seed值,就是第一节中的 “开始位置”
tf.set_random_seed():设置全局随机种子,在使用全局种子后,后面所有的随机生成函数的 “开始位置”都是相同的
-----------------------------------------------------------------------------------------------------
通过代码理解一下,操作级和图级的区别
import tensorflow as tfa1 = tf.random_uniform([5]) #均匀分布中返回随机数 【0,1】
b1 = tf.random_normal([1]) #正态分布中输出随机值 平均值与每个值不超过2#设置在变量中
seed=123a2 = tf.random_uniform([5],seed=seed)
b2 = tf.random_normal([1],seed=seed)#未加随机种子,每次都不相同
#操作级种子,保证每次运行操作级生成随机数相同
print("Session 1")
with tf.Session() as sess1 :print(sess1.run(a1))print(sess1.run(a1))print("------------")print(sess1.run(a2))print(sess1.run(a2))print("------------")print(sess1.run(b1))print(sess1.run(b1))print("------------")print(sess1.run(b2))print(sess1.run(b2))print("Session 2")
with tf.Session() as sess2:print(sess2.run(a1))print(sess2.run(a1))print("------------")print(sess2.run(a2))print(sess2.run(a2))print("------------")print(sess2.run(b1))print(sess2.run(b1))print("------------")print(sess2.run(b2))print(sess2.run(b2))
输出结果
在两个不同的Session会话中,如果没有设置种子的随机生成函数,如a1,b1,两次输出是不同的
若设置了种子,如a2,b2, 两次输出是相同的
值得注意的是,在同一个会话中,a2,b2也分别重复了两次,但是同一会话输出并不相同
所以设置操作级种子,会保证在不同的Session会话中使用设置操作得到的数一致
加下来看看图级操作
import tensorflow as tfseed=123
a1 = tf.random_uniform([5]) #均匀分布中返回随机数 【0,1】
b1 = tf.random_normal([1]) #正态分布中输出随机值 平均值与每个值不超过2a2 = tf.random_uniform([5],seed=seed)
b2 = tf.random_normal([1],seed=seed)print("全局随机设置")
#设置在变量中
seed=12
tf.set_random_seed(seed)a3 = tf.random_uniform([5])
b3 = tf.random_normal([1])print("Session 3")
with tf.Session() as sess3 :print(sess3.run(a1))print(sess3.run(a1))print("------------")print(sess3.run(a2))print(sess3.run(a2))print("------------")print(sess3.run(a3))print(sess3.run(a3))print("------------")print(sess3.run(b1))print(sess3.run(b1))print("------------")print(sess3.run(b2))print(sess3.run(b2))print("------------")print(sess3.run(b3))print(sess3.run(b3))
print("Session 4")
with tf.Session() as sess4:print(sess4.run(a1))print(sess4.run(a1))print("------------")print(sess4.run(a2))print(sess4.run(a2))print("------------")print(sess4.run(a3))print(sess4.run(a3))print("------------")print(sess4.run(b1))print(sess4.run(b1))print("------------")print(sess4.run(b2))print(sess4.run(b2))print("------------")print(sess4.run(b3))print(sess4.run(b3))
输出结果
1.tf.set_random_seed() 是对所有Session对话中的随机生成函数进行操作,简称全局有效
通过a3,b3输出,看出a3,b3没有进行操作级设置,但是两次输出仍是相同的数据
2.set_random_seed() 只对进行声明后的代码有效
通过a1,b1输出数据看出,a1,b1在set_random_seed()声明之前,不受其设置影响,仍输出不同的数据
3.图级比操作级优先级高
观察Session 1,2与Session3,4之间a2,b2数据
a2,b2进行了操作级设置,但是在进行图级设置后,修改了seed为12,其数值改变,由此可见,图级设置优先级更高