Random pictures

Дискриминатор и потеря генератора

Дискриминатор Потеря

Для дискриминатора общая потеря является суммой(d_real_loss + d_fake_loss), гдеd_real_lossпотеря, полученная на изображениях из данных тренировки иd_fake_lossпотеря, полученная на изображениях, сгенерированных из сети генератора. Для-например,

Потеря генератора

Потеря Генератора будет выглядеть аналогично только с перевернутыми метками. Цель генератора — заставить дискриминатор думать, что его сгенерированные изображенияреальный, Для-например,

Вот код дляreal_lossа такжеfake_loss

def real_loss(D_out):    '''Calculates how close discriminator outputs are to being real.       param, D_out: discriminator logits       return: real loss'''    batch_size = D_out.size(0)    labels = torch.ones(batch_size)    if train_on_gpu:        labels = labels.cuda()    criterion = nn.BCEWithLogitsLoss()    loss = criterion(D_out.squeeze(),labels)    return lossdef fake_loss(D_out):    '''Calculates how close discriminator outputs are to being fake.       param, D_out: discriminator logits       return: fake loss'''    batch_size = D_out.size(0)    labels = torch.zeros(batch_size)    if train_on_gpu:        labels = labels.cuda()    criterion =  nn.BCEWithLogitsLoss()    loss = criterion(D_out.squeeze(),labels)    return loss

Несколько советов по обучению DCGAN

Для скрытых устройств могут работать многие функции активации, но Leaky ReLUs являются наиболее популярными. Утечки ReLU гарантируют, что градиент проходит через всю архитектуру

Это очень важно дляDCGANпотому что единственный способ, которым может научиться Генератор, — это получить градиент от Дискриминатора.
Одной из самых популярных функций активации для выходной сети генератора является функция тангенциальной гиперболической активации.(На основеУлучшенные методы обучения для GANбумага),
Поскольку Дискриминатор является двоичным классификатором, мы будем использовать функцию активации сигмоида для получения окончательной вероятности.

До сих пор мы говорили о рабочей интуиции и некоторых советах и ​​приемах для обучения.GANs /DCGANs. Но все же многие вопросы остались без ответа. Некоторые из них:

Какие бывают электрогенераторы

Для бытового применения используется бензиновый генератор переменного тока. Он выдает достаточную мощность, чтобы обеспечить электроэнергией весь дом. Для этого вполне достаточно 5-10 киловатт мощности. Такие генераторы обойдутся в умеренную сумму.

Но не надо забывать, что бензин весьма дорогое топливо, а эксплуатировать бензиновый генератор длительное время не рекомендуется. Да этого и не нужно. Как правило, электричество отключают не более, чем на несколько дней и бензиновый двигатель с такой задачей справится.

Однако подобные установки чаще всего используются в промышленных целях, так как они могут вырабатывать повышенные объемы элетроэнергии.

Если дом большой и потребности выше, то лучше обеспечить себя генератором на 20-50 киловатт. Это, конечно же, с запасом.

Основные операции линейной алгебры

Удивительно, не правда ли?

Пока нет, мы можем выполнить операцию линейной алгебры со скрытым вектором. Результат уравнения также может быть сгенерирован и иметь интересный результат. Возьмите результат от наших первых лиц перед вводным разделом:

G + D

Изображения 15: G + D = GAN

Ган лица является результатом добавления G с D. Вы можете видеть, что волосы становятся немного коричневыми. и волосы следуют за стилем D справа и G слева.

Ниже приведены результаты других операций:

G — D (Абсолют)

Изображения 16: G-D

Умножение по компонентам (G, D)

Изображения 17:Умножение по компонентам (G, D)

Генератор

Генератор должен сэмплировать входные данные и генерировать новое изображение того же размера, что и наши тренировочные данные 32X32X3. Для этого мы будем использовать транспонированные сверточные слои. Вот код для сети генератора.

