Воспроизводимость в параллельных статистических расчетах

Проблемы и факторы при воспроизведении параллельных расчетов

reproducible расчета является таким, который дает одинаковые результаты каждый раз, когда он запускается. Воспроизводимость важна для:

  • Отладка - Чтобы исправить аномальный результат, нужно воспроизвести результат.

  • Доверие - когда можно воспроизвести результаты, можно исследовать и понять их.

  • Изменение существующего кода - Когда вы изменяете существующий код, вы хотите убедиться, что вы ничего не нарушаете.

Как правило, вам не нужно обеспечивать воспроизводимость для вашего расчета. Часто, когда вы хотите воспроизводимости, самый простой метод - запускать последовательно, а не параллельно. В последовательных расчетах можно просто вызвать rng функционировать следующим образом:

s = rng % Obtain the current state of the random stream
% run the statistical function
rng(s) % Reset the stream to the previous state
% run the statistical function again, obtain identical results

В этом разделе рассматривается случай, когда ваша функция использует случайные числа, и вы хотите, чтобы воспроизводимые результаты были параллельными. В этом разделе также рассматривается случай, когда необходимо, чтобы те же результаты были параллельными, как и в последовательной системе.

Выполнение воспроизводимых параллельных расчетов

Чтобы запустить Statistics and Machine Learning Toolbox™ функционируйте воспроизводимо:

  1. Установите UseSubstreams опция для true использование statset.

  2. Установите Streams опция типа, поддерживающего субпотоки: 'mlfg6331_64' или 'mrg32k3a'. Для получения информации об этих потоках смотрите RandStream.list.

  3. Чтобы вычислить параллельно, установите UseParallel опция для true.

  4. Для параллельной подгонки ансамбля с помощью fitcensemble или fitrensemble, создайте шаблон дерева с 'Reproducible' Пара "имя-значение" установлена на true:

    t = templateTree('Reproducible',true);
    ens = fitcensemble(X,Y,'Method','bag','Learners',t,...
        'Options',options);
  5. Вызовите функцию со структурой опций.

  6. Чтобы воспроизвести расчеты, сбросьте поток, а затем снова вызовите функцию.

Чтобы понять, почему этот метод дает воспроизводимость, смотрите, Как Субпотоки Включают Воспроизводимые Параллельные Расчеты.

Например, чтобы использовать 'mlfg6331_64' поток для воспроизводимых расчетов:

  1. Создайте соответствующую структуру опций:

    s = RandStream('mlfg6331_64');
    options = statset('UseParallel',true, ...
        'Streams',s,'UseSubstreams',true);
  2. Выполните параллельные расчеты. Для получения инструкций смотрите Quick Start Parallel Computing for Statistics and Machine Learning Toolbox.

  3. Сброс случайного потока:

    reset(s);
  4. Повторите параллельные расчеты. Вы получаете одинаковые результаты.

Для примеров параллельных расчетов, выполняемых этим воспроизводимым способом, смотрите Воспроизводимые Параллельные Бутстрап и Train Classification Ensemble in Parallel.

Параллельные статистические расчеты с использованием случайных чисел

Что такое субпотоки?

substream является фрагментом случайного потока, который RandStream может получить быстрый доступ. Существует число M таким, что для любого положительного целого числа k, RandStream может перейти в kMномер псевдослучайного числа в потоке. С этой точки RandStream может сгенерировать последующие значения в потоке. В настоящее время, RandStream имеет M  = 272, около 5e21 или более.

Записи в различных субпотоках имеют хорошие статистические свойства, сходные со свойствами записей в одном потоке: независимость и отсутствие k корреляции при различных лагах. Субпотоки настолько длинны, что можно рассматривать субпотоки как независимые потоки, как на следующей картине.

Два RandStream типы потоков поддерживают субпотоки: 'mlfg6331_64' и 'mrg32k3a'.

Как субпотоки включают воспроизводимые параллельные расчеты

