Ускорение функции глубокого обучения для пользовательских циклов обучения

При использовании dlfeval функция в пользовательском цикле обучения, программа отслеживает каждый вход dlarray объект функции градиентов модели для определения вычислительного графика, используемого для автоматической дифференциации. Этот процесс трассировки может занять некоторое время и может потратить время на пересчет того же трассировки. Оптимизируя, кэшируя и повторно используя трассировки, можно ускорить градиентные расчеты в функциях глубокого обучения. Можно также оптимизировать, кэшировать и повторно использовать трассировки для ускорения других функций глубокого обучения, которые не требуют автоматической дифференциации, для примера можно также ускорить функции модели и функции, используемые для предсказания.

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

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

Попробовать использовать dlaccelerate для вызовов функций, которые:

  • являются длительными

  • иметь dlarray объекты, структуры dlarray объекты, или dlnetwork объекты как входы

  • не имеют побочных эффектов, таких как запись в файлы или отображение выхода

Активируйте ускоренную функцию, так как вы бы активировали базовую функцию. Обратите внимание, что ускоренная функция не является указателем на функцию.

Примечание

При использовании dlfeval функция, программное обеспечение автоматически ускоряет forward и predict функции для dlnetwork вход. Если вы ускоряете функцию глубокого обучения, где большинство расчетов происходит в вызовах forward или predict функции для dlnetwork вход, тогда вы можете не увидеть улучшения во времени обучения.

Из-за особенностей следов кэширования не все функции поддерживают ускорение.

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

  • иметь входы со случайными или часто изменяющимися значениями

  • имеют выходы с часто изменяющимися значениями

  • сгенерировать случайные числа

  • использовать if операторы и while циклы с условиями, которые зависят от значений dlarray объекты

  • имеют входы, которые являются указателями или зависят от указателей

  • Считывайте данные из внешних источников (для примера, при помощи datastore или minibatchqueue объект)

Ускоренные функции могут сделать следующее только при вычислении нового трассировки.

  • измените глобальное состояние, например, поток случайных чисел или глобальные переменные

  • использовать вход или вывод файла

  • Отображения данные с помощью графики или командной строки отображения

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

Функции и пользовательские слои, используемые в ускоренных функциях, также должны поддерживать ускорение.

Можно вложить и рекурсивно вызвать ускоренные функции. Однако обычно более эффективно иметь одну ускоренную функцию.

Ускорение функции глубокого обучения непосредственно

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

Примите во внимание следующее использование dlfeval функция в пользовательском цикле обучения.

[gradients,state,loss] = dlfeval(@modelGradients,parameters,dlX,dlT,state)
Чтобы ускорить функцию градиентов модели и вычислить ускоренную функцию, используйте dlaccelerate и вычислите возвращенную AcceleratedFunction объект:
accfun = dlaccelerate(@modelGradients);
[gradients,state,loss] = dlfeval(accfun,parameters,dlX,dlT,state)

Поскольку кэшированные трассировки не присоединены непосредственно к AcceleratedFunction объект и что они являются общими для AcceleratedFunction объекты, которые используют ту же базовую функцию, можно создать AcceleratedFunction либо в, либо перед телом пользовательского цикла обучения.

Ускорение частей функции глубокого обучения

Если функция глубокого обучения не полностью поддерживает ускорение, например, функции, которые требуют if оператор с условием, которое зависит от значения dlarray объект, тогда можно ускорить части функции глубокого обучения путем создания отдельной функции, содержащей любые поддерживаемые вызовы функций, которые вы хотите ускорить.

Например, рассмотрите следующий фрагмент кода, который вызывает различные функции в зависимости от того, является ли сумма dlarray dlX объекта отрицательно или неотрицательно.

if sum(dlX,'all') < 0
   dlX = negFun1(parameters,dlX);
   dlX = negFun2(parameters,dlX);
else
   dlX = posFun1(parameters,dlX);
   dlX = posFun2(parameters,dlX);
end

Потому что if оператор зависит от значения dlarray объект, функция, которая содержит этот фрагмент кода, не поддерживает ускорение. Однако, если блоки кода, используемые внутри тела if ускорение поддержки оператора, затем можно ускорить эти части отдельно путем создания новой функции, содержащей эти блоки, и ускорения новых функций вместо этого.