def deconv(input_c,output,kernel_size,stride = 2, padding =1, batch_norm = True):    layers = []    decon = nn.ConvTranspose2d(input_c,output,kernel_size,stride,padding,bias = False)    layers.append(decon)    if batch_norm:        layers.append(nn.BatchNorm2d(output))    return nn.Sequential(*layers)class Generator(nn.Module):    def __init__(self, z_size, conv_dim):        """        Initialize the Generator Module        :param z_size: The length of the input latent vector, z        :param conv_dim: The depth of the inputs to the *last* transpose convolutional layer        """        super(Generator, self).__init__()        # complete init function        self.conv_dim = conv_dim        self.fc = nn.Linear(z_size,conv_dim*8*2*2)        self.layer_1 = deconv(conv_dim*8,conv_dim*4,4) #4        self.layer_2 = deconv(conv_dim*4,conv_dim*2,4) #8        self.layer_3 = deconv(conv_dim*2,conv_dim,4) #16        self.layer_4 = deconv(conv_dim,3,4,batch_norm = False) #32    def forward(self, x):        """        Forward propagation of the neural network        :param x: The input to the neural network             :return: A 32x32x3 Tensor image as output        """        # define feedforward behavior        x = self.fc(x)        x = x.view(-1,self.conv_dim*8,2,2) #(batch_size,depth,width,height)        x = F.relu(self.layer_1(x))        x = F.relu(self.layer_2(x))        x = F.relu(self.layer_3(x))        x = torch.tanh(self.layer_4(x))        return x

объяснение

  • Следующая архитектура состоит из полностью связанного уровня, за которым следуют четыре уровня транспонирования свертки. Эта архитектура определена так, что выход после четвертого транспонированного слоя свертки приводит к изображению размера 32X32X3(размер изображения из набора обучающих данных).
  • Входами в генератор являются векторы некоторой длиныz_size (z_size — вектор шума),
  • Каждый слой транспонирования свертки, кроме последнего, сопровождаетсяПакетная нормализация (определена в вспомогательной функции deconv),
  • Для скрытых юнитов мы использовалиРЕЛУфункция активации.
  • После каждого транспонирования слоя свертки высота и ширина становятся двойными. Например, после первой транспонированной свертки изображения 2X2 будут изменены в 4X4 и так далее.

(4) Инициализировать вес ваших сетей

Чтобы помочь моделям сходиться, я инициализировал веса сверточного и линейного слоев в модели на основеоригиналDCGANбумага, который говорит: Все веса инициализируются из нормального распределения с нулевым центром со стандартным отклонением 0,02.

def weights_init_normal(m):    """    Applies initial weights to certain layers in a model .    The weights are taken from a normal distribution     with mean = 0, std dev = 0.02.    :param m: A module or layer in a network        """    # classname will be something like:    # `Conv`, `BatchNorm2d`, `Linear`, etc.    classname = m.__class__.__name__    if hasattr(m,'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1):        m.weight.data.normal_(0.0,0.02)        if hasattr(m,'bias') and m.bias is not None:            m.bias.data.zero_()
  • Это будет инициализировать веса к нормальному распределению, центрированному около 0, со стандартным отклонением 0,02.
  • Термины смещения, если они существуют, могут быть оставлены в покое или установлены в 0.

(5) Построить полную сеть

Определите гиперпараметры ваших моделей и создайте экземпляр дискриминатора и генератора из классов, определенных вОпределение моделираздел. Вот код для этого.

def build_network(d_conv_dim, g_conv_dim, z_size):    # define discriminator and generator    D = Discriminator(d_conv_dim)    G = Generator(z_size=z_size, conv_dim=g_conv_dim)# initialize model weights    D.apply(weights_init_normal)    G.apply(weights_init_normal)print(D)    print()    print(G)    return D, G# Define model hyperparamsd_conv_dim = 64g_conv_dim = 64z_size = 100D, G = build_network(d_conv_dim, g_conv_dim, z_size)

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

