Генеративные состязательные сети (GAN) в Керасе - создание комбинированной модели

Я пытаюсь создать довольно простую модель GAN, и не знаю, как объединить генератор и дискриминатор для обучения генератора.

from keras import optimizers
from keras.layers import Input, Dense
from keras.models import Sequential, Model
import numpy as np
def build_generator(input_dim=10, output_dim=40, hidden_dim=28):
     model = Sequential()
     model.add(Dense(hidden_dim, input_dim=input_dim, activation='sigmoid', kernel_initializer="random_uniform"))
     model.add(Dense(output_dim, activation='sigmoid', kernel_initializer="random_uniform"))
     return model

def build_discriminator(input_dim=40, hidden_dim=28, output_dim=50):
    input_d = Input(shape=(input_dim,))
    encoded = Dense(hidden_dim, activation='sigmoid', kernel_initializer="random_uniform")(input_d)
    decoded = Dense(output_dim, activation='sigmoid', kernel_initializer="random_uniform")(encoded)
    x = Dense(1, activation='relu')(encoded)
    y = Dense(1, activation='sigmoid')(encoded)
    model = Model(inputs=input_d, outputs=[decoded, x, y])
    return model

sgd = optimizers.SGD(lr=0.1) 
generator = build_generator(10, 100, 70)
discriminator = build_discriminator(100, 60, 80)
generator.compile(loss='mean_squared_error', optimizer=sgd)
discriminator.trainable = True
discriminator.compile(loss='mean_squared_error', optimizer=sgd)
discriminator.trainable = False

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

2 ответа

Решение

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

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

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

generator = build_generator(....) #don't create a new generator, use the one you have. 
discriminator = build_discriminator(....)

Теперь функциональная модель API имеет свою входную форму, определенную так:

inputTensor = Input(inputShape) #inputShape must be the same as in generator     

И мы работаем, передавая входные данные слоям и получая выходные данные:

#Getting the output of the generator given our input tensor:
genOut = generator(inputTensor) #you call a model just like you call a layer    

#and we pass the generator's output to the discriminator, getting its output:
discOut = discriminator(genOut)

Наконец, мы создаем фактическую модель, определяя ее начальную и конечную точки:

GAN = Model(inputTensor, discOut)

Использовать model.layers[i].trainable параметр перед compile определить, какие слои будут обучаемыми или нет в каждой из моделей.

Комбинирование моделей генератора и дискриминатора действительно иногда может быть весьма запутанным. Я нашел этот репозиторий по ссылке ниже, которая довольно хорошо демонстрирует подробный код того, как построить несколько архитектур GAN в keras:https://github.com/kochlisGit/Keras-GAN

Другие вопросы по тегам