Підручник з обрізки - Підручники з PyTorch 1
Сучасні методи глибокого навчання покладаються на надпараметризовані моделі, які важко застосувати. Навпаки, відомо, що біологічні нейронні мережі використовують ефективний розріджений зв’язок. Визначення оптимальних методів стиснення моделей за рахунок зменшення кількості параметрів у них є важливим для зменшення споживання пам'яті, заряду акумулятора та обладнання без шкоди точності, розгортання легких моделей на пристрої та гарантування конфіденційності при приватних обчисленнях на пристрої. На фронті досліджень обрізання використовується для дослідження відмінностей у динаміці навчання між надпараметризованими та недопараметризованими мережами, для вивчення ролі щасливих розріджених підмереж та ініціалізацій («лотерейних квитків») як деструктивної техніки пошуку нейронної архітектури, і більше.

У цьому підручнику ви дізнаєтесь, як використовувати torch.nn.utils.prune для розрідження нейронних мереж, і як розширити його, щоб реалізувати власну техніку обрізки.
Вимоги¶
Створити модель¶
У цьому посібнику ми використовуємо архітектуру LeNet від LeCun et al., 1998.
Перевірка модуля¶
Давайте перевіримо (необрізаний) рівень conv1 у нашій моделі LeNet. Наразі він буде містити два параметри ваги та упередженості та жодних буферів.
Обрізка модуля¶
Щоб обрізати модуль (у цьому прикладі рівень conv1 нашої архітектури LeNet), спочатку виберіть техніку обрізки серед доступних у torch.nn.utils.prune (або застосуйте свою власну, підкласуючи BasePruningMethod). Потім вкажіть модуль та ім’я параметра, який потрібно обрізати в цьому модулі. Нарешті, використовуючи відповідні аргументи ключових слів, необхідні для обраної техніки обрізки, вкажіть параметри обрізки.
У цьому прикладі ми обрізаємо випадковим чином 30% з'єднань у параметрі з назвою вага у шарі conv1. Модуль передається як перший аргумент функції; name ідентифікує параметр у цьому модулі за допомогою його ідентифікатора рядка; і сума вказує або відсоток з'єднань для обрізки (якщо це плаваюча величина від 0 до 1), або абсолютну кількість з'єднань для обрізки (якщо це невід'ємне ціле число).
Обрізка діє шляхом видалення ваги з параметрів і заміни її новим параметром, який називається weight_orig (тобто додаванням "_orig" до початкового імені параметра). weight_orig зберігає необрізану версію тензора. Упередження не було обрізане, тому воно залишиться цілим.
Маска обрізання, створена вибраною вище технікою обрізки, зберігається як буфер модуля з назвою weight_mask (тобто додаючи "_mask" до початкового імені параметра).
Щоб прямий прохід працював без змін, повинен існувати атрибут вага. Прийоми обрізки, реалізовані в torch.nn.utils.prune, обчислюють обрізану версію ваги (комбінуючи маску з вихідним параметром) і зберігають їх у вазі атрибута. Зауважте, це вже не параметр модуля, це тепер просто атрибут.
Нарешті, обрізка застосовується перед кожним прямим проходом за допомогою forward_pre_hooks PyTorch. Зокрема, коли модуль буде обрізаний, як ми це зробили тут, він отримає forward_pre_hook для кожного пов'язаного з ним параметра, який отримує обрізку. У цьому випадку, оскільки ми досі обрізали лише початковий параметр з назвою вага, буде присутній лише один гачок.
Для повноти ми тепер можемо також обрізати упередження, щоб побачити, як змінюються параметри, буфери, хуки та атрибути модуля. Просто для того, щоб випробувати інший прийом обрізки, тут ми обрізаємо 3 найменші записи в ухилі за нормою L1, як реалізовано у функції l1_unstructured обрізки.