Понимание глубокого обучения: брат-близнец нейронной сети — автоэнкодеры (часть 1)

искусственный интеллект глубокое обучение

предисловие

Эта статья может быть использована в качестве основы для изучения .

Что такое автоэнкодер? Автоэнкодер — это волшебная штука, которая может извлекать из данных глубокие особенности.

Например, если мы вводим изображение, автокодировщик может извлечь черты «лица» на изображении (процесс кодирования), и эта функция сохраняется как скрытая переменная автокодировщика, например, цвет кожи. и цвет волос лица.Кодер также может восстановить наши исходные данные через эти функции после извлечения этих функций. Этот процесс называется «декодированием».

Screen-Shot-2018-03-16-at-10.24.11-PM(Следующие связанные изображения взяты изjeremy)

Автоэнкодер на самом деле является своего рода нейронной сетью. Мы все знаем нейронную сеть. Мы проектируем сетевой слой, вводим наши данные, выполняем прямую операцию для извлечения признаков с помощью данных, предоставленных обучением, а затем сравниваем с подготовленной меткой. Специфическая функция потерь используется для получения потерь, а затем выполняется обратная операция для достижения классификации и калибровки цели.

Так почему же автоэнкодеры говорят, что они похожи на нейронные сети?

Что такое автоэнкодер

Автоэнкодер также имеет свой собственный сетевой слой, который обычно называется скрытым слоем в автоэнкодере.hh, автоэнкодер обычно состоит из двух частей, одна дляh=f(x)h=f(x)представляет энкодер, другойs=g(h)s=g(h)Представленный декодер. этоs=g(f(x))s=g(f(x)).

Конечно кодировщик не может вводитьxxвыводxx, это было бы слишком скучно, основная фишка энкодера - поглощать "особенности" входных данных, а потом их высвобождать, что можно понимать как случайное отображениеpencoder(hx)p_{encoder}(h|x)иpdecoder(xh)p_{decoder}(x|h).

Screen-Shot-2018-03-06-at-3.17.13-PM

Как показано выше (изJeremyjordan), мы видим, что вводinput layerиoutput layerРазмеры те же, а размер скрытого слоя меньше, поэтому мы тоже понимаем автоэнкодер как процесс уменьшения размерности.

Но будьте осторожны,Автоэнкодеры — это обучение без учителя, то есть, в отличие от нейронной сети, автоэнкодеру не нужны никакие другие данные, ему нужно только извлечь входные признаки, конечно, мы должны добавить некоторые дополнительные ограничения, чтобы «заставить» автоэнкодер извлекать то, что мы хотим. что-то.

Screen-Shot-2018-03-06-at-6.09.05-PM

Если это вышеуказанная сеть, то это все линейные слои активации.Слой активации может запомнить наш ввод, но только запомнить его. В практических приложениях необходимый нам скрытый слой должен иметь возможность хорошо конструировать информацию о наших входных данных и изучать некоторые распределения и характеристики наших входных данных.

неполный автоэнкодер

Мы хотим, чтобы автоэнкодер анализировал входные данные для получения некоторых функций, а не просто ввод и вывод, поэтому мы делаем это, ограничивая размерность h, заставляя автоэнкодер находить наиболее важные функции в обучающих данных.

почему это называетсянеполный,это потому, чтоhhразмер, чем входxxмаленький.

Screen-Shot-2018-03-07-at-8.24.37-AM

Мы делаем это, задавая на выходе функцию потерь (по аналогии с функцией потерь в нейронных сетях):

L(x,g(f(x)))L(x,g(f(x)))