Для примера создайте функции negFunAll и posFunAll которые содержат блоки кода, используемые в теле if оператор.

function dlX = negFunAll(parameters,dlX)

dlX = negFun1(parameters,dlX);
dlX = negFun2(parameters,dlX);

end

function dlX = posFunAll(parameters,dlX)

dlX = posFun1(parameters,dlX);
dlX = posFun2(parameters,dlX);

end
Затем ускорите эти функции и используйте их в теле if вместо этого оператор.
accfunNeg = dlaccelerate(@negFunAll)
accfunPos = dlaccelerate(@posFunAll)

if sum(dlX,'all') < 0
   dlX = accfunNeg(parameters,dlX);
else
   dlX = accfunPos(parameters,dlX);
end

Повторное использование кэшей

Повторное использование кэшированного трассировки зависит от входных параметров функции и выходов:

  • Для любого dlarray объект или структура dlarray входы объекта, трассировка зависит от размера, формата и базового типа данных dlarray. То есть ускоренная функция запускает новую трассировку для dlarray входы с размером, форматом или базовым типом данных, не содержащимися в кэше. Любой dlarray входы, различающиеся только значением в ранее кэшированную трассировку, не запускают новую трассировку.

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

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

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

При необходимости программное обеспечение кэширует любые новые трассировки путем оценки базовой функции и кэширования полученного трассировки в AcceleratedFunction объект.

Внимание

Система координат AcceleratedFunction объекту не известно об обновлениях базовой функции. Если вы измените функцию, связанную с ускоренной функцией, то очистите кэш с помощью clearCache функция объекта или альтернативно используйте команду clear functions.

Хранение и очистка кэшей

AcceleratedFunction объекты хранят кэш в очереди:

  • Программа добавляет новые трассировки в заднюю часть очереди.

  • Когда кэш заполнен, программа отбрасывает кэшированный элемент в верхней части очереди.

  • При повторном использовании кэша программа перемещает кэшированный элемент в заднюю часть очереди. Это препятствует сбросу часто повторно используемых кэшированных элементов программным обеспечением.

The AcceleratedFunction объекты не хранят кэш непосредственно. Это означает, что:

  • Несколько AcceleratedFunction объекты, которые имеют ту же базовую функцию, имеют один и тот же кэш.

  • Очистка или перезапись переменной, содержащей AcceleratedFunction объект не очищает кэш.

  • Перезапись переменной, содержащей AcceleratedFunction с другим AcceleratedFunction с той же базовой функцией не очищает кэш.

Ускоренные функции, которые имеют ту же базовую функцию, имеют один и тот же кэш.

Чтобы очистить кэш ускоренной функции, используйте clearCache функция объекта. Также можно очистить все функции в текущем MATLAB® сеанс с помощью команд clear functions или clear all.

Примечание

Очистка AcceleratedFunction переменная не очищает кэш, сопоставленный с функцией входа. Очистка кэша для AcceleratedFunction объект, который больше не существует в рабочей области, создайте новую AcceleratedFunction объект той же функции и использовать clearCache функция на новом объекте. Также можно очистить все функции в текущем сеансе работы с MATLAB с помощью команд clear functions или clear all.

Факторы об ускорении

Из-за особенностей следов кэширования не все функции поддерживают ускорение.

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

  • иметь входы со случайными или часто изменяющимися значениями

  • имеют выходы с часто изменяющимися значениями

  • сгенерировать случайные числа

  • использовать if операторы и while циклы с условиями, которые зависят от значений dlarray объекты

  • имеют входы, которые являются указателями или зависят от указателей

  • Считывайте данные из внешних источников (для примера, при помощи datastore или minibatchqueue объект)

Ускоренные функции могут сделать следующее только при вычислении нового трассировки.

  • измените глобальное состояние, например, поток случайных чисел или глобальные переменные

  • использовать вход или вывод файла

  • Отображения данные с помощью графики или командной строки отображения

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

Функции и пользовательские слои, используемые в ускоренных функциях, также должны поддерживать ускорение.

