इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

यादृच्छिक संख्या पीढ़ी

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

TensorFlow, tf.random मॉड्यूल में छद्म-यादृच्छिक संख्या जनरेटर (RNG) का एक सेट प्रदान करता है। यह दस्तावेज़ बताता है कि आप यादृच्छिक संख्या जनरेटर को कैसे नियंत्रित कर सकते हैं, और ये जनरेटर अन्य टेंसोफ़्लो उप-प्रणालियों के साथ कैसे संपर्क करते हैं।

TensorFlow यादृच्छिक संख्या पीढ़ी प्रक्रिया को नियंत्रित करने के लिए दो दृष्टिकोण प्रदान करता है:

  1. tf.random.Generator वस्तुओं के स्पष्ट उपयोग के माध्यम से। ऐसी प्रत्येक वस्तु एक राज्य बनाए रखती है ( tf.Variable ) जिसे प्रत्येक संख्या पीढ़ी के बाद बदल दिया जाएगा।

  2. विशुद्ध रूप से कार्यात्मक स्टेटलेस यादृच्छिक कार्यों जैसे tf.random.stateless_uniform । इन कार्यों को एक ही तर्क (जिसमें बीज शामिल हैं) और एक ही डिवाइस पर कॉल करना हमेशा समान परिणाम देगा।

सेट अप

 import tensorflow as tf

# Creates 2 virtual devices cpu:0 and cpu:1 for using distribution strategy
physical_devices = tf.config.experimental.list_physical_devices("CPU")
tf.config.experimental.set_virtual_device_configuration(
    physical_devices[0], [
        tf.config.experimental.VirtualDeviceConfiguration(),
        tf.config.experimental.VirtualDeviceConfiguration()
    ])
 

tf.random.Generator वर्ग

tf.random.Generator वर्ग का उपयोग उन मामलों में किया जाता है जहां आप प्रत्येक RNG कॉल को अलग-अलग परिणाम देना चाहते हैं। यह एक आंतरिक स्थिति रखता है (एक tf.Variable ऑब्जेक्ट द्वारा प्रबंधित) जो हर बार यादृच्छिक संख्या उत्पन्न होने पर अपडेट किया जाएगा। क्योंकि राज्य tf.Variable द्वारा प्रबंधित किया tf.Variable , इसलिए यह tf.Variable द्वारा आसान चेकपॉइंटिंग, स्वचालित नियंत्रण-निर्भरता और थ्रेड सुरक्षा जैसी सभी सुविधाएं प्रदान करता है।

आप एक प्राप्त कर सकते हैं tf.random.Generator मैन्युअल वर्ग या कॉल की एक वस्तु बनाने के द्वारा tf.random.get_global_generator() डिफ़ॉल्ट वैश्विक जनरेटर पाने के लिए:

 g1 = tf.random.Generator.from_seed(1)
print(g1.normal(shape=[2, 3]))
g2 = tf.random.get_global_generator()
print(g2.normal(shape=[2, 3]))
 
tf.Tensor(
[[ 0.43842274 -0.53439844 -0.07710262]
 [ 1.5658046  -0.1012345  -0.2744976 ]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[-0.6078218  3.162639  -1.0558378]
 [ 1.2078347  0.6414574  0.4019502]], shape=(2, 3), dtype=float32)

जनरेटर ऑब्जेक्ट बनाने के कई तरीके हैं। सबसे आसान Generator.from_seed , जैसा कि ऊपर दिखाया गया है, जो एक बीज से एक जनरेटर बनाता है। एक बीज किसी भी गैर-नकारात्मक पूर्णांक है। from_seed एक वैकल्पिक तर्क alg भी लेता है जो RNG एल्गोरिथम है जो इस जनरेटर द्वारा उपयोग किया जाएगा:

 g1 = tf.random.Generator.from_seed(1, alg='philox')
print(g1.normal(shape=[2, 3]))
 
tf.Tensor(
[[ 0.43842274 -0.53439844 -0.07710262]
 [ 1.5658046  -0.1012345  -0.2744976 ]], shape=(2, 3), dtype=float32)

