Автомат диф: Дифавтоматы (АВДТ) — купить дифференциальный автомат по низкой цене

Содержание

Дифференциальный автомат. Виды и работа. Устройство

Рассмотрим один из видов защиты – автомат дифференциального тока, или дифференциальный автомат. Это устройство включает в себя функции устройства защитного отключения и автоматического выключателя. Оно обеспечивает защиту контролируемой цепи от токов короткого замыкания и перегрузочных токов, работая в качестве автоматического выключателя. Также дифференциальный автомат защищает человека от возможного удара электрическим током в результате токов утечки, не допускает пожара вследствие повреждения изоляции токоведущих элементов электроустановки, выполняя при этом функции УЗО.

Дифференциальный автомат

Разделение дифавтоматов на виды осуществляется по их характеристикам.

Тип электрической сети

Все устройства защиты выбирают по числу фаз электрической сети. Существуют дифференциальные автоматы для эксплуатации в однофазной сети 220 вольт, для трехфазной сети 380 вольт. На корпусе устройства есть соответствующее обозначение. Трехфазные модели оснащены нулевым полюсом и тремя полюсами фаз. Его размеры значительно больше, в отличие от однофазной модели, на которой имеется полюс фазы и ноля. На первой картинке слева – однофазный автомат, справа – трехфазный.

Параметры тока

Номинальный ток обозначается буквой «С» рядом с числом нагрузки тока в амперах.

В быту популярными стали дифавтоматы С16. Остальные виды используются реже. Ток утечки обозначается символом Δ, а справа от этого символа указывается ток в миллиамперах. В цепях освещения чаще всего используются дифавтоматы с номинальным значением тока утечки 10-30 мА. Из них для одиночных сетей применяют автоматы на 10 мА, а в групповых сетях на 30 мА. Защита с номинальным током утечки 100-300 мА применяется для входных дифавтоматов.

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

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

По параметру тока, при котором срабатывает защита при запуске мощных потребителей, дифференциальные автоматы делятся на типы:
  • В – выдерживает перегрузку от 3 до 5 раз.
  • С – перегрузка от 5 до 10 раз.
  • D – отключение питания происходит при возрастании тока от 10 до 20 раз.

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

Класс защиты

Этот параметр означает, на какие виды токов реагирует дифференциальный автомат.

AC — Для синусоидального переменного тока
A  — Для синусоидального переменного и пульсирующего постоянного
B  — Для переменного, импульсного, постоянного и сглаженного постоянного
S  — Выдержка времени отключения 200-300 мс
G  — Выдержка времени отключения 60-80 мс

В квартирах и собственных домах чаще всего применяются типы защит АС и А. Из них наиболее распространена защита А-класса, так как основная часть устройств потребителей оснащена электронным управлением. Например, светодиодная подсветка и некоторые виды люстр управляются с помощью электроники. АС-класс устанавливают в загородных дачах и домах, не имеющих электронных устройств.

Класс ограничения тока и отключающей способности

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

Класс токоограничения имеет цифровое обозначение:
  • 1 – медленный.
  • 2 – средний.
  • 3 – быстрый.

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

Условия эксплуатации

Основная часть дифавтоматов эксплуатируется в теплых отапливаемых помещениях, и рассчитана на работу в диапазоне -5 +35 градусов. Если дифференциальный автомат необходимо установить вне помещения, то применяют другой тип автоматов, так как в зимнее время температура может опуститься до более низких значений. Для таких случаев существуют морозоустойчивые автоматы, способные работать при более низких температурах.

На корпусе таких автоматов имеется специальный значок снежинки.

При всех аналогичных характеристиках морозоусточивые модели имеют стоимость выше, по сравнению с другими моделями.

Внутреннее устройство

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

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

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

Устройство и принцип работы

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

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

Чтобы проверить работоспособность модуля защиты, корпус дифавтомата оснащен кнопкой «Тест». Если нажать на эту кнопку, то происходит имитация тока утечки, и при исправном автомате питание должно отключиться.

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

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

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

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

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

Похожие темы:

Что нужно сделать, чтобы проверить дифференциальный автомат и УЗО

Что нужно сделать, чтобы проверить дифференциальный автомат и УЗО

Большинству потребителей, абсолютно все равно, что перед ними: УЗО (устройство защитного отключения) или дифатомат (дифференциальный автомат). Но при разработке проектов электросети частных домов или квартир, данный вопрос имеет определенное значение.

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

Принцип действия УЗО и дифавтомата и их отличия

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

Если ток через фазу больше чем через ноль, значит его часть потекла по другому пути, например, произошло повреждение изоляции проводников или ТЭН пробило и ток определенной величины «утекает» в землю.

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

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

Чтобы отличить электронное УЗО от электромеханического, посмотрите на схему на его лицевой панели.

Важно: Устройство защитного отключения реагирует только на дифференциальный ток. Это значит, что УЗО не защищает электропроводку от токов короткого замыкания. От КЗ защищают автоматические выключатели. Дифавтомат — это комбинированное устройство, оно срабатывает и на повышенные токи, как автоматический выключатель, и на дифференциальный ток подобно УЗО. То есть в одном корпусе совмещены два коммутационных защитных аппарата.

Способы проверки

Как вы уже догадались — методика проверки срабатывания УЗО и дифавтомата на утечку аналогична. На лицевой панели и одного и другого прибора есть флажок включения/выключения и кнопка «ТЕСТ». Согласно ПТЭЭП прил. 3, табл. 28, п.28.7 нужно проверять срабатывание с помощью этой кнопки не реже чем раз в квартал (3 месяца).

Важно:

Кнопка «ТЕСТ» проверяет только срабатывание прибора по дифференциальному току или току утечки, но не проверяет срабатывание по превышению номинального тока у дифавтомата.

Есть 5 основных способов проверки:

— с помощью кнопки «ТЕСТ»;

— с помощью батарейки;

— с помощью магнита;

— резистором

— специализированным прибором.

Проверка с помощью кнопки «ТЕСТ»

При нажатии на кнопку проверки срабатывания УЗО или дифавтомата внутри прибора подключается резистор между выходящим фазным контактом и приходящим нулевым. Таким образом ток через фазный провод становится больше чем ток через нулевой провод. Если прибор исправен — он отключится. Следовательно, такая проверка возможна только если прибор подключен к электросети и на него подано питание.

Схема проверки УЗО или дифавтомата с помощью этой кнопки изображена на лицевой панели устройства.

Однако специалисты отзываются негативно о такой проверки, ссылаясь на то что рынок насыщен подделками и иногда встречаются такие экземпляры защитных приборов, в которых при нажатии на «ТЕСТ» прибор срабатывает даже если он не подключен к сети. Происходить этого недолжно.

Проверка с помощью батарейки и магнита

Рассмотрим, как проверить УЗО или дифавтомат в магазине не подключая прибор к электросети. Для этого нужна любая батарейка, подойдет и новая пальчиковая и два провода. Нужно подключить провода к батарейке, для этого можете воспользоваться элементарно изолентой, а вторые их концы соединить с клеммами одного из полюсов проверяемого прибора. При этом он должен быть взведен, то есть переведите флажок в положение «ВКЛ».

При этом нужно учесть тот факт, что УЗО или дифавтоматы устроены так, что срабатывают на одну из полуволн. Т.е. важна полярность при тестировании. Это значит, что, если при таком способе проверки прибор не защита не сработала — поменяйте полярность, для этого просто поменяйте провода местами. Если устройство не срабатывает ни при какой полярности – значит оно электронное, а не электромеханическое!

Примечание: УЗО типа «А» срабатывает при любой полярности, а типа «AC» — только при определенной полярности – переворачивайте батарейку!

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

Для этого нужно поднести магнит к одной из сторон проверяемого прибора. Флажок опять-таки должен быть во включенном состоянии (вверх). Магнитное поле магнита наведет ток в обмотке измерительного трансформатора, в результате чего защита сработает и устройство отключится.

ВАЖНО:

Повторюсь, если УЗО электронное – такая проверка не сработает! Для работы электронных УЗО и дифавтоматов нужно чтобы было подключено питание (фаза и ноль).

Проверка с помощью резистора или лампочки

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

Для начала рассчитайте номинал резистора под величину дифференциального тока срабатывания. Например, очень распространены УЗО с током срабатывания в 30 мА, значит условно представим, что в сети 220 вольт (реальные значение измеряйте непосредственно на объекте где будет установлен прибор). Значит нужно взять резистор на:

220/0.030=7333.33 Ом

Мощность на резисторе выделится кратковременно (порядка 6 Ватт), но тем не менее будет лучше если вы выберете как можно более мощный резистор.

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

Таким же образом и работает кнопка «ТЕСТ».

ВАЖНО:

При такой проверке УЗО должно быть подключено к сети.

Если прибор не отреагировал на подключение рассчитанного резистора — значит он бракованный. Также вы можете измерить ток с помощью мультиметра. Но так как его протекание будет кратковременным — вы можете не увидеть его величину. Для поверок можно собрать такой прибор, как на видео ниже, только его недостаток в том, что указывается расчетный ток.

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

Заключение

Для точной проверки УЗО и дифавтоматов используют специальные приборы, например:

— Sonel MRP-200;

— ПЗО-500;

— ПЗО-500 Про.

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

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

Нормы: Согласно ПТЭЭП проверка выключателей дифференциального тока должна осуществляться в соответствии с рекомендациями завода изготовителя. В среднем они включают в себя проверку перемещения флажка «ВКЛ/ВЫКЛ». Он должен четко переключаться из одного положения в другое, а также 1 раз в указанный период проходить проверку нажатием кнопки «ТЕСТ» (но не реже 1 раза в квартал, согласно ПТЭЭП). Ток срабатывания должен быть не менее чем 0.5In (для УЗО на 30 мА — это 15 мА), другие допустимые величины описаны в ГОСТ Р50571.16-99.

Ранее ЭлектроВести писали, почему бьет током одежда, мебель, машина и окружающие предметы.

По материалам: electrik.info.

Диф.автомат АВДТ63 2 пол.

Диф.автомат АВДТ63 2 пол.

Включите в вашем браузере JavaScript!

Маркировка

  • Номинальный ток – значение тока в амперах (А), который дифференциальный автомат способен пропускать бесконечно долго без отключения цепи.
  • Номинальное напряжение – напряжение переменного тока (знак ~), при котором дифференциальный автомат работает в нормальных условиях.
  • Кривая отключения – отражает порог срабатывания при защите от короткого замыкания.
    • Кривая B– автомат срабатывает при появлении вцепи тока в 3-5 раз больше номинального (т.е. автомат на 16А отключит цепь при токе 48-80А). Используется в бытовых сетях с замоноличенной алюминиевой проводкой.
    • Кривая С– ток вцепи в 5-10 раз больше номинального (т.е. автомат на16А отключит цепь при токе 80-160А). Используют в современном жилом строительстве и в офисных сетях.
  • Номинальная отключающая способность – максимальный ток короткого замыкания, который данный дифференциальный автомат способен отключить и остаться в работоспособном состоянии.
  • Дифференциальный ток – ток в миллиамперах (мА), протекающий по телу человека, прикоснувшегося к токоведущей части и стоящего на токопроводящем полу. Для защиты от поражения используют аппараты с уставками 10, 30 и 100мА. Аппараты с уставкой 300 мА используют для защиты от пожаров или как двухступенчатую селективную защиту.
  • Класс А – дифференциальные автоматы класса А защищают как от синусоидальных, так и пульсирующих дифференциальных токов. Они возникают в цепи, где есть электронная техника – компьютеры, телевизоры, DVD-плееры – т.к. эти приборы обладают импульсными источниками питания.
  • Устройство способно работать при температуре −25°С.

Назначение

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

Применение

  • Групповые линии, питающие розетки наружной установки.
  • Розеточные группы ванных и душевых помещений.
  • Цепи освещения подвалов и гаражей.

Материалы

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

Конструкция

  • Аппарат АВДТ63 представляет собой компактный дифференциальный автомат и сочетает в себе функции автоматического выключателя и выключателя дифференциального тока.
  • Аппарат занимает два стандартных модуля в щитке (36мм).
  • Насечки на контактных зажимах предотвращают перегрев и оплавление проводов за счет более плотного и большего по площади контакта.
  • На лицевой панели выключателя реализован механический индикатор положения контактов (включено/отключено).
  • Аппарат имеет повышенную помехозащищенность.
  • В левом модуле расположен полноценный автоматический выключатель с высокой предельной отключающей способностью (6000А) и увеличенной дугогасящей камерой, в правом – контактная группа нулевого полюса и блок дифференциальной защиты.

Преимущества

  • Универсальная головка усиленного винта клеммного зажима позволяет использовать как крестовую, так и шлицевую отвертку и обеспечить необходимое усилие при затяжении.
  • Подробная инструкция по монтажу и эксплуатации позволяет легко монтировать аппарат даже начинающему монтажнику.
  • Наличие двойного одновременного подключения шины и проводника значительно расширяет диапазон возможных схемных решений.
  • Клеммы аппарата промаркированы и подписаны (Сеть/ Нагрузка), что позволяет избежать ошибок при монтаже.

Дифференциальный автомат ABB | Дифференциальный автоматический выключатель ABB

Технические характеристики дифференциального автомата серии ABB

Номинальный ток 6-63А
Номинальное напряжение 220 и 300В, с частотой 50Гц
Ток утечки 30 мА
Класс дифференциальной защиты А и АС
Температурный режим использования от -5°C до + 35°C
Тип конструктивного исполнения электромеханические или электронные
Номинальная отключающая способность 3000 А, 4500 А, 6000 А, 10 000 А

Механические характеристики полюсного дифавтомата серии ABB

Клеммные блоки верх/низ 25/25 мм2  для кабеля, 10/10 мм2 для шин, выдерживают ударные нагрузки
Материал корпуса термопласт, стойкий к механическим повреждениям или вибрациям
Наличие кнопки тестирования да

Современный автомат дифференциального тока ABB выполняет функции защиты по двум направлениям – от коротких замыканий и перегрузок сети. Кроме того, модели нового поколения исключают риск воспламенения даже при длительной утечке тока.

Купить диф автомат abb недорого в интернет-магазине

В каталоге «77 ВОЛЬТ» представлены автоматы отключения с разным номиналом, рассчитанные на разные рабочие токи. Эти устройства защиты срабатывают при возникновении нештатных ситуаций в электросети. Автоматический выключатель дифференциального тока ABB непрерывно вычисляет векторную сумму токов в однофазной или трехфазной линии и прекращает подачу энергии, если сумма значений превышает чувствительность устройства.

У нас вы можете купить дифавтомат ABB для защиты осветительных и розеточных сетей, для которых обычно используются модели номиналом 10-30 мА. Групповые сети чаще всего защищают аппаратами на 30 mA, для одиночных розеток достаточно номинала 10 мА. Узнать подробные характеристики товаров и получить грамотную консультацию можно у онлайн-менеджера.

В интернет-магазине «77 ВОЛЬТ» всегда в продаже дифференциальные автоматы ABB различной модульности и полюсности по доступной цене, осуществляем доставку по Москве, работаем оптом и с розничными покупателями. Чтобы узнать оптовую стоимость позиций каталога, свяжитесь с нашими специалистами. Также вы можете заказать прайс-лист по телефону, и он будет доставлен вам на электронную почту. Для оптовых покупателей у нас предусмотрены особые условия сотрудничества и специальные скидки для постоянных клиентов.

Характеристики, схема подключения дифавтоматов

Купить Дифавтоматы

Характеристики дифавтоматов
Установка дифавтомата
Подключение дифавтомата
Дифавтомат схема подключения

Характеристики дифавтоматов

