0

I have trained different number of layers in CNN+LSTM encoder and decoder model with attention. The problem I am facing is very strange to me. The validation loss is fluctuating around 3.***. As we can see from the below loss graphs. I have 3 CNN layer+1 layer BLSTM at encoder and 1 LSTM at decoder

3 layer CNN+2 layers of BLSTM at encoder and 1 layer LSTM at encoder

I have also tried weight decay from 0.1 to 0.000001. But still I am getting this type of loss graphs. Note that the Accuracy of the model is increasing on both validation and trainset. How is it possible that validation loss is still around 3 but accuracy is increasing? Can someone explain this?

Thanks ` class Encoder(nn.Module): def init(self,height, width, enc_hid_dim, dec_hid_dim, dropout): super().init() self.height= height self.enc_hid_dim=enc_hid_dim self.width=width

    self.layer0 = nn.Sequential(
            nn.Conv2d(1, 8, kernel_size=(3,3),stride =(1,1), padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(8),
            nn.MaxPool2d(2,2),
            )
    self.layer1 = nn.Sequential(
            nn.Conv2d(8, 32, kernel_size=(3,3),stride =(1,1), padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(32),
            nn.MaxPool2d(2,2),
            )
    self.layer2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=(3,3),stride =(1,1), padding=1),
            nn.ReLU(),
            nn.BatchNorm2d(64),
            nn.MaxPool2d(2,2)
            )

    self.rnn = nn.LSTM(self.height//8*64, self.enc_hid_dim, bidirectional=True)
    
    self.fc = nn.Linear(enc_hid_dim * 2, dec_hid_dim)
    
    self.dropout = nn.Dropout(dropout)
    self.cnn_dropout = nn.Dropout(p=0.2)
    
def forward(self, src, in_data_len, train):
    batch_size = src.shape[0]
    out = self.layer0(src)
    out = self.layer1(out)
    out = self.layer2(out)
    out = self.dropout(out) # torch.Size([batch, channel, h, w])
    out = out.permute(3, 0, 2, 1) # (width, batch, height, channels)
    out.contiguous()
    out = out.reshape(-1, batch_size, self.height//8*64) #(w,batch, (height, channels)) 
   
    width = out.shape[0] 
    src_len = in_data_len.numpy()*(width/self.width) 
    src_len = src_len + 0.999 # in case of 0 length value from float to int
    src_len = src_len.astype('int')
    out = pack_padded_sequence(out, src_len.tolist(), batch_first=False)
    outputs, hidden_out = self.rnn(out)
    hidden=hidden_out[0]
    cell=hidden_out[1]
    # output: t, b, f*2  hidden: 2, b, f
    outputs, output_len = pad_packed_sequence(outputs, batch_first=False)

    hidden = torch.tanh(self.fc(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim = 1)))
    cell = torch.tanh(self.fc(torch.cat((cell[-2,:,:], cell[-1,:,:]), dim = 1)))
    
    return outputs, hidden, cell, output_len

class Decoder(nn.Module): def init(self, output_dim, emb_dim, enc_hid_dim, dec_hid_dim, dropout, attention): super().init()

    self.output_dim = output_dim
    self.attention = attention
    
    self.embedding = nn.Embedding(output_dim, emb_dim)
    
    self.rnn = nn.LSTM((enc_hid_dim * 2) + emb_dim, dec_hid_dim)
    
    self.fc_out = nn.Linear((enc_hid_dim * 2) + dec_hid_dim + emb_dim, output_dim)
    
    self.dropout_layer = nn.Dropout(dropout)
    
    
def forward(self, input, hidden, cell, encoder_outputs, train):
     
    input=torch.topk(input,1)[1] 
    
    embedded = self.embedding(input)
    if train:
        embedded=self.dropout_layer(embedded)
    embedded = embedded.permute(1, 0, 2)
    
    #embedded = [1, batch size, emb dim]
    
    a = self.attention(hidden, encoder_outputs)
            
    #a = [batch size, src len]
    
    a = a.unsqueeze(1)
    
    #a = [batch size, 1, src len]
    
    encoder_outputs = encoder_outputs.permute(1, 0, 2)
    
    #encoder_outputs = [batch size, src len, enc hid dim * 2]
    
    weighted = torch.bmm(a, encoder_outputs)
    
    weighted = weighted.permute(1, 0, 2)
    
    #weighted = [1, batch size, enc hid dim * 2]
    
    rnn_input = torch.cat((embedded, weighted), dim = 2)
    
    output, hidden_out = self.rnn(rnn_input (hidden.unsqueeze(0),cell.unsqueeze(0)))
    hidden=hidden_out[0]
    cell=hidden_out[1]
    
    assert (output == hidden).all()
    
    embedded = embedded.squeeze(0)
    output = output.squeeze(0)
    weighted = weighted.squeeze(0)
    
    prediction = self.fc_out(torch.cat((output, weighted, embedded), dim = 1))
    
    return prediction, hidden.squeeze(0), cell.squeeze(0)

`

Hikmah
  • 1
  • 1

0 Answers0