Главная страница
Навигация по странице:

  • Эксперименты: затухание скорости обучения

  • Инициализация весов

  • Математическое представление и код

  • Эксперименты: инициализация весов

  • Исключение, или дропаут

  • Учет дропаута в остальной модели

  • Эксперимент: дропаут

  • Сверточная нейронная сеть

  • Нейронные сети и обучение представлениям

  • Курсовая работа. Глубокое обучение


    Скачать 4.97 Mb.
    НазваниеГлубокое обучение
    АнкорКурсовая работа
    Дата26.06.2022
    Размер4.97 Mb.
    Формат файлаpdf
    Имя файлаVeydman_S_Glubokoe_obuchenie_Legkaya_razrabotka_proektov_na_Pyth.pdf
    ТипДокументы
    #615357
    страница12 из 22
    1   ...   8   9   10   11   12   13   14   15   ...   22
    144
    Глава 4 . Расширения def _decay_lr(self) -> None:
    if not self.decay_type:
    return if self.decay_type == 'exponential':
    self.lr *= self.decay_per_epoch elif self.decay_type == 'linear':
    self.lr -= self.decay_per_epoch
    Наконец, мы будем вызывать функцию
    _decay_lr из класса
    Trainer в функции fit в конце каждой эпохи:
    if self.optim.final_lr:
    self.optim._decay_lr()
    Теперь проведем несколько экспериментов и посмотрим на результат.
    Эксперименты: затухание скорости обучения
    Попробуем обучить ту же модель, добавив затухание скорости обучения.
    Мы инициализируем скорость обучения таким образом, чтобы «средняя скорость обучения» за цикл была равна предыдущей скорости обучения, равной 0.1. При линейном затухании скорости обучения сделаем снижение с 0.15 до 0.05, а для экспоненциального затухания начальная скорость будет равна 0.2, а снижаться будет до 0.05. Для линейного затухания:
    optimizer = SGDMomentum(0.15, momentum=0.9, final_lr=0.05, decay_ type='linear')
    получим:
    Validation loss after 10 epochs is 0.403
    Validation loss after 20 epochs is 0.343
    Validation loss after 30 epochs is 0.282
    Loss increased after epoch 40, final loss was 0.282, using the model from epoch 30
    The model validation accuracy is: 95.91%
    Для экспоненциального затухания:
    optimizer = SGDMomentum(0.2, momentum=0.9, final_lr=0.05, decay_ type='exponential')

    Инициализация весов
    145
    получим:
    Validation loss after 10 epochs is 0.461
    Validation loss after 20 epochs is 0.323
    Validation loss after 30 epochs is 0.284
    Loss increased after epoch 40, final loss was 0.284, using the model from epoch 30
    The model validation accuracy is: 96.06%
    Потери в «лучших моделях» были равны 0.282 и 0.284, что значительно ниже, чем значение 0.338, полученное раньше!
    Далее поговорим о том, как задавать начальные веса.
    Инициализация весов
    Как мы упоминали при разговоре о функциях активации, некоторые функции активации, такие как сигмоида и гиперболический тангенс, имеют самые крутые градиенты при нулевых входах, а затем быстро сгла- живаются по мере удаления входов от 0. Это может привести к снижению эффективности этих функций, так как, если у многих входов значения далеки от 0, мы получим очень маленькие градиенты на обратном проходе.
    Оказывается, это основная проблема в нейронных сетях, с которыми мы работаем. Рассмотрим скрытый слой в сети MNIST, о которой мы говори- ли. На этот слой приходит 784 единицы данных, а затем они умножаются на матрицу весов, в результате чего получается n нейронов (а затем при необходимости добавляется смещение для каждого нейрона). На рис. 4.8 показано распределение этих n значений в скрытом слое нашей нейронной сети (с 784 входами) до и после прохода через функцию активации
    Tanh
    После прохода через функцию активации большинство активаций при- няли значения –1 или 1! Это связано с тем, что каждая функция матема- тически определена как:
    Поскольку мы инициализировали каждый вес с дисперсией 1 (Var(w
    i,j
    ) = 1 и Var(b
    n
    ) = 1) и Var(X
    1
    + X
    2
    ) = Var(X
    1
    ) + Var(X
    2
    ) для независимых слу- чайных величин X
    1
    и X
    2
    , мы имеем:
    Var(f
    n
    ) = 785.

    146
    Глава 4 . Расширения
    Распределение входов по функции активации для слоя с 784 входами
    Распределение выходов функции tahn для слоя с 784 входами
    Рис. 4.8. Распределение входов по функции активации
    Это дает стандартное отклонение (
    ) чуть более 28, что отражает разброс значений, который показан в верхней половине рис. 4.8.
    Кажется, у нас проблема. Но в том ли она заключается, что передаваемые в функции активации признаки не могут быть «слишком распределенны- ми»? Если бы проблема была в этом, мы бы просто поделили признаки на некоторое значение, чтобы уменьшить их дисперсию. Но тогда очевидный вопрос: откуда мы знаем, на сколько делить? Ответ: значения следует масштабировать в зависимости от количества нейронов, передаваемых в слой. Если бы у нас была многослойная нейронная сеть и в одном слое было 200 нейронов, а в следующем 100, слой из 200 нейронов давал бы большее широкое распределение, чем 100 нейронов. Это нежелательно, так как мы не хотим, чтобы масштаб признаков, которые наша нейронная

    Инициализация весов
    147
    сеть изучает во время обучения, зависел от их количества. Аналогично мы не хотим, чтобы прогнозы нашей сети зависели от масштаба входных признаков. Предсказания нашей модели не должны изменяться от умно- жения или деления всех признаков на 2.
    Существует несколько способов исправить это, и здесь мы рассмотрим один наиболее распространенный вариант: мы можем отрегулировать начальную дисперсию весов по количеству нейронов в слоях, чтобы значения, передаваемые вперед следующему слою во время прямого прохода и назад во время обратного прохода, имели примерно одинако- вый масштаб. Нельзя забывать об обратном проходе, поскольку в этом случае у нас та же проблема: дисперсия градиентов, которые слой полу- чает во время обратного распространения, будет напрямую зависеть от количества объектов в следующем слое, поскольку именно он отправляет градиенты назад к рассматриваемому слою.
    Математическое представление и код
    Как конкретно решить проблему? Если в каждом слое есть n входных нейронов и n выходных нейронов, дисперсия для каждого веса, которая будет поддерживать постоянство дисперсии результирующих характе- ристик на прямом проходе, будет равна:
    1
    n
    in
    Аналогично для обратного прохода:
    1
    n
    out
    Компромисс, который часто называют инициализацией Глорота
    1
    , вы- глядит так:
    Код будет простым — мы добавляем аргумент weight_init к каждому слою и добавляем следующее в нашу функцию
    _setup_layer
    :
    1
    Метод был предложен Глоротом и Бенжио в статье 2010 года Understanding the
    difficulty of training deep feedforward neural networks.

    148
    Глава 4 . Расширения if self.weight_init == "glorot":
    scale = 2/(num_in + self.neurons)
    else:
    scale = 1.0
    Теперь наши модели будут выглядеть так:
    model = NeuralNetwork(
    layers=[Dense(neurons=89,
    activation=Tanh(),
    weight_init="glorot"),
    Dense(neurons=10,
    activation=Linear(),
    weight_init="glorot")],
    loss = SoftmaxCrossEntropy(),
    seed=20190119)
    при этом для каждого слоя задается weight_init
    =
    "glorot"
    Эксперименты: инициализация весов
    Запустим все те же модели, но теперь с инициализацией Глорота:
    Validation loss after 10 epochs is 0.352
    Validation loss after 20 epochs is 0.280
    Validation loss after 30 epochs is 0.244
    Loss increased after epoch 40, final loss was 0.244, using the model from epoch 30
    The model validation accuracy is: 96.71%
    для модели с линейным затуханием скорости обучения и
    Validation loss after 10 epochs is 0.305
    Validation loss after 20 epochs is 0.264
    Validation loss after 30 epochs is 0.245
    Loss increased after epoch 40, final loss was 0.245, using the model from epoch 30
    The model validation accuracy is: 96.71%
    для модели с экспоненциальным затуханием скорости обучения. Снова имеет место существенное снижение потерь: с 0.282 и 0.284, которые были ранее, до 0.244 и 0.245!

    Исключение, или дропаут
    149
    Обратите внимание, что все эти фокусы не привели к увеличению вре- мени обучения или размера нашей модели. Мы всего лишь подстроили процесс обучения, основываясь на понимании конечной цели нейрон- ной сети, которое мы изложили ранее. В этой главе мы рассмотрим еще один прием. Вы, возможно, заметили, что ни одна из моделей, которые
    мы использовали в этой главе, не была моделью глубокого обучения. Это были просто нейронные сети с одним скрытым слоем. Дело в том, что без техники дропаута, которую мы сейчас изучим, трудно обучать модели глубокого обучения без переобучения.
    Исключение, или дропаут
    В этой главе мы изменили процедуру обучения нейронной сети, что позво- лило приблизиться к глобальному минимуму. Возможно, вы заметили, что мы не попробовали, казалось бы, самую очевидную вещь: добавить в сеть больше слоев или больше нейронов. Дело в том, что простое добавление «ог- невой мощи» в большинстве архитектур нейронных сетей лишь затруднит поиск хорошо обобщенного решения. Простое количественное расшире- ние нейронной сети позволит ей моделировать более сложные отношения между входом и выходом, но также влечет за собой риск пере обучения.
    Методика исключения, или дропаута, позволила бы нам увеличивать мощь
    сети, в большинстве случаев снижая вероятность переобучения сети.
    Что же такое этот дропаут?
    Определение
    Дропаут — это случайный выбор некоторой части p нейронов в слое и установка их равными 0 во время прямого прохода. Этот странный трюк снижает мощь сети, но часто позволяет избавиться от переобучения. Это особенно верно в более глубоких сетях, где признаки представляют со- бой несколько уровней абстракции, удаленных из исходных элементов.
    Несмотря на то что дропаут может помочь нашей сети избежать пере- обучения, мы все же хотим помочь ей делать правильные прогнозы, когда это будет нужно. Таким образом, операция
    Dropout будет иметь два режима: режим «обучения», в котором применяется дропаут, и режим
    «вывода», в котором его не будет. Тут будет другая проблема: применение

    150
    Глава 4 . Расширения дропаута к слою уменьшает число передаваемых вперед значений в 1 – p раз в среднем, то есть веса в следующих слоях получат меньше значений с величиной M, вместо этого они получат величину M * (1 – p). Мы хотим имитировать этот сдвиг при работе сети в режиме вывода, поэтому помимо отключения дропаута мы умножим все значения на 1 – p.
    В виде кода будет понятнее.
    Код
    Мы можем реализовать дропаут как отдельную операцию, которую мы добавим в конец каждого слоя. Это будет выглядеть следующим образом:
    class Dropout(Operation):
    def __init__(self,
    keep_prob: float = 0.8):
    super().__init__()
    self.keep_prob = keep_prob def _output(self, inference: bool) -> ndarray:
    if inference:
    return self.inputs * self.keep_prob else:
    self.mask = np.random.binomial(1, self.keep_prob, size=self.inputs.shape)
    return self.inputs * self.mask def _input_grad(self, output_grad: ndarray) -> ndarray:
    return output_grad * self.mask
    На прямом проходе при применении дропаута мы сохраняем «маску», в которой хранится информация об обнуленных нейронах. На обратном проходе мы умножаем градиент, полученный операцией, на эту маску. Это происходит потому, что дропаут делает градиент равным 0 для обнуленных значений (поскольку изменение их значений теперь не будет влиять на потери), а другие градиенты оставим без изменений.
    Учет дропаута в остальной модели
    Возможно, вы заметили, что мы включили флаг inference в метод
    _output
    , который определяет, применяется ли дропаут. Чтобы этот флаг вызы-

    Исключение, или дропаут
    151
    вался правильно, мы должны добавить его в нескольких других местах во время обучения:
    1. Методы пересылки
    Layer и
    NeuralNetwork будут принимать inference в качестве аргумента (по умолчанию равным
    False
    ) и передавать флаг в каждую
    Operation
    , и каждая
    Operation будет вести себя по- разному в зависимости от режима.
    2. Напомним, что в классе
    Trainer мы оцениваем обученную модель на тестовом наборе через каждые eval_every эпох. Во время оценки мы каждый раз будем оценивать флаг inference
    , равный
    True
    :
    test_preds = self.net.forward(X_test, inference=True)
    3. Наконец, мы добавляем ключевое слово dropout в класс
    Layer
    , и пол- ная подпись функции
    __init__
    для класса
    Layer теперь выглядит следующим образом:
    def __init__(self,
    neurons: int,
    activation: Operation = Linear(),
    dropout: float = 1.0,
    weight_init: str = "standard")
    Мы добавляем операцию дропаута с помощью вот такой функции в
    _setup_layer
    :
    if self.dropout < 1.0:
    self.operations.append(Dropout(self.dropout))
    Готово! Давайте посмотрим, как это работает.
    Эксперимент: дропаут
    Во-первых, видно, что добавление в модель дропаута действительно сни- жает потери. Добавим дропаут, равный 0.8 (чтобы 20% нейронов обнули- лось), в первый слой, чтобы наша модель выглядела следующим образом:
    mnist_soft = NeuralNetwork(
    layers=[Dense(neurons=89,
    activation=Tanh(),
    weight_init="glorot",
    dropout=0.8),
    Dense(neurons=10,

    152
    Глава 4 . Расширения activation=Linear(),
    weight_init="glorot")],
    loss = SoftmaxCrossEntropy(),
    seed=20190119)
    и обучим модель с теми же гиперпараметрами, что и раньше (экспонен- циальное снижение скорости обучения с 0.2 до 0.05):
    Validation loss after 10 epochs is 0.285
    Validation loss after 20 epochs is 0.232
    Validation loss after 30 epochs is 0.199
    Validation loss after 40 epochs is 0.196
    Loss increased after epoch 50, final loss was 0.196, using the model from epoch 40
    The model validation accuracy is: 96.95%
    Мы снова значительно уменьшили потери по сравнению с тем, что мы ви- дели ранее: величина потери стала равна 0.196 по сравнению с 0.244 ранее.
    Дропаут проявляет себя во всей красе, когда мы добавляем больше слоев.
    Давайте заменим модель, которую мы использовали в этой главе, на мо- дель глубокого обучения. Пусть в первом скрытом слое будет в два раза больше нейронов, чем в скрытом слое ранее (178), а во втором скрытом слое — вдвое меньше (46). Наша модель выглядит так:
    model = NeuralNetwork(
    layers=[Dense(neurons=178,
    activation=Tanh(),
    weight_init="glorot",
    dropout=0.8),
    Dense(neurons=46,
    activation=Tanh(),
    weight_init="glorot",
    dropout=0.8),
    Dense(neurons=10,
    activation=Linear(),
    weight_init="glorot")],
    loss = SoftmaxCrossEntropy(),
    seed=20190119)
    Обратите внимание на дропаут в первых двух слоях.
    Обучив модель, увидим еще одно уменьшение потерь и повышение точ- ности!

    Заключение
    153
    Validation loss after 10 epochs is 0.321
    Validation loss after 20 epochs is 0.268
    Validation loss after 30 epochs is 0.248
    Validation loss after 40 epochs is 0.222
    Validation loss after 50 epochs is 0.217
    Validation loss after 60 epochs is 0.194
    Validation loss after 70 epochs is 0.191
    Validation loss after 80 epochs is 0.190
    Validation loss after 90 epochs is 0.182
    Loss increased after epoch 100, final loss was 0.182, using the model from epoch 90
    The model validation accuracy is: 97.15%
    Но это улучшение невозможно без дропаута. Ниже приведены обучения той же модели без дропаута:
    Validation loss after 10 epochs is 0.375
    Validation loss after 20 epochs is 0.305
    Validation loss after 30 epochs is 0.262
    Validation loss after 40 epochs is 0.246
    Loss increased after epoch 50, final loss was 0.246, using the model from epoch 40
    The model validation accuracy is: 96.52%
    Без дропаута модель глубокого обучения работает хуже, чем модель с одним скрытым слоем, несмотря на вдвое большее число параметров и время обучения! Это показывает, насколько дропаут важен при обуче- нии моделей глубокого обучения. Он сыграл важную роль в определении модели-победителя на ImageNet 2012 года, что положило начало совре- менной эре глубокого обучения
    1
    . Без дропаута вы, возможно, не читали бы эту книгу!
    Заключение
    В этой главе мы разобрали некоторые из наиболее распространенных методов улучшения обучения нейронной сети, начав с описания ее работы и цели на низком уровне. В конце хотелось бы привести перечень того,
    1
    Подробнее об этом в статье Г. Хинтона и соавт. Improving neural networks by preventing
    co-adaptation of feature detectors.

    154
    Глава 4 . Расширения что вы можете попробовать выжать из своей нейронной сети независимо от задачи:
    y
    Учитывайте инерцию — важный метод оптимизации — при определе- нии правила обновления веса.
    y
    Скорость обучения лучше снижать постепенно, используя линейное или экспоненциальное затухание, или более современный метод, на- пример косинусоидальное затухание. Наиболее эффективные шаблоны скорости работают не только в зависимости от номера эпохи, но также и от величины потерь, то есть скорость обучения снижается только тогда, когда не удается снизить потери. Попробуйте реализовать это!
    y
    Убедитесь, что масштаб инициализации весов является функцией количества нейронов в вашем слое (это делается по умолчанию в боль- шинстве библиотек нейронных сетей).
    y
    Добавьте дропаут, особенно если в вашей сети есть несколько полно- стью связанных слоев подряд.
    Далее мы перейдем к обсуждению архитектур, специально придуманных для конкретных областей, начиная со сверточных нейронных сетей, ис- пользуемых для распознавания изображений. Вперед!

    ГЛАВА 5
    Сверточная нейронная сеть
    В этой главе мы рассмотрим сверточные нейронные сети (англ.: convo-
    lutional neural networks — CNN). CNN — это стандартная архитектура нейронной сети, используемая при работе с изображениями в широком спектре задач. Ранее мы работали только с полносвязными нейронными сетями, которые мы реализовали в виде нескольких полносвязных слоев.
    Начнем с обзора некоторых ключевых элементов этих сетей и объясним, зачем нам для изображений другая архитектура. Затем мы рассмотрим
    CNN так же, как и другие понятия в этой книге: сначала мы обсудим, как они работают на высоком уровне, затем перейдем к низкому уровню и, наконец, закодируем все это с нуля
    1
    . К концу этой главы вы получите достаточно полное представление о том, как работают CNN, чтобы уметь использовать их для своих задач, а также для самостоятельного изуче- ния существующих модификаций CNN, таких как ResNets, DenseNets и Octave Convolutions.
    Нейронные сети и обучение представлениям
    Нейронные сети получают данные о наблюдениях, причем каждое на- блюдение представлено некоторым числом n признаков. Мы приводили два разных примера.
    Первый: набор данных о ценах на жилье, где каждое наблюдение состояло из 13 признаков — числовых характеристик этого дома. Второй: набор данных MNIST рукописных цифр; поскольку изображения были пред- ставлены 784 пикселями (28 пикселей в ширину и 28 пикселей в высоту),
    1
    Наш код для сверточных сетей будет крайне неэффективным. В разделе «Градиент потерь с учетом смещения» приложения А будет предложена более эффективная реализация операции многоканальной свертки, которую мы опишем в этой главе с использованием библиотеки NumPy.

    1   ...   8   9   10   11   12   13   14   15   ...   22


    написать администратору сайта