Основными характеристиками этих электротехнических устройств является:

  1. Номинальный рабочий ток, (А)- ток при котором прибор может оставаться включённым длительное время.
  2. Быстродействие (M/с)- время срабатывания аварийного срабатывания электромагнитного расцепителя.
  3. Номинальное напряжение (В)- ток, при котором устройство способно работать длительное время.
  4. Уставка по токовой утечке (мA)- ток отключения схемы, обозначается значком «дельта» с числом соответствующим току утечки.
  5. Тип тока утечки. В соответствии с этим параметром любой из дифавтоматов может иметь следующие обозначения:
  • «A» – реагирующие на утечки синусоидального переменного (пульсирующего постоянного) тока;
  • «AC» – дифавтоматы, рассчитанные на срабатывания от утечек, содержащих постоянную составляющую тока;
  • «B» – комбинированное исполнение, предполагающее обе указанные ранее возможности.

Также устройства защиты могут работать по селективному принципу, предполагающему наличие задержки по времени срабатывания. Указанная возможность обеспечивает определённую выборочность отключения прибора от сети и электродинамическую устойчивость системы защиты, обзначаетса аббревиатурой «S».

АВДТ — автоматические выключатели дифференциального тока, это устройства, включающие в себя и автоматический выключатель, и УЗО, объединенные в одном корпусе. Дифавтоматы обладают высоким быстродействием срабатывания, защищают от поражения электрическим током в случаях соприкосновения с токопроводящими частями или с электрооборудованием, части которого, вследствие повреждения изоляционного слоя, оказались под напряжением.
Также дифференциальные выключатели применяются для отключения участков электрической сети, которые подверглись повреждениям в случаях коротких замыканий или механических воздействий.

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

Дифавтоматы с порогом срабатывания IΔn=30мA защищают пользователя от случайного контакта с фазным проводом или другими токоведущими элементами цепи.
Следует помнить, что когда защита от контакта осуществляется с использованием устройств защитного отключения, средний провод (нейтраль) должен быть изолирован так же как и фазный и не должен соединяться с землей ниже по цепи чем само устройство или с нейтральным проводом другой цепи.

Устройства защитного отключения с защитой от перегрузки обеспечивают:

  • защиту от поражения электрическим током путем контроля разностных токов
  • защиту от перегрузки
  • защиту от короткого замыкания
  • противопожарную безопасность

Уровень защиты данных автоматов должен быть следующим (CEI EN 60529):

  • IPXXB/IP2X с лицевой стороны: при наружном монтаже пространство вокруг клемм должно быть закрыто крышкой.
  • IPXXD/IP4X для монтажа в соответствующих держателях или панелях .
  • При установке в промышленных помещениях и при наличии особенностей в окружающей среде соответствующий уровень защиты IP должен обеспечиваться за счет установки в корпусах, отвечающих стандарту CEI 64-8/IEC 364.

Примечание: Устройство защитного отключения АВДТ не устраняет ощущений удара электрическим током, однако оно ограничивает промежуток времени, в течение которого ток проходит через тело человека, до уровня, существенно снижающего вероятность летального исхода.

Индикация и причины срабатывания дифавтоматов

  • Черный рычажок управления в нижнем положении (положение О): срабатывание из-за перегрузки, короткого замыкания или защитного отключения (утечка тока на землю).
  • Черный рычажок управления в нижнем положении (положение О) и метка видна через окошко: срабатывание устройства защитного отключения из-за утекания тока на землю.

Повторное включение АВДТ после срабатывания

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

Защитное заземление дифавтоматов

Защитное заземление должно выполняться в соответствии cо стандартом CEI64-8/IEC 364. Все металлические каркасы электрического оборудования должны быть заземлены. Cечение проводника заземления не должно быть меньше сечения проводников электропитания.

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

Данное оборудование должно использоваться в соответствии с требованиями стандарта CEI 64-8/IEC 364. Оно оснащено встроенной системой защиты от перегрузки и короткого замыкания, номинальные значения которых указаны на шильдике прибора, и гарантированно защищают от перегрузки выходные проводники системы.
B системах защиты, использующих непосредственное заземление металлических частей, дополнительная установка устройств защитного отключения обеспечивает дополнительную защиту от растекания тока на землю, что обеспечивает повышенную безопасность при электрическом контакте.
Электропитание может подключаться к диф автомату как сверху, так и снизу.


Установка дифавтомата

  • на монтажных рельсах, соответствующих стандарту EN 50022, установка осуществляется с помощью двойной быстродействующей защелки на задней стенке прибора;
  • на настенных панелях с герметизируемыми вводами, и на панелях для встроенной установки .

Пример установки

Инструкции по установке

  • Помните, что при установке АВДТ с малой чувствительностью IΔn 0.03A защита от непрямого контакта обеспечивается только при использовании заземления, выполненного в соответствии с требованиями стандарта CEI 64-8/IEC 364.
  • Если диф автомат обладает высокой чувствительностью IΔn 0.03A, при этом обеспечивается также защита от прямого контакта.
  • Установите устройство на панели или в корпусе, обеспечивающем уровень защиты IРЕ, соответствующий конкретным условиям применения в соответствии с требованиями CEI 64-8 (IEC 364).
  • Подключите оборудование в точном соответствии со схемой.
  • Включите все нагрузки, подключенные к защищаемой цепи. Если АВДТ срабатывает, выясните, какое устройство является причиной срабатывания, путем последовательного включения нагрузок. При обнаружении такого устройства его необходимо отключить от сети и проверить исправность.
  • Нажмите кнопку тестирования. Если устройство установлено и запитано правильно, оно должно сработать.
  • Если электрическая система распределена на очень большом пространстве, обычные токи утечки на землю могут быть достаточно велики. B этом случае имеется вероятность ложных срабатываний. Чтобы избежать этого, необходимо разделить систему, по крайней мере, на два контура, каждый из которых будет защищаться своим дифавтоматом.
  • Электрические помехи внешнего (грозы) и внутреннего (мощные реактивные нагрузки) характера могут вызывать значительные броски напряжения, которые, в свою очередь, могут, в худшем случае, повредить электронные элементы данных автоматов, а в лучшем — вызывать ложные срабатывания. Поэтому необходимо защищать потребителей электроэнергии с помощью устройств защиты от бросков напряжения и, при необходимости, использовать АВДТ с задержкой отключения (противопомехового типа AP).
  • Еще больший уровень безопасности достигается, когда каждый пользователь, подключенный к общему заземлению, индивидуально защищается собственным устройством защиты.
  • Установка автомата должна производиться профессиональным электромонтером в соответствии с требованиями стандарта СЕ! 64-8 (!ЕС 364).

Установка дифференциального автоматического выключателя существенно повышает уровень безопасности при работе на электроустановках. Кроме того, если на шильдике устройства имеется обозначение IΔn 0.03A или IΔn 0.01A, обеспечивается защита при случайном контакте с токоведущими частями оборудования. Тем не менее, установка автоматического дифференциального автомата не означает отказа от выполнения всех обычных мер предосторожности при работе на электроустановках. B частности:

  • Не забывайте ежемесячно нажимать кнопку «Т», при этом устройство защиты должно сработать. Если этого не происходит, необходимо немедленно вызвать электрика, поскольку безопасность системы не обеспечивается.
  • При использовании персональных компьютеров, электронных пишущих машинок, электронных кассовых аппаратов или другого оборудования с электронными компонентами, оснащенного вилками с контактом заземления, убедитесь в том, что на шильдике УЗО имеется символ «N». Только в этом случае будет обеспечиваться наилучшая защита, которую предоставляет современный уровень развития техники. Если такое обозначение отсутствует, проконсультируйтесь с электриком.
  • Перед заменой ламп или предохранителей убедитесь в том, что электропитание всей установки отключено, разомкнув главный рубильник.
  • Не пользуйтесь проводами с нарушенной изоляцией, примите немедленные меры к их замене.
  • Для выполнения любых работ на стационарных или мобильных электроустановках вызывайте квалифицированного электрика.

Подключение дифавтомата

АВДТ обеспечивают безопасность даже при случайном обрыве среднего провода (нейтрали).
Oни могут использоваться в однофазных электроустановках, питающихся от двух фазных проводов или от фазного провода и нейтрали. Также данные устройства защиты могут устанавливаться в системах, имеющих один из перечисленных ниже видов защиты:

  • подключение к нейтрали или металлоконструкциям выше места установки
  • непосредственное заземление металлических частей
  • активная защита против аварийных токов утечки на землю.

На всех устройствах защитного отключения могут устанавливаться следующие принадлежности:

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


отличия, что лучше выбрать, и как установить

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

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

Назначение устройств защитного отключения

УЗО обеспечивает защиту изоляции электропроводки и предотвращает возникновение пожара. А человека оно предохраняет от воздействия электрического тока при прикосновении к частям устройств, на которых имеется фазное напряжение.

УЗО срабатывает на дисбаланс токов в фазном и нулевом проводах защищаемой электросети. Это бывает, когда происходит пробой изоляции и появляется дополнительная утечка.

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

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

Автоматический выключатель в таком случае не сработает, так как для отключения ему необходимы токи как минимум в десятки ампер. Для жизни человека опасны токи, начиная с 30 мА и выше. Способность устройства защитного отключения реагировать на 10-30 мА является надежной защитой от воздействия электричества.

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

Если стоит вопрос, что выбирать – УЗО или дифавтомат, – надо понимать, что вместе с УЗО в цепь обязательно придется устанавливать автоматический выключатель.

Назначение дифференциального автомата

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

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

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

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

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

Если протекающий по линии ток превышает номинальный более чем на 25%, то примерно через час устройство отключит линию, сработает тепловой расцепитель.

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

Внешний вид

Всеобщая унификация привела к тому, что по форме и размерам корпуса очень сложно уловить разницу между дифавтоматом и УЗО.

Для однофазной сети корпуса этих приборов имеют размер равный двум корпусам однополюсного автоматического выключателя. Каждый из них имеет тестовую кнопку, они двухполюсные. Установка УЗО на DIN-рейку ничем не отличается от монтажа дифавтомата.

Внешне дифференциальные автоматы отличаются от УЗО:

  • по надписям на лицевой панели;
  • маркировке;
  • функциональной схеме.

Обычно в верхней части прибора ниже названия фирмы производителя идет название прибора. К примеру, ВД и несколько цифр. ВД означает выключатель дифференциальный, то есть это УЗО.

Если присутствует аббревиатура АВДТ (сокращение от выражения: автоматический выключатель дифференциального тока), то это дифавтомат. На случай повреждения надписи на лицевой панели производитель предусмотрительно выдавил название устройства на боковой стороне прибора.

Правда, для определения типа устройства придется снимать его с DIN-рейки. Но этот способ касается в основном отечественных производителей.

Зарубежные поставщики на этот счет не заморачиваются. Поэтому приходится ориентироваться по маркировке и схеме.

Обозначение номинального тока

Разница наблюдается в обозначении номинального тока. В УЗО его записывают в виде цифры, например 16 А, которая означает, что прибор будет нормально работать при токах не превышающих 16 ампер. Главная характеристика для него – это значение тока отключения.

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

Поэтому перед значением номинального тока стоит буква, обозначающая предел превышения номинала, при котором произойдет мгновенное срабатывание прибора. Если на передней панели стоит надпись, например, «С16», значит, перед вами дифавтомат.

Электромагнитный расцепитель данного дифавтомата мгновенно отключит линию при превышении номинального тока в 5-10 раз.

Функциональная схема

На схеме УЗО на передней панели, можно видеть изображение магнитопровода дифференциального трансформатора, тестового резистора, трех ключей и управляющей обмотки.

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

На схеме дифавтомата, в дополнение к схеме УЗО, изображается ключ, подсоединенный к фазовому проводу на выходе трансформатора. Или может быть другое изображение.

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

Другие различия

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

Стоимость

Немаловажная разница состоит в цене. Дифференциальный автоматический выключатель значительно выше в цене, чем УЗО. Даже, если функционально УЗО уравнять с дифавтоматом, подсоединив дополнительный автоматический выключатель, все равно стоимость дифавтомата будет выше.

Размеры и ремонтопригодность

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

Зато ремонтопригодность приборов при равном функционале лучше в системе УЗО+ автомат, чем просто дифавтомат. Кроме этого сразу становится ясна причина отключения – токи утечки или перегрузка в сети.

Подключение

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

Что касается УЗО, то здесь возможно два варианта. Если УЗО ставят на несколько групп потребителей, то оно идет первым, а за ним уже автоматические выключатели на каждую группу.

Если одну линию защищает одно УЗО и один автомат, то автомат идет первым.

Еще один момент, который нужно учитывать при выборе между дифференциальным автоматом и УЗО+ автомат. Это надежность устройств. Как известно, чем проще устройство, тем оно надежнее. В этом отношении дифавтомат проигрывает.

Итак, основная разница между дифавтоматом и УЗО состоит в их функциях, маркировке, стоимости, способе подключения и занимаемом месте в щитке.

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

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

Дифференциальный автомат – уникальный аппарат, сочетающий в едином корпусе функции сразу двух защитных устройств – это одновременно УЗО и автоматический выключатель. Профессионалы рекомендуют использовать дифференциальные автоматические выключатели в обязательном порядке при устройстве или реконструкции проводки.

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

Для чего нужны дифференциальные автоматы?

Прямым предназначением дифференциального автомата является защита человека от поражения электрическим током при прямом контакте. Устройство одновременно отслеживает как возникновение короткого замыкания, так и проявление признаков утечки электричества через повреждённые токопроводящие компоненты сети.

Дифференциальный автомат обесточит контролируемую линию при возникновении:

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

Так, простое устройство вполне способно обезопасить квартиру или частный дом, предотвращая возникновение чрезвычайных ситуаций, вызванных проблемами с электричеством.

Преимуществом использования дифференциального автомата является отсутствие необходимости подбора УЗО, ведь он уже содержится в составе компонентов дифференциального автомата. Одно устройство, совмещающее в себе функции двух (УЗО и автоматического выключателя), занимает меньше места в электрическом щитке на размер однополюсного автомат – его ширина 17,5 мм.

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

Техническое устройство

Конструктивно дифавтоматы выполняются из диэлектрического материала. Задняя часть имеет специальное крепление для установки на DIN-рейку. Внутри они состоят из двухполюсного или четырёх полюсного выключателя и включенного последовательно с ним модуля дифзащиты. Данный модуль представляет собой дифференциальный трансформатор тока, через который проходят ноль и фаза, образуя тем самым первичную обмотку и обмотку управления — вторичную обмотку.

Как работает дифференциальный автомат

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

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

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

Основные параметры

Любой дифференциальный автомат располагает 8-ю клеммами для трёхфазной сети и 4-мя для однофазной. Само устройство является модульным и состоит из:

  • Корпуса, изготовленного из негорючего тугоплавкого материала;
  • Клемм с маркировкой, предназначенных для подключения проводников;
  • Рычага включения-выключения. Количество зависит от модели конкретного устройства;
  • Кнопки тестирования, позволяющей вручную проверить работоспособность дифференциального автомата;
  • Сигнального огонька, информирующего о выбранном типе срабатывания (утечка или перегрузка).

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

Выбор дифавтомата нужно производить исходя из множества параметров:

  1. Номинальный ток – показывает, на какую нагрузку рассчитан дифавтомат. Эти значения стандартизированы и могут принимать следующие значения: 6, 10, 16, 20, 25, 32, 40, 50, 63А.
  2. Время-токовая характеристика – значения могут быть равны B, C и D. Для простой сети с маломощным оборудованием (используется редко) подойдёт тип В, в городской квартире – С, на мощных производственных предприятиях – D. Например, при запуске двигателя ток резко возрастает на доли секунд, ведь необходимы определённые усилия для его раскрутки. Данный пусковой ток может в несколько раз превышать номинальный ток. После запуска потребляемый ток становится в несколько раз меньше. Для этого и нужен этот параметр. Характеристика B означает кратковременное превышение такого пускового тока в 3-5 раз, C – 5-10 раз, D – 10-20 раз.
  3. Дифференциальный ток утечки – 10 или 30 мА. Первый тип подойдёт для линии с 1-2 потребителями, второй – с несколькими.
  4. Класс дифференциальной защиты – определяет, на какие утечки будет реагировать дифавтомат. При выборе устройства для квартиры подойдут классы АС или А.
  5. Отключающая способность – значение зависит от номинала автомата и должно быть выше 3 кА для автоматов до 25 А, 6 кА для автоматических выключателей на ток до 63 А и 10 кА для автоматических выключателей на ток до 125 А.
  6. Класс токоограничения – показывает, как быстро будет отключена линия при возникновении критических токов. Существует 3 класса дифавтоматов с самого «медленного» — 1 к самому «быстрому» — 3 по срабатыванию соответственно. Чем выше класс, тем выше цена.
  7. Условия использования – определяются исходя из потребностей.

Выбор дифавтомата по мощности

Для того чтобы выбрать дифавтомат по мощности необходимо учитывать состояние проводки. При условии, что проводка качественная, надёжная и отвечающая всем требованиям, для расчёта номинала можно применить следующую формулу – I=P/U, где P – это суммарная мощность используемых на линии дифференциального автомата электрических приборов. Выбираем дифавтомат ближайший по номиналу. Ниже приведена таблица зависимости номинала дифавтомата от мощности нагрузки для сети 220 В.

Внимание! Электрические провода должны быть правильно подобраны, исходя из мощности нагрузки.

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

На данный момент в продаже имеются дифавтоматы с двумя типами расцепителя:

  • Электронный – имеет электронную схему с усилителем сигнала, которая питается от подключённой фазы, что делает устройство уязвимым при отсутствии питания. При пропаже нуля такой он не сработает.
  • Электромеханический — не потребует для работы внешних источников питания, что делает его автономным.

Подключение

Подключение дифавтомата – весьма несложный процесс. Верхняя часть дифференциального автомата содержит контактные пластины и зажимные винты, предназначенные для подключения нуля N и фазы L от счётчика. Нижняя часть располагает контактами, к которым и подключается линия с потребителями.

Подключение дифавтомата можно представить следующим образом:

  1. Зачистка концов проводников от изоляционного материала примерно на 1 сантиметр.
  2. Ослабление зажимного винта на несколько оборотов.
  3. Подключение проводника.
  4. Затягивание винта.
  5. Проверка качества крепления простейшим физическим усилием.

Выбор между конфигурацией УЗО + автомат и обычным дифавтоматом должен обуславливаться наличием места в щитке и ценой самих устройств. В первом варианте сложность монтажа слегка возрастёт.

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

  1. На входе после электросчётчика для всей квартирной проводки. При использовании данной схемы питающие провода подключаются к верхним клеммам. К нижним же подаётся нагрузка от различных электрических групп, разделённых автоматическими выключателями. Существенным минусом данного варианта является сложность поиска причины выхода из строя в случае срабатывания автоматики и полное отключение всех групп при неполадках.
  2. На каждую группу потребителей по отдельности. Этот метод применяют для защиты в помещениях, где отмечается повышенный уровень влажности воздуха – ванные, кухни. Актуален метод и для мест, где электробезопасность должна быть на высшем уровне – например, для детской. Понадобится несколько дифференциальных автоматов – несмотря на большие затраты, данный способ является наиболее надёжным и гарантирующим бесперебойное электроснабжение, а срабатывание любого из дифавтоматов не заставит сработать остальные.

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

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

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

n \ to \ mathbb {R} f: Rn → R, чтобы вычислить градиент ∇f (x) = (∂f∂x1 (x), ⋯, ∂f∂xn (x)) \ nabla f (x) = \ left (\ frac {\ partial f} {\ partial x_1} (x), \ cdots, \ frac {\ partial f} {\ partial x_n} (x) \ right) ∇f (x) = (∂x1 ∂ f (x), ⋯, ∂xn ∂f (x)), например. Это приблизительно , потому что мы должны выбрать какое-то конечное малое значение длины шага h h h, уравновешивая точность с плавающей запятой с ошибкой математической аппроксимации.

Что мы можем сделать вместо этого?

Один из вариантов — явно записать функцию, которая вычисляет точные производные, используя правила, известные нам из исчисления.Однако это быстро становится утомительным и подверженным ошибкам упражнением. Есть другой способ! Область автоматического дифференцирования предоставляет методы для автоматического вычисления точных производных (с точностью до ошибки с плавающей запятой) с учетом только самой функции f f f. Некоторые методы используют намного меньше вычислений f f f, чем потребовалось бы при использовании конечных разностей. В лучшем случае, точный градиент f f f может быть оценен по стоимости O (1) O (1) O (1) оценок самого f f f .Предостережение в том, что f f f нельзя считать черным ящиком; вместо этого нам нужен либо доступ к исходному коду f f f, либо способ подключения специального типа числа с использованием перегрузки оператора.

JuliaDiff — неформальная организация, целью которой является унификация и документирование пакетов, написанных на Julia для оценки производных инструментов. Технические особенности Julia, а именно множественная отправка, исходный код через отражение, JIT-компиляция и первоклассный доступ к синтаксическому анализу выражений, делают реализацию и использование методов автоматического дифференцирования проще, чем когда-либо (по нашему предвзятому мнению).

Это большой список пакетов Julia Automatic Differentiation (AD) и связанных с ними инструментов. Как видите, здесь много чего происходит. Как и любые такие большие списки, он быстро устаревает. Если вы заметили что-то устаревшее или просто неправильное, отправьте PR.

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

Reverse-mode

  • ReverseDiff.jl: оператор перегрузки AD в обратном режиме. Очень хорошо зарекомендовал себя.

  • Nabla.jl: Оператор перегрузки реверсивного режима AD. Используется в системах Invenia (его сопровождающий).

  • Tracker.jl: Перегрузка оператора AD в обратном режиме. Наиболее известен тем, что AD использовался в более ранних версиях пакета машинного обучения Flux.jl. Больше не используется Flux.jl, но все еще используется в нескольких местах экосистемы Julia.

  • AutoGrad.jl: оператор перегрузки реверсивного режима AD. Первоначально порт пакета Python Autograd. В основном используется в Knet.jl.

  • Zygote.jl: источник ИК-уровня для источника AD обратного режима. Очень широко используется. Особенно примечателен тем, что это AD, используемый Flux.jl. Также имеется секретный экспериментальный источник для AD прямого режима.

  • Yota.jl: Источник ИК-уровня для источника AD обратного режима.

  • XGrad.jl: источник уровня AST для источника AD в обратном режиме.В настоящее время не в активной разработке.

  • ReversePropagation.jl: Скалярный источник на основе трассировки в источник AD в обратном режиме.

  • Enzyme.jl: скалярный источник LLVM в источник AD в обратном режиме. Экспериментальный.

  • Diffractor.jl: источник ИК-излучения нового поколения для источника AD в обратном (и прямом) режиме. В развитии.

Прямой режим

  • ForwardDiff.jl: Скаляр, оператор перегрузки AD прямого режима.Очень стабильно. Очень хорошо зарекомендовал себя.

  • ForwardDiff2: экспериментальная, нескалярная гибридная перегрузка оператора / AD прямого режима между источником. В настоящее время не в разработке.

Символический:

Экзотический

Конечная разность

Да, мы сказали в начале, чтобы прекратить приближение к производным, но эти пакеты быстрее и точнее, чем вы ожидаете когда-либо достигнуть конечной разности. Если вам действительно нужна конечная разность, используйте эти пакеты, а не реализовывайте свои собственные.

  • FiniteDifferences.jl: высокоточное вычисление конечных разностей с поддержкой практически любого типа (не только массивов и чисел).

  • FiniteDiff.jl: Конечное дифференцирование высокой точности с поддержкой эффективного вычисления разреженных якобианов с помощью векторов раскраски.

  • Calculus.jl: устаревший, устаревший пакет. Новым пользователям следует вместо этого обращаться к FiniteDifferences.jl и FiniteDiff.jl.

Наборы правил

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

  • ChainRules: Расширяемые, независимые от AD правила.

  • DiffRules.jl: более ранний набор правил, не зависящих от AD, для скалярных функций. Используется в качестве основного источника для ForwardDiff.jl и частично другими пакетами.

  • ZygoteRules.jl: Легкий пакет для определения правил для Zygote.jl. В значительной степени устарел в пользу независимого от AD ChainRulesCore.jl.

Разреженность

  • Обнаружение разреженности.jl: автоматическое определение паттернов разреженности Якобиана и Гессе.

  • SparseDiffTools.jl: использование разреженности для ускорения FiniteDiff.jl и ForwardDiff.jl, а также других алгоритмов.

Обсуждения JuliaDiff и его использования могут быть направлены на форум Julia Discourse. Сайт autodiff.org служит порталом для академического сообщества, хотя часто он устарел. Проект ChainRules поддерживает список рекомендуемых к прочтению / просмотру для тех, кто хочет получить дополнительную информацию.Наконец, методы автоматического дифференцирования были реализованы на множестве языков. Если вы предпочитаете не использовать Julia, см. Полный список доступных пакетов на странице википедии.

Расширенная автоматическая дифференциация | TensorFlow Core

Руководство «Введение в градиенты и автоматическое различение» включает все необходимое для расчета градиентов в TensorFlow. В этом руководстве рассматриваются более глубокие, менее общие особенности tf.GradientTape API.

Настройка

Примечание. Для этого учебника требуется только пакет tf-nightly для документирования изменений пользовательского градиента SavedModel, доступных в TensorFlow 2.6.
  pip удалить tenorflow keras -y 
  pip install tf-nightly 
 
  импортировать тензорный поток как tf

импортировать matplotlib как mpl
импортировать matplotlib.pyplot как plt

mpl.rcParams ['figure.figsize'] = (8, 6)
  

Управление записью градиента

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

На ленте также есть способы манипулировать записью.

Остановить запись

Если вы хотите остановить запись градиентов, вы можете использовать tf.GradientTape.stop_recording , чтобы временно приостановить запись.

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

  x = tf. Переменная (2.0)
у = tf.Переменная (3,0)

с tf.GradientTape () как t:
  x_sq = х * х
  с t.stop_recording ():
    y_sq = y * y
  z = x_sq + y_sq

grad = t.gradient (z, {'x': x, 'y': y})

print ('dz / dx:', grad ['x']) # 2 * x => 4
print ('dz / dy:', grad ['y'])
  
dz / dx & двоеточие; tf.Tensor (4.0, shape = (), dtype = float32)
дз / ди и двоеточие; Никто
2021-08-02 22 & двоеточие; 12 & двоеточие; 28.993528 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.002398 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.003436 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.005157 и двоеточие; I tensorflow / core / platform / cpu_feature_guard.cc & Colon; 142] Этот двоичный файл TensorFlow оптимизирован с помощью библиотеки глубокой нейронной сети oneAPI (oneDNN) для использования следующих инструкций ЦП в критических для производительности операциях & двоеточие; AVX2 AVX512F FMA
Чтобы включить их в других операциях, перестройте TensorFlow с соответствующими флагами компилятора.
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.005797 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.006878 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.007859 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.564510 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.565453 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.566316 & двоеточие; I tensorflow / stream_executor / cuda / cuda_gpu_executor.cc & двоеточие; 937] успешное чтение узла NUMA из SysFS имело отрицательное значение (-1), но должен быть хотя бы один узел NUMA, поэтому узел NUMA возвращается ноль
2021-08-02 22 & двоеточие; 12 & двоеточие; 29.567203 & двоеточие; I tensorflow / core / common_runtime / gpu / gpu_device.cc & col; 1504] Создано устройство / задание & двоеточие; localhost / replica & двоеточие; 0 / задача & двоеточие; 0 / устройство & двоеточие; GPU & двоеточие; 0 с памятью 14662 МБ и двоеточием; -> устройство и двоеточие; 0, имя & двоеточие; Tesla V100-SXM2-16GB, идентификатор шины pci и двоеточие; 0000 & двоеточие; 00 & двоеточие; 05.0, вычислительные возможности и двоеточие; 7.0
 

Сброс / начало записи с нуля

Если вы хотите начать заново, используйте tf.GradientTape.reset . Простой выход из блока градиентной ленты и перезапуск обычно легче читать, но вы можете использовать метод , сбросить , когда выход из блока ленты затруднен или невозможен.

  x = tf. Переменная (2.0)
y = tf. переменная (3,0)
reset = True

с tf.GradientTape () как t:
  y_sq = y * y
  если сбросить:
    # Выбросьте всю записанную кассету.t.reset ()
  г = х * х + у_sq

grad = t.gradient (z, {'x': x, 'y': y})

print ('dz / dx:', grad ['x']) # 2 * x => 4
print ('dz / dy:', grad ['y'])
  
dz / dx & двоеточие; tf.Tensor (4.0, shape = (), dtype = float32)
дз / ди и двоеточие; Никто
 

Прецизионная остановка градиентного потока

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

  x = tf.Переменная (2,0)
y = tf. переменная (3,0)

с tf.GradientTape () как t:
  y_sq = y ** 2
  z = x ** 2 + tf.stop_gradient (y_sq)

grad = t.gradient (z, {'x': x, 'y': y})

print ('dz / dx:', grad ['x']) # 2 * x => 4
print ('dz / dy:', grad ['y'])
  
dz / dx & двоеточие; tf.Tensor (4.0, shape = (), dtype = float32)
дз / ди и двоеточие; Никто
 

Пользовательские градиенты

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

  1. Нет определенного градиента для новой операции, которую вы пишете.
  2. Расчеты по умолчанию численно нестабильны.
  3. Вы хотите кэшировать дорогостоящие вычисления из прямого прохода.
  4. Вы хотите изменить значение (например, используя tf.clip_by_value или tf.math.round ) без изменения градиента.

В первом случае, чтобы написать новую операцию, вы можете использовать tf.RegisterGradient , чтобы настроить свою собственную (подробности см. В документации API). (Обратите внимание, что реестр градиентов является глобальным, поэтому меняйте его с осторожностью.)

Для последних трех случаев вы можете использовать tf.custom_gradient .

Вот пример, который применяет tf.clip_by_norm к промежуточному градиенту:

  # Установить операцию идентификации, но обрезать во время градиентного прохода.
@ tf.custom_gradient
def clip_gradients (y):
  def назад (dy):
    вернуть tf.clip_by_norm (dy, 0.5)
  вернуть y, назад

v = tf. переменная (2.0)
с tf.GradientTape () как t:
  output = clip_gradients (v * v)
печать (т.gradient (output, v)) # вызывает "backward", который обрезает 4 до 2
  
tf.Tensor (2.0, shape = (), dtype = float32)
 

Дополнительные сведения см. В документации API декоратора tf.custom_gradient .

Пользовательские градиенты в SavedModel

Примечание. Эта функция будет доступна в TensorFlow 2.6.

Пользовательские градиенты можно сохранить в SavedModel с помощью параметра tf.saved_model.SaveOptions (экспериментальный_custom_gradients = True) .

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

  класс MyModule (tf.Module):

  @ tf.function (input_signature = [tf.TensorSpec (None)])
  def call_custom_grad (self, x):
    вернуть clip_gradients (x)

модель = MyModule ()
  
  tf.saved_model.save (
    модель,
    'сохраненная_модель',
    options = tf.saved_model.SaveOptions (экспериментальный_custom_gradients = True))

# Загруженные градиенты будут такими же, как в приведенном выше примере.
v = tf. переменная (2.0)
загружен = tf.saved_model.load ('сохраненная_модель')
с tf.GradientTape () как t:
  вывод = загружен.call_custom_grad (v * v)
print (t.gradient (вывод, v))
  
ИНФОРМАЦИЯ & двоеточие; тензорный поток & двоеточие; Ресурсы, записанные в & двоеточие; сохраненная_модель / активы
tf.Tensor (2.0, shape = (), dtype = float32)
 

Примечание о приведенном выше примере: если вы попытаетесь заменить приведенный выше код на tf.saved_model.SaveOptions (экспериментальный_custom_gradients = False) , градиент по-прежнему будет давать тот же результат при загрузке. Причина в том, что реестр градиентов все еще содержит настраиваемый градиент, используемый в функции call_custom_op .Однако, если вы перезапустите среду выполнения после сохранения без настраиваемых градиентов, запуск загруженной модели под tf.GradientTape вызовет ошибку: LookupError: для операции IdentityN не определен градиент (тип операции: IdentityN) .

Несколько лент

Несколько лент взаимодействуют без проблем.

Например, здесь каждая лента наблюдает за своим набором тензоров:

  x0 = tf.постоянная (0,0)
x1 = tf.constant (0,0)

с tf.GradientTape () как tape0, tf.GradientTape () как tape1:
  tape0.watch (x0)
  tape1.watch (x1)

  y0 = tf.math.sin (x0)
  y1 = tf.nn.sigmoid (x1)

  у = у0 + у1

  ys = tf.reduce_sum (y)
  
  tape0.gradient (ys, x0) .numpy () # cos (x) => 1.0
  
1.0
 
  tape1.gradient (ys, x1) .numpy () # сигмоид (x1) * (1-сигмоид (x1)) => 0,25
  
0,25
 

Градиенты высшего порядка

Операции внутри контекстного менеджера tf.GradientTape записываются для автоматического различения.Если градиенты вычисляются в этом контексте, то вычисление градиента также записывается. В результате тот же API работает и для градиентов более высокого порядка.

Например:

  x = tf.Variable (1.0) # Создать переменную Tensorflow, инициализированную значением 1.0

с tf.GradientTape () как t2:
  с tf.GradientTape () как t1:
    у = х * х * х

  # Вычисляем градиент во внешнем диспетчере контекста `t2`
  # что означает, что вычисление градиента также является дифференцируемым.dy_dx = t1.gradient (y, x)
d2y_dx2 = t2.градиент (dy_dx, x)

print ('dy_dx:', dy_dx.numpy ()) # 3 * x ** 2 => 3.0
print ('d2y_dx2:', d2y_dx2.numpy ()) # 6 * x => 6.0
  
dy_dx & двоеточие; 3.0
d2y_dx2 & двоеточие; 6.0
 

Хотя это дает вам вторую производную скалярной функции , этот шаблон не обобщает для создания матрицы Гессе, поскольку tf.GradientTape.gradient вычисляет только градиент скаляра. Чтобы построить матрицу Гессе, перейдите к примеру Гессе в разделе Якоби.

«Вложенные вызовы к tf.GradientTape.gradient » — хороший шаблон, когда вы вычисляете скаляр из градиента, а затем полученный скаляр действует как источник для вычисления второго градиента, как в следующем примере.

Пример: регуляризация входного градиента

Многие модели подвержены «состязательным примерам». Этот набор методов изменяет входные данные модели, чтобы запутать выходные данные модели. В простейшей реализации — например, в примере Adversarial, использующем атаку метода Fast Gradient Signed Method — делается один шаг по градиенту выходных данных по отношению к входным; «входной градиент».

Одним из методов повышения устойчивости к состязательным примерам является регуляризация входного градиента (Finlay & Oberman, 2019), которая пытается минимизировать величину входного градиента. Если входной градиент небольшой, то изменение на выходе тоже должно быть небольшим.

Ниже представлена ​​простая реализация регуляризации входного градиента. Реализация:

  1. Рассчитайте градиент выхода по отношению к входу, используя внутреннюю ленту.
  2. Рассчитайте величину этого входного градиента.
  3. Рассчитайте градиент этой величины по отношению к модели.
  x = tf.random.normal ([7, 5])

layer = tf.keras.layers.Dense (10, активация = tf.nn.relu)
  
  с tf.GradientTape () как t2:
  # Внутренняя лента принимает только градиент относительно входа,
  # не переменные.
  с tf.GradientTape (watch_accessed_variables = False) как t1:
    t1.watch (x)
    y = слой (x)
    out = tf.reduce_sum (слой (x) ** 2)
  # 1. Рассчитайте входной градиент.g1 = t1.gradient (out, x)
  # 2. Рассчитайте величину входного градиента.
  g1_mag = tf.norm (g1)

# 3. Рассчитайте градиент величины по отношению к модели.
dg1_mag = t2.gradient (g1_mag, layer.trainable_variables)
  
  [var.shape для var в dg1_mag]
  
[TensorShape ([5, 10]), TensorShape ([10])]
 

Якобиане

Во всех предыдущих примерах использовались градиенты скалярной цели относительно некоторого исходного тензора (ов).

Матрица Якоби представляет собой градиенты векторной функции. Каждая строка содержит градиент одного из элементов вектора.

Метод tf.GradientTape.jacobian позволяет эффективно вычислять матрицу Якоби.

Обратите внимание, что:

  • Как gradient : sources аргумент может быть тензором или контейнером тензоров.
  • В отличие от градиента : целевой тензор должен быть одним тензором.

Скалярный источник

В качестве первого примера, вот якобиан вектора-цели относительно скалярного источника.

  x = tf.linspace (-10.0, 10.0, 200 + 1)
дельта = tf. переменная (0,0)

с tf.GradientTape () в качестве ленты:
  y = tf.nn.sigmoid (x + дельта)

dy_dx = tape.jacobian (y, дельта)
  

Когда вы берете якобиан относительно скаляра, результат имеет форму цели и дает градиент каждого элемента относительно источника:

  отпечаток (г.форма)
печать (dy_dx.shape)
  
(201,)
(201,)
 
  plt.plot (x.numpy (), y, label = 'y')
plt.plot (x.numpy (), dy_dx, label = 'dy / dx')
plt.legend ()
_ = plt.xlabel ('x')
  

Источник тензор

Независимо от того, является ли вход скалярным или тензорным, tf.GradientTape.jacobian эффективно вычисляет градиент каждого элемента источника по отношению к каждому элементу цели (целей).

Например, результат этого слоя имеет форму (10, 7) :

  x = tf.random.normal ([7, 5])
layer = tf.keras.layers.Dense (10, активация = tf.nn.relu)

с tf.GradientTape (persistent = True) в качестве ленты:
  y = слой (x)

y.shape
  
TensorShape ([7, 10])
 

А форма ядра слоя - (5, 10) :

  layer.kernel.shape
  
TensorShape ([5, 10])
 

Форма якобиана вывода по отношению к ядру - это эти две формы, сцепленные вместе:

  j = лента.якобиан (y, layer.kernel)
j.shape
  
TensorShape ([7, 10, 5, 10])
 

Если вы суммируете размеры цели, у вас останется градиент суммы, которая была бы вычислена с помощью tf.GradientTape.gradient :

  г = лента.градиент (y, слой.ядро)
print ('g.shape:', g.shape)

j_sum = tf.reduce_sum (j, axis = [0, 1])
дельта = tf.reduce_max (абс (г - j_sum)). numpy ()
утверждать дельту <1e-3
print ('дельта:', дельта)
  
g.shape & двоеточие; (5, 10)
дельта и двоеточие; 4.7683716e-07
 
Пример: Гессен

Хотя tf.GradientTape не дает явного метода построения матрицы Гессе, ее можно построить, используя метод tf.GradientTape.jacobian .

Примечание: Матрица Гессе содержит N ** 2 параметров. По этой и другим причинам это непрактично для большинства моделей. Этот пример включен больше как демонстрация того, как использовать метод tf.GradientTape.jacobian , и не является одобрением прямой оптимизации на основе Гессе.Произведение вектора Гессе можно эффективно вычислить с помощью вложенных лент, и это гораздо более эффективный подход к оптимизации второго порядка.
  x = tf.random.normal ([7, 5])
layer1 = tf.keras.layers.Dense (8, активация = tf.nn.relu)
layer2 = tf.keras.layers.Dense (6, активация = tf.nn.relu)

с tf.GradientTape () как t2:
  с tf.GradientTape () как t1:
    x = слой1 (x)
    x = слой2 (x)
    потеря = tf.reduce_mean (x ** 2)

  g = t1.gradient (потеря, layer1.kernel)

h = t2.jacobian (g, layer1.kernel)
  
  печать (f'layer.kernel.shape: {layer1.kernel.shape} ')
печать (f'h.shape: {h.shape} ')
  
layer.kernel.shape и двоеточие; (5, 8)
h.shape & двоеточие; (5, 8, 5, 8)
 

Чтобы использовать этот гессиан для шага метода Ньютона, вы должны сначала выровнять его оси в матрицу, а градиент - в вектор:

  n_params = tf.reduce_prod (layer1.kernel.shape)

g_vec = tf.reshape (g, [n_params, 1])
h_mat = tf.reshape (h, [n_params, n_params])
  

Матрица Гессе должна быть симметричной:

  def imshow_zero_center (изображение, ** kwargs):
  lim = tf.-1 @ ∇f (X (k))
# h_mat = ∇²f (X (k))
# g_vec = ∇f (X (k))
update = tf.linalg.solve (h_mat + eye_eps, g_vec)

# Измените форму обновления и примените его к переменной.
_ = layer1.kernel.assign_sub (tf.reshape (update, layer1.kernel.shape))
  
2021-08-02 22 & двоеточие; 12 & двоеточие; 31.844887 & двоеточие; I tensorflow / core / util / cuda_solvers.cc & col; 180] Создание дескрипторов CudaSolver для потока 0x6a4df80
 

Хотя это относительно просто для одной переменной tf.Variable , применение этого к нетривиальной модели потребует тщательной конкатенации и нарезки для получения полного гессиана по нескольким переменным.

Пакетный Якобиан

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

Например, здесь вход x имеет форму (партия, входы) , а выход y имеет форму (партия, выходы) :

  x = tf.random.normal ([7, 5])

layer1 = tf.keras.layers.Dense (8, активация = tf.nn.elu)
слой2 = tf.keras.layers.Dense (6, активация = tf.nn.elu)

с tf.GradientTape (persistent = True, watch_accessed_variables = False) в качестве ленты:
  tape.watch (x)
  y = слой1 (x)
  y = слой2 (y)

y.shape
  
TensorShape ([7, 6])
 

Полный якобиан y относительно x имеет форму (партия, входы, партия, выходы) , даже если вам нужно только (партия, входы, выходы) :

  j = лента. Якобиан (y, x)
j.shape
  
TensorShape ([7, 6, 7, 5])
 

Если градиенты каждого элемента в стопке независимы, то каждый (пакет, пакет) срез этого тензора является диагональной матрицей:

  imshow_zero_center (j [:, 0,:, 0])
_ = plt.title ('Срез (партия, партия)')
  

  def plot_as_patches (j):
  # Измените порядок осей так, чтобы каждая диагональ образовывала непрерывный участок.
  j = tf.transpose (j, [1, 0, 3, 2])
  # Прокладывайте между каждым патчем.
  lim = tf.reduce_max (абс (j))
  j = tf.pad (j, [[0, 0], [1, 1], [0, 0], [1, 1]],
             constant_values ​​= -lim)
  # Измените форму, чтобы сформировать единое изображение.
  s = j.shape
  j = tf.reshape (j, [s [0] * s [1], s [2] * s [3]])
  imshow_zero_center (j, протяженность = [- 0,5, с [2] -0,5, с [0] -0,5, -0.5])

plot_as_patches (j)
_ = plt.title ('Все (партия, партия) срезы диагональны')
  

Чтобы получить желаемый результат, вы можете суммировать по дублирующемуся измерению партии или выбрать диагонали, используя tf.einsum :

  j_sum = tf.reduce_sum (j, ось = 2)
печать (j_sum.shape)
j_select = tf.einsum ('bxby-> bxy', j)
печать (j_select.shape)
  
(7, 6, 5)
(7, 6, 5)
 

Было бы гораздо эффективнее провести расчет без дополнительного измерения.Метод tf.GradientTape.batch_jacobian делает именно это:

  jb = tape.batch_jacobian (y, x)
jb.shape
  
ПРЕДУПРЕЖДЕНИЕ & Colon; Tenorflow & Colon; 5 из последних 5 вызовов  .f по адресу 0x7f38cd10ff80> привели к срабатыванию повторной трассировки tf.функции. Трассировка стоит дорого, и чрезмерное количество трассировок может быть связано с (1) многократным созданием функции @ tf. в цикле, (2) передачей тензоров с разными формами, (3) передачей объектов Python вместо тензоров.Для (1) определите функцию @ tf. вне цикла. Для (2) у @ tf.function есть опция экспериментальной_relax_shapes = True, которая ослабляет формы аргументов, чтобы избежать ненужного повторения. Для (3), пожалуйста, обратитесь к https & col; // www.tensorflow.org/guide/function#controlling_retracing и https & col; // www.tensorflow.org/api_docs/python/tf/function для получения дополнительных сведений.
TensorShape ([7, 6, 5])
 
  ошибка = tf.reduce_max (abs (jb - j_sum))
утверждать ошибку <1e-3
печать (error.numpy ())
  
0.0
 
Внимание: tf.GradientTape.batch_jacobian проверяет только соответствие первого измерения исходного и целевого. Он не проверяет, действительно ли градиенты независимы. Вам решать, использовать ли batch_jacobian только там, где это имеет смысл. Например, добавление tf.keras.layers.BatchNormalization разрушает независимость, так как оно нормализуется по измерению
пакета :
  x = tf.random.normal ([7, 5])

слой1 = tf.keras.layers.Dense (8, активация = tf.nn.elu)
bn = tf.keras.layers.BatchNormalization ()
layer2 = tf.keras.layers.Dense (6, активация = tf.nn.elu)

с tf.GradientTape (persistent = True, watch_accessed_variables = False) в качестве ленты:
  tape.watch (x)
  y = слой1 (x)
  y = bn (y, обучение = True)
  y = слой2 (y)

j = лента. якобиан (y, x)
печать (f'j.shape: {j.shape} ')
  
ПРЕДУПРЕЖДЕНИЕ & Colon; Tenorflow & Colon; 6 из последних 6 вызовов  .f по адресу 0x7f39

050> сработали tf.функция обратного отслеживания. Трассировка стоит дорого, и чрезмерное количество трассировок может быть связано с (1) многократным созданием функции @ tf. в цикле, (2) передачей тензоров с разными формами, (3) передачей объектов Python вместо тензоров. Для (1) определите функцию @ tf. вне цикла. Для (2) у @ tf.function есть опция экспериментальной_relax_shapes = True, которая ослабляет формы аргументов, чтобы избежать ненужного повторения. Для (3) см. Https & col; // www.tensorflow.org/guide/function#controlling_retracing и https & col; // www.tenorflow.org/api_docs/python/tf/function для более подробной информации. j. форма и двоеточие; (7, 6, 7, 5)
  plot_as_patches (j)

_ = plt.title ('Эти срезы не диагональные')
_ = plt.xlabel ("Не используйте` batch_jacobian` ")
  

В этом случае batch_jacobian все еще выполняется и возвращает , что-то с ожидаемой формой, но его содержимое имеет неясное значение:

  jb = tape.batch_jacobian (y, x)
печать (f'jb.shape: {jb.shape} ')
  
jb.форма и двоеточие; (7, 6, 5)
 

Поваренная книга Autodiff - документация JAX

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

Градиенты

Начиная с

град

Вы можете дифференцировать функцию с помощью grad :

 grad_tanh = град (jnp.tanh)
печать (grad_tanh (2.0))
 

grad принимает функцию и возвращает функцию. Если у вас есть функция Python f , которая оценивает математическую функцию \ (f \), тогда grad (f) - это функция Python, которая оценивает математическую функцию \ (\ nabla f \). Это означает, что grad (f) (x) представляет значение \ (\ nabla f (x) \).

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

 печать (град (град (jnp.танх)) (2,0))
