Методы без аргументов но с аргументами? Python

Есть метод без аргументов, который возвращает нам тензор размерностью (None, 28, 28, 1)

def make_generator_model():
    model = keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100, )))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    assert model.output_shape == (None, 14, 14, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 28, 28, 1)

    return model

И вот так мы его используем

generator = make_generator_model()


noise = random.normal([1, 100])

И вот c этого момента- странно. Ведь generator = make_generator_model(), а этот метод не имеет аргументов! Или питон работает как то по другому?

generated_image = generator(noise, training=False)

Думал сначала что generator - это какой то встроенный метод, который имеет то же название. Но нет, смена названия переменной ничего не поменяла! А вот если без неё, напрямую в make_generator_model() передать аргументы, то оно не работает. Только через переприсвоение. Это какая то особенность питона или tensorflow или?..


Ответы (1 шт):

Автор решения: Potion

Все достаточно просто! Когда мы пишем

def make_generator_model():
    model = keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100, )))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    assert model.output_shape == (None, 14, 14, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 28, 28, 1)


  return model

То следует обращать внимание на две вещи внутри

Первое - то что внутри метода мы создаем новый экземпляр класса keras.Sequential() Вот в этом строчке

model = keras.Sequential()

А вот в этой строчке мы её возвращает в ответ на вызов метода make_generator_model()

 return model

И получается что в итоге

generator = keras.Sequential() 

А уже туда мы можем передавать аргументы

→ Ссылка