<p>I'm finding it quite hard to sum this up quickly. But here it goes!</p>
<h2>Models in DCGANS</h2>
<p>The DCGAN archetype by <a href="https://arxiv.org/abs/1511.06434" rel="nofollow noreferrer">Radford et al. 2015</a> uses two convolutional neural networks as the discriminator and generator models.</p>
<p>The discriminator develops a hierarchical structure of information that is distilled from images using convolutions. The results of convolutions are called <em>feature maps</em>. Deeper into the model, the convolutions derive feature maps that represent more abstract structures in the images.</p>
<p>This idea is essential to the function of the DCGAN, and is the reason you see the pattern in those numbers. Take a look at the discriminator model in <a href="https://www.tensorflow.org/tutorials/generative/dcgan" rel="nofollow noreferrer">this example</a> to see this in action.</p>
<h2>Your model</h2>
<p>In the DCGAN example I have just linked, the generator is very similar to your model. In a simplistic sense, a DCGAN generator creates samples from a lower-dimensional space of representations, known as the <em>latent space</em>.</p>
<p>You can be see how this model is almost the reverse of a discriminator: the image is 'built-up' by transposed convolutions (again, put simply, transposed convolutions are convolutions for building images up) from a lower-dimensional tensor - a latent space vector.</p>
<h2>The number 256</h2>
<p>The number 256 you are asking about corresponds to the number of feature maps that are stored by the generator and this number decreases through the model as</p>
<pre><code>(7,7,256)
(7,7,128)
(14,14,64)
(28,28,1)
</code></pre>
<p>Think of this as 256 7 by 7 feature maps, then 128 7 by 7 feature maps etc. The <code>strides</code> parameter of the <code>Conv2DTranspose</code> layer is critical. If this number is not equal to one, the image output of this layer is not the same size as before. The last shape listed is this way because it is a sample created by the generator, not a collection of feature maps, hence the number 1.</p>
<p><a href="https://stats.stackexchange.com/questions/360899/difference-between-strided-and-non-strided-convolution">See here</a> for a good explanation on strides in convolutions.</p>
<h2>Re-writing for different images</h2>
<p>If you are going to use this model for different size images, you need to up-size some initial small tensor to the correct image dimensions. The values of the stride parameter in the layers of your model show you how the numbers I listed above relate to each other.</p>
<p>The <code>padding</code> parameter of the <code>Conv2DTranspose</code> layer is critical too. Setting it as <code>same</code> means the image has a convolution kernel for each pixel in the image (<a href="https://arxiv.org/pdf/1603.07285.pdf" rel="nofollow noreferrer">see here</a> for some excellent diagrams relating to this).</p>
<p>In the generator model it is very common to keep <code>padding=same</code> for every convolution. Essentially this means the image stays the same size from input to output of that layer.</p>
<p>I hope this is some helpful information. In my own experience testing small deviations from a tried and tested model like this works well. The <code>assert</code> statements will help you make sure each layer works correctly.</p>
What numbers go into DCGAN Generator models, in order to produce larger images
<p>I really have tried to do my due diligence here but I can't find a lot of documentation on why certain numbers are chosen. I'm also fairly hazy on how convolutions work in generators (have a better understanding in terms of classifiers) so that's not helping my case. I think my question should be pretty simple to address for some more experiences folks out there though.</p>
<p>Take Google's tutorial for example, the Generator class:</p>
<pre><code>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
</code></pre>
<p>Where is 7x7x256 coming from? I understand that 7x7 is a multiple of the eventual 28x28 size, so that makes sense somewhat, but what is the 256 all about? And then in the following layers, I notice a pattern but I'm not sure how to re-write it so it works for a wholly different image size. Any help or direction is appreciated.Thanks!</p>
<p>EDIT:
Thanks to the helpful input I changed my gen to:</p>
<pre><code>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
</code></pre>
<p>and discriminator:</p>
<pre><code>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
</code></pre>