конкретизированныхдискриминатора такжеГенератормодели

Итак, что такое GAN?

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

На GAN есть некоторые характеристики, которые являются генеративной моделью, а именно:

  • Узнает совместную вероятностьР (х, у)гдеИксэто вход иYвыход. Это будет делать вывод на основеР (х | у), учитывая выходу,это выведетИкс.Вы можете сказать, чтоYэто реальные данные в ГАН.
  • Когда модель дается обучение реальные данныеY, он узнает характеристику реальных данных. Это будет учиться путем выявления реальных данныхпеременная скрытого представления объекта, Чтобы упростить его, он изучает функцию базового конструктора изображений в реальных данных. Например, модель может узнать, что лица построены по цвету глаз и волос. Эти два будут одной из основ, которые будут использоваться при создании граней. Изменяя его переменную, он также может изменять сгенерированные грани. Например, подняв переменную глаза, глаза станут чернее. Понижение этого сделает противоположное иначе.
  • Он может построить распределение вероятностей, такое как нормальное распределение, которое можно использовать для предотвращенияостанец, посколькуостанецкак правило, очень редко встречается в дистрибутиве, его очень редко генерируют. Таким образом, GAN хорошо работает с реальными данными, которые имеют выбросы.

Итак, как это работает?

ГАН состоит из двух нейронных сетей,дискриминатора такжеГенератор, GAN заставит эти две сети сражаться друг с другом на игровой основе с нулевой суммой (теория игр). Это игра между этими агентами (сетями).состязательныйимя в GAN происходит от этой концепции.

Изображение 2: Иллюстрация Дискриминатор против Генератора. Изображение изменено и взято изВот

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

Хорошо, другими словами,Генераторбудет имитировать реальные данные путем выборки распределения, которое изучено и предназначено для того же распределения, что и реальные данные. Он обучит свою нейронную сеть, которая может генерировать ее

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

Рисунок 3: Иллюстрация GAN по распределению обучающих данных. Фото сделано сВот,

Вот грубые шаги о том, как работает GAN:

Генерировать случайный шум в распределении вероятностей, таких как нормальное распределение.
Сделайте это в качестве входного сигнала нашей нейронной сети генератора. Будет выведен сгенерированныйподдельные данные, Эти шаги также могут означать, что мы выбираем некоторые данные из дистрибутива, который узнал генератор. Мы отметим шум каки сгенерированные данные как,означает результат шума, обработанного генераторомг,
Мы объединяем сгенерированные поддельные данные с данными, которые взяты из набора данных (которые являются реальными данными). Сделайте их вкладом нашегоДискриминатор. Мы отметим это как D.Дискриминатор попытается узнать, предсказав, являются ли данные поддельными или нет. Обучите нейронную сеть, выполнив прямой проход и затем обратное распространение

ОбновляетDвеса.
Затем нам нужно тренироватьГенератор, Нам нужно сделатьили поддельные данные, сгенерированные из случайных шумов в качестве входаD.Обратите внимание, что эти шаги только вводят поддельные данные вдискриминатор, Вперед пройтивD.Используя нейронную сеть Discriminator, выполняя прямую передачу, предсказывайте, являются ли поддельные данные ложными или нет, Затем выполните обратное распространение, где мы будем только обновлятьгвеса.
Повторяйте эти шаги до тех пор, пока мы не увидим, что генератор предоставляет хорошие поддельные данные или не достигнута максимальная итерация.

Иллюстрация выглядит следующим образом:

Изображение 4: Как работает GAN. Фото сделано сВот,

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

