深入剖析随机数种子

  • 一、定义
  • 1.1 作用
  • 二、实战
  • 2.1 同样的随机数种子
  • 2.2 不同的随机数种子
  • 2.3 不指定随机数种子
  • 三、随机数列的大小是多少呢?
  • 3.1 设定为百万,没问题
  • 3.2 设定为千万,没问题
  • 3.3 设定为亿,没问题
  • 3.4 设定为十亿,没问题
  • 3.5 设定为百亿,内存不够!!
  • 3.6 设定为一万亿,内存更加不够!!!
  • 3.7 换了内存为64G的工作站,设定为一万亿,内存还是不够!!!![在这里插入图片描述](https://s2.51cto.com/images/blog/202309/03084918_64f3d80e9fe5084238.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 四、random模块中的随机数种子
  • 4.1 示例
  • 4.2 random模块与 numpy.random的对比


一、定义







1.1 作用





但是

  • 在大多数情况下,即使设定了随机种子,仍然没有办法完全复现paper中所给出的模型性能,这是因为深度学习代码中除了产生随机数中带有随机性,其训练的过程中使用 mini-batch SGD或者优化算法进行训练时,本身就带有了随机性。
  • 因为每次更新都是从训练数据集中随机采样出batch size个训练样本计算的平均梯度作为当前step对于网络权值的更新值,所以即使提供了原始代码和随机种子,因此想要复现作者paper中的性能也是非常困难的!!

二、实战


  • 更多更具体的类型可以参考 random模块与 numpy.random的区别

2.1 同样的随机数种子

import numpy as np
import random

np.random.seed(0) # 设定种子为0
print(np.random.rand(1)) # 生成1个随机数
# 输出 [0.5488135]

np.random.seed(0) # 设定种子为0
print(np.random.rand(2)) # 生成2个随机数
# 输出 [0.5488135  0.71518937]

np.random.seed(0) # 设定种子为0
print(np.random.rand(3)) # 生成3个随机数
# 输出 [0.5488135  0.71518937 0.60276338]

np.random.seed(0) # 设定种子为0
print(np.random.rand(4)) # 生成4个随机数
# 输出 [0.5488135  0.71518937 0.60276338 0.54488318]

np.random.seed(0) # 设定种子为0
print(np.random.rand(5)) # 生成5个随机数
# 输出 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548 ]

np.random.seed(0) # 设定种子为0
print(np.random.rand(6)) # 生成6个随机数
# 输出 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548  0.64589411]

# 上述运行结果验证了定义里面所说的:只要随机数种子是一样的,那么我们从随机数列中同一个位置里面取到的随机数是一样的!!

2.2 不同的随机数种子

np.random.seed(1) # 设定种子为1
print(np.random.rand(6)) # 生成6个随机数
[4.17022005e-01 7.20324493e-01 1.14374817e-04 3.02332573e-01
 1.46755891e-01 9.23385948e-02]

2.3 不指定随机数种子

  • 系统使用当前的时钟作为随机数种子!
print(np.random.rand(6)) # 生成6个随机数
[0.18626021 0.34556073 0.39676747 0.53881673 0.41919451 0.6852195 ]

三、随机数列的大小是多少呢?




3.1 设定为百万,没问题

np.random.seed(0) # 设定种子为0
print(np.random.rand(1000000)) # 生成百万个随机数
# 输出为[0.5488135  0.71518937 0.60276338 ... 0.36259133 0.51650652 0.90860588]

3.2 设定为千万,没问题

np.random.seed(0) # 设定种子为0
print(np.random.rand(10000000)) # 生成千万个随机数
# 输出为[0.5488135  0.71518937 0.60276338 ... 0.7016828  0.45616281 0.14553608]

3.3 设定为亿,没问题

np.random.seed(0) # 设定种子为0
print(np.random.rand(100000000)) # 生成一亿个随机数
# 输出为[0.5488135  0.71518937 0.60276338 ... 0.08870192 0.45256207 0.17769845]

3.4 设定为十亿,没问题

np.random.seed(0) # 设定种子为0
print(np.random.rand(1000000000)) # 生成十亿个随机数
# 输出为[0.5488135  0.71518937 0.60276338 ... 0.50437869 0.82084559 0.15720507]

3.5 设定为百亿,内存不够!!

np.random.seed(0) # 设定种子为0
print(np.random.rand(10000000000)) # 生成百亿个随机数

# 出错!!!!!
Traceback (most recent call last):
  File "<input>", line 2, in <module>
  File "mtrand.pyx", line 1154, in numpy.random.mtrand.RandomState.rand
  File "mtrand.pyx", line 420, in numpy.random.mtrand.RandomState.random_sample
  File "_common.pyx", line 256, in numpy.random._common.double_fill
MemoryError: Unable to allocate 74.5 GiB for an array with shape (10000000000,) and data type float64

3.6 设定为一万亿,内存更加不够!!!

np.random.seed(0) # 设定种子为0
print(np.random.rand(1000000000000)) # 生成一万亿个随机数

# 出错!!!!!
Traceback (most recent call last):
  File "<input>", line 2, in <module>
  File "mtrand.pyx", line 1154, in numpy.random.mtrand.RandomState.rand
  File "mtrand.pyx", line 420, in numpy.random.mtrand.RandomState.random_sample
  File "_common.pyx", line 256, in numpy.random._common.double_fill
MemoryError: Unable to allocate 7.28 TiB for an array with shape (1000000000000,) and data type float64

# 结果是内存不够!!

3.7 换了内存为64G的工作站,设定为一万亿,内存还是不够!!!

python random 随机数种子 python sample 随机种子_随机数


四、random模块中的随机数种子



4.1 示例

import random
random.seed(0)
print(random.random())
# 输出为 0.8444218515250481

random.seed(0)
print(random.random())
# 输出为 0.8444218515250481

4.2 random模块与 numpy.random的对比






random.seed(0)
print(random.random())
# 输出为 0.8444218515250481
import numpy as np

np.random.seed(0)
print(np.random.rand())
# 输出为 0.5488135039273248