Примечание
Для глубокого обучения поддержка параллельного и графического процессора выполняется автоматически. Вы можете обучить сверточную нейронную сеть (CNN, ConvNet) или сети долговременной памяти (сети LSTM или BiLSTM) с помощью trainNetwork и выберите среду выполнения (CPU, GPU, multi-GPU и параллельный) с помощью trainingOptions.
Параллельное обучение или обучение на графическом процессоре требует Toolbox™ параллельных вычислений. Дополнительные сведения о глубоком обучении с помощью графических процессоров и параллельно см. в разделе Глубокое обучение с использованием больших данных на процессорах, графических процессорах, параллельно и в облаке.
Нейронные сети по своей сути являются параллельными алгоритмами. Многоядерные процессоры, графические процессоры (GPU) и кластеры компьютеров с несколькими CPU и GPU могут использовать преимущества этого параллелизма.
Parallel Computing Toolbox, при использовании в сочетании с Deep Learning Toolbox™, обеспечивает обучение нейронной сети и моделирование, чтобы использовать преимущества каждого режима параллелизма.
Например, ниже показан стандартный однопоточный сеанс обучения и моделирования.
[x, t] = bodyfat_dataset; net1 = feedforwardnet(10); net2 = train(net1, x, t); y = net2(x);
Двумя шагами, которые можно распараллелить в этом сеансе, являются вызов train и неявный вызов sim (где сеть net2 называется функцией).
В Deep Learning Toolbox можно разделить любые данные, такие как x и t в предыдущем примере кода по выборкам. Если x и t содержат только одну выборку, параллелизм отсутствует. Но если x и t содержат сотни или тысячи образцов, параллелизм может обеспечить преимущества как скорости, так и размера проблемы.
Parallel Computing Toolbox позволяет выполнять обучение нейронной сети и моделирование на нескольких ядрах ЦП на одном ПК или на нескольких ЦП на нескольких компьютерах в сети с помощью MATLAB ® Parallel Server™.
Использование нескольких ядер может ускорить вычисления. Использование нескольких компьютеров позволяет решить проблемы, используя слишком большие наборы данных для размещения в оперативной памяти одного компьютера. Единственным ограничением размера проблемы является общее количество оперативной памяти, доступной на всех компьютерах.
Для управления конфигурациями кластера используйте Диспетчер профилей кластера на вкладке Главная страница MATLAB меню Среда Параллельное > Управление профилями кластера.
Чтобы открыть пул работников MATLAB с использованием профиля кластера по умолчанию, который обычно является ядрами локального ЦП, используйте следующую команду:
pool = parpool
Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.
Когда parpool он отображает количество работников, доступных в пуле. Другим способом определения количества работников является запрос пула:
pool.NumWorkers
4
Теперь можно обучать и моделировать нейронную сеть с разделением данных по выборкам по всем работникам. Для этого установите train и sim параметр 'useParallel' кому 'yes'.
net2 = train(net1,x,t,'useParallel','yes') y = net2(x,'useParallel','yes')
Используйте 'showResources' для проверки того, что вычисления выполнялись несколькими работниками.
net2 = train(net1,x,t,'useParallel','yes','showResources','yes'); y = net2(x,'useParallel','yes','showResources','yes');
MATLAB указывает, какие ресурсы были использованы. Например:
Computing Resources: Parallel Workers Worker 1 on MyComputer, MEX on PCWIN64 Worker 2 on MyComputer, MEX on PCWIN64 Worker 3 on MyComputer, MEX on PCWIN64 Worker 4 on MyComputer, MEX on PCWIN64
Когда train и sim называются, они делят входные данные матрицы или массива ячеек на распределенные составные значения перед обучением и моделированием. Когда sim рассчитал Composite, этот вывод преобразуется обратно в ту же форму матрицы или массива ячеек, прежде чем он будет возвращен.
Однако это разделение данных может потребоваться выполнить вручную, если:
Размер проблемы слишком велик для компьютера. Определение элементов составных значений вручную последовательно позволяет определить гораздо большие проблемы.
Известно, что некоторые работники находятся на компьютерах, которые быстрее или имеют больше памяти, чем другие. Можно распределить данные с различным количеством проб на работника. Это называется балансировкой нагрузки.
Следующий код последовательно создает ряд случайных наборов данных и сохраняет их в отдельные файлы:
pool = gcp; for i=1:pool.NumWorkers x = rand(2,1000); save(['inputs' num2str(i)],'x'); t = x(1,:) .* x(2,:) + 2 * (x(1,:) + x(2,:)); save(['targets' num2str(i)],'t'); clear x t end
Поскольку данные были определены последовательно, можно определить общий набор данных, превышающий размер памяти хост-компьютера. Одновременно в памяти ПК должен размещаться только субнабор данных.
Теперь можно последовательно загружать наборы данных между параллельными работниками, а также обучать и моделировать сеть на основе составных данных. Когда train или sim вызывается с использованием составных данных, 'useParallel' аргумент автоматически устанавливается в значение 'yes'. При использовании составных данных настройте входные и выходные данные сети так, чтобы они соответствовали одному из наборов данных вручную с помощью configure выполнять функции перед тренировкой.
xc = Composite; tc = Composite; for i=1:pool.NumWorkers data = load(['inputs' num2str(i)],'x'); xc{i} = data.x; data = load(['targets' num2str(i)],'t'); tc{i} = data.t; clear data end net2 = configure(net1,xc{1},tc{1}); net2 = train(net2,xc,tc); yc = net2(xc);
Преобразование составного вывода, возвращаемого sim, вы можете получить доступ к каждому из его элементов, отдельно, если обеспокоены ограничениями памяти.
for i=1:pool.NumWorkers yi = yc{i} end
Объедините значение Composite в одно локальное значение, если вы не обеспокоены ограничениями памяти.
y = {yc{:}};При балансировке нагрузки происходит один и тот же процесс, но вместо каждого набора данных, имеющего одинаковое количество выборок (1000 в предыдущем примере), количество выборок может быть скорректировано, чтобы наилучшим образом использовать преимущества памяти и разности скоростей рабочих хост-компьютеров.
Не требуется, чтобы у каждого работника были данные. Если элемент i составного значения не определено, рабочий i не будет использоваться в вычислениях.
Число ядер, объем памяти и эффективность работы карт GPU быстро растут с каждым новым поколением. В тех случаях, когда видеоигры уже давно получают пользу от повышения производительности GPU, эти карты теперь достаточно гибки для выполнения общих задач численных вычислений, таких как обучение нейронных сетей.
Последние требования к графическому процессору см. на веб-странице панели инструментов параллельных вычислений; или запросите MATLAB, чтобы определить, поддерживает ли ваш ПК графический процессор. Эта функция возвращает количество графических процессоров в системе:
count = gpuDeviceCount
count =
1Если результат один или несколько, можно запросить каждый графический процессор по индексу для его признаков. Это включает в себя его название, количество многопроцессоров, SIMDWidth каждого многопроцессора и общего объема памяти.
gpu1 = gpuDevice(1)
gpu1 =
CUDADevice with properties:
Name: 'GeForce GTX 470'
Index: 1
ComputeCapability: '2.0'
SupportsDouble: 1
DriverVersion: 4.1000
MaxThreadsPerBlock: 1024
MaxShmemPerBlock: 49152
MaxThreadBlockSize: [1024 1024 64]
MaxGridSize: [65535 65535 1]
SIMDWidth: 32
TotalMemory: 1.3422e+09
AvailableMemory: 1.1056e+09
MultiprocessorCount: 14
ClockRateKHz: 1215000
ComputeMode: 'Default'
GPUOverlapsTransfers: 1
KernelExecutionTimeout: 1
CanMapHostMemory: 1
DeviceSupported: 1
DeviceSelected: 1Самый простой способ воспользоваться преимуществами графического процессора - это указать вызов train и sim с аргументом параметра 'useGPU' установить в значение 'yes' ('no' по умолчанию).
net2 = train(net1,x,t,'useGPU','yes') y = net2(x,'useGPU','yes')
Если net1 имеет функцию обучения по умолчанию trainlm, вы видите предупреждение, что расчеты GPU не поддерживают обучение якобиану, только градиентное обучение. Таким образом, функция обучения автоматически изменяется на функцию градиентного обучения. trainscg. Чтобы избежать уведомления, перед обучением можно указать функцию:
net1.trainFcn = 'trainscg';Чтобы убедиться, что обучение и моделирование выполняются на устройстве графического процессора, попросите показать ресурсы компьютера:
net2 = train(net1,x,t,'useGPU','yes','showResources','yes') y = net2(x,'useGPU','yes','showResources','yes')
Каждая из вышеуказанных строк кода выводит следующую сводку ресурсов:
Computing Resources: GPU device #1, GeForce GTX 470
Многие функции MATLAB автоматически выполняются на GPU, когда любой из входных аргументов является gpuArray. Обычно массивы перемещаются в графический процессор и из него с помощью функций gpuArray и gather. Однако для того, чтобы вычисления нейронной сети на GPU были эффективными, матрицы должны быть транспонированы и столбцы заполнены так, чтобы первый элемент в каждом столбце правильно выравнивался в памяти GPU. Deep Learning Toolbox предоставляет специальную функцию под названием nndata2gpu чтобы переместить массив в графический процессор и правильно организовать его:
xg = nndata2gpu(x); tg = nndata2gpu(t);
Теперь можно обучать и моделировать сеть с использованием преобразованных данных, уже имеющихся в GPU, без необходимости определения 'useGPU' аргумент. Затем преобразуйте и возвращайте результирующий массив GPU обратно в MATLAB с дополнительной функцией gpu2nndata.
Перед обучением с данными gpuArray входные и выходные данные сети должны быть вручную сконфигурированы с помощью обычных матриц MATLAB с помощью configure функция:
net2 = configure(net1,x,t); % Configure with MATLAB arrays net2 = train(net2,xg,tg); % Execute on GPU with NNET formatted gpuArrays yg = net2(xg); % Execute on GPU y = gpu2nndata(yg); % Transfer array to local workspace
На графических процессорах и других аппаратных средствах, где может потребоваться развертывание нейронных сетей, часто бывает, что экспоненциальная функция exp реализован не с аппаратным обеспечением, а с программной библиотекой. Это может замедлить нейронные сети, которые используют tansig сигмоидальная передаточная функция. Альтернативной функцией является сигмоидная функция Эллиота, выражение которой не включает вызов каких-либо функций высшего порядка:
(equation) a = n / (1 + abs(n))
Перед обучением сеть tansig слои могут быть преобразованы в elliotsig слои следующим образом:
for i=1:net.numLayers if strcmp(net.layers{i}.transferFcn,'tansig') net.layers{i}.transferFcn = 'elliotsig'; end end
Теперь обучение и моделирование могут быть более быстрыми на GPU и более простым оборудованием для развертывания.
Распределенные вычисления и вычисления GPU могут быть объединены для выполнения вычислений по нескольким ЦП и/или GPU на одном компьютере или в кластере с MATLAB Parallel Server.
Самый простой способ сделать это - указать train и sim для этого используется параллельный пул, определенный используемым профилем кластера. 'showResources' особенно рекомендуется в этом случае проверить, используется ли ожидаемое аппаратное обеспечение:
net2 = train(net1,x,t,'useParallel','yes','useGPU','yes','showResources','yes') y = net2(x,'useParallel','yes','useGPU','yes','showResources','yes')
В этих строках кода используются все доступные работники в параллельном пуле. Один работник для каждого уникального графического процессора использует этот графический процессор, в то время как другие работники работают как ЦП. В некоторых случаях использование только графических процессоров может быть более быстрым. Например, если один компьютер имеет три GPU и четыре рабочих, три рабочих, которые ускоряются тремя GPU, могут быть ограничены скоростью четвертым рабочим CPU. В этих случаях можно указать, что train и sim использовать только работников с уникальными графическими процессорами.
net2 = train(net1,x,t,'useParallel','yes','useGPU','only','showResources','yes') y = net2(x,'useParallel','yes','useGPU','only','showResources','yes')
Как и в случае простых распределенных вычислений, распределенные вычисления GPU могут получить преимущества от создания составных значений вручную. Определение составных значений позволяет указать, какие работники должны использовать, сколько образцов назначить каждому работнику и какие работники используют графические процессоры.
Например, если у вас четыре работника и только три GPU, можно определить более крупные наборы данных для работников GPU. Здесь создается случайный набор данных с различными выборочными нагрузками на составной элемент:
numSamples = [1000 1000 1000 300]; xc = Composite; tc = Composite; for i=1:4 xi = rand(2,numSamples(i)); ti = xi(1,:).^2 + 3*xi(2,:); xc{i} = xi; tc{i} = ti; end
Теперь можно указать, что train и sim используйте три доступных графических процессора:
net2 = configure(net1,xc{1},tc{1});
net2 = train(net2,xc,tc,'useGPU','yes','showResources','yes');
yc = net2(xc,'showResources','yes');Чтобы обеспечить использование графических процессоров первыми тремя работниками, вручную преобразуйте составные элементы каждого работника в gpuArrays. Каждый работник выполняет это преобразование в параллельном выполнении spmd блок.
spmd if labindex <= 3 xc = nndata2gpu(xc); tc = nndata2gpu(tc); end end
Теперь данные указывают, когда использовать GPU, поэтому вам не нужно указывать train и sim для этого.
net2 = configure(net1,xc{1},tc{1});
net2 = train(net2,xc,tc,'showResources','yes');
yc = net2(xc,'showResources','yes');Убедитесь, что каждый графический процессор используется только одним работником, чтобы вычисления были наиболее эффективными. Если несколько работников назначают данные gpuArray одному и тому же графическому процессору, вычисления будут работать, но будут медленнее, поскольку графический процессор будет работать с данными нескольких работников последовательно.
Для сетей временных рядов просто используйте значения массива ячеек для x и tи дополнительно включать начальные состояния задержки ввода xi и состояния задержки начального уровня ai, по мере необходимости.
net2 = train(net1,x,t,xi,ai,'useGPU','yes') y = net2(x,xi,ai,'useParallel','yes','useGPU','yes') net2 = train(net1,x,t,xi,ai,'useParallel','yes') y = net2(x,xi,ai,'useParallel','yes','useGPU','only') net2 = train(net1,x,t,xi,ai,'useParallel','yes','useGPU','only') y = net2(x,xi,ai,'useParallel','yes','useGPU','only')
Следует отметить, что параллелизм происходит между выборками или в случае временных рядов в разных сериях. Однако, если сеть имеет только задержки на входе без задержек на уровне, задержки на входе могут быть предварительно вычислены так, что для целей вычисления временные этапы становятся различными выборками и могут быть параллельными. Это относится к таким сетям, как timedelaynet и версии с разомкнутым контуром narxnet и narnet. Если сеть имеет задержки уровня, то время не может быть «выровнено» для целей вычисления, и поэтому данные одного ряда не могут быть параллелизованы. Это относится к таким сетям, как layrecnet и варианты с замкнутым контуром narxnet и narnet. Однако, если данные состоят из нескольких последовательностей, они могут быть параллелизованы по отдельным последовательностям.
Как упоминалось выше, можно запросить MATLAB для обнаружения доступных текущих параллельных ресурсов.
Чтобы узнать, какие графические процессоры доступны на хост-компьютере:
gpuCount = gpuDeviceCount for i=1:gpuCount gpuDevice(i) end
Чтобы узнать, сколько работников работает в текущем параллельном пуле:
poolSize = pool.NumWorkers
Для просмотра графических процессоров, доступных в параллельном пуле, работающем на кластере ПК с использованием параллельного сервера MATLAB:
spmd worker.index = labindex; worker.name = system('hostname'); worker.gpuCount = gpuDeviceCount; try worker.gpuInfo = gpuDevice; catch worker.gpuInfo = []; end worker end
Когда 'useParallel' или 'useGPU' имеют значение 'yes', но параллельные или GPU работники недоступны, соглашение заключается в том, что, когда ресурсы запрашиваются, они используются, если доступны. Вычисление выполняется без ошибок, даже если они отсутствуют. Этот процесс возврата от запрашиваемых ресурсов к фактическим происходит следующим образом:
Если 'useParallel' является 'yes' но панель инструментов Parallel Computing Toolbox недоступна или параллельный пул не открыт, после чего вычисления возвращаются к однопоточному MATLAB.
Если 'useGPU' является 'yes' но gpuDevice для текущего сеанса MATLAB не назначен или не поддерживается, то вычисление возвращается в CPU.
Если 'useParallel' и 'useGPU' являются 'yes', то каждый работник с уникальным графическим процессором использует этот графический процессор, а другие работники возвращаются к процессору.
Если 'useParallel' является 'yes' и 'useGPU' является 'only', то используются работники с уникальными графическими процессорами. Другие работники не используются, если только у них нет графических процессоров. В случае отсутствия графических процессоров все работники используют ЦП.
Если вы не уверены, какое оборудование действительно используется, проверьте gpuDeviceCount, gpuDevice, и pool.NumWorkers для обеспечения доступности требуемого аппаратного обеспечения и вызова train и sim с 'showResources' установить в значение 'yes' для проверки фактического использования ресурсов.