深入剖析随机数种子
- 一、定义
- 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的工作站,设定为一万亿,内存还是不够!!!
四、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