इसके बारे में अधिक जानकारी के लिए नीचे एल्गोरिदम अनुभाग देखें।

जेनरेटर बनाने का एक और तरीका है Generator.from_non_deterministic_state । इस तरह से बनाया गया एक जनरेटर एक गैर-नियतात्मक राज्य से शुरू होगा, उदाहरण के लिए समय और ओएस पर निर्भर करता है।

 g = tf.random.Generator.from_non_deterministic_state()
print(g.normal(shape=[2, 3]))
 
tf.Tensor(
[[ 1.1436943  1.729618   1.0391121]
 [-0.8502223 -1.8823647 -1.4051851]], shape=(2, 3), dtype=float32)

जनरेटर बनाने के अन्य तरीके अभी भी हैं, जैसे कि स्पष्ट राज्यों से, जो इस गाइड द्वारा कवर नहीं किए गए हैं।

वैश्विक जनरेटर प्राप्त करने के लिए tf.random.get_global_generator का उपयोग करते tf.random.get_global_generator , आपको डिवाइस प्लेसमेंट के बारे में सावधान रहने की आवश्यकता है। वैश्विक जनरेटर पहली बार tf.random.get_global_generator कहा जाता है, और उस कॉल पर डिफ़ॉल्ट डिवाइस पर रखा जाता है। इसलिए, उदाहरण के लिए, यदि आप पहली साइट जिसे tf.random.get_global_generator कहते हैं, एक tf.device("gpu") दायरे में है, तो वैश्विक जनरेटर को GPU पर रखा जाएगा, और CPU द्वारा बाद में वैश्विक जनरेटर का उपयोग किया जाएगा। एक जीपीयू-से-सीपीयू कॉपी को लाइक करें।

वैश्विक जनरेटर को दूसरे जनरेटर ऑब्जेक्ट के साथ बदलने के लिए एक फ़ंक्शन tf.random.set_global_generator भी है। इस फ़ंक्शन का उपयोग सावधानी से सोचा जाना चाहिए, क्योंकि पुराने वैश्विक जनरेटर को tf.function (एक कमजोर संदर्भ के रूप में) द्वारा कैप्चर किया जा सकता है, और इसकी जगह लेने से यह कचरा एकत्रित हो जाएगा, जिससे tf.function टूट जाएगा। वैश्विक जनरेटर पुनर्स्थापित करने के लिए एक बेहतर तरीका जैसे कि "रीसेट" कार्यों में से एक का उपयोग करने के लिए है Generator.reset_from_seed , जो नए जनरेटर वस्तुओं को बनाने नहीं होंगे।

 g = tf.random.Generator.from_seed(1)
print(g.normal([]))
print(g.normal([]))
g.reset_from_seed(1)
print(g.normal([]))
 
tf.Tensor(0.43842274, shape=(), dtype=float32)
tf.Tensor(1.6272374, shape=(), dtype=float32)
tf.Tensor(0.43842274, shape=(), dtype=float32)

स्वतंत्र यादृच्छिक-संख्या स्ट्रीम बनाना

कई अनुप्रयोगों में एक को कई स्वतंत्र यादृच्छिक-संख्या धाराओं की आवश्यकता होती है, इस अर्थ में स्वतंत्र कि वे ओवरलैप नहीं होंगे और उनके पास कोई सांख्यिकीय पता लगाने योग्य सहसंबंध नहीं होंगे। यह कई जनरेटर बनाने के लिए Generator.split का उपयोग करके प्राप्त किया जाता है जो एक-दूसरे से स्वतंत्र होने की गारंटी देते हैं (यानी स्वतंत्र स्ट्रीम उत्पन्न करते हैं)।

 g = tf.random.Generator.from_seed(1)
print(g.normal([]))
new_gs = g.split(3)
for new_g in new_gs:
  print(new_g.normal([]))
print(g.normal([]))
 
