Training resnet18 - output of resnet18(images)

username: ML0401
cooked: <p>Sorry, for bothering you again.</p>
<p>I am trying to train a resnet18 model to classify images into three different classes. Therefore, I wrote a class train_one_epoch. I would like to calculate the accuracy of the training during one epoch, so I wrote a class accuracy, too. I know, that this kind of accuracy class only siuts binary classifications. The images I feed the netowrk with are in RGB and 350x350. However, I was wondering, why the size of my outputs is [8, 1000] after passing the images to the network. Shouldn’t it be [8, 3]. Afterwards I could<br>
use the maximum as predicted class or am I missing something essential?</p>
<p>Any help is appreciated.</p>
<pre><code class="lang-auto"># device configuration, use cuda if possible
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# define hyper-parameters
num_epochs = 10
learning_rate = 0.001
batchsize = 8

resnet18 = models.resnet18()
resnet18.fc.out_features = 3
# print(resnet18)
resnet18.to(device)

...

def accuracy(outputs, trues):
    
    ### Converting preds to 0 or 1
    outputs = [1 if outputs[i] &gt;= 0.5 else 0 for i in range(len(outputs))]
    print(outputs)
    
    ### Calculating accuracy by comparing predictions with true labels
    acc = [1 if outputs[i] == trues[i] else 0 for i in range(len(outputs))]
    
    ### Summing over all correct predictions
    acc = np.sum(acc) / len(outputs)
    
    return (acc * 100)


# train the model with the help of a for-loop
total_step = len(train_data_loader)
curr_lr = learning_rate

def train_one_epoch(train_data_loader):
    epoch_loss = []
    epoch_acc = []
    start_time = time.time()
    
    for images, labels in train_data_loader:
        images = images.to(device)
        labels = labels.to(device)

        # forward pass
        optimizer.zero_grad()
        outputs = resnet18(images)
        print(outputs.size())
        print(labels.size())
        
        # calculating accuracy and loss
        _loss = criterion(outputs, labels)
        loss = _loss.item()
        epoch_loss.append(loss)
        acc = accuracy(outputs, labels)
        epoch_acc.append(acc)

        # backward and optimize
        _loss.backward()
        optimizer.step()
        
    end_time = time.time()
    total_time = end_time - start_time
    
    ###Acc and Loss
    epoch_loss = np.mean(epoch_loss)
    epoch_acc = np.mean(epoch_acc)
    
    ###Storing results to logs
    train_logs["loss"].append(epoch_loss)
    train_logs["accuracy"].append(epoch_acc)
    train_logs["time"].append(total_time)
    
    return epoch_loss, epoch_acc, total_time
</code></pre>

username: ptrblck
cooked: <p>Changing the <code>out_features</code> of an already initialized module won’t work:</p>
<pre><code class="lang-python">resnet18.fc.out_features = 3
</code></pre>
<p>since the internal parameters were already created.<br>
You should create a new <code>nn.Linear</code> module and assign it to the <code>.fc</code> attribute:</p>
<pre><code class="lang-python">model = models.resnet18()
mdoel.fc = nn.Linear(512, 3)
</code></pre>

username: ML0401
cooked: <p>Thanks ptrblack, but when I add the lines you proposed, I get another error message during the calculation of the loss and backwarding it:</p>
<blockquote>
<p>RuntimeError: cuda runtime error (710) : device-side assert triggered at C:/cb/pytorch_1000000000000/work/aten/src\THC/generic/THCTensorMath.cu:29</p>
</blockquote>
<p>After that, if I try to run the code again, I alawys get the following error message:</p>
<blockquote>
<p>RuntimeError: CUDA error: device-side assert triggered</p>
</blockquote>
<p>This one is raised with passing the model to cuda, quiet in the beginning of the code.</p>
<p>EDIT:</p>
<p>I solved this error by substracting 1 to each label:<br>
labels = labels - 1<br>
The indexing of the labels should start with 0 and end with the number of classes - 1. Is this correct?</p>

username: ptrblck
cooked: <aside class="quote no-group" data-username="ML0401" data-post="3" data-topic="88674">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ml0401/48/26497_2.png" class="avatar"> ML0401:</div>
<blockquote>
<p>The indexing of the labels should start with 0 and end with the number of classes - 1. Is this correct?</p>
</blockquote>
</aside>
<p>Yes, <code>nn.CrossEntropyLoss</code> as well as <code>nn.NLLLoss</code> expects the target tensor to be a <code>LongTensor</code> containing the class indices in the range <code>[0, nb_classes-1]</code>. <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>