CNN channels error

CHAOWU: <p>Hi there,</p>
<p>I am new to deep learning and PyTorch and trying to build a simple CNN model to do a regression task on DNA sequence inputs.<br>
Here is my CNN model:</p>
<h1>
<a name="build-cnn-1" class="anchor" href="#build-cnn-1"></a>Build CNN</h1>
<p>class CNN(nn.Module):<br>
def <strong>init</strong>(self):<br>
super().<strong>init</strong>()<br>
self.CNN_conv_layer1 = nn.Conv2d(in_channels=8, out_channels=32, kernel_size=1, stride=2)<br>
<span class="hashtag">#self</span>.CNN_conv_layer2 = nn.Conv2d(16, 32, 1, 2)<br>
self.CNN_max_pool1 = nn.MaxPool2d(2, 2)</p>
<pre><code>self.CNN_conv_layer3 = nn.Conv2d(32, 64, 1, 2) 
#self.CNN_conv_layer4 = nn.Conv2d(64, 128, 1, 2)
#self.CNN_max_pool2 = nn.MaxPool2d(2, 2)

# flatten and batch normalization
#self.CNN_flatten = torch.flatten()
self.CNN_BatchNorm = nn.BatchNorm1d(525, momentum=0.5) #263-&gt;525

self.CNN_fc1 = nn.Linear(525, 1) #263-&gt;525
#self.CNN_relu1 = nn.ReLU()
self.CNN_relu1 = nn.LeakyReLU()
self.CNN_fc2 = nn.Linear(1,1)
</code></pre>
<p><span class="hashtag">#pass</span> data through CNN<br>
def forward(self, x):<br>
output = self.CNN_conv_layer1(x)<br>
<span class="hashtag">#output</span> = self.CNN_conv_layer2(output)<br>
output = self.CNN_max_pool1(output)</p>
<pre><code>output = self.CNN_conv_layer3(output)
#output = self.CNN_conv_layer4(output)
#output = self.CNN_max_pool2(output)

#output = output.reshape(#reshape size, how to define the size to be compatible with next net)

#output = self.CNN_flatten(output, 1)#
output = self.CNN_BatchNorm(output)
output = output.view(output.size(0), -1)
#print(output.size)
output = self.CNN_fc1(output)
output = self.CNN_relu1(output)
output = self.CNN_fc2(output)
return output
</code></pre>
<p>And here is my training loop:<br>
def train(net, dataloader, epochs=200, lr=0.0001, momentum=0.9, decay=0.0, verbose=1):<br>
‘’’ Trains a neural network. Returns a 2d numpy array, where every list<br>
represents the losses per epoch.<br>
‘’’<br>
losses_per_epoch = []<br>
criterion = nn.MSELoss()<br>
optimizer = optim.SGD(net.parameters(), lr=lr, weight_decay=decay)<br>
for epoch in range(epochs):<br>
<span class="hashtag">#print</span>(epoch)<br>
sum_loss = 0.0<br>
losses = []<br>
for i, data in enumerate(train_dataloader, 0):<br>
# get the inputs; data is a list of [inputs, labels]<br>
<span class="hashtag">#inputs</span>, labels = data[0].to(device), data[1].to(device)<br>
inputs, labels = data<br>
inputs, labels = inputs.to(device), labels.to(device)</p>
<pre><code>  # zero the parameter gradients
  optimizer.zero_grad()

  # forward + backward + optimize
  outputs = net(inputs)
  loss = criterion(outputs, labels)
  #loss = criterion(outputs, labels.float().unsqueeze(1))
  loss.backward()
  optimizer.step()

  # print statistics
  losses.append(loss.item())
  sum_loss += loss.item()
  if i % 100 == 99: # print every 100 mini-batches
    if verbose:
      print('[%d, %5d] train loss: %.3f' % (epoch + 1, i + 1, sum_loss / 20))
    sum_loss = 0.0
