1-D DCGAN Error

username: fllci
cooked: <p>Hi all! I am trying to build a 1D DCGAN model but getting this error:</p>
<p>Expected 3-dimensional input for 3-dimensional weight [1024, 1, 4], but got 1-dimensional input of size [1] instead.</p>
<p>My training set is [262144,1]. I tried the unsqueeze methods. It did not work.<br>
My generator and discriminator:<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/4/8/486eb4997be54c3e2c10284013e0ce59944c96c2.png" data-download-href="https://discuss.pytorch.org/uploads/default/486eb4997be54c3e2c10284013e0ce59944c96c2" title="image"><img src="https://discuss.pytorch.org/uploads/default/original/3X/4/8/486eb4997be54c3e2c10284013e0ce59944c96c2.png" alt="image" data-base62-sha1="akLyV6cT0KMB4OGxIZaskaQfzfc" width="317" height="500" data-dominant-color="242D36"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">525×828 37.4 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
Not sure what is wrong. Thanks for any suggestions!</p>

username: ptrblck
cooked: <p>I don’t know where the error is exactly raised, but both models use a 1D (transposed) convolution, which expects an input in the shape <code>[batch_size, channels, seq_len]</code>.<br>
Based on your input it seems you are using <code>[batch_size=262144, channels=1]</code>, which is missing the temporal dimension so you might need to <code>unsqueeze</code> it.</p>
<p>If you get stuck, please post a minimal, executable code snippet by wrapping it into three backticks ```, which would make debugging easier.</p>

username: fllci
cooked: <p>Thank you for your response. I see your help all over the blog posts and you are doing awesome work! For the sake of better understanding, I drew the model here. I am not totally sure the correctness of this as this is my first time doing 1d conv:</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/1/0/10cbece4d92dc57329a088324c190df3134bfe65.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/10cbece4d92dc57329a088324c190df3134bfe65" title="20210917_094935"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/1/0/10cbece4d92dc57329a088324c190df3134bfe65_2_690x165.jpeg" alt="20210917_094935" data-base62-sha1="2oAxX10gWY3rs0GkLj7Y7mkCPzf" width="690" height="165" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/1/0/10cbece4d92dc57329a088324c190df3134bfe65_2_690x165.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/1/0/10cbece4d92dc57329a088324c190df3134bfe65_2_1035x247.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/1/0/10cbece4d92dc57329a088324c190df3134bfe65_2_1380x330.jpeg 2x" data-dominant-color="C3BEBC"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">20210917_094935</span><span class="informations">1920×461 61.1 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>So, when I unsqueeze my input:</p>
<blockquote>
<p>a11n=torch.unsqueeze(a11n, 1)</p>
</blockquote>
<p>I get this tensor:</p>
<blockquote>
<p>[262144,1,1]</p>
</blockquote>
<p>Then I think I get errors in the discriminator part.<br>
Here is the error I get:</p>
<blockquote>
<p>ValueError: x and y can be no greater than 2-D, but have shapes (512,) and torch.Size([512, 1, 1])</p>
</blockquote>
<p>I really did not understand this error. And also here is my code again:</p>
<blockquote>
<p>batch_size = 512<br>
nz = 100<br>
ngf = 512<br>
ndf = 512<br>
num_epochs = 512<br>
lr = 0.0002<br>
beta1 = 0.5<br>
ngpu = 1<br>
dataloader = torch.utils.data.DataLoader(a11n, batch_size=batch_size,<br>
shuffle=True, num_workers=workers)<br>
device = torch.device(“cuda:0” if (torch.cuda.is_available() and ngpu &gt; 0) else “cpu”)<br>
real_batch = next(iter(dataloader))</p>
<h1>custom weights initialization called on netG and netD</h1>
<p>def weights_init(m):<br>
classname = m.<strong>class</strong>.<strong>name</strong><br>
if classname.find(‘Conv’) != -1:<br>
nn.init.normal_(m.weight.data, 0.0, 0.02)<br>
elif classname.find(‘BatchNorm’) != -1:<br>
nn.init.normal_(m.weight.data, 1.0, 0.02)<br>
nn.init.constant_(m.bias.data, 0)</p>
<h1>Generator Code</h1>
<p>class Generator(nn.Module):<br>
def <strong>init</strong>(self, ngpu):<br>
super(Generator, self).<strong>init</strong>()<br>
self.ngpu = ngpu<br>
self.main = nn.Sequential(<br>
# input is (nz x 1 x 1)<br>
nn.ConvTranspose1d(nz, ngf * 16, 4, 1, 0, bias=False),<br>
nn.BatchNorm1d(ngf * 16),<br>
nn.ReLU(True),<br>
# state size. (ngf<em>16) x 4 x 1<br>
nn.ConvTranspose1d(ngf * 16, ngf * 8, 4, 2, 1, bias=False),<br>
nn.BatchNorm1d(ngf * 8),<br>
nn.ReLU(True),<br>
# state size. (ngf</em>8) x 8 x 1<br>
nn.ConvTranspose1d( ngf * 8, ngf * 4, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ngf * 4),<br>
nn.ReLU(True),<br>
# state size. (ngf<em>4) x 32 x 1<br>
nn.ConvTranspose1d(ngf * 4, ngf</em>2, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ngf<em>2),<br>
nn.ReLU(True),<br>
# state size. (ngf</em>2) x 128 x 1<br>
nn.ConvTranspose1d(ngf*2, ngf, 4, 4, 0, bias=False),<br>
nn.Tanh()<br>
# state size. (512) x 1 x 1<br>
)<br>
def forward(self, input):<br>
return self.main(input)</p>
<h1>Create the generator</h1>
<p>netG = Generator(ngpu).to(device)</p>
<h1>Apply the weights_init function to randomly initialize all weights</h1>
<h1>to mean=0, stdev=0.2.</h1>
<p>netG.apply(weights_init)</p>
<h1>Discriminator Code</h1>
<p>class Discriminator(nn.Module):<br>
def <strong>init</strong>(self, ngpu):<br>
super(Discriminator, self).<strong>init</strong>()<br>
self.ngpu = ngpu<br>
self.main = nn.Sequential(<br>
# input is (1) x 1 x 512<br>
nn.Conv1d(1, ndf<em>2, 4, 4, 0, bias=False),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>2) x 1 x 128<br>
nn.Conv1d(ndf<em>2, ndf * 4, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ndf * 4),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>4) x 1 x 32<br>
nn.Conv1d(ndf * 4, ndf * 8, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ndf * 8),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf<em>8) x 1 x 8<br>
nn.Conv1d(ndf * 8, ndf * 16, 4, 2, 1, bias=False),<br>
nn.BatchNorm1d(ndf * 16),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>16) x 1 x 4<br>
nn.Conv1d(ndf * 16, 1, 4, 1, 0, bias=False),<br>
nn.Sigmoid()<br>
# state size. 1 x 1 x 1<br>
)<br>
def forward(self, input):<br>
return self.main(input)</p>
</blockquote>

username: fllci
cooked: <p>If I don’t unsqueeze it but use the input as is</p>
<blockquote>
<p>[262144,1]</p>
</blockquote>
<p>Then I get this error:</p>
<blockquote>
<p>RuntimeError: Expected 3-dimensional input for 3-dimensional weight [1024, 1, 4], but got 1-dimensional input of size [1] instead</p>
</blockquote>
<p>I actually have [262144,1] tensor, how come it sees 1 dim instead, I don’t get it.</p>
<p>Thank you for your help again!</p>

username: fllci
cooked: <p>Additionally, I found the code in the training that causes the error:</p>
<blockquote>
<p>real_cpu = data[0].to(device)</p>
</blockquote>
<p>which the data[0] is only 1dim tensor but I get the error of 3-dim expected. However, this time, when I unsqueeze it in here:</p>
<blockquote>
<pre><code>def forward(self, input):
    input=torch.unsqueeze(input,2)
    return self.main(input)
</code></pre>
</blockquote>
<p>This time, I get the error:</p>
<blockquote>
<p>Dimension out of range (expected to be in the range of [-2, 1], but got 2)</p>
</blockquote>
<p>It is kind of confusing. It expects 3dimension but it does not allow me to be 3 dimensions, I don’t know why.<br>
Here is the full code below including discriminator and some steps of the training (sorry for the three response):</p>
<blockquote>
<h1>Discriminator Code</h1>
<p>class Discriminator(nn.Module):<br>
def <strong>init</strong>(self, ngpu):<br>
super(Discriminator, self).<strong>init</strong>()<br>
self.ngpu = ngpu<br>
self.main = nn.Sequential(<br>
# input is (1) x 1 x 512<br>
nn.Conv1d(1, ndf<em>2, 4, 4, 0, bias=False),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>2) x 1 x 128<br>
nn.Conv1d(ndf<em>2, ndf * 4, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ndf * 4),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>4) x 1 x 32<br>
nn.Conv1d(ndf * 4, ndf * 8, 4, 4, 0, bias=False),<br>
nn.BatchNorm1d(ndf * 8),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf<em>8) x 1 x 8<br>
nn.Conv1d(ndf * 8, ndf * 16, 4, 2, 1, bias=False),<br>
nn.BatchNorm1d(ndf * 16),<br>
nn.LeakyReLU(0.2, inplace=True),<br>
# state size. (ndf</em>16) x 1 x 4<br>
nn.Conv1d(ndf * 16, 1, 4, 1, 0, bias=False),<br>
nn.Sigmoid()<br>
# state size. 1 x 1 x 1<br>
)<br>
def forward(self, input):<br>
input=torch.unsqueeze(input,2)<br>
return self.main(input)</p>
<h1>Create the Discriminator</h1>
<p>netD = Discriminator(ngpu).to(device)</p>
<h1>Handle multi-gpu if desired</h1>
<p>if (device.type == ‘cuda’) and (ngpu &gt; 1):<br>
netD = nn.DataParallel(netD, list(range(ngpu)))</p>
<h1>Apply the weights_init function to randomly initialize all weights</h1>
<h1>to mean=0, stdev=0.2.</h1>
<p>netD.apply(weights_init)</p>
<h1>Initialize BCELoss function</h1>
<p>criterion = nn.BCELoss()</p>
<h1>Create batch of latent vectors that we will use to visualize</h1>
<h1>the progression of the generator</h1>
<p>fixed_noise = torch.randn(512, nz, 1, device=device)</p>
<h1>Establish convention for real and fake labels during training</h1>
<p>real_label = 1<br>
fake_label = 0</p>
<h1>Setup Adam optimizers for both G and D</h1>
<p>optimizerD = optim.Adam(netD.parameters(), lr=lr, betas=(beta1, 0.999))<br>
optimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))</p>
<h1>Training Loop</h1>
<h1>Lists to keep track of progress</h1>
<p>img_list = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
G_losses = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
D_losses = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
iters = 0<br>
print(“Starting Training Loop…”)</p>
<h1>For each epoch</h1>
<p>for epoch in range(num_epochs):<br>
# For each batch in the dataloader<br>
for i, data in enumerate(dataloader, 0):<br>
############################<br>
# (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))<br>
############################<br>
## Train with all-real batch<br>
netD.zero_grad()<br>
# Format batch<br>
real_cpu = data[0].to(device)<br>
b_size = real_cpu.size(0)<br>
label = torch.full((b_size,), real_label, dtype=torch.float, device=device)<br>
# Forward pass real batch through D<br>
output = netD(real_cpu).view(-1)<br>
.<br>
.<br>
.<br>
.<br>
.<br>
.<br>
.<br>
.</p>
</blockquote>

username: fllci
cooked: <p>OK. I fixed the error. I had to unsqueeze the tensor eventually but that was not the only problem. I actually tried the unsqueeze(input, 0) solution before but it still did not work because one of the thing in the train part was set it wrong which was this:</p>
<blockquote>
<pre><code>    real_cpu = data[0].to(device=device, dtype=torch.float)
</code></pre>
</blockquote>
<p>This is set to [0]. After I removed the [0] and unsqueeze the batch, the model worked!</p>