Когда MATLAB® выполняет расчеты параллельно с parforкаждый рабочий процесс получает итерации цикла в непредсказуемом порядке. Поэтому вы не можете предсказать, какой рабочий получает итерацию, поэтому не можете определить случайные числа, сопоставленные с каждой итерацией.

Субпотоки позволяют MATLAB связывать каждую итерацию с определенной последовательностью случайных чисел. parfor задает каждой итерации индекс. Итерация использует индекс в качестве номера субпотока. Поскольку случайные числа связаны с итерациями, а не с рабочими, все расчеты воспроизводимы.

Чтобы получить воспроизводимые результаты, просто сбросьте поток, и все субпотоки генерируют идентичные случайные числа при повторном вызове. Этот метод удаётся, когда все рабочие используют один и тот же поток, и поток поддерживает субпотоки. Это завершает обсуждение того, как процедура в Running Reproducible Parallel Computations дает воспроизводимые параллельные результаты.

Случайные числа на клиенте или работниках

Несколько функций генерируют случайные числа на клиенте, прежде чем распределять их параллельным рабочим. Рабочие не используют случайные числа, поэтому работают чисто детерминированно. Для этих функций можно запустить параллельные расчеты воспроизводимо, используя любой тип случайного потока.

Функции, которые работают таким образом, включают:

Чтобы получить одинаковые результаты, сбросьте случайный поток на клиенте или случайный поток, который вы передаете клиенту. Для примера:

s = rng % Obtain the current state of the random stream
% run the statistical function
rng(s) % Reset the stream to the previous state
% run the statistical function again, obtain identical results

Хотя этот метод позволяет вам запускать воспроизводимо параллельно, результаты могут отличаться от последовательных расчетов. Причина различия в том, parfor циклы выполняются в обратном порядке от for циклы. Поэтому последовательные расчеты могут генерировать случайные числа в другом порядке, чем параллельные расчеты. Для однозначной воспроизводимости используйте метод в Running Reproducible Parallel Computations.

Явное распределение потоков

Для проверки или сравнения с помощью определенных алгоритмов случайных чисел необходимо задать генераторы случайных чисел. Как вы устанавливаете эти генераторы параллельно или инициализируете потоки на каждом рабочем месте определенным образом? Или можно хотеть запустить расчет, используя другую последовательность случайных чисел, чем любой другой, который вы запустили. Как можно убедиться, что используемая последовательность статистически независима?

Функции Parallel Statistics and Machine Learning Toolbox позволяют вам задать случайные потоки на каждом рабочем месте явным образом. Для получения информации о создании нескольких потоков введите  help RandStream/create в командной строке. Чтобы создать четыре независимых потока с помощью 'mrg32k3a' генератор:

s = RandStream.create('mrg32k3a','NumStreams',4,...
    'CellOutput',true);

Передайте эти потоки в статистическую функцию с помощью Streams опция. Для примера:

parpool(4) % if you have at least 4 cores
s = RandStream.create('mrg32k3a','NumStreams',4,...
    'CellOutput',true); % create 4 independent streams
paroptions = statset('UseParallel',true,...
    'Streams',s); % set the 4 different streams
x = [randn(700,1); 4 + 2*randn(300,1)];
latt = -4:0.01:12;
myfun = @(X) ksdensity(X,latt); 
pdfestimate = myfun(x);
B = bootstrp(200,myfun,x,'Options',paroptions);

Этот метод распределения потоков дает каждому рабочему потоку другой поток для расчетов. Однако он не допускает воспроизводимых расчетов, потому что рабочие выполняют 200 загрузок в непредсказуемом порядке. Если вы хотите выполнить воспроизводимые расчеты, используйте субпотоки, как описано в Running Reproducible Parallel Computations.

Если вы задаете UseSubstreams опция для true, затем установите Streams опция к одному случайному потоку типа, который поддерживает субпотоки ('mlfg6331_64' или 'mrg32k3a'). Эта настройка дает воспроизводимые расчеты.