Почему я получаю разные результаты после сохранения и загрузки весов моделей в pytorch? - PullRequest
0 голосов
/ 29 апреля 2019

Я написал модель, архитектура выглядит следующим образом:

CNNLSTM(                                                                                                                                                                                  
  (cnn): CNNText(                                                                                                                                                                         
    (embed): Embedding(19410, 300, padding_idx=0)                                                                                                                                         
    (convs1): ModuleList(                                                                                                                                                                 
      (0): Conv2d(1, 32, kernel_size=(3, 300), stride=(1, 1))                                                                                                                             
      (1): Conv2d(1, 32, kernel_size=(5, 300), stride=(1, 1))                                                                                                                             
      (2): Conv2d(1, 32, kernel_size=(7, 300), stride=(1, 1))                                                                                                                             
    )                                                                                                                                                                                     
    (dropout): Dropout(p=0.6)                                                                                                                                                             
    (fc1): Linear(in_features=96, out_features=1, bias=True)                                                                                                                              
  )                                                                                                                                                                                       
  (lstm): RNN(                                                                                                                                                                        
    (embedding): Embedding(19410, 300, padding_idx=0)                                                                                                                                     
    (rnn): LSTM(300, 150, batch_first=True, bidirectional=True)                                                                                                                           
    (attention): Attention(                                                                                                                                                               
      (dense): Linear(in_features=300, out_features=1, bias=True)                                                                                                                         
      (tanh): Tanh()                                                                                                                                                                      
      (softmax): Softmax()                                                                                                                                                                
    )                                                                                                                                                                                     
    (fc1): Linear(in_features=300, out_features=50, bias=True)                                                                                                                            
    (dropout): Dropout(p=0.5)                                                                                                                                                             
    (fc2): Linear(in_features=50, out_features=1, bias=True)                                                                                                                              
  )                                                                                                                                                                                       
  (fc1): Linear(in_features=146, out_features=1, bias=True)                                                                                                                               
)

Я использовал RNN и CNN по-разному в одном наборе данных, и у меня сохранены веса. В смешанной модели я загружаю веса, используя следующую функцию:

def load_pretrained_weights(self, model='cnn', path=None):
    if model not in ['cnn', 'rnn']:
        raise AttributeError("Model must be either rnn or cnn")
    if model == 'cnn':
        self.cnn.load_state_dict(torch.load(path))
    if model == 'rnn':
        self.lstm.load_state_dict(torch.load(path))

И заморозить субмодули с помощью функции:

def freeze(self):    
    for p in self.cnn.parameters():
        p.requires_grad = False
    for p in self.lstm.parameters():
        p.requires_grad = False

Затем я тренирую модель и получаю лучший результат по сравнению с каждым обученным субмодулем и оценивается в одиночку. Я использовал технику ранней остановки в цикле своей эпохи, чтобы сохранить лучшие параметры. После обучения я сделал новый экземпляр того же класса, и когда я загружаю сохраненные «лучшие» параметры, я не получаю аналогичного результата. Я попробовал то же самое с каждым подмодулем (здесь RNN и CNNText), это сработало. Но в этом случае он не дает такой же производительности.

Пожалуйста, помогите мне понять, что здесь происходит. Я новичок в концепции глубокого обучения. Спасибо.

Несколько экспериментов, которые я пробовал:

  1. Я загрузил сохраненные веса каждого подмодуля и загрузил лучшие параметры, как-то приблизился к лучшему результату.
  2. Взял скрытый слой из каждого подмодуля перед применением выпадения, стал лучше, чем предыдущий, но не самый лучший!

EDIT

Функция init моего класса выглядит следующим образом. И RNN и CNN - просто обычные реализации.

class CNNLSTM(nn.Module):

    def __init__(self, vocab_size, embedding_dim, embedding_weight, rnn_arch, isCuda=True, class_num=1, kernel_num=32, kernel_sizes=[3,4,5],train_wv=False, rnn_num_layers=1, rnn_bidirectional=True, rnn_use_attention=True):

        super(CNNLSTM, self).__init__()
        self.cnn = CNNText(vocab_size, embedding_dim, embedding_weight, class_num, kernel_num = kernel_num, kernel_sizes=kernel_sizes, static=train_wv,dropout=0.6)
        self.lstm = RNN(rnn_arch, vocab_size, embedding_dim, embedding_weight, num_layers=rnn_num_layers, rnn_unit='lstm', embedding_train=train_wv, isCuda=isCuda, bidirectional=rnn_bidirectional, use_padding=True, use_attention=rnn_use_attention, num_class=class_num)
        self.fc1 = nn.Linear(rnn_arch[-1] + len(kernel_sizes) * kernel_num , class_num)

После объявления объекта

Загружен индивидуальный предварительно обученный субмодуль как,

model.load_pretrained_weights('rnn', 'models/bilstm_2_atten.pth')
model.load_pretrained_weights('cnn', 'models/cnn2.pth')

model.freeze()

Затем я тренирую последний линейный слой. Я сохранил значения параметров модели как

torch.save(model.state_dict(),path)

Таким образом, на 3/4-й от прошлой эпохи я получаю «лучший» результат. И после тренировки я загрузил параметры для лучшего результата с

state_dict = torch.load(MODEL_PATH)
model.load_state_dict(state_dict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...