Чтобы наши агенты научились, убедитесь, чтодискриминатора такжегенератордоминировать друг над другом. Сделайте их как можно более сбалансированными и сделайтедискриминатора такжегенераторучиться одновременно Когдадискриминаторявляется слишком сильным (может различать поддельные и настоящие 100%),Генераторстать неспособным слишком чему-то научиться. Если в процессе обучения мы дойдем до этой точки, лучше ее закончить. Противоположность также имеет эффект, когдаГенераторсильнее, чем дискриминатор. Это вызывает Mode Collapse, где наша модель всегда предсказывает один и тот же результат для любых случайных шумов. Это одна из самых сложных и трудных частей GAN, которая может расстроить кого-то.

Если вы хотите понять больше, я предлагаю взглянуть и прочитать это удивительноестатья,

Как пользоваться генератором

Чтобы генератор начал работать, его необходимо завести. Это можно сделать при помощи ручного стартера. Нужно сильно дернуть за веревочку. Если с двигателем какие-то проблемы или некачественное топливо, то подергать придется несколько раз. Эта процедура тоже не из разряда увлекательных.

Поэтому лучше купить генератор с электрическим стартером. Как только мотор заведется сразу можно подключать нагрузку. Есть варианты автоматического или полуавтоматического включения генератора. Лучше всего приобрести бензиновый генератор с автоматическим запуском.

Когда в Вашем доме отключится электричество генератор запустится сам и выключится самостоятельно при возобновлении подачи электроэнергии.

Подготовка

Обучение будет включать чередование обучения дискриминатора и генератора. Мы будем использоватьreal_lossа такжеfake_lossфункции, определенные ранее, чтобы помочь нам в расчете потерь дискриминатора и генератора.

  • Вы должны тренировать дискриминатор, чередуя реальные и поддельные изображения
  • Тогда генератор, который пытается обмануть дискриминатор и должен иметь противоположную функцию потерь

Вот код для обучения.

def train(D, G, n_epochs, print_every=50):    '''Trains adversarial networks for some number of epochs       param, D: the discriminator network       param, G: the generator network       param, n_epochs: number of epochs to train for       param, print_every: when to print and record the models' losses       return: D and G losses'''    # move models to GPU    if train_on_gpu:        D.cuda()        G.cuda()# keep track of loss and generated, "fake" samples    samples = []    losses = []# Get some fixed data for sampling. These are images that are held    # constant throughout training, and allow us to inspect the model's performance    sample_size=16    fixed_z = np.random.uniform(-1, 1, size=(sample_size, z_size))    fixed_z = torch.from_numpy(fixed_z).float()    # move z to GPU if available    if train_on_gpu:        fixed_z = fixed_z.cuda()# epoch training loop    for epoch in range(n_epochs):# batch training loop        for batch_i, (real_images, _) in enumerate(celeba_train_loader):batch_size = real_images.size(0)            real_images = scale(real_images)            if train_on_gpu:                real_images = real_images.cuda()            # 1. Train the discriminator on real and fake ima.ges            d_optimizer.zero_grad()            d_out_real = D(real_images)            z = np.random.uniform(-1,1,size = (batch_size,z_size))            z = torch.from_numpy(z).float()            if train_on_gpu:                z = z.cuda()            d_loss = real_loss(d_out_real) + fake_loss(D(G(z)))            d_loss.backward()            d_optimizer.step()            # 2. Train the generator with an adversarial loss            G.train()            g_optimizer.zero_grad()            z = np.random.uniform(-1,1,size = (batch_size,z_size))            z = torch.from_numpy(z).float()            if train_on_gpu:                z = z.cuda()            g_loss = real_loss(D(G(z)))            g_loss.backward()            g_optimizer.step()            # Print some loss stats            if batch_i % print_every == 0:                # append discriminator loss and generator loss                losses.append((d_loss.item(), g_loss.item()))                # print discriminator and generator loss                print('Epoch [{:5d}/{:5d}] | d_loss: {:6.4f} | g_loss: {:6.4f}'.format(                        epoch+1, n_epochs, d_loss.item(), g_loss.item()))## AFTER EACH EPOCH##            # this code assumes your generator is named G, feel free to change the name        # generate and save sample, fake images        G.eval() # for generating samples        samples_z = G(fixed_z)        samples.append(samples_z)        G.train() # back to training mode# Save training generator samples    with open('train_samples.pkl', 'wb') as f:        pkl.dump(samples, f)    # finally return losses    return losses# set number of epochs n_epochs = 40# call training functionlosses = train(D, G, n_epochs=n_epochs)

