Џедај техника за намалување на конволуциони мрежи - кастрење

Џедај техника за намалување на конволуциони мрежи - кастрење

Пред вас повторно е задачата за откривање објекти. Приоритет е брзината на работа со прифатлива точност. Ја земате архитектурата YOLOv3 и дополнително ја обучувате. Точноста (mAp75) е поголема од 0.95. Но, стапката на трчање е сè уште ниска. Глупости.

Денес ќе ја заобиколиме квантизацијата. И под сечењето ќе погледнеме Модел кастрење — отсекување на непотребни делови од мрежата за да се забрза заклучокот без губење на точноста. Јасно е каде, колку и како да се намали. Ајде да дознаеме како да го направите ова рачно и каде можете да го автоматизирате. На крајот има складиште на кераси.

Вовед

На моето претходно место на работа, Макроскоп во Перм, стекнав една навика - секогаш да го надгледувам времето на извршување на алгоритмите. И секогаш проверувајте го времето на работа на мрежата преку филтер за адекватност. Обично најсовремените во производството не го поминуваат овој филтер, што ме доведе до Кастрење.

Кастрењето е стара тема за која се дискутираше Предавања на Стенфорд во 2017 година. Главната идеја е да се намали големината на обучената мрежа без губење на точноста со отстранување на различни јазли. Звучи кул, но ретко слушам за неговата употреба. Веројатно, нема доволно имплементации, нема статии на руски јазик или едноставно сите го сметаат за кастрење на знаење и молчат.
Но, ајде да го расклопиме

Увид во биологијата

Ми се допаѓа кога Deep Learning ги разгледува идеите што доаѓаат од биологијата. Ним, како и еволуцијата, може да им се верува (дали знаевте дека ReLU е многу сличен на функција на активирање на невронот во мозокот?)

Процесот на кастрење модел е исто така близок до биологијата. Одговорот на мрежата овде може да се спореди со пластичноста на мозокот. Во книгата има неколку интересни примери. Норман Доиџ:

  1. Мозокот на жена која е родена само со една половина се репрограмирал да ги извршува функциите на половината што недостасува.
  2. Типот го отфрли делот од мозокот одговорен за видот. Со текот на времето, други делови од мозокот ги презедоа овие функции. (не се обидуваме да повториме)

Слично на тоа, можете да отсечете некои од слабите конволуции од вашиот модел. Како последно средство, преостанатите снопови ќе помогнат да се заменат исечените.

Дали го сакате учењето за пренос или учите од нула?

Опција број еден. Вие користите Transfer Learning на Yolov3. Retina, Mask-RCNN или U-Net. Но, најчесто не треба да препознаваме 80 класи на објекти како во COCO. Во мојата пракса, сè е ограничено на оценки 1-2. Може да се претпостави дека архитектурата за 80 класи е вишок овде. Ова сугерира дека архитектурата треба да се направи помала. Згора на тоа, би сакал да го направам ова без да ги изгубам постоечките претходно обучени тегови.

Опција број два. Можеби имате многу податоци и компјутерски ресурси или едноставно ви треба супер-приспособена архитектура. Не е важно. Но, вие ја учите мрежата од нула. Вообичаената процедура е да се погледне структурата на податоците, да се избере архитектура која е прекумерна моќност и да се туркаат напуштањата од преквалификација. Видов 0.6 напуштања, Карл.

Во двата случаи, мрежата може да се намали. Мотивирани. Сега да одиме да дознаеме каков вид на обрежување е

Општ алгоритам

Решивме дека можеме да ги отстраниме сноповите. Изгледа прилично едноставно:

Џедај техника за намалување на конволуциони мрежи - кастрење

Отстранувањето на каква било конволуција е стресно за мрежата, што обично доведува до одредено зголемување на грешката. Од една страна, ова зголемување на грешката е показател за тоа колку правилно ги отстрануваме конволуциите (на пример, големото зголемување покажува дека правиме нешто погрешно). Но, малото зголемување е сосема прифатливо и често се елиминира со последователен лесен дополнителен тренинг со мал LR. Додадете дополнителен чекор за обука:

Џедај техника за намалување на конволуциони мрежи - кастрење

Сега треба да откриеме кога сакаме да го запреме учењето<->Крастење циклус. Тука може да има егзотични опции кога треба да ја намалиме мрежата на одредена големина и брзина (на пример, за мобилни уреди). Сепак, најчеста опција е да се продолжи циклусот додека грешката не стане повисока од прифатлива. Додадете услов:

Џедај техника за намалување на конволуциони мрежи - кастрење

Значи, алгоритмот станува јасен. Останува да откриеме како да ги одредиме избришаните конволуции.

Пребарајте избришани пакети

Треба да отстраниме некои конволуции. Да брзаш напред и да „пукаш“ некого е лоша идеја, иако ќе успее. Но, бидејќи имате глава, можете да размислите и да се обидете да изберете „слаби“ конволуции за отстранување. Постојат неколку опции:

  1. Најмала L1-мерка или кастрење со мала_магнитуда. Идејата дека конволуциите со мали тежини имаат мал придонес во конечната одлука
  2. Најмала L1-мерка земајќи ја предвид просечната и стандардната девијација. Дополнуваме со проценка за природата на дистрибуцијата.
  3. Маскирање на конволуциите и исклучување на оние кои најмалку влијаат на конечната точност. Попрецизно определување на незначителни конволуции, но многу одземаат многу време и одземаат ресурси.
  4. Други

