RandomUniform#
バージョン名: RandomUniform-8
カテゴリー: 生成
簡単な説明: RandomUniform 操作は、一様分布からランダムな値のシーケンスを生成します。
詳細な説明:
RandomUniform 操作は、範囲 [minval, maxval)
の一様分布から乱数を生成します。生成アルゴリズムは、Philox アルゴリズムを使用する基礎となるランダム整数ジェネレーターに基づいています。Philox アルゴリズムは、uint32 値を生成するカウンターベースの擬似乱数ジェネレーターです。Philox アルゴリズムを 1 回呼び出すと、指定されたキーとカウンターの値に応じて 4 つのランダムな結果値が返されます。キーとカウンターはそれぞれ global_seed 属性と op_seed 属性で初期化されます。
両方のシード値がゼロに等しい場合、RandomUniform は非決定論的なシーケンスを生成します。
元の論文 Parallel Random Numbers: As Easy as 1, 2, 3 へのリンク。
Philox の結果は、固定数のキーとカウンターの更新、いわゆる “ラウンド” を適用することによって計算されます。この実装では、Philox アルゴリズムの 4x32_10 バージョン (ラウンド数 = 10) が使用されます。
ランダムシーケンスの n 番目の 4 要素を決定する n があるとします。各ラウンドキーでは、counter と n が uint32 値のペアに分割されます:
ここで、cast_to_uint32 - uint32 への静的キャスト、value - uint64 入力値、L、R - uint32 結果の値、>> - ビット単位の右シフト。
次に、n と counter が次の式で更新されます:
ここで、0xD2511F53
- n 更新、M = 0xCD9E8D57
- カウンター更新。
各ラウンドの後、別の const 値のペアと合計することによってキーが生成されます。
値
[0..1) 間の浮動小数点値は、次の規則に従って 32 ビット整数から取得されます。
Float16 は、符号 (1 ビット) 指数 (5 ビット) 仮数 (10 ビット) のようにフォーマットされます。値は次の式で解釈されます:
したがって、float16 値を取得するには、符号、指数、仮数は次のように設定されます:
符号 = 0 指数 = 15 - ゼロ指数の表現。
仮数 = 生成された uint32 ランダム値からの右 10 ビット。
したがって、結果の float16 値は次のようになります:
x_uint16 = x // 上位 16 ビットを切り捨てます。
val = ((指数 << 10) | x_uint16 & 0x3ffu) - 1.0
ここで、x は uint32 で生成されたランダム値です。
Float32 は、符号 (1 ビット) 指数 (8 ビット) 仮数 (23 ビット) のようにフォーマットされます。値は次の式で解釈されます:
したがって、float 値を取得するには、符号、指数、仮数は次のように設定されます:
符号 = 0 指数 = 127 - ゼロ指数の表現。
仮数 = 生成された uint32 ランダム値からの右 23 ビット。
したがって、結果の float 値は次のようになります:
val = ((指数 << 23) | x & 0x7fffffu) - 1.0,
ここで、x は uint32 で生成されたランダム値です。
Double は次のようにフォーマットされます: 符号 (1 ビット) 指数 (11 ビット) 仮数 (52 ビット)。値は次の式で解釈されます:
したがって、double 値を取得するには、符号、指数、仮数は次のように設定されます:
符号 = 0 指数 = 1023 - ゼロ指数の表現。
仮数 = ランダム整数ジェネレーターからの 2 つの連結された uint32 値の右側の 52 ビット。
したがって、結果の double は次のように取得されます:
mantissa_h = x0 & 0xfffffu; // 仮数の上位 20 ビット
mantissa_l = x1; // 仮数の下位 32 ビット
mantissa = (mantissa_h << 32) | mantissa_l;
val = ((exponent << 52) | mantissa) - 1.0,
ここで、x0、x1 は uint32 で生成されたランダム値です。
指定された範囲の値を取得するには、各値が次の式で処理されます:
float 値の場合:
ここで、x は [0..1) 間のランダムな float または double 値です。
整数値の場合:
ここで、x は uint32 のランダム値です。
例 1global_seed
= 150、op_seed
= 10、output_type
= f32 の RandomUniform 出力:
input_shape = [ 3, 3 ]
output = [[0.7011236 0.30539632 0.93931055] [0.9456035 0.11694777 0.50770056] [0.5197197 0.22727466 0.991374 ]]
例 2global_seed
= 80、op_seed
= 100、output_type
double の RandomUniform 出力:
input_shape = [ 2, 2 ]
minval = 2
maxval = 10
output = [[5.65927959 4.23122376] [2.67008206 2.36423758]]
例 3global_seed
= 80、op_seed
= 100、output_type
= i32 の RandomUniform 出力:
input_shape = [ 2, 3 ]
minval = 50
maxval = 100
output = [[65 70 56] [59 82 92]]
属性:
output_type
説明: 出力のタイプ生成アルゴリズムを決定し、結果の値に影響します。output_type の異なる値に対して生成される出力番号は、等しくない場合があります。
値の範囲: “i32”, “i64”, “f16”, “bf16”, “f32”, “f64”
タイプ: 文字列
必須: はい
global_seed
説明: グローバルシード値。
値の範囲: 正の整数
タイプ: int
デフォルト値: 0
必須: はい
op_seed
説明: 運用シード値。
値の範囲: 正の整数
タイプ: int
デフォルト値: 0
必須: はい
入力:
1:
shape
- 出力形状を記述する T_SHAPE タイプの 1D テンソル。必須。2:
minval
- 属性 output_type で指定されたタイプを持つ 1 つの要素を持つスカラーまたは 1D テンソルは、生成するランダム値の範囲の下限を定義します (両端を含む)。必須。3:
maxval
- 属性 output_type で指定されたタイプを持つ 1 つの要素を持つスカラーまたは 1D テンソルは、生成するランダム値の範囲の上限を定義します (排他的)。必須。
出力:
1: 属性 output_type で指定されたタイプと、
shape
入力テンソルで定義された形状を持つテンソル。
タイプ
T_SHAPE:
int32
またはint64
。
例 1: IR の例。
<layer ... name="RandomUniform" type="RandomUniform">
<data output_type="f32" global_seed="234" op_seed="148"/>
<input>
<port id="0" precision="I32">
<!-- shape 値: [2, 3, 10] -->
<dim>3</dim>
</port>
<port id="1" precision="FP32"/>
<!-- min 値 -->
<port id="2" precision="FP32"/>
<!-- max 値 -->
</input>
<output>
<port id="3" precision="FP32" names="RandomUniform:0">
<dim>2</dim>
<dim>3</dim>
<dim>10</dim>
</port>
</output>
</layer>