Какие числа go используются в моделях генераторов DCGAN для получения изображений большего размера - PullRequest
0 голосов
/ 04 августа 2020

Я действительно попытался проявить здесь должную осмотрительность, но я не могу найти много документации о том, почему выбраны определенные числа. Я также довольно не уверен в том, как свертки работают в генераторах (лучше разбираюсь в классификаторах), так что это не помогает моему делу. Я думаю, что мой вопрос должен быть довольно простым для некоторых опытных людей.

Возьмем, к примеру, учебник Google, класс Generator:

def make_generator_model():
    model = tf.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

Откуда 7x7x256? Я понимаю, что 7x7 кратно возможному размеру 28x28, так что это имеет некоторый смысл, но в чем суть 256? А затем в следующих слоях я замечаю узор, но я не уверен, как его переписать, чтобы он работал для совершенно другого размера изображения. Любая помощь или направление приветствуются. Спасибо!

РЕДАКТИРОВАТЬ: Благодаря полезному вводу я изменил свой ген на:

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

    model.add(layers.Reshape((8, 8, 256)))
    assert model.output_shape == (None, 8, 8, 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, 8, 8, 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, 16, 16, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

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

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

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

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

    return model

и дискриминатор:

def make_discriminator_model():
    model = tf.keras.Sequential()
    model.add(layers.Conv2D(8, (5, 5), strides=(2, 2), padding='same',
                                     input_shape=[IMAGE_DIM[0], IMAGE_DIM[1], IMAGE_DIM[2]]))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Conv2D(16, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Conv2D(32, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Conv2D(256, (5, 5), strides=(1, 1), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    print(model.output_shape)

    model.add(layers.Flatten())
    model.add(layers.Dense(1))
    #16384 65536
    return model

1 Ответ

1 голос
/ 05 августа 2020

Мне довольно сложно быстро подвести итоги. Но вот оно!

Модели в DCGANS

Архетип DCGAN, созданный Radford et al. 2015 использует две сверточные нейронные сети в качестве моделей дискриминатора и генератора.

Дискриминатор создает иерархическую структуру информации, которая извлекается из изображений с помощью сверток. Результаты сверток называются карты характеристик . Глубже в модели свертки выводят карты характеристик, которые представляют более абстрактные структуры на изображениях.

Эта идея важна для работы DCGAN и является причиной того, что вы видите закономерность в этих числах. Взгляните на модель дискриминатора в этом примере , чтобы увидеть это в действии.

Ваша модель

В только что связанном мной примере DCGAN генератор очень похож. к вашей модели. В упрощенном c смысле генератор DCGAN создает сэмплы из низкоразмерного пространства представлений, известного как скрытое пространство .

Вы можете видеть, что эта модель почти обратная сторона дискриминатора: изображение «построено» транспонированными свертками (опять же, проще говоря, транспонированные свертки - это свертки для построения изображений) из тензора меньшей размерности - вектора скрытого пространства.

число 256

Число 256, о котором вы спрашиваете, соответствует количеству карт функций, которые хранятся в генераторе, и это число уменьшается в зависимости от модели как

(7,7,256)
(7,7,128)
(14,14,64)
(28,28,1)

Думайте об этом как о 256 Карты объектов 7 на 7, затем 128 карт объектов 7 на 7 и т. Д. c. Параметр strides слоя Conv2DTranspose критичен. Если это число не равно единице, изображение на выходе этого слоя не того же размера, что и раньше. Последняя фигура в списке указана таким образом, потому что это образец, созданный генератором, а не набор карт функций, отсюда номер 1.

См. Здесь для хорошего объяснения шагов в свертки.

Переписывание для разных изображений

Если вы собираетесь использовать эту модель для изображений разного размера, вам нужно увеличить начальный малый тензор до правильных размеров изображения. Значения параметра шага в слоях вашей модели показывают, как числа, перечисленные выше, соотносятся друг с другом.

Параметр padding слоя Conv2DTranspose также имеет решающее значение. Установка его как same означает, что изображение имеет ядро ​​свертки для каждого пикселя в изображении ( см. Здесь некоторые отличные диаграммы, относящиеся к этому).

В модели генератора это очень обычно сохраняется padding=same для каждой свертки. По сути, это означает, что изображение остается того же размера от входа к выходу этого слоя.

Надеюсь, это некоторая полезная информация. По моему собственному опыту, тестирование небольших отклонений от проверенной и проверенной модели, как эта, работает хорошо. Операторы assert помогут вам убедиться, что каждый слой работает правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...