TensorFlow中的随机数 tf.random_uniform

TF中的随机数

Tensorflow中提供了若干算子来生成均匀分布、正态分布的随机数,或者实现随机排列、随机挑选等功能。

Operations

Functions

tf.random_normal

Outputs random values from a normal distribution. 正态分布

tf.truncated_normal

Outputs random values from a truncated normal distribution.

截断的正态分布,偏离大于2倍标准差的数会被丢弃再重新选择

tf.random_uniform

Outputs random values from a uniform distribution. 均匀分布[min,max)

tf.random_shuffle

Randomly shuffles a tensor along its first dimension. 第一维随机排列

tf.multinomial

Slices a portion out of input tensor at a uniformly chosen offset.

从输入数据value中随机剪切大小为size的部分数据

tf.random_gamma

Draws samples from each of the given Gamma distribution(s). 伽马分布

Tensorflow中也通过设置randomseed来产生不同的随机序列。需要注意的是,TF中有两种级别的random seed一个是operation-level,一个是graph-level都会影响随机数生成:

  1. op-level:  在调用上述表格中的算子时,可以显式指定seed参数,若seed参数相同,则在同一张graph里,每次运行生结果相同;若不指定seed参数,则每次使用随机的seed,运行结果不同
  2. graph-level:  调用tf.set_random_seed来设置graph-level seed。如果设置了graph-level seed,即使不显式设置算子的seed参数,也可以在同一张graph里,每次生成相同的结果。

     

  根据是否设置op-levelseedgraph-level seedTensorflow中有以下4种不同情况:

Set graph-level

Set op-level

Results

A random seed is used for this op

×

The system deterministically picks an operation seed in conjunction with the graph-level seed so that it gets a unique random sequence.

×

A default graph-level seed and the specified operation seed are used to determine the random sequence.

×

×

Both seeds are used in conjunction to determine the random sequence.

参考文献:

https://tensorflow.google.cn/api_guides/python/constant_op#Random_Tensors

https://tensorflow.google.cn/api_docs/python/tf/set_random_seed (这里有详细的代码示例)


tf.random_normal探究

tf.random_uniform为例,再深入看一下。函数接口:

tf.random_uniform(
    shape,
    minval=0,
    maxval=None,
    dtype=tf.float32,
    seed=None,
    name=None
)

在/tensorflow/python/ops/random_ops.py定义了random_uniform:

     TensorFlow中的随机数 tf.random_uniform


 在\tensorflow\core\kernels\random_op.cc中定义了RandomUnifromIntOP:

  TensorFlow中的随机数 tf.random_uniform

       

    在random_op.cc中还定义了FillPhiloxRandom:

      TensorFlow中的随机数 tf.random_uniform

    在\tensorflow\core\lib\random\philox_random.h中定义PhiloxRandom(节选部分代码):

      TensorFlow中的随机数 tf.random_uniform

      TensorFlow中的随机数 tf.random_uniform

  计算了10次ComputeSingleRound:

     TensorFlow中的随机数 tf.random_uniform

  按论文设置的参数:

    TensorFlow中的随机数 tf.random_uniform

 在每次ComputeSingleRound里计算低位、高位的乘法:

    TensorFlow中的随机数 tf.random_uniform

    TensorFlow中的随机数 tf.random_uniform

关于philox_4x32_10

    Philox是一种伪随机数生成方法,来自2011年的论文《ParallelRandom Numbers: As Easy as 1, 2, 3》(https://pdfs.semanticscholar.org/38bc/7fc62136ec779d91b86b6e960a06d67b4a97.pdf)。TF代码中的参数设置也是来自这篇文章。

        Philox_4x32_10是一种在GPU上速度比较快的方法,下图来自论文。

        TensorFlow中的随机数 tf.random_uniform


线性同余法

线性同余法(Linear congruentialgeneratorLCG)是目前应用广泛的伪随机数生成算法,其基本思想是通过对前一个数进行线性运算并取模从而得到下一个数。

TensorFlow中的随机数 tf.random_uniform

线性同余法常用在编程语言函数库中产生随机数,但是不适用于加***的生成。因为当被攻击者获取到某些随机数之后,其种子seed以及ACM都会被反向计算出来,即有可能根据以往随机数预测出之后还未产生的随机数。

参考文献:

https://zh.wikipedia.org/wiki/%E7%B7%9A%E6%80%A7%E5%90%8C%E9%A4%98%E6%96%B9%E6%B3%95

https://blog.****.net/Apollon_krj/article/details/78718598


C/C++中的随机数实现

stdlib.h中,rand()函数可以用来产生随机数,但这不是真正意义上的随机数,是一个伪随机数,是根据一个数(称为种子)为基准以某个递推公式推算出来的一系列数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数。

rand()的内部实现是用线性同余法做的,因其周期特别长,故在一定的范围里可看成是随机的。

实现方法:

1.       先调用srand函数,初始化随机数发生器,seed值相同则生成的随机数也相同。一般采用时间作为参数,每次运行的时间不同,产生的随机数也不同。

2.       再调用rand函数就可以生成随机数了。

1.  #include <iostream>  

2.  #include "cstdlib"  

3.  /* 随机生成1~6之间的整数 */  

4.  using namespace std;  

5.  int main() {  

6.      //基于当前日期与时间为随机生成器确定种子  

7.      srand(static_cast<unsigned int>(time(0)));

8.      int randomNumber = rand();//rand()的返回值是随机数  

9.      int num = (randomNumber % 6) + 1;  

10.     cout << num << endl;  

11.     return 0;  

12. }  

  由于rand函数只能返回一定范围内的随机整数,存在很大的局限性。针对这些问题,C++ 11提供了新的随机数库:random-number enginesrandom-number distributionclasses,来生成不同范围内的随机整数和浮点数、随机分布等。

  不过,生成随机数的原理还是相同的。