Конволюционды желілерді азайтуға арналған Джеди техникасы - кесу
Сіздің алдыңызда тағы да объектілерді анықтау міндеті тұр. Басымдылық - қолайлы дәлдікпен жұмыс істеу жылдамдығы. Сіз YOLOv3 архитектурасын алып, оны әрі қарай үйретесіз. Дәлдік (mAp75) 0.95-тен жоғары. Бірақ жүгіру жылдамдығы әлі де төмен. Қырсық.
Бүгін біз кванттауды айналып өтеміз. Ал кесіндінің астына қараймыз Модельді кесу — дәлдікті жоғалтпай қорытындыны жылдамдату үшін желінің артық бөліктерін кесу. Қайда, қанша және қалай кесу керек екені анық. Мұны қолмен қалай жасауға болатынын және оны қай жерде автоматтандыруға болатынын анықтайық. Соңында керасқа арналған репозиторий бар.
Кіріспе
Бұрынғы жұмыс орнымда, Пермьдегі Макроскопта мен бір әдетке ие болдым - әрқашан алгоритмдердің орындалу уақытын бақылау. Желінің жұмыс уақытын әрқашан сәйкестік сүзгісі арқылы тексеріңіз. Әдетте өндірістегі соңғы үлгілер бұл сүзгіден өтпейді, бұл мені кесуге әкелді.
Кесу - бұл талқыланған ескі тақырып Стэнфорд дәрістері 2017 жылы. Негізгі идея - әртүрлі түйіндерді жою арқылы дәлдікті жоғалтпай оқытылатын желінің көлемін азайту. Бұл керемет естіледі, бірақ мен оны қолдану туралы сирек естимін. Бәлкім, іске асыру жеткіліксіз, орыстілді мақалалар жоқ немесе бәрі оны ноу-хауды кесу деп санайды және үнсіз қалады.
Бірақ оны бөліп алайық
Биологияға шолу
Deep Learning биологиядан келетін идеяларды қарастырғанын жақсы көремін. Оларға эволюция сияқты сенуге болады (сіз ReLU-ға өте ұқсас екенін білесіз бе мидағы нейрондарды белсендіру функциясы?)
Модельді кесу процесі де биологияға жақын. Мұндағы желінің жауабын мидың пластикасымен салыстыруға болады. Кітапта бірнеше қызықты мысалдар бар. Норман Доидж:
Бір жартысы ғана туылған әйелдің миы жетіспейтін жартысының функцияларын орындау үшін өзін қайта бағдарламалаған.
Жігіт миының көру үшін жауапты бөлігін атып тастады. Уақыт өте келе бұл функцияларды мидың басқа бөліктері алды. (қайталауға тырыспаймыз)
Сол сияқты, сіз өзіңіздің үлгіңізден кейбір әлсіз конвульсияларды кесіп тастай аласыз. Соңғы шара ретінде қалған байламдар кесілгендерді ауыстыруға көмектеседі.
Сізге Transfer Learning ұнай ма, әлде нөлден бастап үйренесіз бе?
Бірінші нұсқа. Сіз Yolov3 жүйесінде Transfer Learning қолданбасын пайдаланасыз. Retina, Mask-RCNN немесе U-Net. Бірақ көп жағдайда COCO сияқты 80 нысан класын танудың қажеті жоқ. Менің тәжірибемде барлығы 1-2 сыныптармен шектеледі. Мұнда 80 сыныпқа арналған архитектура артық деп болжауға болады. Бұл архитектураны кішірейту керек дегенді білдіреді. Оның үстіне, мен мұны бұрыннан дайындалған салмақты жоғалтпай орындағым келеді.
Екінші нұсқа. Мүмкін сізде көптеген деректер мен есептеу ресурстары болуы мүмкін немесе жай ғана ерекше архитектура қажет. Маңызды емес. Бірақ сіз желіні нөлден бастап үйренесіз. Әдеттегі процедура деректер құрылымын қарау, қуаты АСҚАН архитектураны таңдау және қайта оқудан шығып қалғандарды итермелеу болып табылады. Мен 0.6 оқушыны көрдім, Карл.
Екі жағдайда да желіні азайтуға болады. Мотивацияланған. Енді сүндеттеу кесу қандай екенін анықтап көрейік
Жалпы алгоритм
Біз байламдарды алып тастай аламыз деп шештік. Бұл өте қарапайым көрінеді:
Кез келген конвульсияны жою желі үшін стресс болып табылады, бұл әдетте қателіктің біршама артуына әкеледі. Бір жағынан, қателіктің бұл ұлғаюы конвульсияларды қаншалықты дұрыс алып тастаудың көрсеткіші болып табылады (мысалы, үлкен өсу біздің дұрыс емес нәрсені істеп жатқанымызды көрсетеді). Бірақ шамалы өсу өте қолайлы және көбінесе шағын LR көмегімен кейінгі жеңіл қосымша жаттығулар арқылы жойылады. Қосымша жаттығу қадамын қосыңыз:
Енді біз Learning<->Pruning циклін қашан тоқтатқымыз келетінін анықтауымыз керек. Желіні белгілі бір өлшемге және жылдамдыққа (мысалы, мобильді құрылғылар үшін) азайту қажет болғанда, мұнда экзотикалық опциялар болуы мүмкін. Дегенмен, ең көп таралған нұсқа - циклды қате рұқсат етілгеннен жоғары болғанша жалғастыру. Шартты қосыңыз:
Осылайша, алгоритм түсінікті болады. Жойылған конвульсияларды қалай анықтау керектігін анықтау қалады.
Жойылған бумаларды іздеңіз
Біз кейбір конвульсияларды алып тастауымыз керек. Алға ұмтылу және кез келген адамды «ату» жаман идея, бірақ ол нәтиже береді. Бірақ сізде бас бар болғандықтан, сіз ойлануға және жою үшін «әлсіз» конвульсияларды таңдауға тырысуға болады. Бірнеше нұсқа бар:
Опциялардың әрқайсысының өмір сүру құқығы және өзінің іске асыру ерекшеліктері бар. Мұнда біз ең кіші L1-өлшемі бар нұсқаны қарастырамыз
YOLOv3 үшін қолмен өңдеу процесі
Түпнұсқа архитектурада қалдық блоктар бар. Бірақ олар терең желілер үшін қаншалықты салқын болса да, олар бізге біраз кедергі жасайды. Қиындық мынада: осы қабаттардағы әртүрлі индекстермен салыстыруды жою мүмкін емес:
Сондықтан, салыстыруларды еркін жоя алатын қабаттарды таңдайық:
Енді жұмыс циклін құрайық:
Жүктеп салу белсендіру
Қанша кесу керектігін анықтау
Шығу
LR=10e-1 арқылы 4 дәуірді үйрену
Тестілеу
Жүктемелерді түсіру белгілі бір қадамда қанша бөлікті алып тастай алатынымызды бағалау үшін пайдалы. Түсіру мысалдары:
Біз барлық жерде дерлік 5% конвульсиялардың L1-нормасының өте төмен екенін көреміз және біз оларды алып тастай аламыз. Әр қадам сайын бұл түсіру қайталанып, қандай қабаттарды және қаншасын кесуге болатынын бағалау жүргізілді.
Бүкіл процесс 4 қадаммен аяқталды (осы жерде және RTX 2060 Super үшін барлық жерде сандар):
Қадам
mAp75
Параметрлер саны, миллион
Желі өлшемі, мб
Бастапқыдан, %
Орындалу уақыты, мс
Сүндет шарты
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 өлшемдері бар конвульсияларды қоспағанда, жойылған бөлікті шектеу:
Осылайша, біз оң жаққа ұқсас дистрибутивтерден тек әлсіз конвульсияларды алып тастауға мүмкіндік береміз және сол жаққа ұқсас дистрибутивтерден жоюға әсер етпейміз:
Бөлу қалыпты жағдайға жақындағанда, кесу_стандартты_ауытқу_бөлігінің коэффициентін мыналардан таңдауға болады:
Мен 2 сигма болжамын ұсынамын. Немесе < 1.0 мәнін қалдырып, бұл мүмкіндікті елемеуіңізге болады.
Шығару - 1.0-ге дейін қалыпқа келтірілген бүкіл сынақ үшін желі өлшемі, жоғалту және желі жұмыс уақытының графигі. Мысалы, мұнда желі өлшемі сапаны жоғалтпастан 2 есеге жуық қысқартылды (салмағы 100к шағын конволюционды желі):
Жүгіру жылдамдығы қалыпты ауытқуларға ұшырайды және іс жүзінде өзгеріссіз қалады. Бұл үшін түсініктеме бар:
Айналымдар саны ыңғайлыдан (32, 64, 128) видеокарталар үшін ең қолайлы емес - 27, 51 және т.б. Мен бұл жерде қателесуім мүмкін, бірақ оның әсері болуы мүмкін.
Архитектура кең емес, бірақ дәйекті. Енді азайту арқылы біз тереңдікке әсер етпейміз. Осылайша, біз жүктемені азайтамыз, бірақ жылдамдықты өзгертпейміз.
Осылайша, жақсарту CUDA жүктемесінің 20-30% -ға қысқаруында байқалды, бірақ жұмыс уақытының қысқаруында емес.
Нәтижелері
Рефлексия жасайық. Біз кесудің 2 нұсқасын қарастырдық - YOLOv3 үшін (қолдарыңызбен жұмыс істеу керек болғанда) және қарапайым архитектурасы бар желілер үшін. Екі жағдайда да дәлдікті жоғалтпай желі өлшемін азайтуға және жылдамдықты арттыруға қол жеткізуге болатынын көруге болады. Нәтижелер:
Өлшемді азайту
Жеделдету жүгірісі
CUDA жүктемесін азайту
Нәтижесінде экологиялық тазалық (Біз есептеу ресурстарын болашақта пайдалануды оңтайландырамыз. Бір жерде біреу бақытты Грета Тунберг)
қосымша
Кесу қадамынан кейін кванттауды қосуға болады (мысалы, TensorRT көмегімен)