печать (град (град (град (jnp.tanh))) (2.0))
 

Давайте посмотрим на вычисление градиентов с градиентом в модели линейной логистической регрессии. Во-первых, установка:

 сигмоида def (x):
    return 0.5 * (jnp.tanh (x / 2) + 1)

# Выводит вероятность того, что метка верна.
def прогноз (W, b, входы):
    вернуть сигмоид (jnp.dot (входы, W) + b)

# Создайте набор данных об игрушках.
входы = jnp.array ([[0.52, 1.12, 0.77],
                   [0,88, -1,08, 0,15],
                   [0,52, 0.06, -1.30],
                   [0,74, -2,49, 1,39]])
target = jnp.array ([Верно, Верно, Ложно, Верно])

# Потеря обучения - это отрицательная логарифмическая вероятность примеров обучения.
def потеря (W, b):
    preds = предсказать (W, b, входные данные)
    label_probs = прогнозы * цели + (1 - прогнозы) * (1 - цели)
    вернуть -jnp.sum (jnp.log (label_probs))

# Инициализировать случайные коэффициенты модели
ключ, W_key, b_key = random.split (ключ, 3)
W = случайный.нормальный (W_key, (3,))
b = случайный.нормальный (b_key, ())
 

Используйте функцию grad с ее аргументом argnums , чтобы дифференцировать функцию по позиционным аргументам.

 # Дифференцировать `проигрыш` относительно первого позиционного аргумента:
W_grad = grad (потеря, argnums = 0) (W, b)
print ('W_grad', W_grad)

# Поскольку по умолчанию argnums = 0, выполняется то же самое:
W_grad = град (потеря) (Вт, б)
print ('W_grad', W_grad)

# Но мы также можем выбрать другие значения и опустить ключевое слово:
b_grad = grad (убыток, 1) (W, b)
print ('b_grad', b_grad)

# Включая значения кортежа
W_grad, b_grad = grad (потеря, (0, 1)) (W, b)
print ('W_grad', W_grad)
print ('b_grad', b_grad)
 
 Вт_град [-0.16965576 -0,8774648 -1,4

5] W_grad [-0,16965576 -0,8774648 -1,4

5] b_grad -0.2922724 W_grad [-0,16965576 -0,8774648 -1,4

5] b_grad -0.2922724

Этот API grad имеет прямое соответствие превосходной нотации в классическом исчислении Спивака на многообразиях (1965), также используемом в Sussman and Wisdom's Structure and Interpretation of Classical Mechanics (2015) and их Functional Differential Geometry (2013). Обе книги находятся в открытом доступе.См., В частности, раздел «Пролог» Функционально-дифференциальной геометрии для защиты этой нотации.

По сути, при использовании аргумента argnums , если f является функцией Python для вычисления математической функции \ (f \), тогда выражение Python grad (f, i) оценивается как функция Python для вычисления \ (\ partial_i f \).

Дифференциация по вложенным спискам, кортежам и диктовкам

Дифференциация по отношению к стандартным контейнерам Python просто работает, поэтому используйте кортежи, списки и словари (и произвольное вложение), как вам нравится.

 def loss2 (params_dict):
    preds = preds (params_dict ['W'], params_dict ['b'], входные данные)
    label_probs = прогнозы * цели + (1 - прогнозы) * (1 - цели)
    вернуть -jnp.sum (jnp.log (label_probs))

print (grad (loss2) ({'W': W, 'b': b}))
 
 {'W': DeviceArray ([- 0,16965576, -0,8774648, -1,4

5], dtype = float32), 'b': DeviceArray (-0,2922724, dtype = float32)}

Вы можете зарегистрировать свои собственные типы контейнеров для работы не только с grad , но и со всеми преобразованиями JAX ( jit , vmap и т. Д.).

Оценить функцию и ее градиент, используя

value_and_grad

Еще одна удобная функция - value_and_grad для эффективного вычисления как значения функции, так и значения ее градиента:

 из jax import value_and_grad
loss_value, Wb_grad = value_and_grad (потеря, (0, 1)) (W, b)
print ('значение потери', значение_утери)
print ('значение убытка', убыток (W, b))
 
 стоимость убытка 3.0519395
стоимость убытка 3.0519395
 

Проверка числовых различий

В производных финансовых инструментах замечательно то, что их легко проверить с помощью конечных разностей:

 # Установить размер шага для расчетов конечных разностей
eps = 1e-4

# Проверяем b_grad с помощью скалярных конечных разностей
b_grad_numerical = (убыток (W, b + eps / 2.) - убыток (W, b - eps / 2.)) / eps
print ('b_grad_numerical', b_grad_numerical)
print ('b_grad_autodiff', grad (потеря, 1) (W, b))

# Проверяем W_grad с конечными разностями в случайном направлении
ключ, подключ = random.split (ключ)
vec = random.normal (подключ, W.shape)
unitvec = vec / jnp.sqrt (jnp.vdot (vec, vec))
W_grad_numerical = (loss (W + eps / 2. * unitvec, b) - убыток (W - eps / 2. * unitvec, b)) / eps
print ('W_dirderiv_numerical', W_grad_numerical)
print ('W_dirderiv_autodiff', jnp.vdot (grad (потеря) (W, b), unitvec))
 
 b_grad_numerical -0.29325485
b_grad_autodiff -0.2922724
 
 W_dirderiv_numerical -0.19788742
W_dirderiv_autodiff -0.19

9

JAX предоставляет простую удобную функцию, которая, по сути, делает то же самое, но проверяет любой порядок дифференциации, который вам нравится:

 из jax.test_util import check_grads
check_grads (loss, (W, b), order = 2) # проверка производных до 2-го порядка
 

векторных произведений Гессе с

град. -оф- град. .

Одна вещь, которую мы можем сделать с grad более высокого порядка, - это построить функцию произведения вектора Гессе.2 f (x) v = \ partial [x \ mapsto \ partial f (x) \ cdot v] = \ partial g (x) \),

, где \ (g (x) = \ partial f (x) \ cdot v \) - новая скалярная функция, которая ставит точки градиента \ (f \) в \ (x \) с вектором \ (v \ ). Обратите внимание, что мы дифференцируем только скалярные функции от векторных аргументов, и именно здесь мы знаем, что grad эффективен.

В коде JAX мы можем просто написать это:

 def hvp (f, x, v):
    вернуть град (лямбда x: jnp.vdot (grad (f) (x), v)) (x)
 

Этот пример показывает, что вы можете свободно использовать лексическое замыкание, и JAX никогда не будет нарушен или запутан.

Мы проверим эту реализацию на несколько ячеек, как только увидим, как вычислять плотные матрицы Гессе. Мы также напишем еще лучшую версию, в которой используются как прямой, так и обратный режимы.

якобианов и гессиан с использованием

jacfwd и jacrev

Вы можете вычислить полные матрицы Якоби, используя функции jacfwd и jacrev :

 из jax import jacfwd, jacrev

# Изолируйте функцию от весовой матрицы до прогнозов
f = лямбда W: прогнозировать (W, b, входные данные)

J = jacfwd (f) (Вт)
print ("результат jacfwd, с формой", Дж.форма)
печать (J)

J = jacrev (f) (Вт)
print ("jacrev result, with shape", J.shape)
печать (J)
 
 результат jacfwd, с формой (4, 3)
[[0,05981752 0,1283775 0,08857594]
 [0,04015911 -0,04928619 0,0068453]
 [0,12188288 0,01406341 -0,3047072]
 [0,00140426 -0,00472516 0,00263774]]
результат jacrev, с формой (4, 3)
[[0,05981752 0,1283773 0,08857594]
 [0,04015911 -0,04928619 0,0068453]
 [0,12188289 0,01406341 -0,3047072]
 [0,00140426 -0,00472516 0,00263774]]
 

Эти две функции вычисляют одни и те же значения (вплоть до машинных чисел), но отличаются своей реализацией: jacfwd использует автоматическое дифференцирование в прямом режиме, которое более эффективно для «высоких» матриц Якоби, а jacrev использует обратный режим. , что более эффективно для «широких» якобиевых матриц.Для матриц, которые почти квадратны, jacfwd , вероятно, имеет преимущество над jacrev .

Вы также можете использовать jacfwd и jacrev с типами контейнеров:

 def прогноз_dict (параметры, входы):
    вернуть прогноз (params ['W'], params ['b'], input)

J_dict = jacrev (pred_dict) ({'W': W, 'b': b}, входные данные)
для k, v в J_dict.items ():
    print ("Якобиан от {} до логитов" .format (k))
    печать (v)
 
 Якобиан от W до логитов равен
[[0.05981752 0,1283773 0,08857594]
 [0,04015911 -0,04928619 0,0068453]
 [0,12188289 0,01406341 -0,3047072]
 [0,00140426 -0,00472516 0,00263774]]
Якобиан от b до логитов равен
[0,11503369 0,04563536 0,23439017 0,00189765]
 

Для получения более подробной информации о прямом и обратном режимах, а также о том, как максимально эффективно реализовать jacfwd и jacrev , читайте дальше!

Использование композиции двух из этих функций дает нам способ вычислить плотные матрицы Гессе:

 def hessian (f):
    вернуть jacfwd (jacrev (f))

H = гессен (f) (W)
print ("гессиан, с формой", H.форма)
печать (H)
 
 гессиан, с формой (4, 3, 3)
[[[0,02285464 0,04922539 0,03384245]
  [0,04922538 0,10602392 0,07289144]
  [0,03384245 0,07289144 0,05011286]]

 [[-0,03195212 0,03921397 -0,00544638]
  [0,03921397 -0,04812624 0,0066842]
  [-0,00544638 0,0066842 -0,00092836]]

 [[-0,01583708 -0,00182736 0,0395927]
  [-0,00182736 -0,00021085 0,00456839]
  [0,0395927 0,00456839 -0,09898175]]

 [[-0,0010352 0,00348332 -0,0019445]
  [0,00348332 -0,01172091 0,006543]
  [-0.n \)), и именно здесь форвард-режим побеждает. 

Как это сделано: две основные функции автодифференцирования

Продукты Якобиана-Вектора (JVP, также известные как autodiff прямого режима)

JAX включает эффективные и общие реализации автоматического дифференцирования как в прямом, так и в обратном режиме. Знакомая функция grad построена на обратном режиме, но чтобы объяснить разницу между двумя режимами, и когда каждый из них может быть полезен, нам понадобится немного математических знаний. {m \ times n} \).м \). Мы называем это отображение от пар \ ((x, v) \) до выходных касательных векторов произведением векторов Якоби и записываем его как

\ (\ qquad (x, v) \ mapsto \ partial f (x) v \)

JVP в коде JAX

Вернувшись в код Python, функция JAX jvp моделирует это преобразование. Учитывая функцию Python, которая вычисляет \ (f \), JAX jvp - это способ получить функцию Python для вычисления \ ((x, v) \ mapsto (f (x), \ partial f (x) v) \ ).

 из jax import jvp

# Изолируйте функцию от весовой матрицы до прогнозов
f = лямбда W: прогнозировать (W, b, входные данные)

ключ, подключ = случайный.разделить (ключ)
v = random.normal (подключ, W.shape)

# Сдвинуть вперед вектор `v` вдоль` f`, вычисленного в `W`
y, u = jvp (f, (W,), (v,))
 

В терминах сигнатур типов, подобных Haskell, мы могли бы написать

 jvp :: (a -> b) -> a -> T a -> (b, T b)
 

, где мы используем T a для обозначения типа касательного пространства для a . Другими словами, jvp принимает в качестве аргументов функцию типа a -> b , значение типа a и значение касательного вектора типа T a .Он возвращает пару, состоящую из значения типа b и выходного касательного вектора типа T b .

Функция jvp, преобразованная в , оценивается во многом так же, как и исходная функция, но в паре с каждым основным значением типа a она проталкивает значения касательных типа T a . Для каждой примитивной числовой операции, которую применила бы исходная функция, преобразованная функция jvp выполняет «правило JVP» для этого примитива, которое одновременно оценивает примитив на примитиве и применяет JVP примитива к этим примитивным значениям.

Эта стратегия оценки имеет некоторые непосредственные последствия для вычислительной сложности: поскольку мы оцениваем JVP по ходу работы, нам не нужно ничего хранить на будущее, и поэтому стоимость памяти не зависит от глубины вычислений. Кроме того, стоимость FLOP для функции, преобразованной в jvp , примерно в 3 раза больше стоимости простой оценки функции (одна единица работы для оценки исходной функции, например sin (x) ; одна единица для линеаризации, например cos (x) и один блок для применения линеаризованной функции к вектору, например cos_x * v ).Другими словами, для фиксированной начальной точки \ (x \) мы можем оценить \ (v \ mapsto \ partial f (x) \ cdot v \) примерно с той же предельной стоимостью, что и оценка \ (f \).

Эта сложность памяти звучит довольно убедительно! Так почему же в машинном обучении мы нечасто встречаем форвард-режим?

Чтобы ответить на этот вопрос, сначала подумайте, как с помощью JVP построить полную матрицу Якоби. Если мы применим JVP к вектору с одним горячим касательным, он обнаружит один столбец матрицы Якоби, соответствующий ненулевой записи, которую мы ввели.п \). Построение этой матрицы по одному столбцу за раз, при каждом вызове с одинаковым количеством FLOP для оценки исходной функции, конечно, кажется неэффективным! В частности, для обучения нейронных сетей, где \ (f \) - функция потерь при обучении, а \ (n \) может быть в миллионах или миллиардах, этот подход просто не будет масштабироваться.

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

Векторно-якобианские произведения (VJP, также известные как автодифференциальный режим в обратном режиме)

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

Соответствующее отображение котангенсных пространств часто называют откатом. из \ (f \) в \ (x \). Ключевым моментом для наших целей является то, что он идет от чего-то, похожего на вывод \ (f \), к чему-то, что выглядит как ввод \ (f \), как мы могли бы ожидать от транспонированной линейной функции.

VJP в коде JAX

При переключении с математики обратно на Python функция JAX vjp может принимать функцию Python для вычисления \ (f \) и возвращать нам функцию Python для оценки VJP \ ((x, v) \ mapsto (f (x ), v ^ \ mathsf {T} \ partial f (x)) \).

 из jax import vjp

# Изолируйте функцию от весовой матрицы до прогнозов
f = лямбда W: прогнозировать (W, b, входные данные)

у, vjp_fun = vjp (f, W)

ключ, подключ = random.split (ключ)
u = random.normal (подключ, y.shape)

# Оттягиваем ковектор `u` вдоль` f`, вычисленный в `W`
v = vjp_fun (u)
 

В терминах сигнатур типов, подобных Haskell, мы могли бы написать

 vjp :: (a -> b) -> a -> (b, CT b -> CT a)
 

, где мы используем CT a для обозначения типа пространства котангенса для a .n \ to \ mathbb {R} \), мы можем сделать это всего за один вызов. Вот почему grad эффективен для оптимизации на основе градиента, даже для таких целей, как функции потерь при обучении нейронной сети для миллионов или миллиардов параметров.

Однако есть цена: хотя FLOP дружественны, память масштабируется в зависимости от глубины вычислений. Кроме того, реализация традиционно более сложна, чем в прямом режиме, хотя у JAX есть некоторые хитрости в рукаве (это история для будущих ноутбуков!).

Подробнее о том, как работает обратный режим, см. В этом обучающем видео Летней школы глубокого обучения в 2017 году.

Векторные градиенты с VJP

Если вы хотите использовать векторные градиенты (например, tf.gradients ):

 из jax import vjp

def vgrad (f, x):
  у, vjp_fn = vjp (f, x)
  return vjp_fn (jnp.ones (y.shape)) [0]

print (vgrad (лямбда x: 3 * x ** 2, jnp.ones ((2, 2))))
 

Произведения вектора Гессе с использованием как прямого, так и обратного режима