Секоја од опциите има право на живот и свои карактеристики за имплементација. Овде ја разгледуваме опцијата со најмала мерка L1

Рачен процес за YOLOv3

Оригиналната архитектура содржи преостанати блокови. Ама колку и да се кул за длабоки мрежи, донекаде ќе не попречат. Тешкотијата е што не можете да ги избришете усогласувањата со различни индекси во овие слоеви:

Џедај техника за намалување на конволуциони мрежи - кастрење

Затоа, да избереме слоеви од кои можеме слободно да ги бришеме помирувањата:

Џедај техника за намалување на конволуциони мрежи - кастрење

Сега да изградиме работен циклус:

  1. Прикачување активации
  2. Откријте колку да исечете
  3. Отсечи го
  4. Учење 10 епохи со LR=1e-4
  5. Тестирање

Растоварувањето на конволуциите е корисно за да се процени колку дел можеме да отстраниме на одреден чекор. Примери за растоварување:

Џедај техника за намалување на конволуциони мрежи - кастрење

Гледаме дека скоро секаде 5% од конволуциите имаат многу ниска L1-норма и можеме да ги отстраниме. На секој чекор, ова растоварување се повторуваше и се проценуваше кои слоеви и колку може да се исечат.

Целиот процес беше завршен во 4 чекори (броеви овде и насекаде за RTX 2060 Super):

Чекор mAp75 Број на параметри, милион Големина на мрежата, mb Од почетната, % Време на работа, ms Состојба на обрежување
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% од сите
2 0.9625 50 197 83 168 5% од сите
3 0.9633 39 155 64 155 15% за слоеви со над 400 конволуции
4 0.9555 31 124 51 146 10% за слоеви со над 100 конволуции

Еден позитивен ефект беше додаден на чекор 2 - серијата големина 4 се вклопува во меморијата, што во голема мера го забрза процесот на дополнителна обука.
На чекор 4, процесот беше запрен бидејќи дури и долгорочната дополнителна обука не го подигна mAp75 на старите вредности.
Како резултат на тоа, успеавме да го забрзаме заклучувањето со 15%, намалете ја големината за 35% и не губи точно.

Автоматизација за поедноставни архитектури

За поедноставни мрежни архитектури (без условно додавање, спојување и преостанати блокови), сосема е можно да се фокусираме на обработка на сите конволуциони слоеви и да се автоматизира процесот на отсекување на конволуции.

Ја имплементирав оваа опција тука.
Едноставно е: потребна ви е само функција за загуба, оптимизатор и генератори на серија:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

Доколку е потребно, можете да ги промените параметрите за конфигурација:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Дополнително, имплементирано е ограничување врз основа на стандардното отстапување. Целта е да се ограничи делот што е отстранет, исклучувајќи ги конволуциите со веќе „доволни“ мерки L1:

Џедај техника за намалување на конволуциони мрежи - кастрење

Така, ви дозволуваме да отстраните само слаби конволуции од дистрибуции слични на десната и да не влијаете на отстранувањето од дистрибуции слични на левата:

Џедај техника за намалување на конволуциони мрежи - кастрење

Кога распределбата се приближува до нормалата, коефициентот pruning_standart_deviation_part може да се избере од:

Џедај техника за намалување на конволуциони мрежи - кастрење
Препорачувам претпоставка од 2 сигма. Или можете да ја игнорирате оваа функција, оставајќи ја вредноста < 1.0.

Излезот е графикон на големината на мрежата, загубата и мрежното време за целиот тест, нормализиран на 1.0. На пример, овде големината на мрежата е намалена за речиси 2 пати без губење на квалитетот (мала конволуциона мрежа со тежини од 100k):

Џедај техника за намалување на конволуциони мрежи - кастрење

Брзината на движење подлежи на нормални флуктуации и останува практично непроменета. Има објаснување за ова:

  1. Бројот на конволуции се менува од погодни (32, 64, 128) до не најзгодни за видео картички - 27, 51, итн. Може да грешам овде, но најверојатно има ефект.
  2. Архитектурата не е широка, но конзистентна. Со намалување на ширината, не влијаеме на длабочината. Така, го намалуваме товарот, но не ја менуваме брзината.

Затоа, подобрувањето беше изразено во намалување на оптоварувањето на CUDA за време на трчањето за 20-30%, но не и во намалување на времето на работа

Резултатите од

Ајде да размислиме. Разгледавме 2 опции за кастрење - за YOLOv3 (кога треба да работите со раце) и за мрежи со поедноставни архитектури. Може да се види дека и во двата случаи е можно да се постигне намалување и забрзување на големината на мрежата без губење на точноста. Резултати:

  • Намалување на големината
  • Забрзување трчање
  • Намалување на оптоварувањето на CUDA
  • Како резултат на тоа, еколошка пријатност (Ја оптимизираме идната употреба на компјутерските ресурси. Некаде некој е среќен Грета Тунберг)

Додаток

  • По чекорот на кастрење, можете да додадете квантизација (на пример, со TensorRT)
  • Tensorflow обезбедува можности за кастрење со мала_магнитуда. Работи.
  • складиште Сакам да се развивам и со задоволство ќе помогнам

Извор: www.habr.com

Додадете коментар