Cálculos Generativos versus Discriminativos
Para compreender os GANs, você deve perceber como os cálculos generativos funcionam, e para isso, destacá-los dos cálculos discriminatórios é esclarecedor. Os cálculos discriminatórios tentam caracterizar a informação de entrada; isto é, dados os pontos altos de uma ocasião de informação, eles antecipam um nome ou classe para a qual essa informação tem um lugar.
Por exemplo, dado cada uma das palavras de um e-mail (o caso da informação), um cálculo discriminatório poderia prever se a mensagem é spam ou não_spam. spam é um dos nomes, e o pacote de palavras acumuladas do e-mail são os destaques que compõem a informação de informação. No momento em que esta questão é comunicada cientificamente, o nome é chamado y e os destaques são chamados x. A definição p(y|x) é utilizada para significar “a probabilidade de y dado x”, o que para esta situação significaria “a probabilidade de um e-mail ser um spam dadas as palavras que ele contém”.
Assim, cálculos discriminatórios mapeiam os destaques para as marcas. Eles estão preocupados exclusivamente com essa conexão. Uma abordagem para considerar cálculos generativos é que eles fazem o inverso. Em vez de antecipar uma marca dada a certos destaques, eles se esforçam para prever os destaques dado um nome específico.
O inquérito que um cálculo generativo tenta responder é: Esperando que este e-mail seja spam, qual é a probabilidade desses destaques? Enquanto modelos discriminatórios se preocupam com a conexão entre y e x, modelos generativos se preocupam com “como você obtém x”. Eles permitem que você pegue p(x|y), a probabilidade de x dado y, ou a probabilidade de destaques dado um nome ou classe. (Tudo considerado, cálculos generativos também podem ser utilizados como classificadores. Por alguma estranha razão, eles podem realizar mais do que informações de entrada de ordem).
Outra abordagem para considerá-lo é reconhecer discriminatórios de generativos como este:
Os modelos discriminatórios tornam-se familiares com o limite entre classes.
Modelos generativos modelam a dispersão de classes individuais
Como funcionam os GANs
Um arranjo neural, chamado gerador, cria novas ocorrências de informação, enquanto que o outro, o discriminador, as avalia para a realidade; por exemplo, o discriminador escolhe se cada ocorrência de informação que pesquisa tem um lugar com o conjunto de dados de preparação genuína ou não.
Suponha que estamos tentando realizar algo mais comum do que copiar a Mona Lisa. Vamos criar manualmente numerais escritos como aqueles encontrados no conjunto de dados MNIST, que é retirado desta realidade atual. O objetivo do discriminador, quando indicado uma ocorrência do conjunto de dados MNIST genuíno, é perceber aqueles que são de boa-fé.
Enquanto isso, o gerador está fazendo novas imagens, projetadas, que vão para o discriminador. Faz como tal nas expectativas de que eles, também, serão estimados válidos, apesar do fato de serem falsos. O objetivo do gerador é criar dígitos toleráveis escritos à mão: mentir sem ser percebido. O objetivo do discriminador é reconhecer como falso as imagens provenientes do gerador.
Aqui estão os meios que um GAN toma:
O gerador tira um número arbitrário e devolve uma foto.
Esta imagem criada é reforçada no discriminador próximo a uma onda de imagens tiradas a partir do conjunto de dados reais, de verdade.
O discriminador tira fotografias verdadeiras e falsificadas e devolve probabilidades, um número algures no intervalo de 0 e 1, com 1 falando para uma expectativa de credibilidade e 0 falando para falsificação.
Portanto, você tem um círculo de entrada duplo:
O discriminador está num círculo de entrada com a verdade das imagens, que nós conhecemos.
O gerador está em um círculo de entrada com o discriminador.
Esquema de GAN
Crédito: O’Reilly
Você pode pensar em um GAN como a restrição de um falsificador e um policial em uma rodada de felino e rato, onde o falsificador está descobrindo como passar notas falsas, e o policial está descobrindo como reconhecê-las. Ambos são dinâmicos; por exemplo, o polícia também está a preparar-se (para alargar a relação, possivelmente o banco nacional está a cobrar taxas que passaram furtivamente), e cada lado vem a familiarizar-se com as diferentes técnicas numa aceleração consistente.
Para o MNIST, a organização discriminadora é um arranjo padrão convolucional que pode classificar as imagens reforçadas a ele, um classificador binomial marcando imagens como genuínas ou falsas. O gerador é um arranjo convolucional inverso, pode ser dito: Enquanto um classificador convolutivo padrão tira uma foto e reduz a sua probabilidade, o gerador tira um vector de comoção irregular e aumenta a sua probabilidade para uma foto. O principal descarta informações através de estratégias de downsampling como maxpooling, e o segundo produz novas informações.
As duas redes estão tentando racionalizar uma capacidade alvo alternativa e contraditória, ou trabalho de azar, em um jogo de zero-zero. Este é basicamente um modelo de pundit de personagens na tela. Como o discriminador muda sua conduta, também muda o gerador, e o contrário. Seus infortúnios empurram uns contra os outros.
GANs
GANs, Autocodificadores e VAEs
Pode ser valioso contrastar sistemas generativos de má disposição com outros sistemas neurais, por exemplo, autoencoders e autoencoders variacionais.
Os autocodificadores codificam a informação de entrada como vetores. Eles formam um retrato coberto, ou compactado, da informação bruta. Eles são úteis na diminuição da dimensionalidade; ou seja, o preenchimento vetorial como um retrato oculto embala a informação bruta em menos medições notáveis. Autoencoders podem ser combinados com um suposto decodificador, o que permite recriar a informação de entrada dependendo do seu retrato oculto, como você faria com uma máquina Boltzmann limitada.
esquema de autocodificadores
Dicas para a preparação de um GAN
No ponto em que você treina o discriminador, mantenha a estima do gerador consistente; e quando você treina o gerador, mantenha o discriminador estável. Cada um deve preparar-se contra um inimigo estático. Por exemplo, isto dá ao gerador uma leitura superior na inclinação pela qual ele deve aprender.
De maneira semelhante, o pré-treinamento do discriminador contra o MNIST antes de você começar a preparar o gerador irá configurar uma inclinação mais clara.
Cada lado do GAN pode sobrecarregar o outro. No caso de o discriminador ser excessivamente grande, ele devolverá estima tão próxima de 0 ou 1 que o gerador lutará para examinar a inclinação. Na hipótese de que o gerador seja excessivamente grande, ele aventurará tenazmente falhas no discriminador que levam a falsos negativos. Isto pode ser moderado pelas taxas de aprendizagem individual das redes. Os dois sistemas neurais devem ter um “nível de aptidão” comparável. 1
Os GANs puseram de lado um longo esforço de preparação. Em uma GPU solitária um GAN pode levar horas, e em uma CPU solitária mais de um dia. Embora difíceis de afinar e, portanto, de utilizar, os GANs revigoraram uma tonelada de exploração e composição fascinantes.
Aqui está um exemplo de um GAN codificado em Keras, do qual os modelos podem ser importados para o Deeplearning4j.
classe GAN():
def __init__(self):
self.img_rows = 28
self.img_cols = 28
self.channels = 1
self.img_shape = (self.img_rows, self.img_cols, self.channels)
otimizador = Adam(0.0002, 0.5)
# Constrói e compila o discriminador
self.discriminator = self.build_discriminator()
self.discriminator.compile(loss='binary_crossentropy',
optimizador=optimizador,
metrics=['precisão'])
# Construir e compilar o gerador
self.generator = self.build_generator()
self.generator.compile(loss='binary_crossentropy', optimizer=optimizer)
# O gerador toma o ruído como entrada e gera imgs
z = Input(forma=(100,))
img = self.generator(z)
# Para o modelo combinado só vamos treinar o gerador
self.discriminator.trainable = Falso
# O válido toma as imagens geradas como entrada e determina a validade
válido = self.discriminator(img)
# O modelo combinado (gerador empilhado e discriminador) leva
# ruído como entrada => gera imagens => determina a validade
self.combined = Modelo(z, válido)
self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)
def build_generator(self):
noise_shape = (100,)
modelo = Sequencial()
model.add(Dense(256, input_shape=noise_shape))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0,8))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0,8))
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0,8))
model.add(Dense(np.prod(self.img_shape), activation='tanh'))
model.add(Reshape(self.img_shape))
model.summary()
ruído = Input(shape=noise_shape)
img = modelo(ruído)
return Modelo(ruído, img)
def build_discriminator(self):
img_shape = (self.img_rows, self.img_cols, self.channels)
modelo = Sequencial()
model.add(Flatten(input_shape=img_shape))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(1, activation='sigmoid'))
model.summary()
img = Input(shape=img_shape)
validade = modelo(img)
return Modelo(img, validade)
def train(self, epochs, batch_size=128, save_interval=50):
# Carregar o conjunto de dados
(X_train, _), (_, _) = mnist.load_data()
# Escala -1 a 1
X_train = (X_train.astype(np.float32) - 127,5) / 127,5
X_train = np.expand_dims(X_train, eixo=3)
half_batch = int(batch_size / 2)
para a época em alcance (épocas):
# ---------------------
# Discriminador do trem
# ---------------------
# Seleccione um meio lote aleatório de imagens
idx = np.random.randint(0, X_train.shape[0], half_batch)
imgs = X_train[idx]
ruído = np.random.normal(0, 1, (meio_batch, 100))
# Gerar meio lote de novas imagens
gen_imgs = self.generator.predict(ruído)
# Treinar o discriminador
d_loss_real = self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1)))
d_loss_fake = self.discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# ---------------------
# Gerador de trens
# ---------------------
ruído = np.random.normal(0, 1, (tamanho_do_lote, 100))
# O gerador quer que o discriminador rotule as amostras geradas
# como válido (uns)
valid_y = np.array([1] * batch_size)
# Treinar o gerador
g_loss = self.combined.train_on_batch(noise, valid_y)
# Plotar o progresso
print ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (época, d_loss[0], 100*d_loss[1], g_loss))
# Se no intervalo de gravação => salvar as amostras de imagem geradas
if epoch % save_interval == 0:
self.save_imgs(epoch)
def save_imgs(self, epoch):
r, c = 5, 5
ruído = np.random.normal(0, 1, (r * c, 100))
gen_imgs = self.generator.predict(ruído)
# Imagens em Escala 0 - 1
gen_imgs = 0.5 * gen_imgs + 0.5
fig, axs = plt.subplots(r, c)
cnt = 0
para i no intervalo(r):
para j no intervalo(c):
axs[i,j].imshow(gen_imgs[cnt, :,:,0], cmap='gray')
axs[i,j].axis('off')
cnt += 1
fig.savefig("gan/images/mnist_%d.png" % epoch)
plt.close()
se __nome__ == '__main__':
gan = GAN()
gan.train(epochs=30000, batch_size=32, save_interval=200)