How do I solve tensor mismatch if I want to use F1 score as a metric in pytorch?

HarshRangwala: <p>I am attempting to build a convulational neural network from scratch for object recognition. My input image size is (3, 256, 256)</p>
<p>Here’s my architecture for CNN.</p>
<pre><code class="lang-auto">class NutSnackClassication(MultiLabelImageClassificationBase):
    def __init__(self):
        super().__init__()
        
        self.network = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size = 3, stride = 1, padding = 1),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            nn.Conv2d(32, 32, kernel_size = 3, stride = 1, padding = 1),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            
            nn.Conv2d(32, 64, kernel_size = 3, stride = 1, padding = 1),
            nn.ReLU(),
            nn.Conv2d(64, 128, kernel_size = 3, stride = 1, padding = 1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2),
            nn.Conv2d(128, 256, kernel_size = 3, stride = 1, padding = 1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size = 3, stride = 1, padding = 1), 
            nn.ReLU(),
            nn.MaxPool2d(2, 2),
            
            nn.Flatten(),
            nn.Linear(7*7*256, 512),
            nn.ReLU(),
            nn.Linear(512, 258),
            nn.LogSoftmax(dim = 1),
        )
    
    def forward(self, xb):
        return self.network(xb)
</code></pre>
<p>I have to use Weighted accuracy of all classes so I chose to use F1 Score as metric to evaluate my models performance.</p>
<pre><code class="lang-auto">def F_score(output, label, threshold=0.5, beta=1):
    prob = output &gt; threshold
    label = label &gt; threshold
    print(prob.shape, "---", label.shape)
    TP = (prob &amp; label).sum(1).float()
    TN = ((~prob) &amp; (~label)).sum(1).float()
    FP = (prob &amp; (~label)).sum(1).float()
    FN = ((~prob) &amp; label).sum(1).float()

    precision = torch.mean(TP / (TP + FP + 1e-12))
    recall = torch.mean(TP / (TP + FN + 1e-12))
    F2 = (1 + beta**2) * precision * recall / (beta**2 * precision + recall + 1e-12)
    return F2.mean(0)
</code></pre>
<p>Specifically I am using this function below:</p>
<pre><code class="lang-auto">    # validation step
    def validation_step(self, batch):
        images, targets = batch
        out = self(images)
        loss = F.nll_loss(out, targets)
        score = F_score(out, targets)
        return {'val_loss': loss.detach(), 'val_score': score.detach() }
</code></pre>
<p>But when I execute this <code>evaluate(model, val_dl) </code> I get an error saying:</p>
<pre><code class="lang-auto">torch.Size([128, 258]) --- torch.Size([128])
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)


RuntimeError: The size of tensor a (258) must match the size of tensor b (128) at non-singleton dimension 1
</code></pre>
<p>I dont understand how to solve this. Is my <code>F1_Score()</code> rightly implemented? How do I approach a solution to this?</p>

ptrblck: <p>The issue is raised by the shape mismatch in:</p>
<pre><code class="lang-python">    print(prob.shape, "---", label.shape)
    TP = (prob &amp; label).sum(1).float()
</code></pre>
<p>as also seen in your print statements:</p>
<pre><code class="lang-python">torch.Size([128, 258]) --- torch.Size([128])
</code></pre>
<p>so you would have to make sure the tensors have the same shape or can be broadcasted, if needed.</p>

HarshRangwala: <p>Okay understood. Thank you!</p>