{
  "id": 98861,
  "title": "Need Help -- DCGAN with Tensorflow/Keras",
  "url": "/competitions/generative-dog-images/discussion/98861",
  "author_name": "",
  "post_date": "2019-07-07T04:30:03.364446800Z",
  "votes": 3,
  "comment_count": 29,
  "views": 0,
  "content": "<p>Hi,</p>\n\n<p>I am very new to GANs and kaggle competitions in general. I want to at least generate something that looks somewhat like a dog but all I get are similar pixelated pictures for every epoch. There is probably a lot missing from my code that I didn't do properly but if anyone could take a look at my kernel and start pointing me in the correct direction for some fixes that would helpful.</p>\n\n<p>I set it to 2 epoch so I can commit, but changing it to 50 will still give same results for the images.</p>\n\n<p>Thanks!</p>\n\n<p><a href=\"https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16836469\">my kernel</a></p>",
  "messages": [
    {
      "id": "569637",
      "postDate": "07/07/2019 04:30:03",
      "content": "<p>Hi,</p>\n\n<p>I am very new to GANs and kaggle competitions in general. I want to at least generate something that looks somewhat like a dog but all I get are similar pixelated pictures for every epoch. There is probably a lot missing from my code that I didn't do properly but if anyone could take a look at my kernel and start pointing me in the correct direction for some fixes that would helpful.</p>\n\n<p>I set it to 2 epoch so I can commit, but changing it to 50 will still give same results for the images.</p>\n\n<p>Thanks!</p>\n\n<p><a href=\"https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16836469\">my kernel</a></p>",
      "rawMarkdown": "Hi,\n\nI am very new to GANs and kaggle competitions in general. I want to at least generate something that looks somewhat like a dog but all I get are similar pixelated pictures for every epoch. There is probably a lot missing from my code that I didn't do properly but if anyone could take a look at my kernel and start pointing me in the correct direction for some fixes that would helpful.\n\nI set it to 2 epoch so I can commit, but changing it to 50 will still give same results for the images.\n\nThanks!\n\n[my kernel](https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16836469)",
      "votes": null
    },
    {
      "id": "569646",
      "postDate": "07/07/2019 05:09:11",
      "content": "<p>Did you try for 50 epochs ?</p>",
      "rawMarkdown": "Did you try for 50 epochs ?",
      "votes": null
    },
    {
      "id": "569653",
      "postDate": "07/07/2019 05:28:52",
      "content": "<p>Yeah I set it to 50 epochs, let it run but the images end up looking the same. </p>",
      "rawMarkdown": "Yeah I set it to 50 epochs, let it run but the images end up looking the same.",
      "votes": null
    },
    {
      "id": "569661",
      "postDate": "07/07/2019 05:47:33",
      "content": "<p>hi Chad ,</p>\n\n<p>I am also a newbee , but learning from the existing Kernels from experts </p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2234817%2F206941851c1e8bd7caa6a1e9566ddc3b%2Fdcgan.png?generation=1562478320280603&amp;alt=media\" alt=\"\"></p>\n\n<p>Please refer to this architecture for DCGAN and validate </p>\n\n<p>Normally  ReLU can be used in Generator .</p>\n\n<p>Please verifiy  the output activation for discriminator , can it be changed to sigmoid ?</p>",
      "rawMarkdown": "hi Chad ,\n\nI am also a newbee , but learning from the existing Kernels from experts \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2234817%2F206941851c1e8bd7caa6a1e9566ddc3b%2Fdcgan.png?generation=1562478320280603&amp;alt=media)\n\nPlease refer to this architecture for DCGAN and validate \n\nNormally  ReLU can be used in Generator .\n\nPlease verifiy  the output activation for discriminator , can it be changed to sigmoid ?",
      "votes": null
    },
    {
      "id": "569676",
      "postDate": "07/07/2019 06:20:22",
      "content": "<p>I tried both activations, sigmoid and tanh but same results. I believe the functions are just inverses (9 for sigmoid gives 1 for tanh and vice versa). </p>\n\n<p>The actual networks I followed closely to <a href=\"/jesucristo\">@jesucristo</a>  's kernal but I feel the problem lies with my training loop. </p>\n\n<p>I just tried training now and I get this error after 14 epoch: </p>\n\n<p>ResourceExhaustedError: OOM when allocating tensor with shape[64,32,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:FusedBatchNormGrad]</p>",
      "rawMarkdown": "I tried both activations, sigmoid and tanh but same results. I believe the functions are just inverses (9 for sigmoid gives 1 for tanh and vice versa). \n\nThe actual networks I followed closely to @jesucristo  's kernal but I feel the problem lies with my training loop. \n\nI just tried training now and I get this error after 14 epoch: \n\nResourceExhaustedError: OOM when allocating tensor with shape[64,32,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:FusedBatchNormGrad]",
      "votes": null
    },
    {
      "id": "569688",
      "postDate": "07/07/2019 06:56:03",
      "content": "<p>I forked your kernel and trying to do modification and run. \nI will get back if I am able to crack . I also follow Nanashi kernels.\nIf you find a solution before me ,please let me know .</p>",
      "rawMarkdown": "I forked your kernel and trying to do modification and run. \nI will get back if I am able to crack . I also follow Nanashi kernels.\nIf you find a solution before me ,please let me know .",
      "votes": null
    },
    {
      "id": "569696",
      "postDate": "07/07/2019 07:19:53",
      "content": "<p>Thank you Nirjhar and yes I will let you know</p>",
      "rawMarkdown": "Thank you Nirjhar and yes I will let you know",
      "votes": null
    },
    {
      "id": "569825",
      "postDate": "07/07/2019 12:10:52",
      "content": "<p>Hi Chad, my first observation is that your generated images take on pixel values between -1 and 1 because your Generator outputs with <code>tanh</code> and the original images are normalized as <code>image /= 255.0</code> which take on pixel values between 0 and 1. Therefore the job of your Discriminator is too easy. Your Discriminator will simply say <code>If I see a pixel less than 0 then it is fake</code>. Try normalizing your images to <code>image = (image - 127.5) / 127.5</code> like the TensorFlow tutorial <a href=\"https://www.tensorflow.org/beta/tutorials/generative/dcgan\">here</a>. (Then change your image shows to <code>plt.imshow((images[image]+1.)/2.)</code> )</p>\n\n<p>Next, the TensorFlow tutorial has the Discriminator output with a <code>linear</code> neuron. When they write <code>model.add(layers.Dense(1))</code>. The absence of an activation causes the neuron to have a <code>linear</code> neuron. This lets your Discriminator output any negative and positive value. I suspect this helps the cost function have better derivatives. Try changing the last line of your Discriminator to <code>tf.keras.layers.Dense(1, activation='linear')</code></p>",
      "rawMarkdown": "Hi Chad, my first observation is that your generated images take on pixel values between -1 and 1 because your Generator outputs with `tanh` and the original images are normalized as `image /= 255.0` which take on pixel values between 0 and 1. Therefore the job of your Discriminator is too easy. Your Discriminator will simply say `If I see a pixel less than 0 then it is fake`. Try normalizing your images to `image = (image - 127.5) / 127.5` like the TensorFlow tutorial [here][1]. (Then change your image shows to `plt.imshow((images[image]+1.)/2.)` )\n\nNext, the TensorFlow tutorial has the Discriminator output with a `linear` neuron. When they write `    model.add(layers.Dense(1))`. The absence of an activation causes the neuron to have a `linear` neuron. This lets your Discriminator output any negative and positive value. I suspect this helps the cost function have better derivatives. Try changing the last line of your Discriminator to `tf.keras.layers.Dense(1, activation='linear')`\n\n[1]: https://www.tensorflow.org/beta/tutorials/generative/dcgan",
      "votes": null
    },
    {
      "id": "570011",
      "postDate": "07/07/2019 16:51:32",
      "content": "<p>The reason that your Discriminator should output linear is because your loss is defined as <code>cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)</code>. The parameter <code>from_logits=True</code> expects the Discriminator output to be all real numbers (it expects logits instead of probs) instead of  just the limited numbers from a sigmoid or tanh.</p>\n\n<p>(Perhaps if you set <code>from_logits=False</code> you can use a sigmoid output to your Discriminator).</p>",
      "rawMarkdown": "The reason that your Discriminator should output linear is because your loss is defined as `cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)`. The parameter `from_logits=True` expects the Discriminator output to be all real numbers (it expects logits instead of probs) instead of  just the limited numbers from a sigmoid or tanh.\n\n(Perhaps if you set `from_logits=False` you can use a sigmoid output to your Discriminator).",
      "votes": null
    },
    {
      "id": "570025",
      "postDate": "07/07/2019 17:27:32",
      "content": "<p>Hi Chris, </p>\n\n<p>Thanks for the help so far. I changed the normalization but I am wondering why 127.5 and not 255.0? I will try using linear activation but if it doesn't improve will change to sigmoid the way you said. </p>\n\n<p>Also I think I didn't batch my dataset correctly so I'm getting the ResourceExhausted. I will debug that and see if anything changes. </p>",
      "rawMarkdown": "Hi Chris, \n\nThanks for the help so far. I changed the normalization but I am wondering why 127.5 and not 255.0? I will try using linear activation but if it doesn't improve will change to sigmoid the way you said. \n\nAlso I think I didn't batch my dataset correctly so I'm getting the ResourceExhausted. I will debug that and see if anything changes.",
      "votes": null
    },
    {
      "id": "570034",
      "postDate": "07/07/2019 17:36:31",
      "content": "<p>The original images have pixel values of <code>0, 1, 2, ..., 253, 254, 255</code>. After applying the formula <code>image = (image - 127.5) / 127.5</code>, the values approximately become <code>-1.0, -0.99, -0.98,... 0.98, 0.99, 1.0</code>. So that formula maps the values from [0,255] to [-1,1]. And <code>tanh</code> outputs values from [-1,1]. Therefore the original images and the generator images will be using the same pixel values.</p>\n\n<p>I've been messing with your code. I've gotten it to make blobs of color in various shapes but I haven't got the dog faces to show up yet. I'm currently working with a slightly simpler generator and discriminator architecture.</p>",
      "rawMarkdown": "The original images have pixel values of `0, 1, 2, ..., 253, 254, 255`. After applying the formula `image = (image - 127.5) / 127.5`, the values approximately become `-1.0, -0.99, -0.98,... 0.98, 0.99, 1.0`. So that formula maps the values from [0,255] to [-1,1]. And `tanh` outputs values from [-1,1]. Therefore the original images and the generator images will be using the same pixel values.\n\nI've been messing with your code. I've gotten it to make blobs of color in various shapes but I haven't got the dog faces to show up yet. I'm currently working with a slightly simpler generator and discriminator architecture.",
      "votes": null
    },
    {
      "id": "570036",
      "postDate": "07/07/2019 17:42:33",
      "content": "<p>What changes did you make to the code and what epoch were you able to run?</p>",
      "rawMarkdown": "What changes did you make to the code and what epoch were you able to run?",
      "votes": null
    },
    {
      "id": "570047",
      "postDate": "07/07/2019 17:56:09",
      "content": "<p>I'm running 50 epochs. I'm not getting anything great yet, but it is better than blue and yellow dots/lines like you had. I'm getting blobs of yellow and blue shapes now. The two big changes are adding <code>image = (image - 127.5) / 127.5</code> in preprocessing and <code>activation='linear'</code> for Discriminator. </p>\n\n<p>Next I crop the images using the bounding boxes to just dogs and use <code>antialiasing</code> (from PIL package, can't find antialiasing in tf 1.13.1) to resize to 64x64. This makes it easier for the GAN to generalize. (I think). Next I'm using</p>\n\n<pre><code>def make_generator():\nmodel = tf.keras.Sequential()\nmodel.add(layers.Dense(4*4*512, use_bias=False, input_shape=(100,)))\nmodel.add(layers.Reshape((4, 4, 512)))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n\nreturn model\n</code></pre>\n\n<p>and </p>\n\n<pre><code>def make_discriminator():\nmodel = tf.keras.Sequential()\nmodel.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',\n                                 input_shape=[64, 64, 3]))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(256, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(512, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(1, activation='linear')) #output logits\n\nreturn model\n</code></pre>\n\n<p>It still needs more work to make anything resembling dogs. I removed the autotune. That was causing the kernel to error. Now I'm experimenting with adjusting batch_sizes, learning rates, adjusting ratio of D updates versus G updates,  and using a Gaussian seed instead of uniform, etc.</p>\n\n<p>I'm new to GANs myself, so I'm not sure exactly what needs to be changed so it learns to draw dogs from scratch quickly.</p>",
      "rawMarkdown": "I'm running 50 epochs. I'm not getting anything great yet, but it is better than blue and yellow dots/lines like you had. I'm getting blobs of yellow and blue shapes now. The two big changes are adding `image = (image - 127.5) / 127.5` in preprocessing and `activation='linear'` for Discriminator. \n\nNext I crop the images using the bounding boxes to just dogs and use `antialiasing` (from PIL package, can't find antialiasing in tf 1.13.1) to resize to 64x64. This makes it easier for the GAN to generalize. (I think). Next I'm using\n\n    def make_generator():\n    model = tf.keras.Sequential()\n    model.add(layers.Dense(4*4*512, use_bias=False, input_shape=(100,)))\n    model.add(layers.Reshape((4, 4, 512)))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    \n    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    \n    model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n\n    return model\n\n\nand \n\n    def make_discriminator():\n    model = tf.keras.Sequential()\n    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',\n                                     input_shape=[64, 64, 3]))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n\n    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n    \n    model.add(layers.Conv2D(256, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n    \n    model.add(layers.Conv2D(512, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n\n    model.add(layers.Flatten())\n    model.add(layers.Dense(1, activation='linear')) #output logits\n\n    return model\n\nIt still needs more work to make anything resembling dogs. I removed the autotune. That was causing the kernel to error. Now I'm experimenting with adjusting batch_sizes, learning rates, adjusting ratio of D updates versus G updates,  and using a Gaussian seed instead of uniform, etc.\n\nI'm new to GANs myself, so I'm not sure exactly what needs to be changed so it learns to draw dogs from scratch quickly.",
      "votes": null
    },
    {
      "id": "570186",
      "postDate": "07/08/2019 01:05:10",
      "content": "<p>I've made more progress. The autotune is causing your kernel to crash <code>ds = ds.prefetch(buffer_size=AUTOTUNE)</code>. Next, your kernel only plots the Red layer of an image with <code>plt.imshow( (generated_image[0, :, :, 0]+1.)/2. )</code> and this causes matplotlib to display a blue yellow map. You need to turn that last 0 into a colon as <code>plt.imshow( (generated_image[0, :, :, :]+1.)/2. )</code> then you will see RGB images. Finally you should plot the <code>disc_loss</code> and <code>gen_loss</code> and make sure they stay equal all the time (by adjusting learning rates). I've found that setting the Generator's Adam optimizer stronger helps keep the two in sync.</p>",
      "rawMarkdown": "I've made more progress. The autotune is causing your kernel to crash `ds = ds.prefetch(buffer_size=AUTOTUNE)`. Next, your kernel only plots the Red layer of an image with `plt.imshow( (generated_image[0, :, :, 0]+1.)/2. )` and this causes matplotlib to display a blue yellow map. You need to turn that last 0 into a colon as `plt.imshow( (generated_image[0, :, :, :]+1.)/2. )` then you will see RGB images. Finally you should plot the `disc_loss` and `gen_loss` and make sure they stay equal all the time (by adjusting learning rates). I've found that setting the Generator's Adam optimizer stronger helps keep the two in sync.",
      "votes": null
    },
    {
      "id": "570213",
      "postDate": "07/08/2019 02:34:58",
      "content": "<p>Oh my, wow thank you so much for your help Chris. </p>\n\n<p>I am currently changing my code to use your bounding code from your <a href=\"https://www.kaggle.com/cdeotte/supervised-generative-dog-net\">kernel</a> . Will make the other changes as well and let you know what has changed. </p>\n\n<p>Thank you again, really helpful and motivated me to not to give up on my first competition. </p>",
      "rawMarkdown": "Oh my, wow thank you so much for your help Chris. \n\nI am currently changing my code to use your bounding code from your [kernel](https://www.kaggle.com/cdeotte/supervised-generative-dog-net) . Will make the other changes as well and let you know what has changed. \n\nThank you again, really helpful and motivated me to not to give up on my first competition.",
      "votes": null
    },
    {
      "id": "570246",
      "postDate": "07/08/2019 03:44:54",
      "content": "<p>Here it is after 50 epochs (31000 batches) (1 hour run). In addition to what we discussed above, I added all the GAN hacks from <a href=\"https://www.kaggle.com/c/generative-dog-images/discussion/98595\">here</a>. I'll post images after 9 hours of running tomorrow. \n<img src=\"http://playagricola.com/Kaggle/dogs3.png\" alt=\"image\">\n(Each epoch is approx 625 batches of size 32. The 50th epoch has <code>mean gen_loss = 1.39</code> and <code>std gen_loss = 0.553</code> per batch. And <code>mean disc_loss = 0.98</code> and <code>std disc_loss = 0.208</code> per batch).</p>",
      "rawMarkdown": "Here it is after 50 epochs (31000 batches) (1 hour run). In addition to what we discussed above, I added all the GAN hacks from [here][1]. I'll post images after 9 hours of running tomorrow. \n![image](http://playagricola.com/Kaggle/dogs3.png)\n(Each epoch is approx 625 batches of size 32. The 50th epoch has `mean gen_loss = 1.39` and `std gen_loss = 0.553` per batch. And `mean disc_loss = 0.98` and `std disc_loss = 0.208` per batch).\n\n[1]: https://www.kaggle.com/c/generative-dog-images/discussion/98595",
      "votes": null
    },
    {
      "id": "570257",
      "postDate": "07/08/2019 04:08:23",
      "content": "<p>Hey Chris , so I have removed the line for prefetching but I am still getting the resource exhausted error.</p>\n\n<p>'OOM when allocating tensor with shape[64,64,64,64]'</p>\n\n<p>That was after 10 epoch, now I am getting shapes so that's good. Is there anything I have configure for the kaggle kernel to manage resources?</p>\n\n<p>This is my updated <a href=\"https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16877018\">kernel</a></p>",
      "rawMarkdown": "Hey Chris , so I have removed the line for prefetching but I am still getting the resource exhausted error.\n\n'OOM when allocating tensor with shape[64,64,64,64]'\n\nThat was after 10 epoch, now I am getting shapes so that's good. Is there anything I have configure for the kaggle kernel to manage resources?\n\nThis is my updated [kernel](https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16877018)",
      "votes": null
    },
    {
      "id": "570552",
      "postDate": "07/08/2019 12:50:30",
      "content": "<p>I'm not sure. Let me think. One thing I noticed is that you are including some blank images. After using my dog crop code only the first <code>idxIn</code> elements are images so you should use <code>imagesIn = tf.cast(imagesIn[:idxIn,:,:,:], 'float32')</code>. </p>\n\n<p>It's exciting that you're getting shapes, that's a great improvement.</p>",
      "rawMarkdown": "I'm not sure. Let me think. One thing I noticed is that you are including some blank images. After using my dog crop code only the first `idxIn` elements are images so you should use `imagesIn = tf.cast(imagesIn[:idxIn,:,:,:], 'float32')`. \n\nIt's exciting that you're getting shapes, that's a great improvement.",
      "votes": null
    },
    {
      "id": "570568",
      "postDate": "07/08/2019 13:24:02",
      "content": "<p>I have a feeling it is because of <code>tf.enable_eager_execution()</code>. If I don't enable eager execution then when it gets to the code block for</p>\n\n<p><code>imagesIn = tf.cast(imagesIn[:idxIn, : , : , :], 'float32')</code>or \n<code>ds = tf.data.Dataset.from_tensor_slices(imagesIn).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)</code>\nI get the error <code>ValueError: Cannot create a tensor proto whose content is larger than 2GB.</code> . Is there workaround for this to cast and make batches from the <code>imagesIn</code> without using <code>tf.enable_eager_execution()</code>?</p>",
      "rawMarkdown": "I have a feeling it is because of `tf.enable_eager_execution() `. If I don't enable eager execution then when it gets to the code block for\n\n`imagesIn = tf.cast(imagesIn[:idxIn, : , : , :], 'float32')`or \n` ds = tf.data.Dataset.from_tensor_slices(imagesIn).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)`\nI get the error `ValueError: Cannot create a tensor proto whose content is larger than 2GB.` . Is there workaround for this to cast and make batches from the `imagesIn` without using `tf.enable_eager_execution()`?",
      "votes": null
    },
    {
      "id": "570573",
      "postDate": "07/08/2019 13:33:21",
      "content": "<p>Good question, let me experiment.</p>",
      "rawMarkdown": "Good question, let me experiment.",
      "votes": null
    },
    {
      "id": "570597",
      "postDate": "07/08/2019 14:16:34",
      "content": "<p>I found the problem. Inside your function <code>def train_step(images)</code>, you have the line <code>fake_pictures.append(generated_images)</code> which saves fake images to the global variable <code>fake_pictures</code>. Each epoch it saves 1GB of data to RAM. You need to remove or change that.</p>\n\n<p>If you remove the two instances of <code>display.clear_output(wait=True)</code> inside your <code>train()</code> function then images will get drawn to the screen (without overwriting each other) and you won't need to save them all to see them.</p>",
      "rawMarkdown": "I found the problem. Inside your function `def train_step(images)`, you have the line `fake_pictures.append(generated_images)` which saves fake images to the global variable `fake_pictures`. Each epoch it saves 1GB of data to RAM. You need to remove or change that.\n\nIf you remove the two instances of `display.clear_output(wait=True)` inside your `train()` function then images will get drawn to the screen (without overwriting each other) and you won't need to save them all to see them.",
      "votes": null
    },
    {
      "id": "570687",
      "postDate": "07/08/2019 16:32:02",
      "content": "<p>Ahh, okay I removed that line and running it now. By the way, did the 9 hour training finish for you?</p>",
      "rawMarkdown": "Ahh, okay I removed that line and running it now. By the way, did the 9 hour training finish for you?",
      "votes": null
    },
    {
      "id": "570705",
      "postDate": "07/08/2019 17:14:21",
      "content": "<p>Yes. I ran my code for 7 hours. It did 300 epochs (approx 200000 batches). Here's the output:\n<img src=\"http://playagricola.com/Kaggle/dogs7819.png\" alt=\"image\">\nThe means of <code>Gen_loss</code> and <code>Disc_loss</code> stayed near 1.0 the whole time, that's good. So I could probably train it longer if I can speed up the code (to finish under 9 hours).</p>",
      "rawMarkdown": "Yes. I ran my code for 7 hours. It did 300 epochs (approx 200000 batches). Here's the output:\n![image](http://playagricola.com/Kaggle/dogs7819.png)\nThe means of `Gen_loss` and `Disc_loss` stayed near 1.0 the whole time, that's good. So I could probably train it longer if I can speed up the code (to finish under 9 hours).",
      "votes": null
    },
    {
      "id": "570712",
      "postDate": "07/08/2019 17:21:57",
      "content": "<p>Great results! I am at 40 epoch now without any errors so that line was the culprit. Thanks very much for catching. Next I will apply the previously mentioned optimizations and from that the kernel you mentioned.  </p>",
      "rawMarkdown": "Great results! I am at 40 epoch now without any errors so that line was the culprit. Thanks very much for catching. Next I will apply the previously mentioned optimizations and from that the kernel you mentioned.",
      "votes": null
    },
    {
      "id": "570713",
      "postDate": "07/08/2019 17:24:01",
      "content": "<p><a href=\"/cdeotte\">@cdeotte</a> Did you use the same architecture as posted in the thread ? I read in some place to add dropout only to generator . I had some weird result in adding dropout in discriminator . </p>",
      "rawMarkdown": "cdeotte Did you use the same architecture as posted in the thread ? I read in some place to add dropout only to generator . I had some weird result in adding dropout in discriminator .",
      "votes": null
    },
    {
      "id": "570714",
      "postDate": "07/08/2019 17:25:58",
      "content": "<p>Yes, those pictures come from the above architectures. Currently my generator has no dropout. I also heard about the recommendation to add dropout to the generator both during training and image generation. I'll try that.</p>",
      "rawMarkdown": "Yes, those pictures come from the above architectures. Currently my generator has no dropout. I also heard about the recommendation to add dropout to the generator both during training and image generation. I'll try that.",
      "votes": null
    },
    {
      "id": "570717",
      "postDate": "07/08/2019 17:30:23",
      "content": "<p>I am currently running one with Dropout(0.5) in generator . Without Dropout it gave 100 FID . Lets see if it improves , or cracks ...</p>",
      "rawMarkdown": "I am currently running one with Dropout(0.5) in generator . Without Dropout it gave 100 FID . Lets see if it improves , or cracks ...",
      "votes": null
    },
    {
      "id": "571084",
      "postDate": "07/09/2019 06:25:59",
      "content": "<p>Which lr are you using on Generator and Discriminator?</p>",
      "rawMarkdown": "Which lr are you using on Generator and Discriminator?",
      "votes": null
    },
    {
      "id": "571103",
      "postDate": "07/09/2019 07:00:38",
      "content": "<p>Unfortunately it didnt give better results with dropout . But i am not completely discarding it . Might be few other reasons as well</p>",
      "rawMarkdown": "Unfortunately it didnt give better results with dropout . But i am not completely discarding it . Might be few other reasons as well",
      "votes": null
    },
    {
      "id": "571256",
      "postDate": "07/09/2019 11:40:55",
      "content": "<p>&gt; Which lr are you using on Generator and Discriminator?</p>\n\n<p>I'm using Adam with <code>lr=0.0002</code> and <code>beta1=0.5</code> in both G and D with smoothed positive and negative labels. This and other tricks are recommended from GAN hacks <a href=\"https://machinelearningmastery.com/how-to-code-generative-adversarial-network-hacks/\">here</a>. (And brought to my attention by Luca in <a href=\"https://www.kaggle.com/c/generative-dog-images/discussion/98595\">this</a> thread).</p>",
      "rawMarkdown": "&gt; Which lr are you using on Generator and Discriminator?\n\nI'm using Adam with `lr=0.0002` and `beta1=0.5` in both G and D with smoothed positive and negative labels. This and other tricks are recommended from GAN hacks [here][1]. (And brought to my attention by Luca in [this][2] thread).\n\n[1]: https://machinelearningmastery.com/how-to-code-generative-adversarial-network-hacks/\n[2]: https://www.kaggle.com/c/generative-dog-images/discussion/98595",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 569646,
      "author_name": "whizzkid",
      "author_url": "",
      "post_date": "07/07/2019 05:09:11",
      "content": "<p>Did you try for 50 epochs ?</p>",
      "votes": null,
      "replies": [
        {
          "id": 569653,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/07/2019 05:28:52",
          "content": "<p>Yeah I set it to 50 epochs, let it run but the images end up looking the same. </p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 569661,
      "author_name": "phoenix9032",
      "author_url": "",
      "post_date": "07/07/2019 05:47:33",
      "content": "<p>hi Chad ,</p>\n\n<p>I am also a newbee , but learning from the existing Kernels from experts </p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2234817%2F206941851c1e8bd7caa6a1e9566ddc3b%2Fdcgan.png?generation=1562478320280603&amp;alt=media\" alt=\"\"></p>\n\n<p>Please refer to this architecture for DCGAN and validate </p>\n\n<p>Normally  ReLU can be used in Generator .</p>\n\n<p>Please verifiy  the output activation for discriminator , can it be changed to sigmoid ?</p>",
      "votes": null,
      "replies": [
        {
          "id": 569676,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/07/2019 06:20:22",
          "content": "<p>I tried both activations, sigmoid and tanh but same results. I believe the functions are just inverses (9 for sigmoid gives 1 for tanh and vice versa). </p>\n\n<p>The actual networks I followed closely to <a href=\"/jesucristo\">@jesucristo</a>  's kernal but I feel the problem lies with my training loop. </p>\n\n<p>I just tried training now and I get this error after 14 epoch: </p>\n\n<p>ResourceExhaustedError: OOM when allocating tensor with shape[64,32,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:FusedBatchNormGrad]</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 569688,
          "author_name": "phoenix9032",
          "author_url": "",
          "post_date": "07/07/2019 06:56:03",
          "content": "<p>I forked your kernel and trying to do modification and run. \nI will get back if I am able to crack . I also follow Nanashi kernels.\nIf you find a solution before me ,please let me know .</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 569696,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/07/2019 07:19:53",
          "content": "<p>Thank you Nirjhar and yes I will let you know</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 569825,
      "author_name": "cdeotte",
      "author_url": "",
      "post_date": "07/07/2019 12:10:52",
      "content": "<p>Hi Chad, my first observation is that your generated images take on pixel values between -1 and 1 because your Generator outputs with <code>tanh</code> and the original images are normalized as <code>image /= 255.0</code> which take on pixel values between 0 and 1. Therefore the job of your Discriminator is too easy. Your Discriminator will simply say <code>If I see a pixel less than 0 then it is fake</code>. Try normalizing your images to <code>image = (image - 127.5) / 127.5</code> like the TensorFlow tutorial <a href=\"https://www.tensorflow.org/beta/tutorials/generative/dcgan\">here</a>. (Then change your image shows to <code>plt.imshow((images[image]+1.)/2.)</code> )</p>\n\n<p>Next, the TensorFlow tutorial has the Discriminator output with a <code>linear</code> neuron. When they write <code>model.add(layers.Dense(1))</code>. The absence of an activation causes the neuron to have a <code>linear</code> neuron. This lets your Discriminator output any negative and positive value. I suspect this helps the cost function have better derivatives. Try changing the last line of your Discriminator to <code>tf.keras.layers.Dense(1, activation='linear')</code></p>",
      "votes": null,
      "replies": [
        {
          "id": 570011,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/07/2019 16:51:32",
          "content": "<p>The reason that your Discriminator should output linear is because your loss is defined as <code>cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)</code>. The parameter <code>from_logits=True</code> expects the Discriminator output to be all real numbers (it expects logits instead of probs) instead of  just the limited numbers from a sigmoid or tanh.</p>\n\n<p>(Perhaps if you set <code>from_logits=False</code> you can use a sigmoid output to your Discriminator).</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570025,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/07/2019 17:27:32",
          "content": "<p>Hi Chris, </p>\n\n<p>Thanks for the help so far. I changed the normalization but I am wondering why 127.5 and not 255.0? I will try using linear activation but if it doesn't improve will change to sigmoid the way you said. </p>\n\n<p>Also I think I didn't batch my dataset correctly so I'm getting the ResourceExhausted. I will debug that and see if anything changes. </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570034,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/07/2019 17:36:31",
          "content": "<p>The original images have pixel values of <code>0, 1, 2, ..., 253, 254, 255</code>. After applying the formula <code>image = (image - 127.5) / 127.5</code>, the values approximately become <code>-1.0, -0.99, -0.98,... 0.98, 0.99, 1.0</code>. So that formula maps the values from [0,255] to [-1,1]. And <code>tanh</code> outputs values from [-1,1]. Therefore the original images and the generator images will be using the same pixel values.</p>\n\n<p>I've been messing with your code. I've gotten it to make blobs of color in various shapes but I haven't got the dog faces to show up yet. I'm currently working with a slightly simpler generator and discriminator architecture.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570036,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/07/2019 17:42:33",
          "content": "<p>What changes did you make to the code and what epoch were you able to run?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570047,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/07/2019 17:56:09",
          "content": "<p>I'm running 50 epochs. I'm not getting anything great yet, but it is better than blue and yellow dots/lines like you had. I'm getting blobs of yellow and blue shapes now. The two big changes are adding <code>image = (image - 127.5) / 127.5</code> in preprocessing and <code>activation='linear'</code> for Discriminator. </p>\n\n<p>Next I crop the images using the bounding boxes to just dogs and use <code>antialiasing</code> (from PIL package, can't find antialiasing in tf 1.13.1) to resize to 64x64. This makes it easier for the GAN to generalize. (I think). Next I'm using</p>\n\n<pre><code>def make_generator():\nmodel = tf.keras.Sequential()\nmodel.add(layers.Dense(4*4*512, use_bias=False, input_shape=(100,)))\nmodel.add(layers.Reshape((4, 4, 512)))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\n\nmodel.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n\nreturn model\n</code></pre>\n\n<p>and </p>\n\n<pre><code>def make_discriminator():\nmodel = tf.keras.Sequential()\nmodel.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',\n                                 input_shape=[64, 64, 3]))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(256, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Conv2D(512, (5, 5), strides=(2, 2), padding='same'))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.LeakyReLU())\nmodel.add(layers.Dropout(0.5))\n\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(1, activation='linear')) #output logits\n\nreturn model\n</code></pre>\n\n<p>It still needs more work to make anything resembling dogs. I removed the autotune. That was causing the kernel to error. Now I'm experimenting with adjusting batch_sizes, learning rates, adjusting ratio of D updates versus G updates,  and using a Gaussian seed instead of uniform, etc.</p>\n\n<p>I'm new to GANs myself, so I'm not sure exactly what needs to be changed so it learns to draw dogs from scratch quickly.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570186,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 01:05:10",
          "content": "<p>I've made more progress. The autotune is causing your kernel to crash <code>ds = ds.prefetch(buffer_size=AUTOTUNE)</code>. Next, your kernel only plots the Red layer of an image with <code>plt.imshow( (generated_image[0, :, :, 0]+1.)/2. )</code> and this causes matplotlib to display a blue yellow map. You need to turn that last 0 into a colon as <code>plt.imshow( (generated_image[0, :, :, :]+1.)/2. )</code> then you will see RGB images. Finally you should plot the <code>disc_loss</code> and <code>gen_loss</code> and make sure they stay equal all the time (by adjusting learning rates). I've found that setting the Generator's Adam optimizer stronger helps keep the two in sync.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570213,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/08/2019 02:34:58",
          "content": "<p>Oh my, wow thank you so much for your help Chris. </p>\n\n<p>I am currently changing my code to use your bounding code from your <a href=\"https://www.kaggle.com/cdeotte/supervised-generative-dog-net\">kernel</a> . Will make the other changes as well and let you know what has changed. </p>\n\n<p>Thank you again, really helpful and motivated me to not to give up on my first competition. </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570246,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 03:44:54",
          "content": "<p>Here it is after 50 epochs (31000 batches) (1 hour run). In addition to what we discussed above, I added all the GAN hacks from <a href=\"https://www.kaggle.com/c/generative-dog-images/discussion/98595\">here</a>. I'll post images after 9 hours of running tomorrow. \n<img src=\"http://playagricola.com/Kaggle/dogs3.png\" alt=\"image\">\n(Each epoch is approx 625 batches of size 32. The 50th epoch has <code>mean gen_loss = 1.39</code> and <code>std gen_loss = 0.553</code> per batch. And <code>mean disc_loss = 0.98</code> and <code>std disc_loss = 0.208</code> per batch).</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570257,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/08/2019 04:08:23",
          "content": "<p>Hey Chris , so I have removed the line for prefetching but I am still getting the resource exhausted error.</p>\n\n<p>'OOM when allocating tensor with shape[64,64,64,64]'</p>\n\n<p>That was after 10 epoch, now I am getting shapes so that's good. Is there anything I have configure for the kaggle kernel to manage resources?</p>\n\n<p>This is my updated <a href=\"https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16877018\">kernel</a></p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570552,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 12:50:30",
          "content": "<p>I'm not sure. Let me think. One thing I noticed is that you are including some blank images. After using my dog crop code only the first <code>idxIn</code> elements are images so you should use <code>imagesIn = tf.cast(imagesIn[:idxIn,:,:,:], 'float32')</code>. </p>\n\n<p>It's exciting that you're getting shapes, that's a great improvement.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570568,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/08/2019 13:24:02",
          "content": "<p>I have a feeling it is because of <code>tf.enable_eager_execution()</code>. If I don't enable eager execution then when it gets to the code block for</p>\n\n<p><code>imagesIn = tf.cast(imagesIn[:idxIn, : , : , :], 'float32')</code>or \n<code>ds = tf.data.Dataset.from_tensor_slices(imagesIn).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)</code>\nI get the error <code>ValueError: Cannot create a tensor proto whose content is larger than 2GB.</code> . Is there workaround for this to cast and make batches from the <code>imagesIn</code> without using <code>tf.enable_eager_execution()</code>?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570573,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 13:33:21",
          "content": "<p>Good question, let me experiment.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570597,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 14:16:34",
          "content": "<p>I found the problem. Inside your function <code>def train_step(images)</code>, you have the line <code>fake_pictures.append(generated_images)</code> which saves fake images to the global variable <code>fake_pictures</code>. Each epoch it saves 1GB of data to RAM. You need to remove or change that.</p>\n\n<p>If you remove the two instances of <code>display.clear_output(wait=True)</code> inside your <code>train()</code> function then images will get drawn to the screen (without overwriting each other) and you won't need to save them all to see them.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570687,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/08/2019 16:32:02",
          "content": "<p>Ahh, okay I removed that line and running it now. By the way, did the 9 hour training finish for you?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570705,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 17:14:21",
          "content": "<p>Yes. I ran my code for 7 hours. It did 300 epochs (approx 200000 batches). Here's the output:\n<img src=\"http://playagricola.com/Kaggle/dogs7819.png\" alt=\"image\">\nThe means of <code>Gen_loss</code> and <code>Disc_loss</code> stayed near 1.0 the whole time, that's good. So I could probably train it longer if I can speed up the code (to finish under 9 hours).</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570712,
          "author_name": "cmalla94",
          "author_url": "",
          "post_date": "07/08/2019 17:21:57",
          "content": "<p>Great results! I am at 40 epoch now without any errors so that line was the culprit. Thanks very much for catching. Next I will apply the previously mentioned optimizations and from that the kernel you mentioned.  </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570713,
          "author_name": "phoenix9032",
          "author_url": "",
          "post_date": "07/08/2019 17:24:01",
          "content": "<p><a href=\"/cdeotte\">@cdeotte</a> Did you use the same architecture as posted in the thread ? I read in some place to add dropout only to generator . I had some weird result in adding dropout in discriminator . </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570714,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/08/2019 17:25:58",
          "content": "<p>Yes, those pictures come from the above architectures. Currently my generator has no dropout. I also heard about the recommendation to add dropout to the generator both during training and image generation. I'll try that.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 570717,
          "author_name": "phoenix9032",
          "author_url": "",
          "post_date": "07/08/2019 17:30:23",
          "content": "<p>I am currently running one with Dropout(0.5) in generator . Without Dropout it gave 100 FID . Lets see if it improves , or cracks ...</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 571084,
          "author_name": "enric1296",
          "author_url": "",
          "post_date": "07/09/2019 06:25:59",
          "content": "<p>Which lr are you using on Generator and Discriminator?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 571103,
          "author_name": "phoenix9032",
          "author_url": "",
          "post_date": "07/09/2019 07:00:38",
          "content": "<p>Unfortunately it didnt give better results with dropout . But i am not completely discarding it . Might be few other reasons as well</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 571256,
          "author_name": "cdeotte",
          "author_url": "",
          "post_date": "07/09/2019 11:40:55",
          "content": "<p>&gt; Which lr are you using on Generator and Discriminator?</p>\n\n<p>I'm using Adam with <code>lr=0.0002</code> and <code>beta1=0.5</code> in both G and D with smoothed positive and negative labels. This and other tricks are recommended from GAN hacks <a href=\"https://machinelearningmastery.com/how-to-code-generative-adversarial-network-hacks/\">here</a>. (And brought to my attention by Luca in <a href=\"https://www.kaggle.com/c/generative-dog-images/discussion/98595\">this</a> thread).</p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "569637": "Hi,\n\nI am very new to GANs and kaggle competitions in general. I want to at least generate something that looks somewhat like a dog but all I get are similar pixelated pictures for every epoch. There is probably a lot missing from my code that I didn't do properly but if anyone could take a look at my kernel and start pointing me in the correct direction for some fixes that would helpful.\n\nI set it to 2 epoch so I can commit, but changing it to 50 will still give same results for the images.\n\nThanks!\n\n[my kernel](https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16836469)",
    "569646": "Did you try for 50 epochs ?",
    "569653": "Yeah I set it to 50 epochs, let it run but the images end up looking the same.",
    "569661": "hi Chad ,\n\nI am also a newbee , but learning from the existing Kernels from experts \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2234817%2F206941851c1e8bd7caa6a1e9566ddc3b%2Fdcgan.png?generation=1562478320280603&amp;alt=media)\n\nPlease refer to this architecture for DCGAN and validate \n\nNormally  ReLU can be used in Generator .\n\nPlease verifiy  the output activation for discriminator , can it be changed to sigmoid ?",
    "569676": "I tried both activations, sigmoid and tanh but same results. I believe the functions are just inverses (9 for sigmoid gives 1 for tanh and vice versa). \n\nThe actual networks I followed closely to @jesucristo  's kernal but I feel the problem lies with my training loop. \n\nI just tried training now and I get this error after 14 epoch: \n\nResourceExhaustedError: OOM when allocating tensor with shape[64,32,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:FusedBatchNormGrad]",
    "569688": "I forked your kernel and trying to do modification and run. \nI will get back if I am able to crack . I also follow Nanashi kernels.\nIf you find a solution before me ,please let me know .",
    "569696": "Thank you Nirjhar and yes I will let you know",
    "569825": "Hi Chad, my first observation is that your generated images take on pixel values between -1 and 1 because your Generator outputs with `tanh` and the original images are normalized as `image /= 255.0` which take on pixel values between 0 and 1. Therefore the job of your Discriminator is too easy. Your Discriminator will simply say `If I see a pixel less than 0 then it is fake`. Try normalizing your images to `image = (image - 127.5) / 127.5` like the TensorFlow tutorial [here][1]. (Then change your image shows to `plt.imshow((images[image]+1.)/2.)` )\n\nNext, the TensorFlow tutorial has the Discriminator output with a `linear` neuron. When they write `    model.add(layers.Dense(1))`. The absence of an activation causes the neuron to have a `linear` neuron. This lets your Discriminator output any negative and positive value. I suspect this helps the cost function have better derivatives. Try changing the last line of your Discriminator to `tf.keras.layers.Dense(1, activation='linear')`\n\n[1]: https://www.tensorflow.org/beta/tutorials/generative/dcgan",
    "570011": "The reason that your Discriminator should output linear is because your loss is defined as `cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)`. The parameter `from_logits=True` expects the Discriminator output to be all real numbers (it expects logits instead of probs) instead of  just the limited numbers from a sigmoid or tanh.\n\n(Perhaps if you set `from_logits=False` you can use a sigmoid output to your Discriminator).",
    "570025": "Hi Chris, \n\nThanks for the help so far. I changed the normalization but I am wondering why 127.5 and not 255.0? I will try using linear activation but if it doesn't improve will change to sigmoid the way you said. \n\nAlso I think I didn't batch my dataset correctly so I'm getting the ResourceExhausted. I will debug that and see if anything changes.",
    "570034": "The original images have pixel values of `0, 1, 2, ..., 253, 254, 255`. After applying the formula `image = (image - 127.5) / 127.5`, the values approximately become `-1.0, -0.99, -0.98,... 0.98, 0.99, 1.0`. So that formula maps the values from [0,255] to [-1,1]. And `tanh` outputs values from [-1,1]. Therefore the original images and the generator images will be using the same pixel values.\n\nI've been messing with your code. I've gotten it to make blobs of color in various shapes but I haven't got the dog faces to show up yet. I'm currently working with a slightly simpler generator and discriminator architecture.",
    "570036": "What changes did you make to the code and what epoch were you able to run?",
    "570047": "I'm running 50 epochs. I'm not getting anything great yet, but it is better than blue and yellow dots/lines like you had. I'm getting blobs of yellow and blue shapes now. The two big changes are adding `image = (image - 127.5) / 127.5` in preprocessing and `activation='linear'` for Discriminator. \n\nNext I crop the images using the bounding boxes to just dogs and use `antialiasing` (from PIL package, can't find antialiasing in tf 1.13.1) to resize to 64x64. This makes it easier for the GAN to generalize. (I think). Next I'm using\n\n    def make_generator():\n    model = tf.keras.Sequential()\n    model.add(layers.Dense(4*4*512, use_bias=False, input_shape=(100,)))\n    model.add(layers.Reshape((4, 4, 512)))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    \n    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    \n    model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n\n    return model\n\n\nand \n\n    def make_discriminator():\n    model = tf.keras.Sequential()\n    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',\n                                     input_shape=[64, 64, 3]))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n\n    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n    \n    model.add(layers.Conv2D(256, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n    \n    model.add(layers.Conv2D(512, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.5))\n\n    model.add(layers.Flatten())\n    model.add(layers.Dense(1, activation='linear')) #output logits\n\n    return model\n\nIt still needs more work to make anything resembling dogs. I removed the autotune. That was causing the kernel to error. Now I'm experimenting with adjusting batch_sizes, learning rates, adjusting ratio of D updates versus G updates,  and using a Gaussian seed instead of uniform, etc.\n\nI'm new to GANs myself, so I'm not sure exactly what needs to be changed so it learns to draw dogs from scratch quickly.",
    "570186": "I've made more progress. The autotune is causing your kernel to crash `ds = ds.prefetch(buffer_size=AUTOTUNE)`. Next, your kernel only plots the Red layer of an image with `plt.imshow( (generated_image[0, :, :, 0]+1.)/2. )` and this causes matplotlib to display a blue yellow map. You need to turn that last 0 into a colon as `plt.imshow( (generated_image[0, :, :, :]+1.)/2. )` then you will see RGB images. Finally you should plot the `disc_loss` and `gen_loss` and make sure they stay equal all the time (by adjusting learning rates). I've found that setting the Generator's Adam optimizer stronger helps keep the two in sync.",
    "570213": "Oh my, wow thank you so much for your help Chris. \n\nI am currently changing my code to use your bounding code from your [kernel](https://www.kaggle.com/cdeotte/supervised-generative-dog-net) . Will make the other changes as well and let you know what has changed. \n\nThank you again, really helpful and motivated me to not to give up on my first competition.",
    "570246": "Here it is after 50 epochs (31000 batches) (1 hour run). In addition to what we discussed above, I added all the GAN hacks from [here][1]. I'll post images after 9 hours of running tomorrow. \n![image](http://playagricola.com/Kaggle/dogs3.png)\n(Each epoch is approx 625 batches of size 32. The 50th epoch has `mean gen_loss = 1.39` and `std gen_loss = 0.553` per batch. And `mean disc_loss = 0.98` and `std disc_loss = 0.208` per batch).\n\n[1]: https://www.kaggle.com/c/generative-dog-images/discussion/98595",
    "570257": "Hey Chris , so I have removed the line for prefetching but I am still getting the resource exhausted error.\n\n'OOM when allocating tensor with shape[64,64,64,64]'\n\nThat was after 10 epoch, now I am getting shapes so that's good. Is there anything I have configure for the kaggle kernel to manage resources?\n\nThis is my updated [kernel](https://www.kaggle.com/cmalla94/dcgan-generating-dog-images-with-tensorflow?scriptVersionId=16877018)",
    "570552": "I'm not sure. Let me think. One thing I noticed is that you are including some blank images. After using my dog crop code only the first `idxIn` elements are images so you should use `imagesIn = tf.cast(imagesIn[:idxIn,:,:,:], 'float32')`. \n\nIt's exciting that you're getting shapes, that's a great improvement.",
    "570568": "I have a feeling it is because of `tf.enable_eager_execution() `. If I don't enable eager execution then when it gets to the code block for\n\n`imagesIn = tf.cast(imagesIn[:idxIn, : , : , :], 'float32')`or \n` ds = tf.data.Dataset.from_tensor_slices(imagesIn).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)`\nI get the error `ValueError: Cannot create a tensor proto whose content is larger than 2GB.` . Is there workaround for this to cast and make batches from the `imagesIn` without using `tf.enable_eager_execution()`?",
    "570573": "Good question, let me experiment.",
    "570597": "I found the problem. Inside your function `def train_step(images)`, you have the line `fake_pictures.append(generated_images)` which saves fake images to the global variable `fake_pictures`. Each epoch it saves 1GB of data to RAM. You need to remove or change that.\n\nIf you remove the two instances of `display.clear_output(wait=True)` inside your `train()` function then images will get drawn to the screen (without overwriting each other) and you won't need to save them all to see them.",
    "570687": "Ahh, okay I removed that line and running it now. By the way, did the 9 hour training finish for you?",
    "570705": "Yes. I ran my code for 7 hours. It did 300 epochs (approx 200000 batches). Here's the output:\n![image](http://playagricola.com/Kaggle/dogs7819.png)\nThe means of `Gen_loss` and `Disc_loss` stayed near 1.0 the whole time, that's good. So I could probably train it longer if I can speed up the code (to finish under 9 hours).",
    "570712": "Great results! I am at 40 epoch now without any errors so that line was the culprit. Thanks very much for catching. Next I will apply the previously mentioned optimizations and from that the kernel you mentioned.",
    "570713": "cdeotte Did you use the same architecture as posted in the thread ? I read in some place to add dropout only to generator . I had some weird result in adding dropout in discriminator .",
    "570714": "Yes, those pictures come from the above architectures. Currently my generator has no dropout. I also heard about the recommendation to add dropout to the generator both during training and image generation. I'll try that.",
    "570717": "I am currently running one with Dropout(0.5) in generator . Without Dropout it gave 100 FID . Lets see if it improves , or cracks ...",
    "571084": "Which lr are you using on Generator and Discriminator?",
    "571103": "Unfortunately it didnt give better results with dropout . But i am not completely discarding it . Might be few other reasons as well",
    "571256": "&gt; Which lr are you using on Generator and Discriminator?\n\nI'm using Adam with `lr=0.0002` and `beta1=0.5` in both G and D with smoothed positive and negative labels. This and other tricks are recommended from GAN hacks [here][1]. (And brought to my attention by Luca in [this][2] thread).\n\n[1]: https://machinelearningmastery.com/how-to-code-generative-adversarial-network-hacks/\n[2]: https://www.kaggle.com/c/generative-dog-images/discussion/98595"
  },
  "source": "meta"
}