tf.Tensor(0.43842274, shape=(), dtype=float32)
tf.Tensor(2.536413, shape=(), dtype=float32)
tf.Tensor(0.33186463, shape=(), dtype=float32)
tf.Tensor(-0.07144657, shape=(), dtype=float32)
tf.Tensor(-0.79253083, shape=(), dtype=float32)

split जनरेटर की स्थिति को बदल देगा, जिस पर इसे कहा जाता है (उपरोक्त उदाहरण में g ), normal जैसे आरएनजी विधि के समान। एक दूसरे से स्वतंत्र होने के अलावा, नए जनरेटर ( new_gs ) को पुराने ( g ) से स्वतंत्र होने की गारंटी भी दी जाती है।

नए जेनरेटर्स को पैदा करना तब भी उपयोगी होता है जब आप यह सुनिश्चित करना चाहते हैं कि आप जिस जनरेटर का उपयोग करते हैं, वह अन्य डिवाइसों के समान डिवाइस पर हो, क्रॉस-डिवाइस कॉपी के ओवरहेड से बचने के लिए। उदाहरण के लिए:

 with tf.device("cpu"):  # change "cpu" to the device you want
  g = tf.random.get_global_generator().split(1)[0]  
  print(g.normal([]))  # use of g won't cause cross-device copy, unlike the global generator
 
tf.Tensor(-1.7580209, shape=(), dtype=float32)

आप विभाजन को पुनरावर्ती रूप से कर सकते हैं, स्प्लिटेड जनरेटर पर split को बुला सकते हैं। पुनरावृत्तियों की गहराई पर कोई सीमा (पूर्णांक ओवरफ़्लो को रोकना) नहीं है।

tf.function साथ tf.function

tf.random.Generator रूप में एक ही नियमों का अनुसरण करता tf.Variable जब साथ प्रयोग किया tf.function । इसमें तीन पहलू शामिल हैं।

tf.function बाहर जनरेटर बनाना

tf.function इसके बाहर निर्मित जनरेटर का उपयोग कर सकता है।

 g = tf.random.Generator.from_seed(1)
@tf.function
def foo():
  return g.normal([])
print(foo())
 
tf.Tensor(0.43842274, shape=(), dtype=float32)

उपयोगकर्ता को यह सुनिश्चित करने की आवश्यकता होती है कि फ़ंक्शन कहा जाने पर जनरेटर ऑब्जेक्ट अभी भी जीवित है (कचरा एकत्र नहीं)।

tf.function अंदर जनरेटर बनाना

एक tf.function अंदर जनरेटर का निर्माण केवल फ़ंक्शन के पहले रन के दौरान ही हो सकता है।

 g = None
@tf.function
def foo():
  global g
  if g is None:
    g = tf.random.Generator.from_seed(1)
  return g.normal([])
print(foo())
print(foo())
 
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
tf.Tensor(0.43842274, shape=(), dtype=float32)
tf.Tensor(1.6272374, shape=(), dtype=float32)

tf.function तर्क के रूप में जनरेटर पारित tf.function

जब एक tf.function तर्क के रूप में उपयोग किया जाता है, तो एक ही राज्य आकार (राज्य आकार RNG एल्गोरिथ्म द्वारा निर्धारित किया जाता है) के साथ विभिन्न जनरेटर ऑब्जेक्ट tf.function का tf.function का कारण नहीं होगा, जबकि विभिन्न राज्य आकार वाले।

 num_traces = 0
@tf.function
def foo(g):
  global num_traces
  num_traces += 1
  return g.normal([])
foo(tf.random.Generator.from_seed(1))
foo(tf.random.Generator.from_seed(2))
print(num_traces)
 
1

वितरण रणनीतियों के साथ सहभागिता

तीन तरीके हैं जिनमें Generator वितरण रणनीतियों के साथ बातचीत करता है।

वितरण रणनीतियों के बाहर जनरेटर बनाना

यदि कोई जनरेटर रणनीति स्कोप के बाहर बनाया जाता है, तो सभी प्रतिकृति की जनरेटर तक पहुंच को क्रमबद्ध किया जाएगा, और इसलिए प्रतिकृतियों को अलग-अलग यादृच्छिक संख्याएं मिलेंगी।

 g = tf.random.Generator.from_seed(1)
