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

Time:12-11

I have defined a image, img_shape , its shape is (28,28,1) before this model,

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")

Then I tried to directly use it as input and print the structure of this model,

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

However, it shows

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

But when I tried to add build() before summary,

D = make_discriminator(img_shape = img_shape)

it shows

build() got an unexpected keyword argument 'img_shape'

I dont know how to solve this problem...and the process of creating image is below,

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)

CodePudding user response:

Try 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())

Or set the input_shape in the first layer of your model. Then, the remaining output shapes will be inferred and you do not have to call 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())
  • Related