随机种子Random seed

使用计算机执行随机事件操作中,随机函数是按照一定算法模拟产生的,其结果是可见的。故计算机产生的随机操作是被称为伪随机,随机可被复现。随机种子可以找到生成随机的规律以达到复现这次随机的操作。

我对随机种子的通俗理解就是:作为执行随机操作的带规则的暗号(一种暗号代表一种规则)。第一次执行随机操作设置seed暗号,计算机执行伪随机操作。第二次或者后面执行随机操作时,将seed暗号对上,就会寻找第一次随机操作的规律以复现第一次随机操作得到的结果。

那我们为什么要复现第一次的随机呢?
答案是要保留第一次执行的结果。试想一下,一个模型在不同的随机中会达到不同的预测结果,90%,89%,94%,……,执行同一代码会因为计算机模型随机的规则不同产生这么多伪随机,导致最终结果无法预测,使得预测精度永远无法到达最佳。如果将实验最佳的94%的规律保存保存起来,封装模型后就能使得每次执行该模型都会得到94%的预测精度。

依赖随机种子的操作是从两个种子中派生的:图形级别种子和操作级别种子
随机种子的作用范围比作全局和局部的作用范围,在此基础之上同一个随机种子还得考虑一个计数问题:
1.先考虑随机种子的作用范围(从全局变量和局部变量的角度思考),作用范围决定复现范围
2.同一个随机种子,在其作用范围下会进行计数操作,每次计数结果都会产生伪随机性

先解决随机种子中的计数问题:
(1)不设置随机种子
这种相当于操作时分配了随机种子,在分配种子的情况下,第一次操作计数1,第二操作计数2,但因为随机种子没有指定,所以无法复现这次随机操作。

种子计数

计数操作:随机种子系统分配,作用范围在程序执行中,所以两个打印中的随机操作是同一个种子的计数操作

import numpy as np
#随机种子系统分配,作用范围在程序执行中,所以两个打印中的随机操作是同一个种子的计数操作
print(np.random.rand(1, 5))#第一次计数
print(np.random.rand(1, 5))#第二次计数

结果:第一次随机,第二次随机

[[0.17051135 0.97529881 0.89418946 0.50140075 0.66125893]]
[[0.44943569 0.31041837 0.55052514 0.07441008 0.48824769]]

(2)放到函数中可以体现出,对应第一次和第二次的操作,随机种子因为没有被设置,随机种子的作用范围是在fun0()中,每次执行fun0()都会重新分配随机种子,两次执行函数的结果不同
**无法复现:**将随机函数放到fun0中,这里的随机种子的作用范围就只在fun0()中起作用,每次fun0()都会重新分配随机种子,所以两次执行相同函数无法复现

def fun0():
    print(np.random.rand(1, 5))#第一次计数
    print(np.random.rand(1, 5))#第二次计数

fun0()
fun0()

第一次执行函数结果

[[0.68932653 0.23582158 0.54445028 0.52733226 0.6735728 ]]
[[0.94994109 0.35874023 0.51411189 0.37284521 0.71009123]]

第二次执行函数结果

[[0.63869668 0.80899726 0.16438696 0.06589287 0.70395222]]
[[0.21223191 0.69264513 0.07276136 0.26785799 0.29842939]]

(3)在函数中设置随机种子,函数中在seed=1234下进行计数操作,两个打印结果不同
可以复现:相较于(2),给fun()函数增加1234的随机种子,每次执行fun()都是在seed=1234规律下进行,所以两次结果复现

def fun():
    np.random.seed(1234)
    print(np.random.rand(1, 5))#第一次计数
    print(np.random.rand(1, 5))#第二次计数

fun()
fun()

第一次执行函数结果

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]

第二次执行函数结果

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]

第一次和第二次因为随机种子相同,故而结果复现。

种子范围:

(1)全局范围

np.random.seed(1234) #全局种子,全局复现
def fun2():
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
def fun3():
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
fun2()
fun2()
fun3()
fun3()

**范围:**这个种子的作用范围是全局,对于fun2(),fun3()的函数,只要执行random操作都是在这个范围下进行计数的,出现8个不同结果。
第一次跑结果:

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
[[0.35781727 0.50099513 0.68346294 0.71270203 0.37025075]]
[[0.56119619 0.50308317 0.01376845 0.77282662 0.88264119]]
[[0.36488598 0.61539618 0.07538124 0.36882401 0.9331401 ]]
[[0.65137814 0.39720258 0.78873014 0.31683612 0.56809865]]
[[0.86912739 0.43617342 0.80214764 0.14376682 0.70426097]]
[[0.70458131 0.21879211 0.92486763 0.44214076 0.90931596]]

但,这个函数无论怎么跑,都是会产生相同的8个结果,这就是因为全局的种子在起作用,全局复现.
再跑一次结果:

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
[[0.35781727 0.50099513 0.68346294 0.71270203 0.37025075]]
[[0.56119619 0.50308317 0.01376845 0.77282662 0.88264119]]
[[0.36488598 0.61539618 0.07538124 0.36882401 0.9331401 ]]
[[0.65137814 0.39720258 0.78873014 0.31683612 0.56809865]]
[[0.86912739 0.43617342 0.80214764 0.14376682 0.70426097]]
[[0.70458131 0.21879211 0.92486763 0.44214076 0.90931596]]

(2)局部范围 第一种

def fun2():
    np.random.seed(1234)#1234种子,局部复现
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
def fun3():#1234种子,全局复现
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
fun2()
fun2()
fun3()
fun3()

这里的随机种子仅设置在fun2()范围内,所以,前两个结果不同是因为seed=1234下的计数操作,一二和三四相同是因为fun2()的两次执行都是seed=1234。
五六七八都不同,因为他不在复现范围内,数据在1234种子的计数操作中,能够在1234的全局复现。所以只要执行fun2()都会得到前两个结果。只要执行这个程序,得到的结果只有一种。
第一次跑结果:

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]  1
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]	2
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]	1
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]	2
[[0.35781727 0.50099513 0.68346294 0.71270203 0.37025075]]	3
[[0.56119619 0.50308317 0.01376845 0.77282662 0.88264119]]	4
[[0.36488598 0.61539618 0.07538124 0.36882401 0.9331401 ]]	5
[[0.65137814 0.39720258 0.78873014 0.31683612 0.56809865]]	6

再跑一次结果:

[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
[[0.35781727 0.50099513 0.68346294 0.71270203 0.37025075]]
[[0.56119619 0.50308317 0.01376845 0.77282662 0.88264119]]
[[0.36488598 0.61539618 0.07538124 0.36882401 0.9331401 ]]
[[0.65137814 0.39720258 0.78873014 0.31683612 0.56809865]]

(3)局部范围 第二种

def fun2():
#随机种子,不会复现
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
def fun3():
    np.random.seed(1234)#1234种子,局部复现
    print(np.random.rand(1, 5))
    print(np.random.rand(1, 5))
fun2()
fun2()
fun3()
fun3()
五六和七八相同叫复现,五六不同叫计数。一二三四是随机分配的种子的计数操作。
结果是再次运行操作时,一二三四会随机,五六七八还是不变

结果:

[[0.11615226 0.3427353  0.34684771 0.93112869 0.55646673]]	*
[[0.53208177 0.39310779 0.97887637 0.19903748 0.5545923 ]]	*
[[0.30238599 0.35561907 0.01597365 0.37605328 0.43928673]]	*
[[0.97388219 0.6356066  0.33832807 0.62468604 0.22892785]]	*
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]	1
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]	2
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]	1
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]	2

再次跑程序结果:

[[0.55843385 0.69376482 0.03878164 0.92269791 0.12950639]]
[[0.61162718 0.50353035 0.3889969  0.47456832 0.23182931]]
[[0.39501976 0.22830436 0.50689852 0.48358058 0.45633601]]
[[0.3627926  0.70313669 0.04387424 0.54884913 0.96772476]]
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
[[0.19151945 0.62210877 0.43772774 0.78535858 0.77997581]]
[[0.27259261 0.27646426 0.80187218 0.95813935 0.87593263]]
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值