GAN 中的编译问题

compilation issue in GAN

我有以下用于实现 GAN 模型的简单代码

import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.layers import Dense ,Flatten,Reshape
from keras.layers.advanced_activations import LeakyReLU
from keras.models import Sequential
from keras.optimizers import Adam
img_rows =28
img_cols =28
channels =1
img_shape =(img_rows,img_cols,channels)
z_dim =100
def  Generator(img_shape,z_dim):
  model =Sequential()
  model.add(Dense(units=128,input_dim=z_dim))
  model.add(LeakyReLU(alpha=0.01))
  model.add(Dense(units=28*28*1,activation='tanh'))
  model.add(Reshape(img_shape))
  return model
def Discriminator(img_shape):
  model =Sequential()
  model.add(Flatten(input_shape=img_shape))
  model.add(Dense(units=128))
  model.add(LeakyReLU(alpha=0.01))
  model.add(Dense(units=1,activation='sigmoid'))
  return model
def build_gan(generator,discriminator):
  model =Sequential()
  model.add(generator)
  model.add(discriminator)
  return model
discriminator =Discriminator(img_shape)
discriminator.compile(loss='binary_crossentropy',optimizer=Adam(),metrics=['accuracy'])
generator =Generator(img_shape,z_dim)
discriminator.trainable = False
gan =build_gan(generator,discriminator)
gan.compile(loss='binary_crossentropy', optimizer=Adam())
losses =[]
accuracies =[]
iteration_checkpoints =[]
def train(iterations,batch_size,sample_interval):
  (X_train,_),(_,_) =mnist.load_data()
  X_train =X_train /127.5 -1.0 # [-1 1]
  X_train =np.expand_dims(X_train,axis=3)
  real =np.ones((batch_size,1))
  fake =np.ones((batch_size,1))
  for iteration in range(iterations):
    index =np.random.randint(0,X_train.shape[0],batch_size)
    real_images =X_train[index]
    z =np.random.normal(loc=0,scale=1,size=(batch_size,100))
    fake_images =generator.predict(z)
    d_loss_real =discriminator.train_on_batch(real_images,real)
    d_loss_fake =discriminator.train_on_batch(fake_images,fake)
    d_loss,accuracy =0.5*np.add(d_loss_real,d_loss_fake)
    z =np.random.normal(loc=0,scale=1,size=(batch_size,100))
    fake_images =generator.predict(z)
    g_loss =generator.train_on_batch(z,real)
    if (iteration + 1) % sample_interval == 0:
          losses.append((d_loss, g_loss))
          accuracies.append(100.0 * accuracy)
          iteration_checkpoints.append(iteration + 1)
    print('%d [D loss: %f, acc.: %.2f%%] [G loss: %f]' %(iteration + 1, d_loss, 100.0 * accuracy, g_loss))
def sample_images(generator, image_grid_rows=4, image_grid_columns=4):
  z = np.random.normal(loc=0, scale=1, size=(image_grid_rows * image_grid_columns, z_dim))
  gen_imgs = generator.predict(z)
  gen_imgs = 0.5 * gen_imgs + 0.5
  fig, axs = plt.subplots(image_grid_rows,image_grid_columns,figsize=(4, 4),sharey=True,sharex=True)
  cnt = 0
  for i in range(image_grid_rows):
    for j in range(image_grid_columns):
      axs[i, j].imshow(gen_imgs[cnt, :, :, 0], cmap='gray')
      axs[i, j].axis('off')
      cnt += 1
iterations = 20000
batch_size = 128
sample_interval = 1000
train(iterations, batch_size, sample_interval)

但是returns错误

RuntimeError: You must compile your model before training/testing. Use `model.compile(optimizer, loss)`.

哪个模型是未编译的?在GAN模型中编译判别器和编译生成器。

您已使用以下语句编译了鉴别器和 GAN 模型

discriminator.compile(loss='binary_crossentropy',optimizer=Adam(),metrics=['accuracy'])

gan.compile(loss='binary_crossentropy', optimizer=Adam())

分别,但是对于生成器模型你没有这样做;实际上,这是完整的错误跟踪:

---------------------------------------------------------------------------

RuntimeError                              Traceback (most recent call last)

<ipython-input-5-71e55f83d68c> in <module>()
      2 batch_size = 128
      3 sample_interval = 1000
----> 4 train(iterations, batch_size, sample_interval)

2 frames

<ipython-input-4-8ef6103457da> in train(iterations, batch_size, sample_interval)
     15     z =np.random.normal(loc=0,scale=1,size=(batch_size,100))
     16     fake_images =generator.predict(z)
---> 17     g_loss =generator.train_on_batch(z,real)
     18     if (iteration + 1) % sample_interval == 0:
     19           losses.append((d_loss, g_loss))

/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py in train_on_batch(self, x, y, sample_weight, class_weight, reset_metrics, return_dict)
   1716       ValueError: In case of invalid user-provided arguments.
   1717     """
-> 1718     self._assert_compile_was_called()
   1719     self._check_call_args('train_on_batch')
   1720     _disallow_inside_tf_function('train_on_batch')

/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py in _assert_compile_was_called(self)
   2590     # (i.e. whether the model is built and its inputs/outputs are set).
   2591     if not self._is_compiled:
-> 2592       raise RuntimeError('You must compile your model before '
   2593                          'training/testing. '
   2594                          'Use `model.compile(optimizer, loss)`.')

RuntimeError: You must compile your model before training/testing. Use `model.compile(optimizer, loss)`.

这清楚地表明问题出在命令上

g_loss =generator.train_on_batch(z,real)

在你的 train() 函数中,因为确实 generator 还没有被编译。

generator is compiled in GAN model

gan.compile() 适用于 gan 模型,单独调用时不适用于 generator 模型。