Затем, уменьшив потери (эти потери могут быть среднеквадратичными ошибками и т.hhСкрытый слой изучает наиболее важную информацию в данных. То есть изучение скрытых атрибутов в данных.

Грубо говоря, этот автоэнкодер иPCA(PCA — это простой алгоритм машинного обучения, который находит «характеристики» входных данных, находя наибольший собственный вектор в матрице). Неявная информация обучающих данных получается путем кодирования и декодирования, но если скрытый слой является линейным слоем (упомянутым на рисунке выше) или емкость скрытого слоя велика, то автоэнкодер не может изучить наш ввод. о данных. Он действует только как копия.

Разница между автоэнкодером и PCA заключается в том, что автоэнкодер может изучать нелинейные функции, то есть самокодировщик может реализовать понимание и восстановление данных посредством нелинейного кодирования и нелинейного декодирования. Для многомерных данных автоэнкодер может изучить сложное представление данных (многообразие,manifold). Эти представления данных могут быть двухмерными или трехмерными (в зависимости от наших собственных настроек).

LinearNonLinear Image credit

Почему нелинейное отображение может узнать больше вещей, конечно, потому что способность нелинейного представления тем сильнее, чем больше вещей изучено, как видно из рисунка ниже, для ряда точек в двумерном пространстве прямая линия аппроксимирует Фитинга (PCA) намного уступает подбору кривой (автоэнкодер).

Screen-Shot-2018-03-07-at-8.52.21-AM

Мы используем Pytorch (v0.4.0), чтобы просто написать программу для наблюдения за эффектом недозаполнения автоэнкодера:

Сначала мы проектируем базовый сетевой уровень (уровень самокодировщика), данные, которые мы вводим здесь, представляют собой рукописный набор данных MNIST, а размер изображения набора данных составляет 28 * 28 = 784, поэтому разработанный нами неполный самокодировщик будет возьмите наши входные функции для уменьшения размерности (наш ввод28*28=78428 *28=784многомерные данные), а затем мы уменьшаем трехмерность, уменьшая 784 измерения до трех измерений, чтобы мы могли это визуализировать.

Дизайн следующего слоя автоэнкодера:

class AutoEncoder(nn.Module):
    def __init__(self):
        super(AutoEncoder, self).__init__()
        # 自编码器的编码器构造
        self.encoder = nn.Sequential(
            nn.Linear(28*28, 128),              # 784 => 128
            nn.LeakyReLU(0.1, inplace=True),    # 激活层
            nn.Linear(128, 64),                 # 128 => 64
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(64, 12),                  # 64 => 12
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(12, 3),                   # 最后我们得到3维的特征,之后我们在3维坐标中进行展示
        )
        # 自编码器的解码器构造
        self.decoder = nn.Sequential(
            nn.Linear(3, 12),                   # 3 => 12
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(12, 64),                  # 12 => 64
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(64, 128),                 # 64 -> 128
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(128, 28*28),              # 128 => 784
            nn.Sigmoid(),                       # 压缩值的范围到0-1便于显示
        )

    def forward(self, x):
        hidden = self.encoder(x)                # 编码操作,得到hidden隐含特征
        output = self.decoder(hidden)           # 解码操作,通过隐含特征还原我们的原始图
        return hidden, output

Наш оптимизатор:

optimizer = torch.optim.Adam(autoencoder.parameters(), lr=configure['lr'])

Затем можно установить функцию потерь для обучения.

Сначала мы читаем нужный нам набор цифровых изображений, MNIST, а затем помещаем его в автоэнкодер, который мы разработали для обучения. Мы используем исходное входное изображение и реконструированное изображение для обучения потерям. Уменьшая потери, мы можем извлечь функции в числовом Наборы данных. Наконец, мы представляем наши извлеченные 3D-объекты в 3D-координатах:

myplot

Очевидно, что у каждого типа чисел (0-9) есть свой характерный кластер, и обычно они группируются вместе, давайте посмотрим на это под другим углом:

myplot1

Таким образом, мы уменьшили некоторые цифровые карты с 784 измерений до 3 измерений и отобразили извлеченные объекты через 3D-координаты.

Мы также можем восстановить наши входные данные (верхняя строка - это входное изображение, а следующая строка восстанавливается по 3-мерным признакам). Хотя восстановление относительно расплывчато, также видно, что мы правильно извлекли признаки этих числа.

5446099-831328ed34cac900

Разреженный автоэнкодер

Разреженный автоэнкодер — это разновидность обычного кодировщика, что означает регуляризацию. В предыдущем автоэнкодере размерность нашего скрытого слоя меньше входного слоя, поэтому мы можем заставить автоэнкодер изучить «особенности» данных». Однако, если размер скрытого слоя такой же или больше, чем размер входного слоя (также называется емкостью). Тогда наш автоэнкодер, скорее всего, не узнает ничего полезного.

Что нам делать в это время, мы можем узнать то, что часто используется в нейронных сетях, то естьРегуляризация.

Разреженный кодировщик может быть просто выражен как:L(x,g(f(x)))+Ом(h)L(x,g(f(x))) + \Omega(h)вg(h)g(h)представляет вывод декодера,hhэто вывод энкодераh=f(x)h=f(x).

Очень просто, мы добавляем к функции потерь обычный член, который также можно назвать штрафным членом. В сочетании с некоторыми концепциями нейронной сети мы можем понимать это как обычный термин в сети прямой связи автоэнкодера.

Обычный термин, который мы обычно используем, этоL1Потеря регуляризации, штрафуйте абсолютное значение весов, затем используйте регуляризациюλ\lambdaкоэффициент для корректировки.

L(x,x^)+λiai(h) L(x,\hat x)+ \lambda\sum\limits_i|a_i^{(h)}|

Другой часто используемыйKLKLДивергенция, KL-дивергенция часто используется для оценки взаимосвязи между двумя распределениями, выбора распределения (обычно распределения Бернулли) и последующего сравнения с ним распределения наших весовых коэффициентов как части функции потерь:

L(x,x^)+jKL(рр^j)L(x,\hat x)+\sum\limits_{j}KL(\rho||\hat \rho_j)

вр\rhoэто распределение, которое мы выбираем для сравнения, ир^\hat \rhoПредставляет собой распределение наших весовых коэффициентов.

Кроме того, в «Глубоком обучении» разреженный кодировщик объясняется максимальной вероятностью:

TIM截图20180713200024

TIM截图20180713200032

Объясняя, мы можем понять, почему, добавляя обычный термин, скрытый слой может узнать то, что мы хотим узнать.

Так же есть небольшая проблема, почему он называется разреженным автоэнкодером?Из рисунка ниже видно, что некоторые узлы в скрытом слое исчезают, который естественно становится разреженным. Разница между разреженным скрытым слоем и незавершенным скрытым слоем, который мы представили ранее, заключается в следующем:Разреженные автоэнкодеры могут сделать относительно независимые узлы в наших скрытых слоях более чувствительными к определенным входным функциям или атрибутам.То есть скрытый слой неполного автокодировщика наблюдает и использует всю информацию входных данных, а разреженность другая, она избирательна и обнаруживает только интересующую область.

Screen-Shot-2018-03-07-at-1.50.55-PM

через вышеуказанное稀疏策略Мы можем гарантировать уменьшение пропускной способности сети, не жертвуя способностью сети извлекать признаки, чтобы мы могли выбирать конкретную информацию во входной информации для извлечения.

Давайте продемонстрируем с помощью программирования Pytorch, Мы модифицируем скрытый слой автоэнкодера и изменим скрытый слой на тот же размер (784), что и входные данные, так что, если обучение будет выполнено... значение потери функции потерь Это не будет Мы добавляем штатный срок (штрафной срок) по характеристикам разреженного автоэнкодера. Как его добавить? По сути, штраф за вес - это затухание веса. При проектировании оптимизатора мы добавляем предложение в Вот это Это:


# weight_decay为权重衰减系数,我们这里设置为1e-4
# 但这里的惩罚函数为L2
optimizer = torch.optim.Adam(autoencoder.parameters(), lr=configure['lr'], weight_decay=1e-4)

Это эквивалентно подсчету члена регуляризации для весов, затем нашего слоя автоэнкодера, и вы можете видеть, что все измерения одинаковы.

class AutoEncoder(nn.Module):
    def __init__(self):
        super(AutoEncoder, self).__init__()

        self.encoder = nn.Sequential(
            nn.Linear(28*28, 28*28),        # 现在所有隐含层的维数是一样的,没有缩小也没有放大
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(28*28, 28*28),
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(28*28, 28*28),
        )
        self.decoder = nn.Sequential(
            nn.Linear(28*28, 28*28),
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(28*28, 28*28),
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(28*28, 28*28),
            nn.Sigmoid(),
        )

    def forward(self, x):
        hidden = self.encoder(x)
        output = self.decoder(hidden)
        return hidden, output

Конечно, мы также можемdropoutДля реализации штрафа по весу мы его здесь демонстрировать не будем, а обучим приведенный выше автоэнкодер на получение результата, а затем5Изображение восстановлено:myplot12

Что ж, эффект не так хорош, как раньше, может быть, коэффициент регуляризации (коэффициент затухания веса) нужно скорректировать, но этого простого примера достаточно, чтобы показать, что мы можем использовать регуляризацию, чтобы скрытый слой научился тому, что мы хотим узнать.

Продолжение следует.

Использованная литература:

дразни меня

  • Если вы похожи на меня, Лао Пан очень хочет с вами общаться;
  • Если вам нравится контент Лао Пана, подпишитесь и поддержите его.
  • Если вам понравилась моя статья, надеюсь, она вам понравится? Избранное ? Комментарии ? Три в ряд~

Я хочу знать, как Лао Пан научился наступать на яму, и я хочу обменяться со мной вопросами ~ Пожалуйста, обратите внимание на публичный аккаунт "старый блог". Лао Пан также организует некоторые из своих частных коллекций, надеясь помочь всем, нажмитеТаинственный порталПолучать.