(6) Результаты

Ниже приведен график потерь обучения для Генератора и Дискриминатора, записанных после каждой эпохи.

Потеря обучения длядискриминатора такжеГенератор

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

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

Сгенерированные образцы после40 эпох,

Сгенерированные поддельные изображения

Наша модель была в состоянии генерировать новые изображения поддельных человеческих лиц, которые выглядят максимально реалистично. Мы также можем заметить, что все изображения светлее в тени, даже коричневые лица немного светлее. Это потому чтоCelebAнабор данных смещен; он состоит из «знаменитостей», которые в основном белые. При этом DCGAN успешно генерирует почти реальные изображения из простого шума.

Как выбрать генератор

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

Хороший продавец продемонстрирует устройство в действии, и Вы в результате приобретете то, что прослужит долгие годы.

Ценовой диапазон этих агрегатов весьма разнообразен. Не нужно излишне экономить и покупать некачественный товар. Электрический генератор приобретается на долгие годы.

оптимизаторы

ДляGANs мы определяем два оптимизатора, один для генератора и другой для дискриминатора. Идея состоит в том, чтобы запустить их одновременно, чтобы продолжать улучшать обе сети. В этой реализации я использовалАдамоптимизаторв обоих случаях. Чтобы узнать больше о различных оптимизаторах, обратитесь к этомуссылка,

# Create optimizers for the discriminator D and generator Gd_optimizer = optim.Adam(D.parameters(),lr = .0002, betas = )g_optimizer = optim.Adam(G.parameters(),lr = .0002, betas = )

Скорость обучения (лр)а такжебетызначения основаны на оригиналеБумага DCGAN,

Манипулировать скрытыми векторами

Посмотрим, как будут создаваться изображения, если мы будем манипулировать измерением в скрытом векторе. Как я уже говорил ранее, модель научится скрытому представлению признаков. Итак, каждый элемент в скрытом векторе имеет своей целью генерацию изображения.

Чтобы сделать визуализацию, мы заморозим все элементы в векторах и изменим выбранное измерение, которое нужно проверить.

Изображения 18: Иллюстрация о том, что мы делаем в этом разделе

Например, мы хотим исследовать 1-й элемент в скрытом векторе, мы изменяем это измерение и оставляем остальные неизменными.

Мы сгенерируем несколько граней, которые имеют среднее значение в этих точках:

Для каждой средней точки мы сгенерируем грани, размер которых в скрытом векторе будет изменен с этими значениями итеративно:

Позвольте визуализировать на нашем выбранном измерении: (Этот раздел будет использовать только МОДЕЛЬ-A)

28-е измерение:

Изображение 19: Результат изменения 28-й скрытой переменной в разных средних точках.

Каковы цели 28-й скрытой переменной?

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

Давайте посмотрим еще один!

5-е измерение

Рисунок 20: Результат изменения 5-й скрытой переменной разными способами

Что это за скрытые переменные цели?

Я думаю, что это как-то связано с левыми глазами, даже несмотря на то, как левые глаза отличаются для каждой средней точки. Это также делает волосы немного темнее. Что вы думаете?

11-е измерение

Рисунок 21: Результат изменения 11-ых скрытых переменных различными способами

Я думаю, это измерение заботит рот и правый глаз.

Другой пример для граней, которые генерируются из средних точек только путем подстройки скрытой переменной:

Изображение 22: Результат на лицах путем изменения скрытой переменной

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector