Най-добри практики за задълбочено обучение (1) - Инициализиране на теглото

Основи, клопки и инициализация на теглото и най-добри практики

https://pixabay.com/photo-1600668/

мотивиране

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

Докато пишете този блог, предположението е, че имате основна идея как се тренират невронните мрежи. Разбирането на тегла, пристрастия, скрити слоеве, активирания и активиращи функции ще направи съдържанието по-ясно. Бих препоръчал този курс, ако искате да изградите основен фундамент за задълбочено обучение.

Забележка - Всеки път, когато визирам слоеве на невронна мрежа, това предполага слоевете на обикновена невронна мрежа, т.е. напълно свързани слоеве. Разбира се, някои от методите, за които говоря, се прилагат и за конволюционни и повтарящи се невронни мрежи. В този блог ще говоря за проблемите, свързани с инициализирането на матриците за тегло и начините за тяхното смекчаване. Преди това, нека просто да покрием някои основи и бележки, които ще използваме напред.

Основи и обозначения

Помислете за невронна мрежа от L слой, която има скрити слоеве L-1 и 1 изходен слой. Параметрите (тегла и отклонения) на слоя l са представени като

В допълнение към теглата и отклоненията, по време на тренировъчния процес се изчисляват следните междинни променливи

Обучението на невронна мрежа се състои от 4 стъпки:

  1. Инициализирайте тежести и пристрастия.
  2. Напредно разпространение: Използвайки входа X, тежи W и отклонения b, за всеки слой изчисляваме Z и A. В крайния слой изчисляваме f (A ^ (L-1)), което може да бъде сигмоидна, софтмакс или линейна функция на A ^ (L-1) и това дава прогнозата y_hat.
  3. Изчислете функцията за загуба: Това е функция на действителния етикет y и прогнозирания етикет y_hat. Той отчита колко далече са нашите прогнози от реалната цел. Нашата цел е да сведем до минимум тази функция за загуба.
  4. Обратно разпространение: В тази стъпка изчисляваме градиентите на функцията на загуба f (y, y_hat) по отношение на A, W и b, наречени dA, dW и db. Използвайки тези градиенти, ние актуализираме стойностите на параметрите от последния слой до първия.
  5. Повтаряйте стъпки 2–4 за n итерации / епохи, докато почувстваме, че сме намалили до минимум загубата, без да прекаляваме с данните на влака (повече за това по-късно!)

Ето бърз поглед към стъпки 2, 3 и 4 за мрежа с 2 слоя, т.е. един скрит слой. (Обърнете внимание, че тук не съм добавил отклоненията за простота):

Напред РазпространениеОбратно разпространение

Инициализиране на тегла W

Една от изходните точки, за която трябва да се грижите, докато изграждате вашата мрежа, е да инициализирате правилно вашата матрица за тегло. Нека разгледаме 2 сценария, които могат да причинят проблеми по време на обучението на модела:

1. Инициализиране на всички тегла до 0

Нека просто го поставим там - това прави вашия модел еквивалентен на линеен модел. Когато зададете цялото тегло на 0, производната по отношение на функцията на загуба е една и съща за всеки w в W ^ l, следователно всички тегла имат еднакви стойности при следващата итерация. Това прави скритите единици симетрични и продължават за всички n итерации, които стартирате. По този начин поставянето на тегла на нула прави вашата мрежа не по-добра от линеен модел. Важно е да се отбележи, че задаването на отклонения на 0 няма да създаде проблеми, тъй като ненулевите тегла се грижат за нарушаване на симетрията и дори ако отклонението е 0, стойностите във всеки неврон все още са различни.

2. Инициализиране на тежести на случаен принцип

Инициализирането на тежести на случаен принцип, следвайки стандартното нормално разпределение (np.random.randn (size_l, size_l-1) в Python), докато работите с (дълбока) мрежа, потенциално може да доведе до 2 проблема - изчезване на градиенти или избухване на градиенти.

а) Изчезващи градиенти - В случай на дълбоки мрежи, за всяка функция на активиране, abs (dW) ще става все по-малък и по-малък, докато вървим назад с всеки слой по време на размножаването на гърба. По-ранните слоеве са най-бавните за обучение в такъв случай.

Актуализацията на теглото е незначителна и води до по-бавна конвергенция. Това прави бавното оптимизиране на функцията за загуба. В най-лошия случай това може напълно да спре нервната мрежа да продължи да тренира.

По-конкретно, в случай на сигмоид (z) и tanh (z), ако теглото ви е голямо, тогава наклонът ще бъде изчезващо малък, което ефективно ще попречи на тежестите да променят стойността си. Това е така, защото абс (dW) ще се увеличи много леко или евентуално ще стане по-малък и по-малък при всяка итерация. С RELU (z) изчезващите градиенти обикновено не са проблем, тъй като градиентът е 0 за отрицателни (и нула) входове и 1 за положителни входове.

б) експлодиращи градиенти - това е точно обратното на изчезващите градиенти. Помислете, че имате неотрицателни и големи тежести и малки активации A (както може да се случи при сигмоида (z)). Когато тези тегла се умножат по слоевете, те причиняват голяма промяна в цената. По този начин градиентите също ще бъдат големи. Това означава, че промените в W, от W - ⍺ * dW, ще бъдат в огромни стъпки, низходящият момент ще се увеличи.

Това може да доведе до колебание около минимумите или дори превишаване на оптималното отново и отново и моделът никога няма да се научи!

Друго въздействие на експлодиращите градиенти е, че огромните стойности на градиентите могат да причинят преливане на броя, което води до неправилни изчисления или въвеждане на NaN. Това може също да доведе до загуба, приемаща стойността NaN.

Най-добри практики

1. Използване на RELU / leaky RELU като функция за активиране, тъй като е сравнително здрав към изчезващия / избухващ проблем с градиент (особено за мрежи, които не са твърде дълбоки). В случай на течови RELU, те никога нямат 0 наклона. Така те никога не умират и тренировките продължават.

2. За дълбоки мрежи можем да използваме евристика за инициализиране на теглата в зависимост от нелинейната функция на активиране. Тук, вместо да черпим от стандартното нормално разпределение, ние черпим W от нормалното разпределение с дисперсия k / n, където k зависи от функцията на активиране. Въпреки че тези евристики не решават напълно проблема с градиентите, които избухват / изчезват, те помагат да го смекчат до голяма степен. Най-често срещаните са:

а) За RELU (z) - Умножаваме произволно генерираните стойности на W по:

б) За tanh (z) - евристичният се нарича инициализация на Xavier. Той е подобен на предишния, с изключение на това, че k е 1, вместо 2.

В TensorFlow W = tf.get_variable ('W', [dims], инициализатор), където Initilizer = tf.contrib.layers.xavier_initializer ()

в) Друго често използвано евристично е:

Те служат като добри отправни точки за инициализиране и смекчаване на шансовете за експлозия или изчезване на градиентите. Те задават тежестите нито твърде много по-големи от 1, нито твърде много по-малки от 1. Така градиентите не изчезват или не избухват твърде бързо. Те помагат да се избегне бавното сближаване, като също така гарантират, че не продължаваме да колебаем от минимумите. Съществуват и други варианти на горното, където основната цел отново е да се намали дисперсията на параметрите.

3. Градиентно изрязване - Това е друг начин за справяне с избухналия градиент. Задаваме прагова стойност и ако избрана функция на градиент е по-голяма от този праг, ние я задаваме на друга стойност. Например, нормализирайте градиентите, когато нормата L2 надвишава определен праг - W = W * праг / l2_norm (W), ако праг l2_norm (W)>

Важен момент, който трябва да се отбележи, е, че говорихме за различни инициализации на W, но не и пристрастия b. Това е така, защото градиентите по отношение на отклонението зависят само от линейното активиране на този слой, а не от градиентите на по-дълбоките слоеве. По този начин няма намаляване или експлозия на градиенти за условията на пристрастие. Както бе споменато по-рано, те могат да бъдат инициализирани безопасно до 0.

заключение

В този блог сме обхванали клонките за инициализиране на теглото и някои техники за смекчаване. Ако съм пропуснал всякакви други полезни прозрения, свързани с тази тема, ще се радвам да го науча от вас! В следващия блог ще говоря за методи на регуларизация, за да се намали преоборудването и проверката на градиента - трик, с който да направите по-лесно отстраняване на грешки!

Препратки

  1. https://www.coursera.org/learn/deep-neural-network/lecture/RwqYe/weight-initialization-for-deep-networks
  2. Невронни мрежи: обучение с гръб на размножаване - Джеръми Джордан
  3. Нежно въведение в експлодирането на градиенти в невронните мрежи от Джейсън Браунли
  4. Изчезващ проблем с градиента
  5. https://www.quora.com/Why-is-it-a-problem-to-have-exploding-gradients-in-a-neural-net-especially-in-an-RNN

За мен: Завършил съм MS Data Science в USF и завършил „Компютърни науки“, имам 2 години опит в изграждането на прогнозни и препоръчителни алгоритми и извличане на бизнес прозрения за финанси и клиенти на дребно. Развълнуван съм от възможностите за прилагане на моето машинно обучение и знания за задълбочено обучение при проблеми в реалния свят.
Вижте и другите ми блогове тук!
LinkedIn: https://www.linkedin.com/in/neerja-doshi/