strat = tf.distribute.MirroredStrategy(devices=["cpu:0", "cpu:1"])
with strat.scope():
  def f():
    print(g.normal([]))
  results = strat.run(f)
 
WARNING:tensorflow:There are non-GPU devices in `tf.distribute.Strategy`, not using nccl allreduce.
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:CPU:0', '/job:localhost/replica:0/task:0/device:CPU:1')
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `run` inside a tf.function to get the best performance.
tf.Tensor(0.43842274, shape=(), dtype=float32)
tf.Tensor(1.6272374, shape=(), dtype=float32)

ध्यान दें कि इस उपयोग में प्रदर्शन समस्याएँ हो सकती हैं क्योंकि जनरेटर का उपकरण प्रतिकृतियों से भिन्न होता है।

वितरण रणनीतियों के अंदर जनरेटर बनाना

रणनीति स्कोप के अंदर जनरेटर बनाना बंद कर दिया जाता है, क्योंकि एक जनरेटर को दोहराने के तरीके पर अस्पष्टता है (जैसे कि इसे कॉपी किया जाना चाहिए ताकि प्रत्येक प्रतिकृति को एक ही यादृच्छिक संख्या मिल जाए, या 'विभाजन' हो ताकि प्रत्येक प्रतिकृति को अलग-अलग यादृच्छिक संख्याएं मिलें)।

 strat = tf.distribute.MirroredStrategy(devices=["cpu:0", "cpu:1"])
with strat.scope():
  try:
    tf.random.Generator.from_seed(1)
  except ValueError as e:
    print("ValueError:", e)
 
WARNING:tensorflow:There are non-GPU devices in `tf.distribute.Strategy`, not using nccl allreduce.
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:CPU:0', '/job:localhost/replica:0/task:0/device:CPU:1')
ValueError: Creating a generator within a strategy scope is disallowed, because there is ambiguity on how to replicate a generator (e.g. should it be copied so that each replica gets the same random numbers, or 'split' so that each replica gets different random numbers).

ध्यान दें कि Strategy.run अपने तर्क फ़ंक्शन को एक रणनीति दायरे में निहित करेगा:

 strat = tf.distribute.MirroredStrategy(devices=["cpu:0", "cpu:1"])
def f():
  tf.random.Generator.from_seed(1)
try:
  strat.run(f)
except ValueError as e:
  print("ValueError:", e)
 
WARNING:tensorflow:There are non-GPU devices in `tf.distribute.Strategy`, not using nccl allreduce.
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:CPU:0', '/job:localhost/replica:0/task:0/device:CPU:1')
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `run` inside a tf.function to get the best performance.
INFO:tensorflow:Error reported to Coordinator: Creating a generator within a strategy scope is disallowed, because there is ambiguity on how to replicate a generator (e.g. should it be copied so that each replica gets the same random numbers, or 'split' so that each replica gets different random numbers).
Traceback (most recent call last):
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/coordinator.py", line 297, in stop_on_exception
    yield
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/distribute/mirrored_strategy.py", line 998, in run
    self.main_result = self.main_fn(*self.main_args, **self.main_kwargs)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/autograph/impl/api.py", line 282, in wrapper
    return func(*args, **kwargs)
  File "<ipython-input-14-2cd7806456bd>", line 3, in f
    tf.random.Generator.from_seed(1)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/stateful_random_ops.py", line 444, in from_seed
    return cls(state=state, alg=alg)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/stateful_random_ops.py", line 386, in __init__
    trainable=False)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/stateful_random_ops.py", line 272, in _create_variable
    "Creating a generator within a strategy scope is disallowed, because "
ValueError: Creating a generator within a strategy scope is disallowed, because there is ambiguity on how to replicate a generator (e.g. should it be copied so that each replica gets the same random numbers, or 'split' so that each replica gets different random numbers).
ValueError: Creating a generator within a strategy scope is disallowed, because there is ambiguity on how to replicate a generator (e.g. should it be copied so that each replica gets the same random numbers, or 'split' so that each replica gets different random numbers).

