【问题标题】:Random seed across different PBS jobs跨不同 PBS 作业的随机种子
【发布时间】:2013-06-18 08:52:51
【问题描述】:

我正在尝试在 Matlab 中创建随机数,这将在多个 PBS 作业中有所不同(我正在使用作业数组)。每个 Matlab 作业都使用一个并行 parfor 循环,其中生成随机数,如下所示:

parfor k = 1:10      
  tmp = randi(100, [1 200]);
end

但是,当我绘制结果时,我发现来自不同工作的结果并非完全随机 - 我无法量化它,例如说数字完全相同,因为我的结果是随机数的函数,但是绘制它时是明白无误的。 我尝试使用进程 ID 和/或时钟来初始化每个作业中的随机种子:

rngSeed = feature('getpid'); % OR: rngSeed = RandStream.shuffleSeed;
rng(rngSeed);

但这并没有解决问题。在使用 shuffleSeed(基于时钟)之前,我还尝试在每个作业中暂停不同的秒数。

所有这一切让我认为 parfor 在某种程度上弄乱了随机种子 - 如果 parfor 需要确保您在 parfor 的不同迭代中获得不同的随机数,这是有道理的。

我的问题是,真的是这样吗?我该如何解决它并在不同的 PBS 作业中获得随机性?

EDIT 运行 4 个作业,每个作业使用 parfor 和 2 个工人,我验证虽然每个作业都有自己的种子(设置在 parfor 之外),但生成的数字在作业之间是相同的(而不是在迭代之间parfor 的 - 由 Matlab 处理)。

EDIT 2尝试@Sam Roberts 的建议,我使用以下代码:

matlabpool open local 2
st = RandStream('mlfg6331_64');
RandStream.setGlobalStream(st);
rng('shuffle');

parfor n = 1:4       
  x=randi(100,[1 10]);
  fprintf('%d ',x(:)');
  fprintf('\n')
end
matlabpool close

但在对上述脚本的不同调用中,我仍然得到相同的数字。

【问题讨论】:

    标签: matlab random pbs parfor


    【解决方案1】:

    您可能需要考虑使用随机子流,以便在并行运行时获得正确的随机性和可重复性。

    RandStream 类允许您创建伪随机数流 - 从该流中提取的数字具有您希望的属性(独立性等),并且如果您控制种子,您还具有可重复性。

    但情况可能并非如此,例如,从流中提取的每一秒或每第四个数字都具有相同的属性。此外,当您使用parfor 时,您无法控制循环迭代的运行顺序,这意味着您将失去可重复性。您可以在 parfor 循环中对每个工作人员使用不同的子流。

    一些 RNG,例如 mlfg6331_64,一个乘法滞后斐波那契生成器,或 mrg32k3a,一个组合的多重递归生成器,支持 子流 - 由同一 RNG 生成的独立流,但保留相同的伪随机属性,可以单独选择,保持可重复性。此外,许多 MATLAB 和 Toolbox 函数都有一个选项 'UseParallel''UseSubstreams',它们会告诉它们自动为你做这些事情。

    虽然上述内容在 MATLAB 文档中以技术级别进行了记录,但很难找到。 Statistics Toolbox 文档中有更多解释性指南(如果你问我,应该真的移到 MATLAB)。你可以在线阅读here

    希望有帮助!

    【讨论】:

    • 这里有几篇博客文章:blogs.mathworks.com/loren/2008/11/05/…blogs.mathworks.com/loren/2008/11/13/…,它们提供了一些额外的见解。此外,引用 Peter Perkins 的话:“通过将流(或子流)索引基于任务、工作人员或运行,您可以确保不会重复使用相同的随机数。”
    • 那么,基本上你建议我自己在 parfor 中处理种子,而不是让 parfor 处理并行性质?我只是想确保我理解你的提议。
    • 否 - 在客户端上创建一个 RandStream,使用上面支持子流的生成器之一。比如说,叫它s。如果您愿意,可以在客户端上设置一次s 的种子。然后在parfor 中,MATLAB 给每次迭代一个索引,并使用它来选择不同的子流来生成随机数。
    • 谢谢。如果我使用支持子流的生成器,我会在不同的调用中得到相同的随机数流,即使我在 parfor 之前调用 rng('shuffle')。我无法在 parfor 内设置子流,因为它会导致 parfor 在保存流的变量上返回 variable cannot be classified - 无论如何我的问题是在调用之间,而不是在 parfor 的迭代之间。任何的想法? (我会将我的代码粘贴到问题中)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2018-07-15
    • 2011-06-13
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多