Accuracies doesnt get better . Is my model even training?

username: Dr_Aniket_Singha
cooked: <p>My model is an emotion predictor for 7 classes. The model seems to be working fine. But it isnt learning. What could be the problem?<br>
My training and valid functions.</p>
<pre><code class="lang-auto">import torch.optim as optim
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=0.0, betas=(0.9, 0.98), eps=1e-9)
criterion = nn.CrossEntropyLoss()
def train(train_dataloader,epoch):
    running_loss = 0.0
    correct=0
    total=0
    train_loss_list=[]
    model.train()
    for i, data in enumerate(train_dataloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data
        inputs.requires_grad = True
        # zero the parameter gradients
        optimizer.zero_grad()
        labels = torch.argmax(labels,dim =1)
        # forward + backward + optimize
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        train_loss_list.append(loss.item())
        total += labels.size(0)
        _, predicted = torch.max(outputs.data, 1)
        correct += (predicted == labels).sum().item()
        mean_loss = np.mean(np.asarray(train_loss_list))
#         if i%100==0:
#             print('Iteration - {} Epoch - {} Total training loss - {}'.format(i,epoch,mean_loss))
    print("train accuracy after epoch " +str(epoch) +" is " + str(100 * correct / total))
            
def validation(valid_dataloader,epoch):
    model.eval()
    with torch.no_grad():
        val_loss_list=[]
        correct = 0
        total = 0
        for i, data in enumerate(valid_dataloader, 0):
            inputs, labels = data
            labels = torch.argmax(labels,dim =1)
            outputs = model(inputs)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
            loss = criterion(outputs, labels)
            val_loss_list.append(loss.item())
#             if i%100==0:
#                 print('Iteration - {} Epoch - {} Loss - {}'.format(i,epoch,np.mean(np.asarray(val_loss_list))))
        print("valid accuracy after epoch "+str(epoch) +" is " + str(100 * correct / total))        
        mean_loss = np.mean(np.asarray(val_loss_list))
#         print('Total validation loss {} after {} epochs'.format(mean_loss,epoch))
        model_save_path = os.path.join( 'best_check_point_'+str(epoch)+'_'+str(mean_loss))
        state_dict = {'model': model.state_dict(),'optimizer': optimizer.state_dict(),'epoch': epoch}
        torch.save(state_dict, model_save_path)

</code></pre>
<pre><code class="lang-auto">for epoch in range(100):
    train(train_dataloader,epoch)
    validation(val_dataloader,epoch)
</code></pre>
<p>This is my output:</p>
<p>train accuracy after epoch 0 is 55.35390199637023<br>
valid accuracy after epoch 0 is 33.05322128851541<br>
train accuracy after epoch 1 is 56.152450090744104<br>
valid accuracy after epoch 1 is 24.089635854341736<br>
train accuracy after epoch 2 is 56.91470054446461<br>
valid accuracy after epoch 2 is 32.212885154061624<br>
train accuracy after epoch 3 is 56.8421052631579<br>
valid accuracy after epoch 3 is 22.689075630252102<br>
train accuracy after epoch 4 is 57.168784029038115<br>
valid accuracy after epoch 4 is 22.689075630252102<br>
train accuracy after epoch 5 is 57.53176043557169<br>
valid accuracy after epoch 5 is 21.568627450980394<br>
train accuracy after epoch 6 is 57.313974591651544<br>
valid accuracy after epoch 6 is 21.288515406162464<br>
train accuracy after epoch 7 is 58.87477313974592<br>
valid accuracy after epoch 7 is 36.97478991596638<br>
train accuracy after epoch 8 is 56.95099818511797<br>
valid accuracy after epoch 8 is 31.092436974789916<br>
train accuracy after epoch 9 is 55.82577132486389<br>
valid accuracy after epoch 9 is 26.050420168067227<br>
train accuracy after epoch 10 is 56.95099818511797<br>
valid accuracy after epoch 10 is 26.050420168067227<br>
train accuracy after epoch 11 is 57.3502722323049<br>
valid accuracy after epoch 11 is 21.288515406162464<br>
train accuracy after epoch 12 is 58.22141560798548<br>
valid accuracy after epoch 12 is 21.008403361344538<br>
train accuracy after epoch 13 is 56.62431941923775<br>
valid accuracy after epoch 13 is 21.84873949579832<br>
train accuracy after epoch 14 is 57.168784029038115<br>
valid accuracy after epoch 14 is 26.89075630252101<br>
train accuracy after epoch 15 is 57.45916515426497<br>
valid accuracy after epoch 15 is 21.84873949579832<br>
train accuracy after epoch 16 is 56.261343012704174<br>
valid accuracy after epoch 16 is 28.571428571428573<br>
train accuracy after epoch 17 is 57.93103448275862<br>
valid accuracy after epoch 17 is 21.568627450980394<br>
train accuracy after epoch 18 is 58.00362976406534<br>
valid accuracy after epoch 18 is 19.327731092436974<br>
train accuracy after epoch 19 is 56.33393829401089<br>
valid accuracy after epoch 19 is 19.88795518207283<br>
train accuracy after epoch 20 is 57.3502722323049<br>
valid accuracy after epoch 20 is 19.327731092436974</p>
<p>Model:</p>
<pre><code class="lang-auto">import torch.nn as nn
import torch.nn.functional as F

class TDNN(nn.Module):
    
    def __init__(
                    self, 
                    input_dim=23, 
                    output_dim=512,
                    context_size=5,
                    stride=1,
                    dilation=1,
                    batch_norm=False,
                    dropout_p=0.2
                ):
        super(TDNN, self).__init__()
        self.context_size = context_size
        self.stride = stride
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.dilation = dilation
        self.dropout_p = dropout_p
        self.batch_norm = batch_norm
      
        self.kernel = nn.Linear(input_dim*context_size, output_dim)
        self.nonlinearity = nn.ReLU()
        if self.batch_norm:
            self.bn = nn.BatchNorm1d(output_dim)
        if self.dropout_p:
            self.drop = nn.Dropout(p=self.dropout_p)
        
    def forward(self, x):
        
        
        _, _, d = x.shape
        assert (d == self.input_dim), 'Input dimension was wrong. Expected ({}), got ({})'.format(self.input_dim, d)
        x = x.unsqueeze(1)

        # Unfold input into smaller temporal contexts
        x = F.unfold(
                        x, 
                        (self.context_size, self.input_dim), 
                        stride=(1,self.input_dim), 
                        dilation=(self.dilation,1)
                    )

        # N, output_dim*context_size, new_t = x.shape
        x = x.transpose(1,2)
        x = self.kernel(x.float())
        x = self.nonlinearity(x)
        
        if self.dropout_p:
            x = self.drop(x)

        if self.batch_norm:
            x = x.transpose(1,2)
            x = self.bn(x)
            x = x.transpose(1,2)

        return x
import torch.nn as nn
# from models.tdnn import TDNN
import torch
import torch.nn.functional as F

class X_vector(nn.Module):
    def __init__(self, input_dim = 20, num_classes=7):
        super(X_vector, self).__init__()
        self.tdnn1 = TDNN(input_dim=input_dim, output_dim=512, context_size=5, dilation=1,dropout_p=0.5)
        self.tdnn2 = TDNN(input_dim=512, output_dim=512, context_size=3, dilation=1,dropout_p=0.5)
        self.tdnn3 = TDNN(input_dim=512, output_dim=512, context_size=2, dilation=2,dropout_p=0.5)
        self.tdnn4 = TDNN(input_dim=512, output_dim=512, context_size=1, dilation=1,dropout_p=0.5)
        self.tdnn5 = TDNN(input_dim=512, output_dim=512, context_size=1, dilation=3,dropout_p=0.5)
        #### Frame levelPooling
        self.segment6 = nn.Linear(1024, 512)
        self.segment7 = nn.Linear(512, 512)
        self.output = nn.Linear(512, num_classes)
#         self.softmax = nn.Softmax(dim=1)
    def forward(self, inputs):
        tdnn1_out = self.tdnn1(inputs)
#         return tdnn1_out
        tdnn2_out = self.tdnn2(tdnn1_out)
        tdnn3_out = self.tdnn3(tdnn2_out)
        tdnn4_out = self.tdnn4(tdnn3_out)
        tdnn5_out = self.tdnn5(tdnn4_out)
        ### Stat Pool
        mean = torch.mean(tdnn5_out,1)
        std = torch.std(tdnn5_out,1)
        stat_pooling = torch.cat((mean,std),1)
        segment6_out = self.segment6(stat_pooling)
        x_vec = self.segment7(segment6_out)
        predictions = self.output(x_vec)
        return predictions
</code></pre>
<pre><code class="lang-auto">input_feats = [4,100,20]
input = torch.rand(input_feats)
model = X_vector()
out = model(input)
print(out)
</code></pre>
<p>tensor([[ 0.0170, -0.0404, -0.0174, -0.0133,  0.0375,  0.0010,  0.0251],<br>
[ 0.0170, -0.0417, -0.0166, -0.0157,  0.0377, -0.0012,  0.0280],<br>
[ 0.0174, -0.0404, -0.0149, -0.0133,  0.0371, -0.0003,  0.0263],<br>
[ 0.0173, -0.0411, -0.0154, -0.0155,  0.0387, -0.0016,  0.0273]],<br>
grad_fn=)</p>