# print(len(losses))
losses_per_epoch.append(np.mean(losses))
</code></pre>
<p>return losses_per_epoch</p>
<p>train(net=net, dataloader=train_dataloader)<br>
print(f"Using {device} device")</p>
<h2>
<a name="i-got-a-continuous-error-usrlocallibpython37dist-packagestorchnnmoduleslosspy529-userwarning-using-a-target-size-torchsize8-that-is-different-to-the-input-size-torchsize64-1-this-will-likely-lead-to-incorrect-results-due-to-broadcasting-please-ensure-they-have-the-same-size-return-fmse_lossinput-target-reductionselfreduction-1-100-train-loss-57159-1-200-train-loss-57104-1-300-train-loss-56298-1-400-train-loss-61532-1-500-train-loss-59678-1-600-train-loss-57460-2" class="anchor" href="#i-got-a-continuous-error-usrlocallibpython37dist-packagestorchnnmoduleslosspy529-userwarning-using-a-target-size-torchsize8-that-is-different-to-the-input-size-torchsize64-1-this-will-likely-lead-to-incorrect-results-due-to-broadcasting-please-ensure-they-have-the-same-size-return-fmse_lossinput-target-reductionselfreduction-1-100-train-loss-57159-1-200-train-loss-57104-1-300-train-loss-56298-1-400-train-loss-61532-1-500-train-loss-59678-1-600-train-loss-57460-2"></a>I got a continuous error:<br>
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/loss.py:529: UserWarning: Using a target size (torch.Size([8])) that is different to the input size (torch.Size([64, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.<br>
return F.mse_loss(input, target, reduction=self.reduction)<br>
[1,   100] train loss: 57.159<br>
[1,   200] train loss: 57.104<br>
[1,   300] train loss: 56.298<br>
[1,   400] train loss: 61.532<br>
[1,   500] train loss: 59.678<br>
[1,   600] train loss: 57.460</h2>
<p>RuntimeError                              Traceback (most recent call last)<br>
 in ()<br>
37   return losses_per_epoch<br>
38<br>
—&gt; 39 train(net=net, dataloader=train_dataloader)<br>
40 print(f"Using {device} device")</p>
<p>5 frames<br>
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)<br>
442                             _pair(0), self.dilation, self.groups)<br>
443         return F.conv2d(input, weight, bias, self.stride,<br>
 → 444                         self.padding, self.dilation, self.groups)<br>
445<br>
446     def forward(self, input: Tensor) → Tensor:</p>
<p>RuntimeError: Given groups=1, weight of size [32, 8, 1, 1], expected input[1, 7, 4200, 4] to have 8 channels, but got 7 channels instead</p>
<p>When I change the input channels to 7, another error will be dropped as:<br>
RuntimeError: Given groups=1, weight of size [32, 7, 1, 1], expected input[1, 8, 4200, 4] to have 7 channels, but got 8 channels instead</p>
<p>I am totally confused and have no clues to fix it.<br>
May I ask if anyone can help me on this?<br>
Thank you!!!</p>
<p>Best regards,<br>
Chao</p>

ptrblck: <p>Could you check your dataset and make sure all samples have either 7 or 8 channels as it seems the number of channels is variable in your dataset?</p>
<p>Also, your current model definition won’t work as the <code>BatchNorm1d</code> layer will raise a dimension error and after fixing it to <code>BatchNorm2d</code> it’ll raise a shape mismatch error.</p>
<p>You can post code snippets by wrapping them into three backticks ```, which makes debugging easier.</p>

CHAOWU: <p>Dear ptrblck,</p>
<p>Thank you for the kind help.<br>
The input is each line of one hot encoded DNA sequence, the size of tensor is torch.Size([7393, 4200, 4]), which means I have 7393 lines of 4200 DNA bases which is encoded as [0, 0, 0,1] for example. 7 or 8 is changed with the change of batch size as 7 and 8, I have some trouble in understanding its correlation.<br>
And also, is it possible to remove the batchnorm layer if the regression performance is okay?</p>
<p>Best regards,<br>
Chao</p>

ptrblck: <p>Thanks for the followup.</p>
<aside class="quote no-group" data-username="CHAOWU" data-post="3" data-topic="152193">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/c/a4c791/48.png" class="avatar"> CHAOWU:</div>
<blockquote>
<p>7 or 8 is changed with the change of batch size as 7 and 8, I have some trouble in understanding its correlation.</p>
</blockquote>
</aside>
<p>Based on this description your input shape and model architecture are wrong.<br>
By default <code>nn.Conv2d</code> expects a 4-dimensional tensor in the shape <code>[batch_size, channels, height, width]</code>. In recent PyTorch version the batch dimension might be missing and PyTorch will then treat the input as a single sample.<br>
I have to admit that I’m not a huge fan of this behavior and prefer the explicit requirements regarding the shape etc. as this could yield confusing error messages and debugging as your use case shows.</p>
<p>Now look at this code snippet:</p>
<pre data-code-wrap="python"><code class="lang-python"># setup
conv = nn.Conv2d(in_channels=8, out_channels=32, kernel_size=1, stride=2)

# standard approach
x = torch.randn(1, 8, 24, 24)
out = conv(x) # works

# missing batch dimension
x = torch.randn(8, 24, 24)
out = conv(x) # works
print(out.shape)
# torch.Size([32, 12, 12])

x = torch.randn(7, 24, 24)
out = conv(x) # fails
# RuntimeError: Given groups=1, weight of size [32, 8, 1, 1], expected input[1, 7, 24, 24] to have 8 channels, but got 7 channels instead
</code></pre>
<p>Based on your description I guess you are also passing a 3-dimensional input tensor to the model with a shape of 7 or 8 in dim0.<br>
In this case this shape will be interpreted as the channel dimension not the batch dimension and will thus yield the error.</p>
<p>If you want to use 7/8 as the batch dimension, the <code>in_channels</code> of the first conv layer has to be changed as it specifies the input channels not the batch size.</p>
<p>Could you describe the input shape in more detail, i.e. how many dimensions and which shapes are used?</p>

CHAOWU: <p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/8/2/8262fac0992544646b90dd23545e1d66d994cb64.png" data-download-href="https://discuss.pytorch.org/uploads/default/8262fac0992544646b90dd23545e1d66d994cb64" title="螢幕截圖 2022-05-22 下午3.12.22"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/8/2/8262fac0992544646b90dd23545e1d66d994cb64_2_690x390.png" alt="螢幕截圖 2022-05-22 下午3.12.22" data-base62-sha1="iBs8ibd7N0Y7kuVAn8oGwcLX672" width="690" height="390" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/8/2/8262fac0992544646b90dd23545e1d66d994cb64_2_690x390.png, https://discuss.pytorch.org/uploads/default/original/3X/8/2/8262fac0992544646b90dd23545e1d66d994cb64.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/8/2/8262fac0992544646b90dd23545e1d66d994cb64.png 2x" data-dominant-color="CCCCCC"><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">螢幕截圖 2022-05-22 下午3.12.22</span><span class="informations">792×448 192 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>
Dear ptrblck,</p>
<p>Thank you for the informative demo.<br>
The input of model in my case is a sheet containing gene id, 4 DNA features and labels. Each DNA feature has different length, for example, 3000, 300, 300, and 600 bases, and each base has been transformed to one hot encoding, such as [0, 0, 0, 1], [0,0,1,0], [0,1,0,0] and [1, 0, 0, 0], all features are concatenated and transform to tensors after the one hot transformation. I have 7393 genes, so the shape of input may be (7393, 4200, 4). And the batch size is 8.</p>