0

我在 CNN+LSTM 编码器和解码器模型中训练了不同数量的层,并注意。我面临的问题对我来说很奇怪。验证损失在 3.*** 左右波动。从下面的损失图中我们可以看出。我在编码器有3 个 CNN 层 + 1 层 BLSTM,在解码器有 1 个 LSTM

3层CNN+2层BLSTM编码器和1层LSTM编码器

我还尝试了从 0.1 到 0.000001 的重量衰减。但我仍然得到这种类型的损失图。请注意,模型的准确性在验证和训练集上都在增加。验证损失怎么可能仍然在 3 左右,但准确性却在提高?有人可以解释一下吗?

谢谢`类编码器(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

类解码器(nn.Module):def init(self,output_dim,emb_dim,enc_hid_dim,dec_hid_dim,dropout,attention):super()。初始化()

    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)

`

4

0 回答 0