В предыдущем разделе мы реализовали функцию произведения вектора Гессе, просто используя обратный режим (предполагая непрерывные вторые производные):

 def hvp (f, x, v):
    вернуть град (лямбда x: jnp.2 е (х) v \). 

Мы можем перевести это почти прямо в код:

 из jax import jvp, grad

# вперед-назад-назад
def hvp (f, прямые, касательные):
  вернуть jvp (grad (f), прямые, касательные) [1]
 

Еще лучше, поскольку нам не нужно было напрямую вызывать jnp.dot , эта функция hvp работает с массивами любой формы и с произвольными типами контейнеров (например, с векторами, хранящимися в виде вложенных списков / диктов / кортежей), и не работает. Нет даже зависимости от jax.Кирилл .

Вот пример того, как его использовать:

 def f (X):
  вернуть jnp.sum (jnp.tanh (X) ** 2)

ключ, подключ1, подключ2 = random.split (ключ, 3)
X = случайный.нормальный (подключ1, (30, 40))
V = random.normal (подключ2, (30, 40))

ans1 = hvp (f, (X,), (V,))
ans2 = jnp.tensordot (гессиан (f) (X), V, 2)

печать (jnp.allclose (ans1, ans2, 1e-4, 1e-4))
 

Другой способ, которым вы могли бы подумать о написании этого, - это использование обратного переадресации:

 # назад-вперед-вперед
def hvp_revfwd (f, прямые, касательные):
  g = прямые лямбда: jvp (f, прямые, касательные) [1]
  вернуть град (г) (первичные)
 

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

 # reverse-over-reverse, работает только для одиночных аргументов
def hvp_revrev (f, прямые, касательные):
  x, = основные
  v = касательные
  вернуть град (лямбда x: jnp.vdot (grad (f) (x), v)) (x)


print ("Вперед назад")
% timeit -n10 -r3 hvp (f, (X,), (V,))
print ("Назад вперед")
% timeit -n10 -r3 hvp_revfwd (f, (X,), (V,))
print («Обратный через обратный»)
% timeit -n10 -r3 hvp_revrev (f, (X,), (V,))

print («Наивная полная гессенская материализация»)
% timeit -n10 -r3 jnp.tensordot (гессиан (f) (X), V, 2)
 
 вперед-назад
4,01 мс ± 121 мкс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)
Назад вперед
 
 7,34 мс ± 3,39 мс на цикл (среднее ± ст.разработчик из 3 сбн по 10 петель)
Обратный обратный
 
 12 мс ± 6,66 мс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)
Наивная полная гессенская материализация
 
 51,2 мс ± 754 мкс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)
 

Создание VJP, JVP и

vmap

Якобиан-матрица и матрица-якобиан произведения

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

 # Отделяем функцию от весовой матрицы до прогнозов
f = лямбда W: прогнозировать (W, b, входные данные)

# Оттягиваем ковекторы `m_i` вдоль` f`, вычисленные как `W`, для всех` i`.
# Во-первых, воспользуйтесь списком, чтобы перебрать строки в матрице M.
def loop_mjp (f, x, M):
    у, vjp_fun = vjp (f, x)
    вернуть jnp.vstack ([vjp_fun (mi) для mi в M])

# Теперь используйте vmap для построения вычисления, которое выполняет одну быструю матрицу-матрицу
# умножение, а не внешний цикл векторно-матричного умножения.def vmap_mjp (f, x, M):
    у, vjp_fun = vjp (f, x)
    выходы, = vmap (vjp_fun) (M)
    возвратные выходы

ключ = random.PRNGKey (0)
num_covecs = 128
U = random.normal (ключ, (num_covecs,) + y.shape)

loop_vs = loop_mjp (f, W, M = U)
print ('Матрично-якобиево произведение без отображения v')
% timeit -n10 -r3 loop_mjp (f, W, M = U)

print ('\ nVmapped матрично-якобиево произведение')
vmap_vs = vmap_mjp (f, W, M = U)
% timeit -n10 -r3 vmap_mjp (f, W, M = U)

assert jnp.allclose (loop_vs, vmap_vs), 'Vmap и матрично-якобианские продукты без vmapped должны быть идентичны'
 
 Матрично-якобиево произведение без vmapped
 
 114 мс ± 460 мкс на цикл (среднее ± ст.разработчик из 3 сбн по 10 петель)

Отображенное матрично-якобиево произведение
4,39 мс ± 25,2 мкс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)
 
 def loop_jmp (f, W, M):
    # jvp немедленно возвращает прямое и касательное значения в виде кортежа,
    # поэтому мы вычислим и выберем касательные в понимании списка
    return jnp.vstack ([jvp (f, (W,), (mi,)) [1] для mi в M])

def vmap_jmp (f, W, M):
    _jvp = лямбда s: jvp (f, (W,), (s,)) [1]
    вернуть vmap (_jvp) (M)

num_vecs = 128
S = случайный.нормальный (ключ, (num_vecs,) + W.shape)

loop_vs = loop_jmp (f, W, M = S)
print ('Якобиан-матричное произведение без отображения v')
% timeit -n10 -r3 loop_jmp (f, W, M = S)
vmap_vs = vmap_jmp (f, W, M = S)
print ('\ nVmapped якобиан-матричное произведение')
% timeit -n10 -r3 vmap_jmp (f, W, M = S)

assert jnp.allclose (loop_vs, vmap_vs), 'Продукты Vmap и не-vmapped Jacobian-Matrix должны быть идентичны'
 
 Якобиан-матричное произведение без v-отображения
 
 219 мс ± 418 мкс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)

Отображенное матричное произведение Якоби
2.25 мс ± 22,4 мкс на цикл (среднее ± стандартное отклонение из 3 прогонов, по 10 циклов в каждом)
 

Реализация

jacfwd и jacrev

Теперь, когда мы увидели быстрые произведения на матрицу Якоби и матрицу Якоби, нетрудно догадаться, как записать jacfwd и jacrev . Мы просто используем ту же технику для одновременного продвижения или возврата всего стандартного базиса (изоморфного единичной матрице).

 из jax import jacrev как builtin_jacrev

def our_jacrev (f):
    def jacfun (x):
        у, vjp_fun = vjp (f, x)
        # Используйте vmap для создания матрично-якобиевого произведения.# Здесь матрица является евклидовым базисом, поэтому мы получаем все
        Сразу # записи в якобиане.
        J, = vmap (vjp_fun, in_axes = 0) (jnp.eye (len (y)))
        вернуть J
    вернуть jacfun

assert jnp.allclose (builtin_jacrev (f) (W), our_jacrev (f) (W)), 'Неверные результаты якобиана обратного режима!'
 
 из jax import jacfwd как builtin_jacfwd

def our_jacfwd (f):
    def jacfun (x):
        _jvp = лямбда s: jvp (f, (x,), (s,)) [1]
        Jt = vmap (_jvp, in_axes = 1) (jnp.eye (len (x)))
        вернуть jnp.транспонировать (Jt)
    вернуть jacfun

assert jnp.allclose (builtin_jacfwd (f) (W), our_jacfwd (f) (W)), 'Неверные результаты якобиана прямого режима!'
 

Интересно, что «Автоград» не смог этого сделать. Наша реализация якобиана в обратном режиме в Autograd должна была откатывать по одному вектору за раз с помощью карты внешнего цикла . Пропуск одного вектора через вычисление намного менее эффективен, чем пакетирование всего этого вместе с vmap .

Еще одна вещь, которую Autograd не смог сделать, - это jit .Интересно, что независимо от того, насколько динамизм Python вы используете в своей функции для дифференциации, мы всегда можем использовать jit в линейной части вычислений. Например:

 def f (x):
    пытаться:
        если x <3:
            возврат 2 * x ** 3
        еще:
            поднять ValueError
    кроме ValueError:
        вернуть jnp.pi * x

y, f_vjp = vjp (f, 4.)
печать (jit (f_vjp) (1.))
 
 (DeviceArray (3,1415927, dtype = float32),)
 

Комплексные числа и дифференцирование

JAX отлично подходит для комплексных чисел и дифференцирования.2 \), а именно

\ (\ begin {bmatrix} \ partial_0 u (x, y) & \ partial_1 u (x, y) \\ \ partial_0 v (x, y) & \ partial_1 v (x, y) \ end {bmatrix} \ begin {bmatrix} c \\ d \ end {bmatrix} \).

Чтобы получить JVP для исходной функции \ (f \), примененной к касательному вектору \ (c + di \ in \ mathbb {C} \), мы просто используем то же определение и идентифицируем результат как другое комплексное число,

\ (\ частичное е (х + у я) (с + д я) = \ begin {matrix} \ begin {bmatrix} 1 & i \ end {bmatrix} \\ ~ \ end {matrix} \ begin {bmatrix} \ partial_0 u (x, y) & \ partial_1 u (x, y) \\ \ partial_0 v (x, y) & \ partial_1 v (x, y) \ end {bmatrix} \ begin {bmatrix} c \\ d \ end {bmatrix} \).

Это наше определение JVP функции \ (\ mathbb {C} \ to \ mathbb {C} \)! Обратите внимание, не имеет значения, является ли \ (f \) голоморфным: JVP однозначно.

Вот чек:

Проверка
 def (seed):
  key = random.PRNGKey (начальное число)

  # случайные коэффициенты для u и v
  ключ, подключ = random.split (ключ)
  a, b, c, d = random.uniform (подключ, (4,))

  def fun (z):
    х, у = jnp.real (z), jnp.imag (z)
    вернуть u (x, y) + v (x, y) * 1j

  def u (x, y):
    вернуть a * x + b * y

  def v (x, y):
    вернуть c * x + d * y

  # основная точка
  ключ, подключ = случайный.разделить (ключ)
  x, y = random.uniform (подключ, (2,))
  г = х + у * 1j

  # касательный вектор
  ключ, подключ = random.split (ключ)
  c, d = random.uniform (подключ, (2,))
  z_dot = c + d * 1j

  # проверить jvp
  _, ans = jvp (веселье, (z,), (z_dot,))
  ожидаемый = (grad (u, 0) (x, y) * c +
              град (и, 1) (х, у) * д +
              град (v, 0) (x, y) * c * 1j +
              град (v, 1) (x, y) * d * 1j)
  print (jnp. * \; \ частичное е (х + у я) =
\ begin {matrix} \ begin {bmatrix} c & -d \ end {bmatrix} \\ ~ \ end {matrix}
\ begin {bmatrix} \ partial_0 u (x, y) & \ partial_1 u (x, y) \\ \ partial_0 v (x, y) & \ partial_1 v (x, y) \ end {bmatrix}
\ begin {bmatrix} 1 \\ -i \ end {bmatrix} \).

Что с негативами? Они просто позаботятся о сложном спряжении и о том, что мы работаем с ковекторами.

Вот проверка правил VJP:

Проверка
 def (seed):
  key = random.PRNGKey (начальное число)

  # случайные коэффициенты для u и v
  ключ, подключ = random.split (ключ)
  a, b, c, d = random.uniform (подключ, (4,))

  def fun (z):
    х, у = jnp.real (z), jnp.imag (z)
    вернуть u (x, y) + v (x, y) * 1j

  def u (x, y):
    вернуть a * x + b * y

  def v (x, y):
    вернуть c * x + d * y

  # основная точка
  ключ, подключ = случайный.разделить (ключ)
  x, y = random.uniform (подключ, (2,))
  г = х + у * 1j

  # котангенс вектор
  ключ, подключ = random.split (ключ)
  c, d = random.uniform (подключ, (2,))
  z_bar = jnp.array (c + d * 1j) # для управления dtype

  # проверить vjp
  _, fun_vjp = vjp (веселье, z)
  ans, = fun_vjp (z_bar)
  ожидаемый = (grad (u, 0) (x, y) * c +
              град (v, 0) (x, y) * (-d) +
              град (и, 1) (х, у) * с * (-1j) +
              град (v, 1) (x, y) * (-d) * (-1j))
  assert jnp.allclose (ans, ожидаемый, atol = 1e-5, rtol = 1e-5)
 
 чек (0)
в клетку (1)
в клетку (2)
 

А как насчет удобных оберток, таких как grad , jacfwd и jacrev ?

Напомним, что для функций \ (\ mathbb {R} \ to \ mathbb {R} \) мы определили grad (f) (x) как vjp (f, x) [1] (1.0) , который работает, потому что применение VJP к значению 1.0 показывает градиент (то есть якобиан или производную). Мы можем сделать то же самое для функций \ (\ mathbb {C} \ to \ mathbb {R} \): мы все еще можем использовать 1.0 в качестве котангенса вектора, и мы просто получаем результат комплексного числа, суммирующий полный якобиан :

 def f (z):
  х, у = jnp.real (z), jnp.imag (z)
  возврат x ** 2 + y ** 2

z = 3. + 4j
град (е) (г)
 
 DeviceArray (6.-8.j, dtype = complex64)
 

Для общих функций \ (\ mathbb {C} \ to \ mathbb {C} \) якобиан имеет 4 действительные степени свободы (как в матрицах Якоби 2x2 выше), поэтому мы не можем надеяться представить все из них в комплексном числе.Но мы можем для голоморфных функций! Голоморфная функция - это в точности функция \ (\ mathbb {C} \ to \ mathbb {C} \) со специальным свойством, что ее производная может быть представлена ​​как одно комплексное число. (Уравнения Коши-Римана гарантируют, что указанные выше якобианы 2x2 имеют особую форму матрицы масштабирования и поворота в комплексной плоскости, то есть действие одного комплексного числа при умножении.) И мы можем выявить это одно комплексное число, используя один звонок на vjp с ковектором 1.0 .

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

 def f (z):
  вернуть jnp.sin (z)

z = 3. + 4j
grad (f, голоморфный = True) (z)
 
 DeviceArray (-27.034946-3.8511534j, dtype = complex64)
 

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

 def f (z):
  вернуть jnp.conjugate (z)

z = 3. + 4j
grad (f, holomorphic = True) (z) # f на самом деле не голоморфен!
 
 DeviceArray (1.-0.j, dtype = complex64)
 

Здесь есть несколько полезных апшотов о том, как работает grad :

  1. Мы можем использовать grad для голоморфных \ (\ mathbb {C} \ to \ mathbb {C} \) функций.

  2. Мы можем использовать grad для оптимизации функций \ (f: \ mathbb {C} \ to \ mathbb {R} \), таких как вещественные функции потерь комплексных параметров x , предпринимая шаги в направлении конъюгат grad (f) (x) .

  3. Если у нас есть функция \ (\ mathbb {R} \ to \ mathbb {R} \), которая просто использует некоторые комплексные операции внутри (некоторые из которых должны быть неголоморфными, например, БПФ, используемые в свертках) тогда grad все еще работает, и мы получаем тот же результат, который дала бы реализация, использующая только реальные значения.

В любом случае, JVP и VJP всегда однозначны. И если мы хотим вычислить полную матрицу Якоби неголоморфной функции \ (\ mathbb {C} \ to \ mathbb {C} \), мы можем сделать это с помощью JVP или VJP!

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

 A = jnp.array ([[5., 2. + 3j, 5j],
              [2.-3j, 7., 1. + 7j],
              [-5j, 1.-7j, 12.]])

def f (X):
    L = jnp.linalg.cholesky (X)
    вернуть jnp.sum ((L - jnp.sin (L)) ** 2)

grad (f, голоморфный = True) (A)
 
 DeviceArray ([[- 0.7534186 + 0.j, -3.0509028 -10.940545j,
               5,9896846 + 3,542303j],
             [-3.0509028 + 10.940545j, -8.1 + 0.j,
              -5,1351523 -6,559373j],
             [5.9896846 -3.542303j, -5.1351523 + 6.559373j,
               0,01320427 + 0.j]], dtype = complex64)
 

Мягкое знакомство с резаком.autograd - Руководство по PyTorch 1.9.0 + документация cu102