Входные параметры функции со случайными или часто изменяющимися значениями

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

Можно проверить наличие таких сценариев путем проверки Occupancy и HitRate свойства AcceleratedFunction объект. Если на Occupancy свойство высокое и HitRate низкая, тогда это может указать, что AcceleratedFunction объект создает много новых трассировок, которые он не использует повторно.

Для dlarray вход объекта, изменения в значении, чтобы не запускать новые трассировки. Чтобы предотвратить часто изменяющиеся входы от запуска новых трассировок для каждой оценки, рефактируйте ваш код так, чтобы случайные входы dlarray входы.

Для примера рассмотрим функцию градиентов модели, которая принимает случайный массив значений шума:

function [gradients,state,loss] = modelGradients(parameters,dlX,dlT,state,noise)

dlX = dlX + noise;
[dlYPred,state] = model(parameters,dlX,state);
loss = crossentropy(dlYPred,dlT);
gradients = dlgradient(loss,parameters);

end

Чтобы ускорить функцию градиентов модели, преобразуйте входную noise на dlarray перед вычислением ускоренной функции. Потому что modelGradients функция также поддерживает dlarray вход для шума, вам не нужно вносить изменения в функцию.

noise = dlarray(noise,'SSCB');
accfun = dlaccelerate(@modelGradients);
[gradients,state,loss] = dlfeval(accfun,parameters,dlX,dlT,state,noise);

Кроме того, можно ускорить части функции градиентов модели, которые не требуют случайного входа.

Функции с генерацией случайных чисел

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

Генерация случайных чисел с использованием 'like' опция rand функция со dlarray объект поддерживает ускорение. Чтобы использовать генерацию случайных чисел в ускоренной функции, убедитесь, что функция использует rand функция со 'like' набор опций равен трассированному dlarray объект (а dlarray объект, который зависит от входа dlarray объект).

Для примера рассмотрим следующую функцию градиентов модели.

[gradients,state,loss] = modelGradients(parameters,dlX,dlT,state)

sz = size(dlX);
noise = rand(sz);
dlX = dlX + noise;

[dlYPred,state] = model(parameters,dlX,state);
loss = crossentropy(dlYPred,dlT);
gradients = dlgradient(loss,parameters);

end

Чтобы гарантировать, что rand функция генерирует новое значение для каждой оценки, используйте 'like' опция с трассировкой dlarray dlX объекта.

[gradients,state,loss] = modelGradients(parameters,dlX,dlT,state)

sz = size(dlX);
noise = rand(sz,'like',dlX);
dlX = dlX + noise;

[dlYPred,state] = model(parameters,dlX);
loss = crossentropy(dlYPred,dlT);
gradients = dlgradient(loss,parameters);

end

Кроме того, можно ускорить части функции градиентов модели, которые не требуют генерации случайных чисел.

Использование if Операторы и while Циклы

Вы должны позаботиться при ускорении функций, которые используют if операторы и while циклы. В частности, if операторы и while циклы поддерживают ускорение только, когда условия не зависят от значений dlarray объекты.

Попытка ускорить функции, имеющие if операторы и while циклы с условиями, которые зависят от dlarray значения могут привести к неожиданному поведению. Когда ускоренная функция кэширует новую трассировку, если трассировка содержит if оператор или while условие цикла, которое зависит от значения dlarray объект, затем функция кэширует трассировку полученного пути кода, заданную if оператор или while цикл для этого значения. Потому что изменения в значении dlarray вход не запускает новую трассировку, при повторном использовании трассировки функция использует ту же кэшированную трассировку (которая представляет один и тот же путь кода), даже когда различие в значении может привести к другому пути кода.

Как использовать if операторы и while циклы, которые зависят от dlarray значения объектов, ускорение тела if оператор или while только цикл.

Входные параметры функции, которые зависят от указателей

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

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

Отладка

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

Чтобы отлажить код в базовой функции с помощью точек по оси Х, отключите ускорение, установив Enabled свойство к false.

Чтобы отлажить кэшированные трассировки, можно сравнить выходы ускоренных функций с выходами базовой функции, путем установки CheckMode свойство к 'tolerance'.

См. также

| | | | |

Похожие темы