为什么我已经定义了参数,这个模型还需要先调用'build()'?

Why did this model still need calling 'build()' firstly when I have defined parameters?

我定义了一个图像,img_shape,在这个模型之前它的形状是(28,28,1),

def make_discriminator(img_shape):
    return keras.Sequential([
        keras.layers.Dropout(0.3),
        keras.layers.Conv2D(32, 5, strides = 2, 
                            padding='same',
                            input_shape = img_shape,
                            use_bias = False),
        keras.layers.BatchNormalization(),
        keras.layers.LeakyReLU(),
        keras.layers.Conv2D(64, 5, strides = 2,
                            padding = 'same',
                            use_bias = False),
        keras.layers.BatchNormalization(),
        keras.layers.LeakyReLU(),
        keras.layers.Flatten(),
        keras.layers.Dense(1)
    ], "Discriminator")

然后我尝试直接将它作为输入并打印这个模型的结构,

D = make_discriminator(img_shape = img_shape)
print(D.summary())

但是,它显示

This model has not yet been built. Build the model first by calling build() or by calling the model on a batch of data.

但是当我尝试在摘要之前添加 build() 时,

D = make_discriminator(img_shape = img_shape)

显示

build() got an unexpected keyword argument 'img_shape'

我不知道如何解决这个问题...创建图像的过程如下,

import keras
import tensorflow as tf
import tensorflow_datasets as tfds

fmist = tfds.load('fashion_mnist')
def process(data):
    img = tf.cast(data['image'], tf.float32)
    lab = data['label']
    img = (img / 255.0 - 0.5) * 2.0
    return img

BATCH_SIZE = 256
train = fmist['train'].shuffle(10000).batch(BATCH_SIZE).\
    map(process).prefetch(tf.data.experimental.AUTOTUNE)
img_shape = tf.data.experimental.get_structure(train).shape[1:]
print("image shape:", img_shape)

尝试 discriminator.build(input_shape=(1, 28, 28, 1)):

def make_discriminator(img_shape):
    return tf.keras.Sequential([
        tf.keras.layers.Dropout(0.3),
        tf.keras.layers.Conv2D(32, 5, strides = 2, 
                            padding='same',
                            input_shape = img_shape,
                            use_bias = False),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.LeakyReLU(),
        tf.keras.layers.Conv2D(64, 5, strides = 2,
                            padding = 'same',
                            use_bias = False),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.LeakyReLU(),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(1)
    ], "Discriminator")

discriminator = make_discriminator((28, 28, 1))
discriminator.build(input_shape=(1, 28, 28, 1))
print(discriminator.summary())

或者在模型的层中设置input_shape。然后,将推断剩余的输出形状,您不必调用 model.build():

def make_discriminator(img_shape):
    return tf.keras.Sequential([
        tf.keras.layers.Dropout(0.3, input_shape = img_shape),
        tf.keras.layers.Conv2D(32, 5, strides = 2, 
                            padding='same',
                            use_bias = False),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.LeakyReLU(),
        tf.keras.layers.Conv2D(64, 5, strides = 2,
                            padding = 'same',
                            use_bias = False),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.LeakyReLU(),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(1)
    ], "Discriminator")

discriminator = make_discriminator((28, 28, 1))
print(discriminator.summary())