感觉一直碰到随机数生成器numpy.random.seed()这个函数,然后每次都是直接过去了,但是最近在目标检测的代码中老是碰到这个函数用来绘制表示不同目标类别的检测框(不同目标类别的检测框用不同的颜色进行绘制),想想还是把它弄懂吧。
首先说一下numpy.random.seed()函数的作用:主要作用就是利用随机数种子,每次都生成相同的随机数。具体的说就是(先通过看下面的例子再理解会比较容易):
seed( ) 用于指定随机数生成时所用算法(所用算法可以是np.random.randn(),numpy.random.shuffle()等等)开始位置的整数值,如果使用相同的seed( )值,则每次生成的随机数都相同,因为该参数指定了一个随机数生成的起始位置,每个参数对应一个位置,并且在该参数确定后,其后面的随机数的生成顺序也就确定了。 如果不设置这个值,则系统会根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。 例如:可以在numpy.random.seed(整数值)后使用numpy.random.shuffle(array)来实现同样随机结果的打乱,即seed(整数值)确定后,每次numpy.random.shuffle(array)结果是相同的,整数值可以随意取,因为这个参数只是确定一下随机数的起始位置而已。np.random.randn(),numpy.random.shuffle()这些函数生成的数据可以理解成本身是固定不变的,只不过系统会根据时间自己选择开始位置的这个值,这样每次生成的随机数就会因时间差异而不同,所以就看到了我们理解的每次生成了不同的随机数(np.random.randn())和打乱顺序后的每次不一样的数据(numpy.random.shuffle())。
举例1说明:
import numpy as np
if __name__ == '__main__':
i = 0
while (i < 6):
if (i < 3):
np.random.seed(10101)
print(np.random.randn(1, 5))
else:
print(np.random.randn(1, 5))
pass
i += 1
i = 0
while (i < 2):
print(np.random.randn(1, 5))
i += 1
print(np.random.randn(2, 5))
np.random.seed(10101)
i = 0
while (i < 8):
print(np.random.randn(1, 5))
i += 1
输出结果:
[[-0.80798286 -0.715672 -0.05469627 -0.02866989 -0.60651316]]
[[-0.80798286 -0.715672 -0.05469627 -0.02866989 -0.60651316]]
[[-0.80798286 -0.715672 -0.05469627 -0.02866989 -0.60651316]]
[[-0.07166339 -0.90191647 -1.44930689 0.47544392 -0.69504091]]
[[-0.2945898 -0.29136881 -1.20912878 1.8411507 0.93088861]]
[[-0.3128147 0.26967738 0.79639595 1.63459931 -0.07928265]]
[[ 0.22448867 -0.18460644 0.16075816 1.03187033 -2.06079503]]
[[-0.20519297 -0.94413355 -0.7711631 -3.22276525 -1.03337154]]
[[ 0.59808117 1.43416183 -0.59450108 0.22930244 0.73604297]
[-0.05268705 -0.40967487 0.64970281 -0.91149992 -1.40876439]]
[[-0.80798286 -0.715672 -0.05469627 -0.02866989 -0.60651316]]
[[-0.07166339 -0.90191647 -1.44930689 0.47544392 -0.69504091]]
[[-0.2945898 -0.29136881 -1.20912878 1.8411507 0.93088861]]
[[-0.3128147 0.26967738 0.79639595 1.63459931 -0.07928265]]
[[ 0.22448867 -0.18460644 0.16075816 1.03187033 -2.06079503]]
[[-0.20519297 -0.94413355 -0.7711631 -3.22276525 -1.03337154]]
[[ 0.59808117 1.43416183 -0.59450108 0.22930244 0.73604297]]
[[-0.05268705 -0.40967487 0.64970281 -0.91149992 -1.40876439]]
结果解释:
从以上输出结果中可以看出在第一个while循环中(while i<6),i = 0,1,2的时候,seed()函数里的参数值都是10101,即生成随机数的起始位置都相同,所以生成的随机数也相同(结果都是[[-0.80798286 -0.715672 -0.05469627 -0.02866989 -0.60651316]])。当i = 3,4,5的时候,没有指定种子点,那么系统会根据时间自己选择生成随机数的起始位置,所以每次生成的随机数因时间差异而不同。
在第二个while循环中(while i<2),同样没有指定种子点,系统根据时间自己选择生成随机数的起始位置,所以每次生成的随机数因时间差异也不相同。
在第三个while循环中(while i<8),在进入循环前设置了随机数生成器种子点np.random.seed(10101),
与第一次循环中i = 0,1,2时seed()函数里的参数值相同,即生成随机数的起始位置都相同,所以生成的随机数也相同。但这里的随机数种子点是在循环前设置的,所以仅对进入循环后的i=0有效,当i=1时,系统就会根据时间自己选择生成随机数的起始位置,但是发现与第一次循环中从i=3开始生成的随机数相同,这也说明了像np.random.randn(),numpy.random.shuffle()等这些函数生成的数据可以理解成本身是固定不变的,即前一次如果种子点设置成10101,那么下一次如果没有设置种子点的话,系统根据时间自己选择的起始位置也是固定的,所以我们看到后面的7行数据与前两次循环中的7行数据是一样的。
还有在np.random.randn(2, 5)
中生成的数据与第三次循环中最后两行数据是一样的,这也说明了在生成多行随机数组时是由单行随机数组组合而成的。
举例2说明(目标检测中利用不同颜色绘制不同目标类别检测框):
import numpy as np import colorsys if __name__ == '__main__': hsv_tuples = [(x / 10, 1., 1.) for x in range(10)] colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), colors)) print(colors) np.random.seed(10100) np.random.shuffle(colors) # np.random.seed(None)#恢复默认种子点,即系统根据时间自己选择生成随机数的起始位置 print(colors)
输出结果(每次输出都是一样的):即在numpy.random.seed()后使用numpy.random.shuffle(array)可以实现同样随机结果的打乱顺序
[(255, 0, 0), (255, 153, 0), (203, 255, 0), (51, 255, 0), (0, 255, 102), (0, 255, 255), (0, 102, 255), (50, 0, 255), (204, 0, 255), (255, 0, 152)]
[(255, 0, 152), (50, 0, 255), (51, 255, 0), (0, 255, 255), (0, 255, 102), (255, 153, 0), (204, 0, 255), (203, 255, 0), (255, 0, 0), (0, 102, 255)]