Strategy.run लिए तर्क के रूप में जनरेटर पारित करना

यदि आप प्रत्येक प्रतिकृति को अपने स्वयं के जनरेटर का उपयोग करना चाहते हैं, तो आपको n जनरेटर बनाने की आवश्यकता है (या तो कॉपी करके या विभाजित करके), जहां n प्रतिकृतियों की संख्या है, और फिर उन्हें Strategy.run तर्क के रूप में पास करें।

 strat = tf.distribute.MirroredStrategy(devices=["cpu:0", "cpu:1"])
gs = tf.random.get_global_generator().split(2)
# to_args is a workaround for the absence of APIs to create arguments for 
# run. It will be replaced when such APIs are available.
def to_args(gs):  
  with strat.scope():
    def f():
      return [gs[tf.distribute.get_replica_context().replica_id_in_sync_group]]
    return strat.run(f)
args = to_args(gs)
def f(g):
  print(g.normal([]))
results = strat.run(f, args=args)
 
WARNING:tensorflow:There are non-GPU devices in `tf.distribute.Strategy`, not using nccl allreduce.
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:CPU:0', '/job:localhost/replica:0/task:0/device:CPU:1')
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `run` inside a tf.function to get the best performance.
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `run` inside a tf.function to get the best performance.
tf.Tensor(-0.15682742, shape=(), dtype=float32)
tf.Tensor(-0.38042808, shape=(), dtype=float32)

स्टेटलेस आरएनजी

स्टेटलेस RNG का उपयोग सरल है। चूंकि वे सिर्फ शुद्ध कार्य हैं, कोई राज्य या साइड इफेक्ट शामिल नहीं है।

 print(tf.random.stateless_normal(shape=[2, 3], seed=[1, 2]))
print(tf.random.stateless_normal(shape=[2, 3], seed=[1, 2]))
 
tf.Tensor(
[[ 0.5441101   0.20738031  0.07356433]
 [ 0.04643455 -1.3015898  -0.95385665]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[ 0.5441101   0.20738031  0.07356433]
 [ 0.04643455 -1.3015898  -0.95385665]], shape=(2, 3), dtype=float32)

प्रत्येक स्टेटलेस RNG को एक seed तर्क की आवश्यकता होती है, जिसे आकार का पूर्णांक Tensor होना आवश्यक है [2] । इस बीज से ऑप के परिणाम पूरी तरह से निर्धारित होते हैं।

एल्गोरिदम

सामान्य

दोनों tf.random.Generator वर्ग और stateless फ़ंक्शंस सभी उपकरणों पर Philox एल्गोरिथ्म ( "philox" या tf.random.Algorithm.PHILOX रूप में लिखे tf.random.Algorithm.PHILOX ) का समर्थन करते हैं।

यदि एक ही एल्गोरिथ्म का उपयोग कर और एक ही राज्य से शुरू करने पर विभिन्न डिवाइस एक ही पूर्णांक संख्या उत्पन्न करेंगे। वे "लगभग समान" फ्लोट-पॉइंट नंबर भी उत्पन्न करेंगे, हालांकि छोटे-छोटे संख्यात्मक विसंगतियां हो सकती हैं, क्योंकि विभिन्न तरीके से फ़्लोट-पॉइंट कम्प्यूटेशन (जैसे कमी क्रम) को पूरा करते हैं।

XLA डिवाइस

XLA- चालित उपकरणों पर (जैसे कि TPU, और CPU / GPU जब XLA सक्षम होता है) थ्रीफ्री एल्गोरिथम ( "threefry" या tf.random.Algorithm.THREEFRY एल्गोरिदम. tf.random.Algorithm.THREEFRY ) के रूप में भी समर्थित है। यह एल्गोरिथ्म TPU पर तेज़ है लेकिन Philox की तुलना में CPU / GPU पर धीमा है।

इन एल्गोरिदम के बारे में अधिक जानकारी के लिए पेपर 'समानांतर रैंडम संख्या: जितना आसान 1, 2, 3' देखें।