DC GAN Modification — RGB to Grayscale

web_tracer: <p>The full code is available here — <a href="https://pytorch.org/tutorials/beginner/dcgan_faces_tutorial.html" class="inline-onebox" rel="noopener nofollow ugc">DCGAN Tutorial — PyTorch Tutorials 1.9.0+cu102 documentation</a></p>
<p>What is a proper way to modify the code above to adjust the model for a dataset that consists of black and white/grayscale images, not RGB?</p>
<p>This model is designed for processing 3-channel images (RGB) while I need to handle some black and white image data, so I’d like to change the “ch” parameter to “1” instead of “3.”</p>
<p>But if we just change this parameter — “nc = 3” → “nc = 1” — without adjusting generator’s and discriminator’s code blocks, executing just gives an error message:</p>
<pre><code class="lang-auto">RuntimeError: Given groups=1, weight of size [64, 1, 4, 4], expected input[128, 3, 64, 64] to have 1 channels, but got 3 channels instead
</code></pre>
<p>Please advise.</p>

ayalaa2: <p>Changing <code>nc--&gt;1</code> will result in a generator/discriminator capable of handling one channel (grayscale). However, you need to also adjust the dataloading/transforming step to convert the images into grayscale. That error suggests that this is not happening yet.</p>
<p>You can add a transform like this: <a href="https://pytorch.org/vision/stable/transforms.html#torchvision.transforms.Grayscale" class="inline-onebox" rel="noopener nofollow ugc">torchvision.transforms — Torchvision 0.10.0 documentation</a></p>

web_tracer: <p>Hi Alex,</p>
<p>Thanks for stepping in! Can you please shed some lite on what is the proper way of adjusting the dataloading/transforming phase step-by-step?</p>
<p>I’m afraid I’m a bit stuck here.</p>
<p>Thanks in advance.</p>

ayalaa2: <p>Sure, so the dataset object creation is the issue here:</p>
<pre><code class="lang-auto">dataset = dset.ImageFolder(root=dataroot,
                           transform=transforms.Compose([
                               transforms.Resize(image_size),
                               transforms.CenterCrop(image_size),
                               transforms.ToTensor(),
                               transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
                           ]))
</code></pre>
<p>Specifically, we’re interested in those transforms. Each datapoint starts off as a PIL image. The transforms suggest that each datapoint will:</p>
<ol>
<li>Get resized</li>
<li>Cropped</li>
<li>Turned into a tensor</li>
<li>Normalized. Here the first tuple denotes the mean for each channel and the second tuple denotes the std for each channel.</li>
</ol>
<p>We’ll need to do 2 things here. We need to add a transformation for grayscale and because we’ll only have one channel, we’ll go ahead and adjust that normalization step as well.</p>
<p>We’ll end up with something like this:</p>
<pre><code class="lang-auto">dataset = dset.ImageFolder(root=dataroot,
                           transform=transforms.Compose([
                               transforms.Resize(image_size),
                               transforms.CenterCrop(image_size),
                               transforms.Grayscale(num_output_channels=1),
                               transforms.ToTensor(),
                               transforms.Normalize(0.5, 0.5),
                           ]))
</code></pre>
<p>This dataset will now return tensors of channel size 1.</p>

web_tracer: <p>Thank you very much! It worked. <img src="https://discuss.pytorch.org/images/emoji/apple/+1.png?v=10" title=":+1:" class="emoji" alt=":+1:"></p>