torch.autograd - это механизм автоматической дифференциации PyTorch, который обеспечивает работу обучение нейронной сети. В этом разделе вы получите концептуальный понимание того, как автоград помогает обучению нейронной сети.

Фон

Нейронные сети (NN) - это набор вложенных функций, которые выполняется на некоторых входных данных. Эти функции определяются параметрами (состоящий из весов и смещений), которые в PyTorch хранятся в тензоры.

Обучение NN происходит в два этапа:

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

Обратное распространение : В обратном распространении NN регулирует свои параметры пропорционально ошибке в его предположении. Это делается путем прохождения назад от вывода, собирая производные ошибки с относительно параметров функций ( градиента, ) и оптимизируя параметры с использованием градиентного спуска.Для более подробного прохождения обратного распространения, посмотрите это видео на 3Синий1Коричневый.

Использование в PyTorch

Давайте посмотрим на один шаг обучения. В этом примере мы загружаем предварительно обученную модель resnet18 из torchvision . Мы создаем тензор случайных данных для представления одного изображения с 3 каналами, высотой и шириной 64, и соответствующая ему метка инициализирована некоторыми случайными значениями.

 импортный фонарик, torchvision
модель = torchvision.models.resnet18 (предварительно обучено = True)
data = torch.rand (1, 3, 64, 64)
label = torch.rand (1, 1000)
 

Затем мы пропускаем входные данные через модель через каждый из ее слоев, чтобы сделать прогноз. Это прямой проход .

 прогноз = модель (данные) # прямой проход
 

Мы используем прогноз модели и соответствующую метку для вычисления ошибки ( потерь ). Следующим шагом будет обратное распространение этой ошибки по сети. Обратное распространение начинается, когда мы звоним по номеру .backward () на тензоре ошибок. Затем Autograd вычисляет и сохраняет градиенты для каждого параметра модели в атрибуте параметра .grad .

 потеря = (прогноз - метки) .sum ()
loss.backward () # обратный проход
 

Затем мы загружаем оптимизатор, в данном случае SGD со скоростью обучения 0,01 и импульсом 0,9. Регистрируем все параметры модели в оптимизаторе.

 optim = torch.optim.SGD (параметры модели (), lr = 1e-2, импульс = 0,9)
 

Наконец, мы звоним по телефону .step () , чтобы начать градиентный спуск. Оптимизатор настраивает каждый параметр по его градиенту, хранящемуся в .grad .

 optim.step () # градиентный спуск
 

На данный момент у вас есть все необходимое для обучения нейронной сети. В следующих разделах подробно рассказывается о работе autograd - не стесняйтесь их пропустить.


Дифференциация в Автограде

Давайте посмотрим, как autograd собирает градиенты. Мы создаем два тензора a и b с requires_grad = True .2 \]

\ [\ frac {\ partial Q} {\ partial b} = -2b \]

Когда мы вызываем .backward () на Q , autograd вычисляет эти градиенты и сохраняет их в атрибуте .grad соответствующих тензоров.

Нам нужно явно передать аргумент gradient в Q.backward () , потому что это вектор. градиент - это тензор той же формы, что и Q , и он представляет градиент Q относительно сам, т.е.

\ [\ frac {dQ} {dQ} = 1 \]

Аналогично, мы также можем агрегировать Q в скаляр и неявно выполнять обратный вызов, например, Q.sum (). Backward () .

 external_grad = torch.tensor ([1., 1.])
Q. назад (gradient = external_grad)
 

Градиенты теперь хранятся в a.grad и b.grad

 # проверяем правильность собранных градиентов
print (9 * a ** 2 == a.grad)
печать (-2 * b == b.grad)
 

Ушел:

 тензор ([True, True])
тензор ([True, True])
 

Дополнительное чтение - Векторное исчисление с использованием автограда

Математически, если у вас есть функция с векторным знаком \ (\ vec {y} = f (\ vec {x}) \), тогда градиент \ (\ vec {y} \) с относительно \ (\ vec {x} \) является матрицей Якоби \ (J \):

\ [J знак равно \ left (\ begin {array} {cc} \ frac {\ partial \ bf {y}} {\ partial x_ {1}} & ... & \ frac {\ partial \ bf {y}} {\ partial x_ {n}} \ end {array} \ right) знак равно \ left (\ begin {array} {ccc} \ frac {\ partial y_ {1}} {\ partial x_ {1}} & \ cdots & \ frac {\ partial y_ {1}} {\ partial x_ {n}} \\ \ vdots & \ ddots & \ vdots \\ \ frac {\ partial y_ {m}} {\ partial x_ {1}} & \ cdots & \ frac {\ partial y_ {m}} {\ partial x_ {n}} \ end {array} \ right) \]

Вообще говоря, torch. {T} \ cdot \ vec {v} = \ left (\ begin {array} {ccc} \ frac {\ partial y_ {1}} {\ partial x_ {1}} & \ cdots & \ frac {\ partial y_ {m}} {\ partial x_ {1}} \\ \ vdots & \ ddots & \ vdots \\ \ frac {\ partial y_ {1}} {\ partial x_ {n}} & \ cdots & \ frac {\ partial y_ {m}} {\ partial x_ {n}} \ end {array} \ right) \ left (\ begin {array} {c} \ frac {\ partial l} {\ partial y_ {1}} \\ \ vdots \\ \ frac {\ partial l} {\ partial y_ {m}} \ end {array} \ right) = \ left (\ begin {array} {c} \ frac {\ partial l} {\ partial x_ {1}} \\ \ vdots \\ \ frac {\ partial l} {\ partial x_ {n}} \ end {array} \ right) \]

Эту характеристику векторно-якобиевого произведения мы используем в приведенном выше примере; external_grad представляет \ (\ vec {v} \).

Вычислительный граф

Концептуально autograd ведет запись данных (тензоров) и всех выполненных операций (вместе с полученными новыми тензорами) в направленном ациклическом граф (DAG), состоящий из Функция объекты. В этом DAG листья являются входными тензорами, корни - выходными. тензоры. Прослеживая этот график от корней до листьев, вы можете автоматически вычислить градиенты, используя цепное правило.

При прямом проходе autograd одновременно выполняет две задачи:

  • запустить запрошенную операцию для вычисления результирующего тензора, а
  • поддерживает функцию градиента операции в DAG.

Обратный проход начинается, когда .backward () вызывается на DAG корень. автоград то:

  • вычисляет градиенты от каждого .grad_fn ,
  • накапливает их в соответствующем атрибуте тензора .grad , а
  • , используя правило цепочки, распространяется на все листовые тензоры.

Ниже представлено визуальное представление группы DAG в нашем примере. На графике стрелки указывают направление переднего прохода.Узлы представляют собой обратные функции каждой операции в прямом проходе. Листовые узлы синего цвета представляют наши листовые тензоры a и b .

Примечание

DAG являются динамическими в PyTorch Важно отметить, что график воссоздается с нуля; после каждого .backward () , autograd начинает заполнять новый граф. Это именно то, что позволяет вам использовать операторы потока управления в вашей модели; вы можете изменять форму, размер и операции на каждой итерации, если нужный.

Исключение из DAG

torch.autograd отслеживает операции на всех тензорах, у которых есть свои Флаг требует_града установлен на Истинный . Для тензоров, которые не требуют градиенты, установка этого атрибута на Ложь исключает его из вычисление градиента DAG.

Выходной тензор операции потребует градиентов, даже если один входной тензор имеет requires_grad = True .

 x = torch.rand (5, 5)
y = факел.ранд (5, 5)
z = torch.rand ((5, 5), requires_grad = True)

а = х + у
print (f "Требуются ли для` a` градиенты?: {a.requires_grad} ")
б = х + г
print (f "Требуются ли для` b` градиенты ?: {b.requires_grad} ")
 

Ушел:

 Требуются ли градиенты для a? : Ложь
Требуются ли градиенты для b ?: Верно
 

В NN параметры, которые не вычисляют градиенты, обычно называются замороженными параметрами . Полезно «заморозить» часть вашей модели, если вы заранее знаете, что градиенты этих параметров вам не понадобятся. (это дает некоторые преимущества в производительности за счет сокращения вычислений автограда).

Другой распространенный вариант использования, в котором важно исключение из группы DAG, - это Тонкая настройка предварительно обученной сети

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

 от torch import nn, optim

model = torchvision.models.resnet18 (предварительно обучено = True)

# Заморозить все параметры в сети
для параметра в модели.параметры ():
    param.requires_grad = Ложь
 

Допустим, мы хотим настроить модель на новом наборе данных с 10 метками. В реснете классификатор - это последний линейный слой model.fc . Мы можем просто заменить его новым линейным слоем (по умолчанию незамороженным). который действует как наш классификатор.

 model.fc = nn.Linear (512, 10)
 

Теперь все параметры в модели, кроме параметров model.fc , заморожены. Единственными параметрами, которые вычисляют градиенты, являются веса и смещение модели .FC .

 # Оптимизировать только классификатор
optimizer = optim.SGD (model.parameters (), lr = 1e-2, импульс = 0,9)
 

Обратите внимание, хотя мы регистрируем все параметры в оптимизаторе, единственные параметры, которые вычисляют градиенты (и, следовательно, обновляются при градиентном спуске) - веса и смещение классификатора.

Те же исключительные функции доступны в качестве диспетчера контекста в torch.no_grad ()


Автоматическая дифференциация | MOOSE

История вопроса

Исторически наиболее частым вопросом в списке рассылки MOOSE был вопрос: «Почему мои решения не сходятся?» Эквивалентный вопрос также размещен на StackExchange по вычислительным наукам под заголовком Почему метод Ньютона не сходится? Главный пункт принятого ответа состоит в том, что якобиан неверен.Кодирование якобианов может быть сложной и утомительной задачей, особенно для физики, требующей сложных моделей материалов. Вместо того, чтобы тратить свое время на моделирование и получение результатов, физики и инженеры могут потратить дни или недели на построение точных якобианов. Часто разработчик просто опускает руки и выбирает приближенный якобианский метод, такой как Preconditioned Jacobian Free Newton Krylov (PJFNK), где якобиан никогда не формируется явно, а вместо этого его действие на векторы аппроксимируется с использованием конечных разностей и приближенная матрица предобусловливания находится вручную закодирован для построения эффективного предобуславливателя.Будучи эффективным во многих случаях, качество безматричного приближения тесно связано с выбором разностного параметра, размер которого должен изменяться в зависимости от зашумленности нелинейной системы уравнений. Если нелинейные функции зашумлены и выбран слишком маленький разностный параметр, усечение приведет к приближению Якоби, которое на самом деле является нелинейным оператором. Если параметр разности слишком велик, то приближенные производные будут неточными, если функция разности нелинейна.Для мультифизических задач, в которых величины решения и остаточных компонентов могут сильно различаться, произвольный выбор разностного параметра может привести к точной аппроксимации действия Якоби для одной физики, но привести к вышеупомянутой ошибке усечения в другой. Наличие ошибки усечения и, следовательно, нелинейного оператора очевидно в линейном решении, полученном из уравнений пористого потока в сочетании с переносом тепла:

 
 0 Норма безусловного остатка KSP 5.645573426379e + 16 истинная норма остатка 5.645573426379e + 16 || r (i) || / || b || 1.000000000000e + 00
 1 KSP безусловная норма остатка 2.965618482980e + 12 истинная норма остатка 2.965618483296e + 12 || r (i) || / || b || 5.252997807874e-05
 2 KSP безусловная норма остатка 2.724648158452e + 12 истинная норма остатка 2.8312561e + 14 || r (i) || / || b || 5.119360061914e-03
 3 KSP безусловная норма остатка 8,335608026448e + 11 истинная норма остатка 5,178511494633e + 15 || r (i) || / || b || 9.172693548605e-02
 4 KSP безусловная норма остатка 8,335450

7e + 11 истинная норма остатка 8.675

9302e + 17 || r (i) || / || b || 1.536762998912e + 01 5 KSP безусловная норма остатка 6.022626374152e + 11 истинная норма остатка 1.028328406646e + 22 || r (i) || / || b || 1.821477339823e + 05 6 KSP безусловная норма остатка 6.020981842850e + 11 истинная норма остатка 1.028926824260e + 22 || r (i) || / || b || 1.822537316498e + 05 7 Норма безусловного остатка KSP 2.079735227207e + 11 норма истинного остатка 6.050540886054e + 21 || r (i) || / || b || 1.071731855932e + 05

В то время как безусловная норма невязки, полученная с помощью итераций обобщенного метода минимальной невязки (GMRES), уменьшается на пять порядков во время решения, истинная норма невязки, вычисленная с помощью, фактически увеличивается на пять порядков.В MOOSE по умолчанию выбирается правильно подготовленный GMRES, где безусловный остаток математически равен фактическому остатку, если матрица предварительного кондиционирования хорошо обусловлена. Возникшие здесь несоответствия частично объясняются неточностью матрицы предварительной обработки. Конечным результатом таких плохих линейных решений является расходящийся метод Ньютона, поскольку вычисленное обновление Ньютона «неверно»:

 
0 Нелинейный | R | = 1,138921e + 06
1 Нелинейный | R | = 1,392349e + 11
2 Нелинейный | R | = 2.881060e + 10
3 Нелинейный | R | = 8.473409e + 09
4 Нелинейный | R | = 2,017729e + 09
5 Нелинейный | R | = 7.634503e + 08
6 Нелинейный | R | = 5,645573e + 16
Нелинейное решение не сходилось из-за DIVERGED_FNORM_NAN итераций 6
  

Если вместо этого мы формируем явный якобиан и избегаем конечных разностей, метод Ньютона сходится, хотя и субквадратично, поскольку кодированный вручную якобиан неточен: 0 Нелинейный | R | = 1,138921e + 06 1 Нелинейный | R | = 2,171654e + 05 2 Нелинейный | R | = 4.550729e + 04 3 Нелинейный | R | = 1.026123e + 04 4 Нелинейный | R | = 1,267614e + 03 5 Нелинейный | R | = 6.531982e + 01 6 Нелинейный | R | = 4.427446e-01 7 Нелинейный | R | = 8.025639e-05 8 Нелинейный | R | = 3,195008e-06 9 Нелинейный | R | = 1.669770e-07 10 Нелинейный | R | = 1.201906e-08 Нелинейное решение сходилось из-за итераций CONVERGED_FNORM_ABS 10

Учитывая мультифизическую цель MOOSE и явные ловушки, связанные с разностными приближениями, есть явная мотивация для формирования точных явных представлений матрицы.Обратите внимание: даже если идеальное действие Якоби может быть достигнуто с помощью конечно-разностной схемы, для построения надежного и эффективного решателя требуется подходящая матрица предварительного кондиционирования.

Некоторые пользователи предпочитают использовать пакеты символьного дифференцирования, такие как SymPy или Mathematica; однако для функций любой сложности результирующие выражения градиента могут занимать до нескольких страниц и их довольно сложно перевести из записной книжки в код. Альтернативой числовому и символьному дифференцированию является автоматическое дифференцирование (AD), которое применяет правило цепочки к элементарным операциям на каждом этапе компьютерной программы и которое применяет не более чем небольшой постоянный коэффициент (по оценкам, имеющий верхнюю границу 5) дополнительных арифметические операции.В сравнении с неисчислимым количеством часов, затраченных разработчиками на попытки создать точные написанные вручную якобианы, и часами аналитиков, потраченных на ожидание проблем с плохо написанными вручную или приближенными якобианами, чтобы сойтись, небольшая дополнительная стоимость процессора, наложенная AD, казалась вполне оправданной. С точным якобианом, сформированным с использованием AD, общее моделирование может быть намного быстрее, чем при использовании несовершенной матрицы, кодированной вручную. Приняв решение продолжить AD, нужно было выбирать между прямым и обратным режимами.Прямой режим AD лучше всего подходит для задач с гораздо большим количеством выходов, чем входов; Обратный режим лучше всего подходит для гораздо большего количества входов, чем выходов. Последний случай более распространен в приложениях глубокого обучения и реализован в популярных библиотеках машинного обучения, таких как PyTorch. При решении нелинейных систем уравнений количество входов и выходов эквивалентно, поэтому выбор не однозначен. Однако, учитывая архитектуру MOOSE, в которой невязки строятся из решений конечных элементов, которые сами естественным образом строятся из нелинейных степеней свободы, прямое распространение было логичным выбором.В прямом режиме AD используется концепция DualNumbers , которая может быть реализована либо путем преобразования исходного кода, либо путем перегрузки оператора. Последнее легче реализовать в языках программирования, которые его поддерживают, таких как C ++, язык, на котором написан MOOSE. Для удобства библиотека C ++, содержащая только заголовок, MetaPhysicL поставляется в готовом виде с классом шаблона DualNumber и перегрузкой оператора AD. реализация, которая вписывается в архитектуру MOOSE с минимальным нарушением кода.Возможности AD MetaPhysicL были объединены с кодовой базой MOOSE осенью 2018 года.

Классы автоматического дифференцирования в MetaPhysicL были первоначально разработаны и протестированы в библиотеке Industrial Analytical Solution Abstraction ( MASA ), используемой для создания готового решения. тесты для все более сложных физических симуляций, когда было обнаружено, что несколько пакетов символьного дифференцирования терпят программные сбои на достаточно больших проблемах.Символическая дифференциация полей искусственных решений с помощью, например, \ 3-мерной физики Навье-Стокса вызвала комбинаторный взрыв, который привел к соответствующим функциям принуждения, длина которых составляла сотни килобайт, или требовала много человеко-часов ручного упрощения, или вообще не выполнялась на некоторой компьютерной алгебре. Программное обеспечение. Автоматическое дифференцирование позволило генерировать готовые решения форсирующих функций с использованием кода, который был едва ли более сложным, чем сами уравнения физики.Классы, использованные для этой работы, в конечном итоге были опубликованы в виде независимой библиотеки MetaPhysicL для более широкого использования и дальнейшего развития.

DualNumber - это центральный класс возможностей автоматического распознавания. Он хранит значений, и производных, членов, которые соответствуют и соответственно. значение и производные Типы определяются параметрами шаблона T и D , где T - это некоторый тип с плавающей запятой, а D эквивалентен T для функций с одним аргументом или равен некоторым тип контейнера для универсального вектора аргументов.MetaPhysicL перегружает двоичные арифметические операторы ( +, -, *, / ), унарные функции ( std :: sin, std :: cos, std :: exp и т. Д.) И двоичные функции ( std :: pow, std :: max, std :: min и т. д.), гарантируя, что любое вычисление, включающее DualNumber , распространяет как значение функции, так и его производные.

MOOSE использует один из двух шаблонов контейнерных классов MetaPhysicL в зависимости от конфигурации пользователя. Конфигурация MOOSE по умолчанию использует шаблон класса NumberArray , который принимает аргументы шаблона std :: size_t N и typename T , где N обозначает длину базового C-массива, который содержит данные NumberArray и T - это тип с плавающей запятой, содержащийся в C-массиве.Что касается DualNumber , MetaPhysicL предоставляет перегрузки арифметических, унарных и двоичных функций для управления типами контейнеров. NumberArray - идеальный вариант контейнера для производных, когда существует плотная связь между физическими переменными; это связано с тем, что перегрузки операторов и функций для NumberArray работают со всем базовым C-массивом. Второй класс контейнера MetaPhysicL, используемый MOOSE, - это SemiDynamicSparseNumberArray , который является более идеальным выбором для задач, в которых связь переменных является разреженной, или когда пользователь желает решить множество проблем с помощью единой конфигурации библиотеки.В отличие от NumberArray , который содержит только один C-массив данных плавающего типа, SemiDynamicSparseNumberArray дополнительно содержит массив (как std :: array ) целых чисел, соответствующих индексам степеней свободы. Существование этого дополнительного элемента данных позволяет выполнять разреженные операции, которые могут включать только подмножество элементов в базовых данных с плавающей запятой. В качестве явного примера того, когда эти разреженные операции полезны, рассмотрим пользователя, который может настроить MOOSE с базовым производным контейнером для хранения размером 81 для моделирования механики твердого тела на трехмерных гексагональных конечных элементах второго порядка (3 переменных смещения * 27 степеней свободы на переменная на конечный элемент = 81 локальная глубина резкости).При выполнении трехмерных наблюдений второго порядка нерезкий контейнер NumberArray будет эффективен на 100%. Однако, если пользователь желает запустить двухмерный случай второго порядка с той же конфигурацией MOOSE, он будет выполнять в раз больше работы, чем необходимо, при использовании NumberArray . Поскольку SemiDynamicSparseNumberArray отслеживает шаблон разреженности, он будет инициализировать и работать только с необходимыми элементами массива с плавающей запятой, например разреженный размер '' (сохраненный как член данных _dynamic_N ) его контейнеров данных никогда не превысит то, что требуется для проблемы времени выполнения, например.г. 18 для двумерного примера механики твердого тела второго порядка. Конечно, отслеживание шаблона разреженности имеет ненулевую стоимость, поэтому, если пользователь знает, что он всегда будет сталкиваться с определенными проблемами, их лучше всего решить, настроив нерезкий контейнер NumberArray .

AD в MOOSE

Как упоминалось выше, MetaPhysicL - это пакет AD прямого режима. Для структуры конечных элементов, такой как MOOSE, заполнение производной начинается при построении локальных решений конечных элементов.Приближение решения методом конечных элементов задается выражением, где - степени свободы, а - функции формы, связанные с степенями свободы. Для базиса Лагранжа функции формы и степени свободы привязаны к узлам сетки. Чтобы проиллюстрировать запуск процесса AD, мы рассмотрим построение локального решения методом конечных элементов на элементе QUAD4 , то есть четырехмерном материале с числом узлов, равным числу вершин. Этот тип элемента в сочетании с базисом Лагранжа имеет четыре степени свободы, которые вносят вклад в локальное решение, по одной для каждого узла элемента.В MOOSE мы назначаем эти локальные значения решения степени свободы (локальные) члену данных класса переменных с именем _ad_dof_values ​​, где префикс ad обозначает автоматическое дифференцирование. Затем мы заполняем производное значение (понимая, что когда) в соответствующий локальный индекс степеней свободы, определенный с помощью несколько произвольной схемы нумерации. Мы выбираем схему основной нумерации переменных так, чтобы локальные степени свободы находились в непрерывном блоке для каждой переменной, e.г. если у нас есть две переменные в системе, и, тогда схема нумерации для элемента QUAD4 с базисом Лагранжа будет выглядеть с индексами, соответствующими номеру локального узла. Мы можем исследовать зависимость локального решения методом конечных элементов от каждой степени свободы для произвольной точки в области; мы знаем аналитически ожидаемые производные:. Для выбранной точки интегрирования по Гауссу нам известны соответствующие значения Лагранжа:, и мы можем проверить и проверить, совпадает ли наше автоматически дифференцированное решение _ad_u :

 
(lldb) p _ad_u [0]
(MetaPhysicL :: DualNumber >, false>) $ 10 = {
  _val = 0
  _deriv = {
    MetaPhysicL :: DynamicSparseNumberBase >, MetaPhysicL :: DynamicStdArrayWrapper <беззнаковое целое, MetaPhysicL :: NWrapperPray <50> : NWrapper <50>> = {
      _data = {
        _data = {
          _M_elems = {
            [0] = 0.62200846792814624
            [1] = 0,16666666666666669
            [2] = 0,044658198738520456
            [3] = 0,16666666666666669
            [4] = 0
            [5] = 4,82252338622924E-317
            [6] = 4,8224680508769058E-317
            [7] = 3,9525251667299724E-323
  

Обратите внимание, что некоторые из неиспользуемых значений в индексах 4–7, похоже, содержат мусор. Это действительно желательно; он указывает, что для контейнера SemiDynamicSparseNumberArray ненужные компоненты производного вектора остаются неинициализированными.

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

 
(lldb) p strong_residual
(MetaPhysicL :: DualNumber >, false>) $ 1 = {
  _val = 0
  _deriv = {
    MetaPhysicL :: DynamicSparseNumberBase >, MetaPhysicL :: DynamicStdArrayWrapper <беззнаковое целое, MetaPhysicL :: NWrapperPray <50> : NWrapper <50>> = {
      _data = {
        _data = {
          _M_elems = {
            [0] = 0.62200846792814624
            [1] = 0,16666666666666669
            [2] = 0,044658198738520456
            [3] = 0,16666666666666669
            [4] = -0,62200846792814624
            [5] = -0,16666666666666669
            [6] = -0,044658198738520456
            [7] = -0,16666666666666669
  

мы видим именно то, что мы ожидали: значения 0–3, соответствующие индексам, эквивалентны показанным в предыдущем выводе lldb, тогда как значения в 4-7, соответствующие индексам, равны отрицательным значениям показанного в предыдущем выводе lldb.В общем, качество результатов автоматического дифференцирования проверяется с помощью модульного тестирования в MetaPhysicL и с помощью PetscJacobianTester в MOOSE, который сравнивает якобиан, полученный с помощью автоматического дифференцирования, с якобианом, полученным с использованием конечных разностей остатков. Последний тест основан на использовании хорошо масштабированных задач; для плохо масштабируемых задач ошибки с плавающей запятой могут привести к потере точности конечно-разностного якобиана.

Использование AD в MOOSE

Использование возможностей автоматического дифференцирования в MOOSE так же просто, как наследование от наших базовых классов AD, например.г. ADKernel, ADIntegratedBC, ADDGKernel, ADNodalBC и т. Д. Единственный метод, который разработчик приложения должен переопределить, - это computeQpResidual или, если он получен из ADKernelGrad или ADKernelValue , затем переопределить precomputeQpResidual . Для объединения переменных AD разработчик приложения должен использовать такие методы, как adCoupledValue, adCoupledGradient, adCoupledSecond и т. д. унаследован через интерфейс Coupleable . Свойства материала с информацией об автоматическом различении могут быть созданы в классах Material с помощью API-интерфейса declareADProperty .Свойства материала AD можно получить в вычислительных объектах, таких как ADKernels , с помощью API getADMaterialProperty . Для получения подробных примеров использования AD читателю предлагается изучить тензорную механику, модули навигации и установки уровней, все из которых в значительной степени используют возможности AD MOOSE.

Автоматическая дифференциация

Переключение режимов AD

Turing поддерживает четыре пакета автоматической дифференциации (AD) в бэкенде во время выборки.Бэкэнд AD по умолчанию - ForwardDiff для AD прямого режима. Также поддерживаются три серверных модуля AD обратного режима, а именно Tracker, Zygote и ReverseDiff. Zygote и ReverseDiff поддерживаются дополнительно, если явно загружены пользователем с с использованием Zygote или с использованием ReverseDiff рядом с с использованием Turing .

Для переключения между различными серверными модулями AD можно вызвать функцию Turing.setadbackend (backend_sym) , где backend_sym может быть : forwarddiff ( ForwardDiff ), : трекер ( Tracker ) zygote ( Zygote ) или : reversediff ( ReverseDiff.jl ). При использовании ReverseDiff , чтобы скомпилировать ленту только один раз и кэшировать ее для дальнейшего использования, пользователю необходимо сначала загрузить Memoization.jl с , используя Memoization , затем вызвать Turing.setrdcache (true) . Однако обратите внимание, что использование кэширования в определенных типах моделей может привести к неверным результатам и / или ошибкам. Модели, для которых скомпилированная лента может быть безопасно кэширована, - это модели с циклами фиксированного размера и без выполняемых операторов if. Операторы if во время компиляции в порядке.Чтобы очистить кеш, вы можете вызвать Turing.emptyrdcache () .

Композиционная выборка с различными режимами AD

Turing поддерживает смешанные методы автоматического дифференцирования для различных пространств переменных. В приведенном ниже фрагменте показано использование ForwardDiff для выборки среднего параметра ( м ) и использование основанного на трекере автодиффа TrackerAD для параметра дисперсии ( s ):

  с использованием Тьюринга

# Определите простую нормальную модель с неизвестным средним значением и дисперсией[email protected] функция gdemo (x, y)
    s² ~ InverseGamma (2, 3)
    м ~ Нормальный (0, sqrt (s²))
    x ~ Нормальный (м, кв (с²))
    y ~ Нормальный (м, кв (с²))
конец

# Пример с использованием Гиббса и различных бэкендов autodiff.
c = образец (
gdemo (1.5, 2),
  Гиббс (
    HMC {Turing.ForwardDiffAD {1}} (0,1, 5,: m),
        HMC {Turing.TrackerAD} (0,1, 5,: s)
    ),
    1000,
)
  

Как правило, TrackerAD работает быстрее при выборке из переменных высокой размерности (больше 20), а ForwardDiffAD более эффективен для переменных меньшей размерности.Эта функция позволяет тем, кто чувствителен к производительности, настроить автоматическую дифференциацию для своих конкретных моделей.

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

Новый фреймворк с открытым исходным кодом для автоматического дифференцирования с помощью графиков

Содержание исследования:

GTN - это фреймворк с открытым исходным кодом для автоматического дифференцирования с мощным, выразительным типом графа, называемым взвешенными преобразователями конечного состояния (WFST).Подобно тому, как PyTorch предоставляет основу для автоматического дифференцирования с помощью тензоров, GTN предоставляет такую ​​основу для WFST. Исследователи и инженеры искусственного интеллекта могут использовать GTN для более эффективного обучения графических моделей машинного обучения.

Структура данных WFST обычно используется для объединения различных источников информации в таких приложениях, как распознавание речи, обработка естественного языка и распознавание рукописного ввода. Стандартный распознаватель речи может состоять из акустической модели, которая предсказывает буквы, присутствующие в фрагменте речи, и языковой модели, которая предсказывает вероятность того, что данное слово следует за другим.Эти модели могут быть представлены как WFST и обычно обучаются отдельно и объединяются для получения наиболее вероятной транскрипции. Наша новая библиотека GTN позволяет обучать модели разных типов вместе, что обеспечивает лучшие результаты.

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

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

На этой схеме показан простой WFST, встроенный в GTN, который преобразует разложения слова «the» в само слово.

Как это работает:

С помощью GTN (сокращенно от сетей преобразователей графов) исследователи могут легко создавать WFST, визуализировать их и выполнять с ними операции.Градиенты могут быть вычислены относительно любого из графов, участвующих в вычислении, с помощью простого вызова gtn.backward. Вот пример:

 
import gtn
g1 = gtn.Graph ()
g2 = gtn.Graph ()
# ... добавить несколько узлов и дуг к графу ...
# Вычислить функцию графиков:
пересечение = gtn.intersect (g1, g2)
score = gtn.forward_score (пересечение)
# Вычислить градиенты:
gtn.backward (score)

Стиль программирования GTN кажется таким же знакомым для использования в таких популярных фреймворках, как PyTorch.Императивный стиль, API автограда и реализация автограда основаны на схожих принципах проектирования. Основное отличие состоит в том, что мы заменили тензоры на WFST и соответствующие им операции. Как и любой фреймворк, GTN прост в использовании без ущерба для производительности.

В нашей исследовательской статье мы показываем примеры реализации алгоритмов с помощью GTN. В одном примере GTN используется для дополнения любой функции потерь на уровне последовательности с возможностью маргинализации при разложении фраз на части слов.Модель может свободно выбирать, как разложить такое слово, как «the», на части. Например, модель может выбрать использование «th» и «e» или «t», «h» и «e». Части слова часто используются в машинном переводе и распознавании речи, но декомпозиции выбираются из моделей, не зависящих от задачи. Наш новый подход позволяет модели изучить оптимальное разложение слова или фразы для данной задачи.

Почему это важно:

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *